/* Copyright (C) 2012 Modelon AB This program is free software: you can redistribute it and/or modify it under the terms of the BSD style license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the FMILIB_License.txt file for more details. You should have received a copy of the FMILIB_License.txt file along with this program. If not, contact Modelon AB . */ #ifndef FMI2_XML_XMLPARSER_H #define FMI2_XML_XMLPARSER_H #include #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif #define FMI2_XML_ATTRLIST(EXPAND_XML_ATTRNAME) \ EXPAND_XML_ATTRNAME(fmiVersion) \ EXPAND_XML_ATTRNAME(factor) \ EXPAND_XML_ATTRNAME(offset) \ FMI2_SI_BASE_UNITS(EXPAND_XML_ATTRNAME) \ EXPAND_XML_ATTRNAME(name) \ EXPAND_XML_ATTRNAME(description) \ EXPAND_XML_ATTRNAME(quantity) \ EXPAND_XML_ATTRNAME(unit) \ EXPAND_XML_ATTRNAME(displayUnit) \ EXPAND_XML_ATTRNAME(relativeQuantity) \ EXPAND_XML_ATTRNAME(unbounded) \ EXPAND_XML_ATTRNAME(min) \ EXPAND_XML_ATTRNAME(max) \ EXPAND_XML_ATTRNAME(nominal) \ EXPAND_XML_ATTRNAME(declaredType) \ EXPAND_XML_ATTRNAME(start) \ EXPAND_XML_ATTRNAME(derivative) \ EXPAND_XML_ATTRNAME(reinit) \ EXPAND_XML_ATTRNAME(startTime) \ EXPAND_XML_ATTRNAME(stopTime) \ EXPAND_XML_ATTRNAME(tolerance) \ EXPAND_XML_ATTRNAME(stepSize) \ EXPAND_XML_ATTRNAME(value) \ EXPAND_XML_ATTRNAME(valueReference) \ EXPAND_XML_ATTRNAME(variability) \ EXPAND_XML_ATTRNAME(causality) \ EXPAND_XML_ATTRNAME(initial) \ EXPAND_XML_ATTRNAME(previous) \ EXPAND_XML_ATTRNAME(canHandleMultipleSetPerTimeInstant) \ EXPAND_XML_ATTRNAME(index) \ EXPAND_XML_ATTRNAME(dependencies) \ EXPAND_XML_ATTRNAME(dependenciesKind) \ EXPAND_XML_ATTRNAME(modelName) \ EXPAND_XML_ATTRNAME(modelIdentifier) \ EXPAND_XML_ATTRNAME(guid) \ EXPAND_XML_ATTRNAME(author) \ EXPAND_XML_ATTRNAME(copyright) \ EXPAND_XML_ATTRNAME(license) \ EXPAND_XML_ATTRNAME(version) \ EXPAND_XML_ATTRNAME(generationTool) \ EXPAND_XML_ATTRNAME(generationDateAndTime) \ EXPAND_XML_ATTRNAME(variableNamingConvention) \ EXPAND_XML_ATTRNAME(numberOfEventIndicators) \ EXPAND_XML_ATTRNAME(input) \ EXPAND_XML_ATTRNAME(needsExecutionTool) \ EXPAND_XML_ATTRNAME(canHandleVariableCommunicationStepSize) \ EXPAND_XML_ATTRNAME(completedIntegratorStepNotNeeded) \ EXPAND_XML_ATTRNAME(canBeInstantiatedOnlyOncePerProcess) \ EXPAND_XML_ATTRNAME(canNotUseMemoryManagementFunctions) \ EXPAND_XML_ATTRNAME(canGetAndSetFMUstate) \ EXPAND_XML_ATTRNAME(canSerializeFMUstate) \ EXPAND_XML_ATTRNAME(providesDirectionalDerivatives) /* Beta4 spelling. TODO: remove */ \ EXPAND_XML_ATTRNAME(providesDirectionalDerivative) \ EXPAND_XML_ATTRNAME(canInterpolateInputs) \ EXPAND_XML_ATTRNAME(maxOutputDerivativeOrder) \ EXPAND_XML_ATTRNAME(canRunAsynchronuously) #define FMI2_XML_ATTR_ID(attr) fmi_attr_id_##attr, typedef enum fmi2_xml_attr_enu_t { FMI2_XML_ATTRLIST(FMI2_XML_ATTR_ID) fmi2_xml_attr_number } fmi2_xml_attr_enu_t; /** \brief Element names used in XML */ #define FMI2_XML_ELMLIST(EXPAND_XML_ELMNAME) \ EXPAND_XML_ELMNAME(fmiModelDescription) \ EXPAND_XML_ELMNAME(ModelExchange) \ EXPAND_XML_ELMNAME(CoSimulation) \ EXPAND_XML_ELMNAME(SourceFiles) \ EXPAND_XML_ELMNAME(File) \ EXPAND_XML_ELMNAME(UnitDefinitions) \ EXPAND_XML_ELMNAME(Unit) \ EXPAND_XML_ELMNAME(BaseUnit) \ EXPAND_XML_ELMNAME(DisplayUnit) \ EXPAND_XML_ELMNAME(TypeDefinitions) \ EXPAND_XML_ELMNAME(SimpleType) \ EXPAND_XML_ELMNAME(Item) \ EXPAND_XML_ELMNAME(DefaultExperiment) \ EXPAND_XML_ELMNAME(VendorAnnotations) \ EXPAND_XML_ELMNAME(Tool) \ EXPAND_XML_ELMNAME(ModelVariables) \ EXPAND_XML_ELMNAME(ScalarVariable) \ EXPAND_XML_ELMNAME(Annotations) \ EXPAND_XML_ELMNAME(LogCategories) \ EXPAND_XML_ELMNAME(Category) \ EXPAND_XML_ELMNAME(Real) \ EXPAND_XML_ELMNAME(Integer) \ EXPAND_XML_ELMNAME(Boolean) \ EXPAND_XML_ELMNAME(String) \ EXPAND_XML_ELMNAME(Enumeration) \ EXPAND_XML_ELMNAME(ModelStructure) \ EXPAND_XML_ELMNAME(Outputs) \ EXPAND_XML_ELMNAME(Derivatives) \ EXPAND_XML_ELMNAME(DiscreteStates) \ EXPAND_XML_ELMNAME(InitialUnknowns) \ EXPAND_XML_ELMNAME(Unknown) /** \brief Element that can be placed under different parents get alternative names from the info struct */ #define FMI2_XML_ELMLIST_ALT(EXPAND_XML_ELMNAME) \ EXPAND_XML_ELMNAME(RealVariable) \ EXPAND_XML_ELMNAME(IntegerVariable) \ EXPAND_XML_ELMNAME(BooleanVariable) \ EXPAND_XML_ELMNAME(StringVariable) \ EXPAND_XML_ELMNAME(EnumerationVariable) \ EXPAND_XML_ELMNAME(VariableTool) \ EXPAND_XML_ELMNAME(SourceFilesCS) \ EXPAND_XML_ELMNAME(FileCS) \ EXPAND_XML_ELMNAME(DerivativeUnknown) \ EXPAND_XML_ELMNAME(DiscreteStateUnknown) \ EXPAND_XML_ELMNAME(InitialUnknown) typedef struct fmi2_xml_parser_context_t fmi2_xml_parser_context_t; #define EXPAND_ELM_HANDLE(elm) extern int fmi2_xml_handle_##elm(fmi2_xml_parser_context_t *context, const char* data); FMI2_XML_ELMLIST(EXPAND_ELM_HANDLE) FMI2_XML_ELMLIST_ALT(EXPAND_ELM_HANDLE) #define FMI2_XML_ELM_ID(elm) fmi2_xml_elmID_##elm #define FMI2_XML_LIST_ELM_ID(elm) ,FMI2_XML_ELM_ID(elm) typedef enum fmi2_xml_elm_enu_t { fmi2_xml_elmID_none = -1 FMI2_XML_ELMLIST(FMI2_XML_LIST_ELM_ID) ,fmi2_xml_elm_actual_number FMI2_XML_ELMLIST_ALT(FMI2_XML_LIST_ELM_ID) ,fmi2_xml_elm_number } fmi2_xml_elm_enu_t; typedef int (*fmi2_xml_element_handle_ft)(fmi2_xml_parser_context_t *context, const char* data); typedef struct fmi2_xml_element_handle_map_t fmi2_xml_element_handle_map_t; /** Keeps information about the allowed parent element ID, index among siblings in a sequence and if multiple elements of this type are allowed in a sequence. */ typedef struct { fmi2_xml_elm_enu_t parentID; /* expected parent ID for an element */ int siblingIndex; /* index among siblings */ int multipleAllowed; /* multiple elements of this kind kan come in a sequence as siblings*/ } fmi2_xml_scheme_info_t; struct fmi2_xml_element_handle_map_t { const char* elementName; fmi2_xml_element_handle_ft elementHandle; fmi2_xml_elm_enu_t elemID; }; jm_vector_declare_template(fmi2_xml_element_handle_map_t) #define fmi2_xml_diff_elmName(a, b) strcmp(a.elementName,b.elementName) jm_define_comp_f(fmi2_xml_compare_elmName, fmi2_xml_element_handle_map_t, fmi2_xml_diff_elmName) #define XML_BLOCK_SIZE 16000 struct fmi2_xml_parser_context_t { fmi2_xml_model_description_t* modelDescription; jm_callbacks* callbacks; XML_Parser parser; jm_vector(jm_voidp) parseBuffer; jm_vector(jm_named_ptr)* attrMap; jm_vector(fmi2_xml_element_handle_map_t)* elmMap; jm_vector(jm_string)* attrBuffer; fmi2_xml_unit_t* lastBaseUnit; int skipOneVariableFlag; int skipElementCnt; int has_produced_data_warning; jm_stack(int) elmStack; jm_vector(char) elmData; fmi2_xml_elm_enu_t lastElmID; fmi2_xml_elm_enu_t currentElmID; int anyElmCount; int useAnyHandleFlg; char* anyToolName; void* anyParent; fmi2_xml_callbacks_t* anyHandle; }; jm_vector(char) * fmi2_xml_reserve_parse_buffer(fmi2_xml_parser_context_t *context, size_t index, size_t size); jm_vector(char) * fmi2_xml_get_parse_buffer(fmi2_xml_parser_context_t *context, size_t index); int fmi2_xml_alloc_parse_buffer(fmi2_xml_parser_context_t *context, size_t items); void fmi2_xml_free_parse_buffer(fmi2_xml_parser_context_t *context); void fmi2_xml_parse_fatal(fmi2_xml_parser_context_t *context, const char* fmt, ...); void fmi2_xml_parse_error(fmi2_xml_parser_context_t *context, const char* fmt, ...); int fmi2_xml_set_attr_string(fmi2_xml_parser_context_t *context, fmi2_xml_elm_enu_t elmID, fmi2_xml_attr_enu_t attrID, int required, jm_vector(char)* field); int fmi2_xml_set_attr_uint(fmi2_xml_parser_context_t *context, fmi2_xml_elm_enu_t elmID, fmi2_xml_attr_enu_t attrID, int required, unsigned int* field, unsigned int defaultVal); int fmi2_xml_set_attr_enum(fmi2_xml_parser_context_t *context, fmi2_xml_elm_enu_t elmID, fmi2_xml_attr_enu_t attrID, int required, unsigned int* field, unsigned int defaultVal, jm_name_ID_map_t* nameMap); int fmi2_xml_set_attr_boolean(fmi2_xml_parser_context_t *context, fmi2_xml_elm_enu_t elmID, fmi2_xml_attr_enu_t attrID, int required, unsigned int* field, unsigned int defaultVal); int fmi2_xml_set_attr_int(fmi2_xml_parser_context_t *context, fmi2_xml_elm_enu_t elmID, fmi2_xml_attr_enu_t attrID, int required, int* field, int defaultVal); int fmi2_xml_set_attr_double(fmi2_xml_parser_context_t *context, fmi2_xml_elm_enu_t elmID, fmi2_xml_attr_enu_t attrID, int required, double* field, double defaultVal); int fmi2_xml_is_attr_defined(fmi2_xml_parser_context_t *context, fmi2_xml_attr_enu_t attrID); int fmi2_xml_get_attr_str(fmi2_xml_parser_context_t *context, fmi2_xml_elm_enu_t elmID, fmi2_xml_attr_enu_t attrID, int required,const char** valp); void fmi2_xml_set_element_handle(fmi2_xml_parser_context_t *context, const char* elm, fmi2_xml_elm_enu_t id); #ifdef __cplusplus } #endif #endif /* FMI2_XML_XMLPARSER_H */