unsigned int fmi1_xml_get_unit_definitions_number(fmi1_xml_unit_definitions_t* ud) { if(!ud) { assert(ud && "Unit definitions cannot be NULL"); return 0; } return (unsigned int)jm_vector_get_size(jm_named_ptr)(&ud->definitions); }
unsigned int fmi1_xml_get_number_of_vendors(fmi1_xml_vendor_list_t* vl) { if(!vl) { assert(vl && "Vendor list cannot be NULL"); return 0; } return (unsigned int)jm_vector_get_size(jm_voidp)(&vl->vendors); }
fmi1_xml_vendor_t* fmi1_xml_get_vendor(fmi1_xml_vendor_list_t* v, unsigned int index) { jm_vector(jm_voidp)* vl; if(!v) { assert(v && "Vendor list cannot be NULL"); return 0; } vl = &v->vendors; if(index >= jm_vector_get_size(jm_voidp)(vl)) return 0; return (fmi1_xml_vendor_t*)jm_vector_get_item(jm_voidp)(vl, index); }
void fmi2_xml_zero_empty_dependencies(fmi2_xml_dependencies_t** pdep) { fmi2_xml_dependencies_t* dep =*pdep; size_t ndep = jm_vector_get_size(size_t)(&dep->dependencyIndex); size_t i; if(!dep) return; for(i = 0; i<ndep;i++) { if(jm_vector_get_item(size_t)(&dep->dependencyIndex, i)) break; } if(i == ndep) { fmi2_xml_free_dependencies(dep); *pdep = 0; } }
int fmi2_xml_handle_Derivatives(fmi2_xml_parser_context_t *context, const char* data) { if (!data) { jm_log_verbose(context->callbacks, module, "Parsing XML element Derivatives"); /* reset handles for the elements that are specific under Derivatives */ fmi2_xml_set_element_handle(context, "Unknown", FMI2_XML_ELM_ID(DerivativeUnknown)); } else { fmi2_xml_model_description_t* md = context->modelDescription; fmi2_xml_model_structure_t* ms = md->modelStructure; /* count the number of continuous states as the number of <Unknown> elements under <Derivatives> */ md->numberOfContinuousStates = jm_vector_get_size(jm_voidp)(&ms->derivatives); } return 0; }
void fmi2_xml_get_dependencies(fmi2_xml_dependencies_t* dep, size_t** startIndex, size_t** dependency, char** factorKind){ if(dep) { if (jm_vector_get_size(size_t)(&dep->dependencyIndex) == 0) { *startIndex = NULL; *dependency = NULL; *factorKind = NULL; } else { *startIndex = jm_vector_get_itemp(size_t)(&dep->startIndex, 0); *dependency = jm_vector_get_itemp(size_t)(&dep->dependencyIndex, 0); *factorKind = jm_vector_get_itemp(char)(&dep->dependencyFactorKind, 0); } } else { *startIndex = 0; } }
/* Get the list of all the variables in the model in alphabetical order */ fmi1_import_variable_list_t* fmi1_import_get_variable_list_alphabetical_order(fmi1_import_t* fmu) { jm_vector(jm_named_ptr)* vars; fmi1_import_variable_list_t* vl; size_t nv, i; if(!fmu->md) { jm_log_error(fmu->callbacks, module,"No FMU is loaded"); return 0; } vars = fmi1_xml_get_variables_alphabetical_order(fmu->md); nv = jm_vector_get_size(jm_named_ptr)(vars); vl = fmi1_import_alloc_variable_list(fmu, nv); if(!vl) return 0; for(i = 0; i< nv; i++) { jm_vector_set_item(jm_voidp)(&vl->variables, i, jm_vector_get_item(jm_named_ptr)(vars, i).ptr); } return vl; }
int fmi1_xml_handle_Annotation(fmi1_xml_parser_context_t *context, const char* data) { if(!data) { fmi1_xml_model_description_t* md = context->modelDescription; size_t numVendors = jm_vector_get_size(jm_voidp)(&(md->vendorList)); fmi1_xml_vendor_t* vendor =(fmi1_xml_vendor_t*)jm_vector_get_item(jm_voidp)(&(md->vendorList), numVendors-1); jm_vector(char)* bufName = fmi1_xml_reserve_parse_buffer(context,1,100); jm_vector(char)* bufValue = fmi1_xml_reserve_parse_buffer(context,2,100); jm_named_ptr named, *pnamed; fmi1_xml_annotation_t* annotation = 0; size_t vallen; if(!bufName || !bufValue || /* <xs:attribute name="name" type="xs:normalizedString" use="required"/> */ fmi1_xml_set_attr_string(context, fmi1_xml_elmID_Annotation, fmi_attr_id_name, 1, bufName) || /* <xs:attribute name="value" type="xs:string" use="required"/> */ fmi1_xml_set_attr_string(context, fmi1_xml_elmID_Annotation, fmi_attr_id_value, 1, bufValue) ) return -1; vallen = jm_vector_get_size(char)(bufValue); named.ptr = 0; named.name = 0; pnamed = jm_vector_push_back(jm_named_ptr)(&vendor->annotations, named); if(pnamed) *pnamed = named = jm_named_alloc_v(bufName,sizeof(fmi1_xml_annotation_t)+vallen+1,sizeof(fmi1_xml_annotation_t)+vallen,context->callbacks); annotation = named.ptr; if( !pnamed || !annotation ) { fmi1_xml_parse_fatal(context, "Could not allocate memory"); return -1; } annotation->name = named.name; if(vallen) memcpy(annotation->value,jm_vector_get_itemp(char)(bufValue,0), vallen); annotation->value[vallen] = 0; } else { /* don't do anything. might give out a warning if(data[0] != 0) */ return 0; } return 0; }
unsigned int fmi1_xml_get_number_of_vendor_annotations(fmi1_xml_vendor_t* v) { return (unsigned int)jm_vector_get_size(jm_named_ptr)(&v->annotations); }
key.aliasKind = fmi1_variable_is_not_alias; found = jm_vector_bsearch(jm_voidp)(md->variablesByVR,(void**)&pkey, fmi1_xml_compare_vr); assert(found); base = *found; return base; } /* Return the list of all the variables aliased to the given one (including the base one. The list is ordered: base variable, aliases, negated aliases. */ jm_status_enu_t fmi1_xml_get_variable_aliases(fmi1_xml_model_description_t* md,fmi1_xml_variable_t* v, jm_vector(jm_voidp)* list) { fmi1_xml_variable_t key, *cur; fmi1_value_reference_t vr = fmi1_xml_get_variable_vr(v); size_t baseIndex, i, num = jm_vector_get_size(jm_voidp)(md->variablesByVR); key = *v; key.aliasKind = 0; cur = &key; baseIndex = jm_vector_bsearch_index(jm_voidp)(md->variablesByVR,(void**)&cur, fmi1_xml_compare_vr); cur = (fmi1_xml_variable_t*)jm_vector_get_item(jm_voidp)(md->variablesByVR, baseIndex); assert(cur); i = baseIndex + 1; while(fmi1_xml_get_variable_vr(cur) == vr) { if(!jm_vector_push_back(jm_voidp)(list, cur)) { jm_log_fatal(md->callbacks,module,"Could not allocate memory"); return jm_status_error; }; if(i >= num) break; cur = (fmi1_xml_variable_t*)jm_vector_get_item(jm_voidp)(md->variablesByVR, i); assert(cur);
int fmi2_xml_parse_dependencies(fmi2_xml_parser_context_t *context, fmi2_xml_elm_enu_t parentElmID, fmi2_xml_dependencies_t* deps) { fmi2_xml_model_description_t* md = context->modelDescription; fmi2_xml_model_structure_t* ms = md->modelStructure; const char* listInd; const char* listKind; size_t numDepInd = 0; size_t numDepKind = 0; size_t totNumDep = jm_vector_get_size(size_t)(&deps->dependencyIndex); /* <xs:attribute name="dependencies"> <xs:simpleType> <xs:list itemType="xs:unsignedInt"/> </xs:simpleType> </xs:attribute> */ if(fmi2_xml_get_attr_str(context, fmi2_xml_elmID_Unknown, fmi_attr_id_dependencies, 0, &listInd)) { ms->isValidFlag = 0; return 0; } if(listInd) { const char* cur = listInd; int ind; while(*cur) { char ch = *cur; while((ch ==' ') || (ch == '\t') || (ch =='\n') || (ch == '\r')) { cur++; ch = *cur; if(!ch) break; } if(!ch) break; if(sscanf(cur, "%d", &ind) != 1) { fmi2_xml_parse_error(context, "XML element 'Unknown': could not parse item %d in the list for attribute 'dependencies'", numDepInd); ms->isValidFlag = 0; return 0; } if(ind < 1) { fmi2_xml_parse_error(context, "XML element 'Unknown': item %d=%d is less than one in the list for attribute 'dependencies'", numDepInd, ind); ms->isValidFlag = 0; return 0; } if(!jm_vector_push_back(size_t)(&deps->dependencyIndex, (size_t)ind)) { fmi2_xml_parse_fatal(context, "Could not allocate memory"); return -1; } while((*cur >= '0') && (*cur <= '9')) cur++; numDepInd++; } } /* <xs:attribute name="dependenciesKind"> <xs:simpleType> <xs:list> <xs:simpleType> <xs:restriction base="xs:normalizedString"> <xs:enumeration value="dependent"/> <xs:enumeration value="constant"/> <xs:enumeration value="fixed"/> <xs:enumeration value="tunable"/> <xs:enumeration value="discrete"/> </xs:restriction> </xs:simpleType> </xs:list> </xs:simpleType> </xs:attribute> */ if(fmi2_xml_get_attr_str(context, fmi2_xml_elmID_Unknown, fmi_attr_id_dependenciesKind, 0, &listKind)) { ms->isValidFlag = 0; return 0; } if(listKind) { const char* cur = listKind; char kind; while(*cur) { char ch = *cur; while(ch && ((ch ==' ') || (ch == '\t') || (ch =='\n') || (ch == '\r'))) { cur++; ch = *cur; } if(!ch) break; if(strncmp("dependent", cur, 9) == 0) { kind = fmi2_dependency_factor_kind_dependent; cur+=9; } else if(strncmp("constant", cur, 8) == 0) { kind = fmi2_dependency_factor_kind_constant; cur+=8; } else if(strncmp("fixed", cur, 5) == 0) { kind = fmi2_dependency_factor_kind_fixed; cur+=5; } else if(strncmp("tunable", cur, 7) == 0) { kind = fmi2_dependency_factor_kind_tunable; cur+=7; } else if(strncmp("discrete", cur, 8) == 0) { kind = fmi2_dependency_factor_kind_discrete; cur+=8; } else { fmi2_xml_parse_error(context, "XML element 'Unknown': could not parse item %d in the list for attribute 'dependenciesKind'", numDepKind); ms->isValidFlag = 0; return 0; } if (parentElmID == fmi2_xml_elmID_InitialUnknowns) { if (kind == fmi2_dependency_factor_kind_fixed) { fmi2_xml_parse_error(context, "XML element 'Unknown' within 'InitialUnknowns': 'fixed' is not allowed in list for attribute 'dependenciesKind'; setting to 'dependent'"); kind = fmi2_dependency_factor_kind_dependent; } else if (!(kind == fmi2_dependency_factor_kind_dependent || kind == fmi2_dependency_factor_kind_constant)) { fmi2_xml_parse_error(context, "XML element 'Unknown' within 'InitialUnknowns': only 'dependent' and 'constant' allowed in list for attribute 'dependenciesKind'"); ms->isValidFlag = 0; return 0; } } if(!jm_vector_push_back(char)(&deps->dependencyFactorKind, kind)) { fmi2_xml_parse_fatal(context, "Could not allocate memory"); return -1; } numDepKind++; } } if(listInd && listKind) { /* both lists are present - the number of items must match */ if(numDepInd != numDepKind) { fmi2_xml_parse_error(context, "XML element 'Unknown': different number of items (%u and %u) in the lists for 'dependencies' and 'dependenciesKind'", numDepInd, numDepKind); ms->isValidFlag = 0; return 0; } } else if(listInd) { /* only Dependencies are present, set all kinds to dependent */ char kind = fmi2_dependency_factor_kind_dependent; if(jm_vector_reserve(char)(&deps->dependencyFactorKind,totNumDep + numDepInd) < totNumDep + numDepInd) { fmi2_xml_parse_fatal(context, "Could not allocate memory"); return -1; } for(;numDepKind < numDepInd; numDepKind++) jm_vector_push_back(char)(&deps->dependencyFactorKind, kind); } else if(listKind) { fmi2_xml_parse_error(context, "XML element 'Unknown': if `dependenciesKind` attribute is present then the `dependencies` attribute must be present also."); ms->isValidFlag = 0; return 0; } else { /* Dependencies are not provided. Put zero index/dependent to indicate that full row must be considered. */ numDepInd = numDepKind = 1; if(!jm_vector_push_back(char)(&deps->dependencyFactorKind, fmi2_dependency_factor_kind_dependent) || !jm_vector_push_back(size_t)(&deps->dependencyIndex, 0) ) { fmi2_xml_parse_fatal(context, "Could not allocate memory"); return -1; } } if(!jm_vector_push_back(size_t)(&deps->startIndex, totNumDep + numDepInd)) { fmi2_xml_parse_fatal(context, "Could not allocate memory"); return -1; } return 0; }
/** \brief Collect model information by counting the number of variables with specific properties and fillinf in fmi1_import_model_counts_t struct. \param fmu - An fmu object as returned by fmi1_import_parse_xml(). \param counts - a pointer to a preallocated struct. */ void fmi1_import_collect_model_counts(fmi1_import_t* fmu, fmi1_import_model_counts_t* counts) { jm_vector(jm_voidp)* vars = fmi1_xml_get_variables_original_order(fmu->md); size_t nv, i; memset(counts,0,sizeof(fmi1_import_model_counts_t)); if(!vars) return; nv = jm_vector_get_size(jm_voidp)(vars); for(i = 0; i< nv; i++) { fmi1_xml_variable_t* var = (fmi1_xml_variable_t*)jm_vector_get_item(jm_voidp)(vars, i); switch (fmi1_xml_get_variability(var)) { case fmi1_variability_enu_constant: counts->num_constants++; break; case fmi1_variability_enu_parameter: counts->num_parameters++; break; case fmi1_variability_enu_discrete: counts->num_discrete++; break; case fmi1_variability_enu_continuous: counts->num_continuous++; break; default: assert(0); } switch(fmi1_xml_get_causality(var)) { case fmi1_causality_enu_none: counts->num_causality_none++; break; case fmi1_causality_enu_input: counts->num_inputs++; break; case fmi1_causality_enu_output: counts->num_outputs++; break; case fmi1_causality_enu_internal: counts->num_internal++; break; default: assert(0); } switch(fmi1_xml_get_variable_base_type(var)) { case fmi1_base_type_real: counts->num_real_vars++; break; case fmi1_base_type_int: counts->num_integer_vars++; break; case fmi1_base_type_bool: counts->num_bool_vars++; break; case fmi1_base_type_str: counts->num_string_vars++; break; case fmi1_base_type_enum: counts->num_enum_vars++; break; default: assert(0); } } return; }
void fmi1_log_forwarding_v(fmi1_component_t c, fmi1_string_t instanceName, fmi1_status_t status, fmi1_string_t category, fmi1_string_t message, va_list args) { char buf[50000], *curp; const char* statusStr; fmi1_import_t* fmu = 0; jm_callbacks* cb = jm_get_default_callbacks(); jm_log_level_enu_t logLevel = jm_log_level_error; if(fmi1_import_active_fmu) { size_t n = jm_vector_get_size(jm_voidp)(fmi1_import_active_fmu); size_t i; for(i= 0; i < n; i++) { fmu = (fmi1_import_t*)jm_vector_get_item(jm_voidp)(fmi1_import_active_fmu, i); if(fmu->capi->c == c) { cb = fmu->callbacks; break; } } if(i >= n) { /* Could not find matching FMU -> use default callbacks */ fmu = 0; cb = jm_get_default_callbacks(); } } switch(status) { case fmi1_status_discard: case fmi1_status_pending: case fmi1_status_ok: logLevel = jm_log_level_info; break; case fmi1_status_warning: logLevel = jm_log_level_warning; break; case fmi1_status_error: logLevel = jm_log_level_error; break; case fmi1_status_fatal: default: logLevel = jm_log_level_fatal; } if(logLevel > cb->log_level) return; curp = buf; *curp = 0; if(category) { sprintf(curp, "[%s]", category); curp += strlen(category)+2; } statusStr = fmi1_status_to_string(status); sprintf(curp, "[FMU status:%s] ", statusStr); curp += strlen(statusStr) + strlen("[FMU status:] "); vsprintf(curp, message, args); if(fmu) { fmi1_import_expand_variable_references(fmu, buf, cb->errMessageBuffer,JM_MAX_ERROR_MESSAGE_SIZE); } else { strncpy(cb->errMessageBuffer, buf, JM_MAX_ERROR_MESSAGE_SIZE); cb->errMessageBuffer[JM_MAX_ERROR_MESSAGE_SIZE - 1] = '\0'; } if(cb->logger) { cb->logger(cb, instanceName, logLevel, cb->errMessageBuffer); } }
unsigned int fmi1_xml_get_unit_display_unit_number(fmi1_xml_unit_t* u) { return (unsigned int)jm_vector_get_size(jm_voidp)(&u->displayUnits); }