2 Copyright (C) 2012 Modelon AB
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the BSD style license.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 FMILIB_License.txt file for more details.
12 You should have received a copy of the FMILIB_License.txt file
13 along with this program. If not, contact Modelon AB <http://www.modelon.com>.
20 #include "fmi1_xml_model_description_impl.h"
21 #include "fmi1_xml_type_impl.h"
22 #include "fmi1_xml_unit_impl.h"
23 #include "fmi1_xml_parser.h"
25 static const char* module = "FMI1XML";
27 fmi1_xml_display_unit_t* fmi1_xml_get_type_display_unit(fmi1_xml_real_typedef_t* t) {
28 fmi1_xml_variable_typedef_t* vt = (void*)t;
29 fmi1_xml_real_type_props_t * props = (fmi1_xml_real_type_props_t*)vt->typeBase.baseTypeStruct;
30 fmi1_xml_display_unit_t* du = props->displayUnit;
31 if(du->displayUnit) return du;
35 size_t fmi1_xml_get_type_definition_number(fmi1_xml_type_definitions_t* td) {
36 return jm_vector_get_size(jm_named_ptr)(&td->typeDefinitions);
39 fmi1_xml_variable_typedef_t* fmi1_xml_get_typedef(fmi1_xml_type_definitions_t* td, unsigned int index) {
40 if(index >= fmi1_xml_get_type_definition_number(td)) return 0;
41 return (fmi1_xml_variable_typedef_t*)jm_vector_get_item(jm_named_ptr)(&td->typeDefinitions, index).ptr;
44 const char* fmi1_xml_get_type_name(fmi1_xml_variable_typedef_t* t) {
48 const char* fmi1_xml_get_type_description(fmi1_xml_variable_typedef_t* t) {
49 const char * ret = t->description;
50 return (ret ? ret : "");
53 fmi1_base_type_enu_t fmi1_xml_get_base_type(fmi1_xml_variable_typedef_t* t) {
54 return t->typeBase.baseType;
57 fmi1_xml_real_typedef_t* fmi1_xml_get_type_as_real(fmi1_xml_variable_typedef_t* t) {
58 if(fmi1_xml_get_base_type(t) == fmi1_base_type_real) return (fmi1_xml_real_typedef_t*)t;
61 fmi1_xml_integer_typedef_t* fmi1_xml_get_type_as_int(fmi1_xml_variable_typedef_t* t) {
62 if(fmi1_xml_get_base_type(t) == fmi1_base_type_int) return (fmi1_xml_integer_typedef_t*)t;
66 fmi1_xml_enumeration_typedef_t* fmi1_xml_get_type_as_enum(fmi1_xml_variable_typedef_t* t) {
67 if(fmi1_xml_get_base_type(t) == fmi1_base_type_enum) return (fmi1_xml_enumeration_typedef_t*)t;
71 /* Note that 0-pointer is returned for strings and booleans, empty string quantity if not defined*/
72 const char* fmi1_xml_get_type_quantity(fmi1_xml_variable_typedef_t* t) {
73 fmi1_xml_variable_type_base_t* props = t->typeBase.baseTypeStruct;
75 if(props->structKind != fmi1_xml_type_struct_enu_props) return 0;
76 switch(props->baseType) {
77 case fmi1_base_type_real:
78 ret = ((fmi1_xml_real_type_props_t*)props)->quantity;
80 case fmi1_base_type_int:
81 ret = ((fmi1_xml_integer_type_props_t*)props)->quantity;
83 case fmi1_base_type_bool:
85 case fmi1_base_type_str:
87 case fmi1_base_type_enum:
88 ret = ((fmi1_xml_enum_type_props_t*)props)->quantity;
93 return (ret ? ret : 0);
96 double fmi1_xml_get_real_type_min(fmi1_xml_real_typedef_t* t) {
97 fmi1_xml_variable_typedef_t* vt = (void*)t;
98 fmi1_xml_real_type_props_t* props = (fmi1_xml_real_type_props_t*)(vt->typeBase.baseTypeStruct);
99 return props->typeMin;
102 double fmi1_xml_get_real_type_max(fmi1_xml_real_typedef_t* t) {
103 fmi1_xml_variable_typedef_t* vt = (void*)t;
104 fmi1_xml_real_type_props_t* props = (fmi1_xml_real_type_props_t*)(vt->typeBase.baseTypeStruct);
105 return props->typeMax;
108 double fmi1_xml_get_real_type_nominal(fmi1_xml_real_typedef_t* t) {
109 fmi1_xml_variable_typedef_t* vt = (void*)t;
110 fmi1_xml_real_type_props_t* props = (fmi1_xml_real_type_props_t*)(vt->typeBase.baseTypeStruct);
111 return props->typeNominal;
114 fmi1_xml_unit_t* fmi1_xml_get_real_type_unit(fmi1_xml_real_typedef_t* t) {
115 fmi1_xml_variable_typedef_t* vt = (void*)t;
116 fmi1_xml_real_type_props_t* props = (fmi1_xml_real_type_props_t*)(vt->typeBase.baseTypeStruct);
117 fmi1_xml_display_unit_t* du = props->displayUnit;
118 if(du) return du->baseUnit;
122 int fmi1_xml_get_real_type_is_relative_quantity(fmi1_xml_real_typedef_t* t) {
123 fmi1_xml_variable_typedef_t* vt = (void*)t;
124 fmi1_xml_real_type_props_t* props = (fmi1_xml_real_type_props_t*)(vt->typeBase.baseTypeStruct);
125 return props->typeBase.relativeQuantity;
128 fmi1_integer_t fmi1_xml_get_integer_type_min(fmi1_xml_integer_typedef_t* t) {
129 fmi1_xml_variable_typedef_t* vt = (void*)t;
130 fmi1_xml_integer_type_props_t* props = (fmi1_xml_integer_type_props_t*)(vt->typeBase.baseTypeStruct);
131 return props->typeMin;
134 fmi1_integer_t fmi1_xml_get_integer_type_max(fmi1_xml_integer_typedef_t* t){
135 fmi1_xml_variable_typedef_t* vt = (void*)t;
136 fmi1_xml_integer_type_props_t* props = (fmi1_xml_integer_type_props_t*)(vt->typeBase.baseTypeStruct);
137 return props->typeMax;
140 int fmi1_xml_get_enum_type_min(fmi1_xml_enumeration_typedef_t* t){
141 fmi1_xml_variable_typedef_t* vt = (void*)t;
142 fmi1_xml_enum_type_props_t* props = (fmi1_xml_enum_type_props_t*)(vt->typeBase.baseTypeStruct);
143 return props->typeMin;
146 int fmi1_xml_get_enum_type_max(fmi1_xml_enumeration_typedef_t* t){
147 fmi1_xml_variable_typedef_t* vt = (void*)t;
148 fmi1_xml_enum_type_props_t* props = (fmi1_xml_enum_type_props_t*)(vt->typeBase.baseTypeStruct);
149 return props->typeMax;
152 unsigned int fmi1_xml_get_enum_type_size(fmi1_xml_enumeration_typedef_t* t) {
153 fmi1_xml_variable_typedef_t* vt = (void*)t;
154 fmi1_xml_enum_type_props_t* props = (fmi1_xml_enum_type_props_t*)(vt->typeBase.baseTypeStruct);
155 return (unsigned int)jm_vector_get_size(jm_named_ptr)(&props->enumItems);
158 const char* fmi1_xml_get_enum_type_item_name(fmi1_xml_enumeration_typedef_t* t, unsigned int item) {
159 fmi1_xml_variable_typedef_t* vt = (fmi1_xml_variable_typedef_t*)(void*)t;
160 fmi1_xml_enum_type_props_t* props = (fmi1_xml_enum_type_props_t*)(vt->typeBase.baseTypeStruct);
161 if((item == 0) || (item > fmi1_xml_get_enum_type_size(t) )) return 0;
162 return jm_vector_get_item(jm_named_ptr)(&props->enumItems,item-1).name;
165 const char* fmi1_xml_get_enum_type_item_description(fmi1_xml_enumeration_typedef_t* t, unsigned int item){
166 fmi1_xml_variable_typedef_t* vt = (void*)t;
167 fmi1_xml_enum_type_props_t* props = (fmi1_xml_enum_type_props_t*)(vt->typeBase.baseTypeStruct);
168 fmi1_xml_enum_type_item_t* e;
169 if((item == 0) || (item > fmi1_xml_get_enum_type_size(t) )) return 0;
170 e = jm_vector_get_item(jm_named_ptr)(&props->enumItems,item-1).ptr;
171 return e->itemDesciption;
174 void fmi1_xml_init_variable_type_base(fmi1_xml_variable_type_base_t* type, fmi1_xml_type_struct_kind_enu_t kind, fmi1_base_type_enu_t baseType) {
175 type->baseTypeStruct = 0;
177 type->structKind = kind;
178 type->baseType = baseType;
179 type->relativeQuantity = 0;
183 void fmi1_xml_init_real_type_properties(fmi1_xml_real_type_props_t* type) {
184 fmi1_xml_init_variable_type_base(&type->typeBase, fmi1_xml_type_struct_enu_props,fmi1_base_type_real);
186 type->typeMin = -DBL_MAX;
187 type->typeMax = DBL_MAX;
188 type->typeNominal = 1.0;
189 type->displayUnit = 0;
192 void fmi1_xml_init_integer_type_properties(fmi1_xml_integer_type_props_t* type) {
193 fmi1_xml_init_variable_type_base(&type->typeBase, fmi1_xml_type_struct_enu_props,fmi1_base_type_int);
195 type->typeMin = INT_MIN;
196 type->typeMax = INT_MAX;
199 void fmi1_xml_init_enumeration_type_properties(fmi1_xml_enum_type_props_t* type, jm_callbacks* cb) {
200 fmi1_xml_init_variable_type_base(&type->typeBase, fmi1_xml_type_struct_enu_props,fmi1_base_type_enum);
203 type->typeMax = INT_MAX;
204 jm_vector_init(jm_named_ptr)(&type->enumItems,0,cb);
207 void fmi1_xml_free_enumeration_type_props(fmi1_xml_enum_type_props_t* type) {
208 jm_named_vector_free_data(&type->enumItems);
212 void fmi1_xml_init_type_definitions(fmi1_xml_type_definitions_t* td, jm_callbacks* cb) {
213 jm_vector_init(jm_named_ptr)(&td->typeDefinitions,0,cb);
215 jm_vector_init(jm_string)(&td->quantities, 0, cb);
217 fmi1_xml_init_real_type_properties(&td->defaultRealType);
218 td->defaultRealType.typeBase.structKind = fmi1_xml_type_struct_enu_base;
219 fmi1_xml_init_enumeration_type_properties(&td->defaultEnumType,cb);
220 td->defaultEnumType.typeBase.structKind = fmi1_xml_type_struct_enu_base;
221 fmi1_xml_init_integer_type_properties(&td->defaultIntegerType);
222 td->defaultIntegerType.typeBase.structKind = fmi1_xml_type_struct_enu_base;
224 fmi1_xml_init_variable_type_base(&td->defaultBooleanType, fmi1_xml_type_struct_enu_base,fmi1_base_type_bool);
225 fmi1_xml_init_variable_type_base(&td->defaultStringType, fmi1_xml_type_struct_enu_base,fmi1_base_type_str);
227 td->typePropsList = 0;
230 void fmi1_xml_free_type_definitions_data(fmi1_xml_type_definitions_t* td) {
231 jm_callbacks* cb = td->typeDefinitions.callbacks;
233 jm_vector_foreach(jm_string)(&td->quantities,(void(*)(const char*))cb->free);
234 jm_vector_free_data(jm_string)(&td->quantities);
237 fmi1_xml_variable_type_base_t* next;
238 fmi1_xml_variable_type_base_t* cur = td->typePropsList;
241 if((cur->baseType == fmi1_base_type_enum) && (cur->structKind == fmi1_xml_type_struct_enu_props)) {
242 fmi1_xml_enum_type_props_t* props = (fmi1_xml_enum_type_props_t*)cur;
243 fmi1_xml_free_enumeration_type_props(props);
248 td->typePropsList = 0;
251 jm_named_vector_free_data(&td->typeDefinitions);
254 int fmi1_xml_handle_TypeDefinitions(fmi1_xml_parser_context_t *context, const char* data) {
256 jm_log_verbose(context->callbacks, module, "Parsing XML element TypeDefinitions");
259 fmi1_xml_type_definitions_t* defs = &context->modelDescription->typeDefinitions;
261 jm_vector_qsort(jm_named_ptr)(&defs->typeDefinitions, jm_compare_named);
262 /* might give out a warning if(data[0] != 0) */
268 int fmi1_xml_handle_Type(fmi1_xml_parser_context_t *context, const char* data) {
270 fmi1_xml_model_description_t* md = context->modelDescription;
271 fmi1_xml_type_definitions_t* td = &md->typeDefinitions;
272 jm_named_ptr named, *pnamed;
273 jm_vector(char)* bufName = fmi1_xml_reserve_parse_buffer(context,1,100);
274 jm_vector(char)* bufDescr = fmi1_xml_reserve_parse_buffer(context,2,100);
276 if(!bufName || !bufDescr) return -1;
278 /* <xs:attribute name="name" type="xs:normalizedString" use="required"/> */
279 fmi1_xml_set_attr_string(context, fmi1_xml_elmID_Type, fmi_attr_id_name, 1, bufName) ||
280 /* <xs:attribute name="description" type="xs:string"/> */
281 fmi1_xml_set_attr_string(context, fmi1_xml_elmID_Type, fmi_attr_id_description, 0, bufDescr)
285 pnamed = jm_vector_push_back(jm_named_ptr)(&td->typeDefinitions,named);
287 fmi1_xml_variable_typedef_t dummy;
288 *pnamed = named = jm_named_alloc_v(bufName, sizeof(fmi1_xml_variable_typedef_t), dummy.typeName - (char*)&dummy, context->callbacks);
290 if(!pnamed || !named.ptr) {
291 fmi1_xml_parse_fatal(context, "Could not allocate memory");
295 fmi1_xml_variable_typedef_t* type = named.ptr;
296 fmi1_xml_init_variable_type_base(&type->typeBase,fmi1_xml_type_struct_enu_typedef,fmi1_base_type_real);
297 if(jm_vector_get_size(char)(bufDescr)) {
298 const char* description = jm_string_set_put(&md->descriptions, jm_vector_get_itemp(char)(bufDescr,0));
299 type->description = description;
301 else type->description = "";
305 jm_named_ptr named = jm_vector_get_last(jm_named_ptr)(&(context->modelDescription->typeDefinitions.typeDefinitions));
306 fmi1_xml_variable_typedef_t* type = named.ptr;
307 if(type->typeBase.baseTypeStruct == 0) {
308 fmi1_xml_parse_fatal(context, "No specific type given for type definition %s", type->typeName);
311 /* might give out a warning if(data[0] != 0) */
317 int fmi1_check_last_elem_is_specific_type(fmi1_xml_parser_context_t *context) {
319 (context->lastElmID == fmi1_xml_elmID_RealType) ||
320 (context->lastElmID == fmi1_xml_elmID_IntegerType) ||
321 (context->lastElmID == fmi1_xml_elmID_BooleanType) ||
322 (context->lastElmID == fmi1_xml_elmID_StringType) ||
323 (context->lastElmID == fmi1_xml_elmID_EnumerationType)
325 fmi1_xml_parse_fatal(context, "Multiple definitions for a type are not allowed");
331 fmi1_xml_variable_type_base_t* fmi1_xml_alloc_variable_type_props(fmi1_xml_type_definitions_t* td, fmi1_xml_variable_type_base_t* base, size_t typeSize) {
332 jm_callbacks* cb = td->typeDefinitions.callbacks;
333 fmi1_xml_variable_type_base_t* type = cb->malloc(typeSize);
335 fmi1_xml_init_variable_type_base(type,fmi1_xml_type_struct_enu_props,base->baseType);
336 type->baseTypeStruct = base;
337 type->next = td->typePropsList;
338 td->typePropsList = type;
342 fmi1_xml_variable_type_base_t* fmi1_xml_alloc_variable_type_start(fmi1_xml_type_definitions_t* td,fmi1_xml_variable_type_base_t* base, size_t typeSize) {
343 jm_callbacks* cb = td->typeDefinitions.callbacks;
344 fmi1_xml_variable_type_base_t* type = cb->malloc(typeSize);
346 fmi1_xml_init_variable_type_base(type,fmi1_xml_type_struct_enu_start,base->baseType);
347 type->baseTypeStruct = base;
348 type->next = td->typePropsList;
349 td->typePropsList = type;
354 fmi1_xml_real_type_props_t* fmi1_xml_parse_real_type_properties(fmi1_xml_parser_context_t* context, fmi1_xml_elm_enu_t elmID) {
355 jm_named_ptr named, *pnamed;
356 fmi1_xml_model_description_t* md = context->modelDescription;
357 fmi1_xml_real_type_props_t* props;
358 const char* quantity = 0;
361 /* jm_vector(char)* bufName = fmi_get_parse_buffer(context,1);
362 jm_vector(char)* bufDescr = fmi_get_parse_buffer(context,2); */
363 jm_vector(char)* bufQuantity = fmi1_xml_reserve_parse_buffer(context,3,100);
364 jm_vector(char)* bufUnit = fmi1_xml_reserve_parse_buffer(context,4,100);
365 jm_vector(char)* bufDispUnit = fmi1_xml_reserve_parse_buffer(context,5,100);
367 props = (fmi1_xml_real_type_props_t*)fmi1_xml_alloc_variable_type_props(&md->typeDefinitions, &md->typeDefinitions.defaultRealType.typeBase, sizeof(fmi1_xml_real_type_props_t));
369 if(!bufQuantity || !bufUnit || !bufDispUnit || !props ||
370 /* <xs:attribute name="quantity" type="xs:normalizedString"/> */
371 fmi1_xml_set_attr_string(context, elmID, fmi_attr_id_quantity, 0, bufQuantity) ||
372 /* <xs:attribute name="unit" type="xs:normalizedString"/> */
373 fmi1_xml_set_attr_string(context, elmID, fmi_attr_id_unit, 0, bufUnit) ||
374 /* <xs:attribute name="displayUnit" type="xs:normalizedString"> */
375 fmi1_xml_set_attr_string(context, elmID, fmi_attr_id_displayUnit, 0, bufDispUnit)
377 fmi1_xml_parse_fatal(context, "Error parsing real type properties");
380 if(jm_vector_get_size(char)(bufQuantity))
381 quantity = jm_string_set_put(&md->typeDefinitions.quantities, jm_vector_get_itemp(char)(bufQuantity, 0));
383 props->quantity = quantity;
384 props->displayUnit = 0;
385 if(jm_vector_get_size(char)(bufDispUnit)) {
386 named.name = jm_vector_get_itemp(char)(bufDispUnit, 0);
387 pnamed = jm_vector_bsearch(jm_named_ptr)(&(md->displayUnitDefinitions), &named, jm_compare_named);
389 fmi1_xml_parse_fatal(context, "Unknown display unit %s in real type definition", jm_vector_get_itemp(char)(bufDispUnit, 0));
392 props->displayUnit = pnamed->ptr;
395 if(jm_vector_get_size(char)(bufUnit)) {
396 props->displayUnit = fmi1_xml_get_parsed_unit(context, bufUnit, 1);
399 if( /* <xs:attribute name="relativeQuantity" type="xs:boolean" default="false"> */
400 fmi1_xml_set_attr_boolean(context, elmID, fmi_attr_id_relativeQuantity, 0, &boolBuf, 0) ||
401 /* <xs:attribute name="min" type="xs:double"/> */
402 fmi1_xml_set_attr_double(context, elmID, fmi_attr_id_min, 0, &props->typeMin, -DBL_MAX) ||
403 /* <xs:attribute name="max" type="xs:double"/> */
404 fmi1_xml_set_attr_double(context, elmID, fmi_attr_id_max, 0, &props->typeMax, DBL_MAX) ||
405 /* <xs:attribute name="nominal" type="xs:double"/> */
406 fmi1_xml_set_attr_double(context, elmID, fmi_attr_id_nominal, 0, &props->typeNominal, 1)
408 props->typeBase.relativeQuantity = boolBuf;
412 int fmi1_xml_handle_RealType(fmi1_xml_parser_context_t *context, const char* data) {
414 fmi1_xml_model_description_t* md = context->modelDescription;
416 fmi1_xml_variable_typedef_t* type;
417 fmi1_xml_real_type_props_t * props;
418 if(fmi1_check_last_elem_is_specific_type(context)) return -1;
420 props = fmi1_xml_parse_real_type_properties(context, fmi1_xml_elmID_RealType);
421 if(!props) return -1;
422 named = jm_vector_get_last(jm_named_ptr)(&md->typeDefinitions.typeDefinitions);
424 type->typeBase.baseType = fmi1_base_type_real;
425 type->typeBase.baseTypeStruct = &props->typeBase;
428 /* don't do anything. might give out a warning if(data[0] != 0) */
434 fmi1_xml_integer_type_props_t * fmi1_xml_parse_integer_type_properties(fmi1_xml_parser_context_t* context, fmi1_xml_elm_enu_t elmID) {
436 fmi1_xml_model_description_t* md = context->modelDescription;
437 fmi1_xml_integer_type_props_t * props = 0;
438 const char* quantity = 0;
440 /* jm_vector(char)* bufName = fmi_get_parse_buffer(context,1);
441 jm_vector(char)* bufDescr = fmi_get_parse_buffer(context,2); */
442 jm_vector(char)* bufQuantity = fmi1_xml_reserve_parse_buffer(context,3,100);
444 props = (fmi1_xml_integer_type_props_t*)fmi1_xml_alloc_variable_type_props(&md->typeDefinitions, &md->typeDefinitions.defaultIntegerType.typeBase, sizeof(fmi1_xml_integer_type_props_t));
446 if(!bufQuantity || !props ||
447 /* <xs:attribute name="quantity" type="xs:normalizedString"/> */
448 fmi1_xml_set_attr_string(context, elmID, fmi_attr_id_quantity, 0, bufQuantity)
451 if(jm_vector_get_size(char)(bufQuantity))
452 quantity = jm_string_set_put(&md->typeDefinitions.quantities, jm_vector_get_itemp(char)(bufQuantity, 0));
454 props->quantity = quantity;
457 /* <xs:attribute name="min" type="xs:int"/> */
458 fmi1_xml_set_attr_int(context, elmID, fmi_attr_id_min, 0, &props->typeMin, INT_MIN) ||
459 /* <xs:attribute name="max" type="xs:int"/> */
460 fmi1_xml_set_attr_int(context, elmID, fmi_attr_id_max, 0, &props->typeMax, INT_MAX)
465 int fmi1_xml_handle_IntegerType(fmi1_xml_parser_context_t *context, const char* data) {
467 fmi1_xml_model_description_t* md = context->modelDescription;
469 fmi1_xml_variable_typedef_t* type;
470 fmi1_xml_integer_type_props_t * props;
471 if(fmi1_check_last_elem_is_specific_type(context)) return -1;
473 props = fmi1_xml_parse_integer_type_properties(context, fmi1_xml_elmID_IntegerType);
474 if(!props) return -1;
475 named = jm_vector_get_last(jm_named_ptr)(&md->typeDefinitions.typeDefinitions);
477 type->typeBase.baseType = fmi1_base_type_int;
478 type->typeBase.baseTypeStruct = &props->typeBase;
481 /* don't do anything. might give out a warning if(data[0] != 0) */
488 int fmi1_xml_handle_BooleanType(fmi1_xml_parser_context_t *context, const char* data) {
490 fmi1_xml_model_description_t* md = context->modelDescription;
492 fmi1_xml_variable_typedef_t* type;
493 if(fmi1_check_last_elem_is_specific_type(context)) return -1;
495 named = jm_vector_get_last(jm_named_ptr)(&context->modelDescription->typeDefinitions.typeDefinitions);
497 type->typeBase.baseType = fmi1_base_type_bool;
498 type->typeBase.baseTypeStruct = &md->typeDefinitions.defaultBooleanType;
501 /* don't do anything. might give out a warning if(data[0] != 0) */
507 int fmi1_xml_handle_StringType(fmi1_xml_parser_context_t *context, const char* data) {
509 fmi1_xml_model_description_t* md = context->modelDescription;
511 fmi1_xml_variable_typedef_t* type;
512 if(fmi1_check_last_elem_is_specific_type(context)) return -1;
514 named = jm_vector_get_last(jm_named_ptr)(&context->modelDescription->typeDefinitions.typeDefinitions);
516 type->typeBase.baseType = fmi1_base_type_str;
517 type->typeBase.baseTypeStruct = &md->typeDefinitions.defaultStringType;
520 /* don't do anything. might give out a warning if(data[0] != 0) */
526 int fmi1_xml_handle_EnumerationType(fmi1_xml_parser_context_t *context, const char* data) {
529 fmi1_xml_model_description_t* md = context->modelDescription;
530 fmi1_xml_enum_type_props_t * props;
531 fmi1_xml_variable_typedef_t* type;
532 const char * quantity = 0;
533 /* jm_vector(char)* bufName = fmi_get_parse_buffer(context,1);
534 jm_vector(char)* bufDescr = fmi_get_parse_buffer(context,2); */
535 jm_vector(char)* bufQuantity = fmi1_xml_reserve_parse_buffer(context,3,100);
537 if(fmi1_check_last_elem_is_specific_type(context)) return -1;
539 props = (fmi1_xml_enum_type_props_t*)fmi1_xml_alloc_variable_type_props(&md->typeDefinitions, &md->typeDefinitions.defaultEnumType.typeBase, sizeof(fmi1_xml_enum_type_props_t));
540 if(props) jm_vector_init(jm_named_ptr)(&props->enumItems,0,context->callbacks);
541 if(!bufQuantity || !props ||
542 /* <xs:attribute name="quantity" type="xs:normalizedString"/> */
543 fmi1_xml_set_attr_string(context, fmi1_xml_elmID_IntegerType, fmi_attr_id_quantity, 0, bufQuantity)
546 if(jm_vector_get_size(char)(bufQuantity))
547 quantity = jm_string_set_put(&md->typeDefinitions.quantities, jm_vector_get_itemp(char)(bufQuantity, 0));
549 props->quantity = quantity;
554 /* <xs:attribute name="min" type="xs:int"/> */
555 fmi1_xml_set_attr_int(context, fmi1_xml_elmID_EnumerationType, fmi_attr_id_min, 0, &props->typeMin, 1) ||
556 /* <xs:attribute name="max" type="xs:int"/> */
557 fmi1_xml_set_attr_int(context, fmi1_xml_elmID_EnumerationType, fmi_attr_id_max, 0, &props->typeMax, INT_MAX)
559 named = jm_vector_get_last(jm_named_ptr)(&context->modelDescription->typeDefinitions.typeDefinitions);
561 type->typeBase.baseType = fmi1_base_type_enum;
562 type->typeBase.baseTypeStruct = &props->typeBase;
565 /* don't do anything. might give out a warning if(data[0] != 0) */
571 int fmi1_xml_handle_Item(fmi1_xml_parser_context_t *context, const char* data) {
574 fmi1_xml_model_description_t* md = context->modelDescription;
575 jm_vector(char)* bufName = fmi1_xml_reserve_parse_buffer(context,1,100);
576 jm_vector(char)* bufDescr = fmi1_xml_reserve_parse_buffer(context,2,100);
577 /* this enum item belongs to the last created enum = head of typePropsList */
578 fmi1_xml_enum_type_props_t * enumProps = (fmi1_xml_enum_type_props_t*)md->typeDefinitions.typePropsList;
579 fmi1_xml_enum_type_item_t * item;
580 jm_named_ptr named, *pnamed;
583 assert((enumProps->typeBase.structKind == fmi1_xml_type_struct_enu_props) && (enumProps->typeBase.baseType == fmi1_base_type_enum));
585 if(!bufName || !bufDescr ||
586 /* <xs:attribute name="name" type="xs:normalizedString" use="required"/> */
587 fmi1_xml_set_attr_string(context, fmi1_xml_elmID_Type, fmi_attr_id_name, 1, bufName) ||
588 /* <xs:attribute name="description" type="xs:string"/> */
589 fmi1_xml_set_attr_string(context, fmi1_xml_elmID_Type, fmi_attr_id_description, 0, bufDescr)
592 descrlen = jm_vector_get_size(char)(bufDescr);
595 pnamed = jm_vector_push_back(jm_named_ptr)(&enumProps->enumItems, named);
597 if(pnamed) *pnamed = named = jm_named_alloc_v(bufName,sizeof(fmi1_xml_enum_type_item_t)+descrlen+1,sizeof(fmi1_xml_enum_type_item_t)+descrlen,context->callbacks);
599 if( !pnamed || !item ) {
600 fmi1_xml_parse_fatal(context, "Could not allocate memory");
603 item->itemName = named.name;
605 memcpy(item->itemDesciption,jm_vector_get_itemp(char)(bufDescr,0), descrlen);
606 item->itemDesciption[descrlen] = 0;
610 /* don't do anything. might give out a warning if(data[0] != 0) */
616 fmi1_xml_variable_type_base_t* fmi1_get_declared_type(fmi1_xml_parser_context_t *context, fmi1_xml_elm_enu_t elmID, fmi1_xml_variable_type_base_t* defaultType) {
617 jm_named_ptr key, *found;
618 jm_vector(char)* bufDeclaredType = fmi1_xml_reserve_parse_buffer(context,1, 100);
619 /* <xs:attribute name="declaredType" type="xs:normalizedString"> */
620 fmi1_xml_set_attr_string(context, elmID, fmi_attr_id_declaredType, 0, bufDeclaredType);
621 if(! jm_vector_get_size(char)(bufDeclaredType) ) return defaultType;
622 key.name = jm_vector_get_itemp(char)(bufDeclaredType,0);
623 found = jm_vector_bsearch(jm_named_ptr)(&(context->modelDescription->typeDefinitions.typeDefinitions),&key, jm_compare_named);
625 jm_log_error(context->callbacks, module, "Declared type %s not found in type definitions. Ignoring.", key.name);
629 fmi1_xml_variable_type_base_t* retType = found->ptr;
630 if(retType->baseType != defaultType->baseType) {
631 jm_log_error(context->callbacks, module, "Declared type %s does not match variable type. Ignoring.", key.name);