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;
    }
}
示例#7
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;
}
示例#12
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;
}
示例#13
0
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);
}