|
@@ -1,654 +0,0 @@
|
|
|
-/*
|
|
|
- * Copyright QTronic GmbH. All rights reserved.
|
|
|
- */
|
|
|
-
|
|
|
-/* ---------------------------------------------------------------------------*
|
|
|
- * XmlElement.cpp
|
|
|
- * Elements implementation that describe content of model description of a
|
|
|
- * FMI 2.0 model. All elements have Element as parent class. Elements have
|
|
|
- * attributes and other specific content.
|
|
|
- *
|
|
|
- * Author: Adrian Tirea
|
|
|
- * ---------------------------------------------------------------------------*/
|
|
|
-
|
|
|
-#include "XmlElement.h"
|
|
|
-#include <assert.h>
|
|
|
-#include <map>
|
|
|
-#include <string>
|
|
|
-#include <vector>
|
|
|
-#include "XmlParserException.h"
|
|
|
-
|
|
|
-#ifdef STANDALONE_XML_PARSER
|
|
|
-#define logThis(n, ...) printf(__VA_ARGS__); printf("\n")
|
|
|
-#else
|
|
|
-#include "GlobalIncludes.h"
|
|
|
-#include "logging.h" // logThis
|
|
|
-#endif // STANDALONE_XML_PARSER
|
|
|
-
|
|
|
-Element::~Element() {
|
|
|
- for (std::map<XmlParser::Att, char *>::const_iterator it = attributes.begin(); it != attributes.end(); ++it) {
|
|
|
- free(it->second);
|
|
|
- }
|
|
|
- attributes.clear();
|
|
|
-}
|
|
|
-template <typename T> void Element::deleteListOfElements(const std::vector<T *> &list) {
|
|
|
- typename std::vector<T*>::const_iterator it;
|
|
|
- for (it = list.begin(); it != list.end(); ++it) {
|
|
|
- delete *it;
|
|
|
- }
|
|
|
-}
|
|
|
-void Element::handleElement(XmlParser *parser, const char *childName, int isEmptyElement) {
|
|
|
- throw XmlParserException("Elements are not expected inside '%s'. Found instead '%s'",
|
|
|
- XmlParser::elmNames[type],
|
|
|
- childName);
|
|
|
-}
|
|
|
-void Element::printElement(int indent) {
|
|
|
- std::string indentS(indent, ' ');
|
|
|
- logThis(ERROR_INFO, "%s%s", indentS.c_str(), XmlParser::elmNames[type]);
|
|
|
- for (std::map<XmlParser::Att, char *>::const_iterator it = attributes.begin(); it != attributes.end(); ++it) {
|
|
|
- logThis(ERROR_INFO, "%s%s=%s", indentS.c_str(), XmlParser::attNames[it->first], it->second);
|
|
|
- }
|
|
|
-}
|
|
|
-template <typename T> void Element::printListOfElements(int indent, const std::vector<T *> &list) {
|
|
|
- typename std::vector<T*>::const_iterator it;
|
|
|
- for (it = list.begin(); it != list.end(); ++it) {
|
|
|
- (*it)->printElement(indent);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-const char *Element::getAttributeValue(XmlParser::Att att) {
|
|
|
- std::map<XmlParser::Att, char *>::const_iterator it = attributes.find(att);
|
|
|
- if (it != attributes.end()) {
|
|
|
- return it->second;
|
|
|
- }
|
|
|
- return NULL;
|
|
|
-}
|
|
|
-int Element::getAttributeInt(XmlParser::Att att, XmlParser::ValueStatus *vs) {
|
|
|
- int n = 0;
|
|
|
- const char *value = getAttributeValue(att);
|
|
|
- if (!value) { *vs = XmlParser::valueMissing; return n; }
|
|
|
- *vs = (1 == sscanf(value, "%d", &n)) ? XmlParser::valueDefined : XmlParser::valueIllegal;
|
|
|
- return n;
|
|
|
-}
|
|
|
-unsigned int Element::getAttributeUInt(XmlParser::Att att, XmlParser::ValueStatus *vs) {
|
|
|
- unsigned int u = -1;
|
|
|
- const char* value = getAttributeValue(att);
|
|
|
- if (!value) { *vs = XmlParser::valueMissing; return u; }
|
|
|
- *vs = (1 == sscanf(value, "%u", &u)) ? XmlParser::valueDefined : XmlParser::valueIllegal;
|
|
|
- return u;
|
|
|
-}
|
|
|
-double Element::getAttributeDouble(XmlParser::Att att, XmlParser::ValueStatus *vs) {
|
|
|
- double d = 0;
|
|
|
- const char* value = getAttributeValue(att);
|
|
|
- if (!value) { *vs = XmlParser::valueMissing; return d; }
|
|
|
- *vs = (1 == sscanf(value, "%lf", &d)) ? XmlParser::valueDefined : XmlParser::valueIllegal;
|
|
|
- return d;
|
|
|
-}
|
|
|
-bool Element::getAttributeBool(XmlParser::Att att, XmlParser::ValueStatus *vs) {
|
|
|
- const char* value = getAttributeValue(att);
|
|
|
- if (!value) {*vs = XmlParser::valueMissing; return false;}
|
|
|
- *vs = XmlParser::valueDefined;
|
|
|
- if (!strcmp(value, "true")) return true;
|
|
|
- if (!strcmp(value, "false")) return false;
|
|
|
- *vs = XmlParser::valueIllegal;
|
|
|
- return false;
|
|
|
-}
|
|
|
-
|
|
|
-ListElement::~ListElement() {
|
|
|
- deleteListOfElements(list);
|
|
|
-}
|
|
|
-void ListElement::handleElement(XmlParser *parser, const char *childName, int isEmptyElement) {
|
|
|
- XmlParser::Elm childType = parser->checkElement(childName);
|
|
|
- if (childType == XmlParser::elm_Item) {
|
|
|
- Element *item = new Element;
|
|
|
- item->type = childType;
|
|
|
- parser->parseElementAttributes(item);
|
|
|
- if (!isEmptyElement) {
|
|
|
- parser->parseEndElement();
|
|
|
- }
|
|
|
- list.push_back(item);
|
|
|
- } else {
|
|
|
- throw XmlParserException("Expected '%s' element inside '%s'. Found instead: '%s'.",
|
|
|
- XmlParser::elmNames[XmlParser::elm_Item],
|
|
|
- XmlParser::elmNames[XmlParser::elm_Enumeration],
|
|
|
- childName);
|
|
|
- }
|
|
|
-}
|
|
|
-void ListElement::printElement(int indent) {
|
|
|
- Element::printElement(indent);
|
|
|
- int childIndent = indent + 1;
|
|
|
- printListOfElements(childIndent, list);
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-Unit::Unit() {
|
|
|
- baseUnit = NULL;
|
|
|
-}
|
|
|
-Unit::~Unit() {
|
|
|
- if (baseUnit) delete baseUnit;
|
|
|
- deleteListOfElements(displayUnits);
|
|
|
-}
|
|
|
-void Unit::handleElement(XmlParser *parser, const char *childName, int isEmptyElement) {
|
|
|
- XmlParser::Elm childType = parser->checkElement(childName);
|
|
|
- if (childType == XmlParser::elm_BaseUnit) {
|
|
|
- baseUnit = new Element;
|
|
|
- baseUnit->type = childType;
|
|
|
- parser->parseElementAttributes(baseUnit);
|
|
|
- if (!isEmptyElement) {
|
|
|
- parser->parseEndElement();
|
|
|
- }
|
|
|
- } else if (childType == XmlParser::elm_DisplayUnit) {
|
|
|
- Element *displayUnit = new Element;
|
|
|
- displayUnit->type = childType;
|
|
|
- parser->parseElementAttributes(displayUnit);
|
|
|
- displayUnits.push_back(displayUnit);
|
|
|
- if (!isEmptyElement) {
|
|
|
- parser->parseEndElement();
|
|
|
- }
|
|
|
- } else {
|
|
|
- throw XmlParserException("Expected '%s' | '%s' element inside '%s'. Found instead: '%s'.",
|
|
|
- XmlParser::elmNames[XmlParser::elm_BaseUnit],
|
|
|
- XmlParser::elmNames[XmlParser::elm_DisplayUnit],
|
|
|
- XmlParser::elmNames[XmlParser::elm_SourceFiles],
|
|
|
- childName);
|
|
|
- }
|
|
|
-}
|
|
|
-void Unit::printElement(int indent) {
|
|
|
- Element::printElement(indent);
|
|
|
- int childIndent = indent + 1;
|
|
|
- if (baseUnit) baseUnit->printElement(childIndent);
|
|
|
- printListOfElements(childIndent, displayUnits);
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-SimpleType::SimpleType() {
|
|
|
- typeSpec = NULL;
|
|
|
-}
|
|
|
-SimpleType::~SimpleType() {
|
|
|
- if (typeSpec) delete typeSpec;
|
|
|
-}
|
|
|
-void SimpleType::handleElement(XmlParser *parser, const char *childName, int isEmptyElement) {
|
|
|
- XmlParser::Elm childType = parser->checkElement(childName);
|
|
|
- switch (childType) {
|
|
|
- case XmlParser::elm_Real:
|
|
|
- case XmlParser::elm_Integer:
|
|
|
- case XmlParser::elm_Boolean:
|
|
|
- case XmlParser::elm_String: {
|
|
|
- typeSpec = new Element;
|
|
|
- typeSpec->type = childType;
|
|
|
- parser->parseElementAttributes(typeSpec);
|
|
|
- if (!isEmptyElement) {
|
|
|
- parser->parseEndElement();
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- case XmlParser::elm_Enumeration: {
|
|
|
- typeSpec = new ListElement;
|
|
|
- typeSpec->type = childType;
|
|
|
- parser->parseElementAttributes(typeSpec);
|
|
|
- if (!isEmptyElement) {
|
|
|
- parser->parseChildElements(typeSpec);
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- default: {
|
|
|
- throw XmlParserException(
|
|
|
- "Expected '%s' | '%s' | '%s' | '%s' | '%s' element inside '%s'. Found instead: '%s'.",
|
|
|
- XmlParser::elmNames[XmlParser::elm_Real],
|
|
|
- XmlParser::elmNames[XmlParser::elm_Integer],
|
|
|
- XmlParser::elmNames[XmlParser::elm_Boolean],
|
|
|
- XmlParser::elmNames[XmlParser::elm_String],
|
|
|
- XmlParser::elmNames[XmlParser::elm_Enumeration],
|
|
|
- XmlParser::elmNames[type],
|
|
|
- childName);
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-void SimpleType::printElement(int indent) {
|
|
|
- Element::printElement(indent);
|
|
|
- int childIndent = indent + 1;
|
|
|
- if (typeSpec) typeSpec->printElement(childIndent);
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-Component::~Component() {
|
|
|
- deleteListOfElements(files);
|
|
|
-}
|
|
|
-void Component::handleElement(XmlParser *parser, const char *childName, int isEmptyElement) {
|
|
|
- XmlParser::Elm childType = parser->checkElement(childName);
|
|
|
- if (childType == XmlParser::elm_SourceFiles) {
|
|
|
- if (!isEmptyElement) {
|
|
|
- parser->parseChildElements(this);
|
|
|
- }
|
|
|
- } else if (childType == XmlParser::elm_File) {
|
|
|
- Element *sourceFile = new Element;
|
|
|
- sourceFile->type = childType;
|
|
|
- parser->parseElementAttributes(sourceFile);
|
|
|
- if (!isEmptyElement) {
|
|
|
- parser->parseEndElement();
|
|
|
- }
|
|
|
- files.push_back(sourceFile);
|
|
|
- } else {
|
|
|
- throw XmlParserException("Expected '%s' | '%s' element inside '%s'. Found instead: '%s'.",
|
|
|
- XmlParser::elmNames[XmlParser::elm_File],
|
|
|
- XmlParser::elmNames[XmlParser::elm_SourceFiles],
|
|
|
- XmlParser::elmNames[type],
|
|
|
- childName);
|
|
|
- }
|
|
|
-}
|
|
|
-void Component::printElement(int indent) {
|
|
|
- Element::printElement(indent);
|
|
|
- int childIndent = indent + 1;
|
|
|
- printListOfElements(childIndent, files);
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-ScalarVariable::ScalarVariable() {
|
|
|
- typeSpec = NULL;
|
|
|
-}
|
|
|
-ScalarVariable::~ScalarVariable() {
|
|
|
- delete typeSpec;
|
|
|
- deleteListOfElements(annotations);
|
|
|
-}
|
|
|
-void ScalarVariable::handleElement(XmlParser *parser, const char *childName, int isEmptyElement) {
|
|
|
- XmlParser::Elm childType = parser->checkElement(childName);
|
|
|
- switch (childType) {
|
|
|
- case XmlParser::elm_Real:
|
|
|
- case XmlParser::elm_Integer:
|
|
|
- case XmlParser::elm_Boolean:
|
|
|
- case XmlParser::elm_String:
|
|
|
- case XmlParser::elm_Enumeration: {
|
|
|
- typeSpec = new Element;
|
|
|
- typeSpec->type = childType;
|
|
|
- parser->parseElementAttributes(typeSpec);
|
|
|
- if (!isEmptyElement) {
|
|
|
- parser->parseEndElement();
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- case XmlParser::elm_Annotations: {
|
|
|
- // no attributes expected; this class handles also the Tool
|
|
|
- if (!isEmptyElement) parser->parseChildElements(this);
|
|
|
- break;
|
|
|
- }
|
|
|
- case XmlParser::elm_Tool: {
|
|
|
- Element *tool = new Element;
|
|
|
- tool->type = childType;
|
|
|
- parser->parseElementAttributes(tool, false);
|
|
|
- if (!isEmptyElement) {
|
|
|
- parser->parseSkipChildElement();
|
|
|
- }
|
|
|
- annotations.push_back(tool);
|
|
|
- break;
|
|
|
- }
|
|
|
- default: {
|
|
|
- throw XmlParserException(
|
|
|
- "Expected '%s' | '%s' | '%s' | '%s' | '%s' | '%s' | '%s' element inside '%s'. Found instead: '%s'.",
|
|
|
- XmlParser::elmNames[XmlParser::elm_Real],
|
|
|
- XmlParser::elmNames[XmlParser::elm_Integer],
|
|
|
- XmlParser::elmNames[XmlParser::elm_Boolean],
|
|
|
- XmlParser::elmNames[XmlParser::elm_String],
|
|
|
- XmlParser::elmNames[XmlParser::elm_Enumeration],
|
|
|
- XmlParser::elmNames[XmlParser::elm_Annotations],
|
|
|
- XmlParser::elmNames[XmlParser::elm_Tool],
|
|
|
- XmlParser::elmNames[type],
|
|
|
- childName);
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-fmi2ValueReference ScalarVariable::getValueReference() {
|
|
|
- XmlParser::ValueStatus vs;
|
|
|
- fmi2ValueReference ref = getAttributeUInt(XmlParser::att_valueReference, &vs);
|
|
|
- assert(vs == XmlParser::valueDefined); // this is a required attribute
|
|
|
- return ref;
|
|
|
-}
|
|
|
-XmlParser::Enu ScalarVariable::getVariability() {
|
|
|
- const char *value = getAttributeValue(XmlParser::att_variability);
|
|
|
- if (!value) {
|
|
|
- return XmlParser::enu_continuous; // default
|
|
|
- }
|
|
|
- try {
|
|
|
- return XmlParser::checkEnumValue(value);
|
|
|
- } catch (XmlParserException& ) {
|
|
|
- return XmlParser::enu_BAD_DEFINED;
|
|
|
- }
|
|
|
-}
|
|
|
-XmlParser::Enu ScalarVariable::getCausality() {
|
|
|
- const char *value = getAttributeValue(XmlParser::att_causality);
|
|
|
- if (!value) {
|
|
|
- return XmlParser::enu_local; // default
|
|
|
- }
|
|
|
- try {
|
|
|
- return XmlParser::checkEnumValue(value);
|
|
|
- } catch (XmlParserException& ) {
|
|
|
- return XmlParser::enu_BAD_DEFINED;
|
|
|
- }
|
|
|
-}
|
|
|
-void ScalarVariable::printElement(int indent) {
|
|
|
- Element::printElement(indent);
|
|
|
- int childIndent = indent + 1;
|
|
|
- typeSpec->printElement(childIndent);
|
|
|
- printListOfElements(childIndent, annotations);
|
|
|
-}
|
|
|
-
|
|
|
-ModelStructure::ModelStructure() {
|
|
|
- unknownParentType = XmlParser::elm_BAD_DEFINED;
|
|
|
-}
|
|
|
-
|
|
|
-ModelStructure::~ModelStructure() {
|
|
|
- deleteListOfElements(outputs);
|
|
|
- deleteListOfElements(derivatives);
|
|
|
- deleteListOfElements(discreteStates);
|
|
|
- deleteListOfElements(initialUnknowns);
|
|
|
-}
|
|
|
-void ModelStructure::handleElement(XmlParser *parser, const char *childName, int isEmptyElement) {
|
|
|
- XmlParser::Elm childType = parser->checkElement(childName);
|
|
|
- switch (childType) {
|
|
|
- case XmlParser::elm_Outputs:
|
|
|
- case XmlParser::elm_Derivatives:
|
|
|
- case XmlParser::elm_DiscreteStates:
|
|
|
- case XmlParser::elm_InitialUnknowns:
|
|
|
- {
|
|
|
- // no attributes expected; this class handles also the Unknown
|
|
|
- if (!isEmptyElement) {
|
|
|
- unknownParentType = childType;
|
|
|
- parser->parseChildElements(this);
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- case XmlParser::elm_Unknown:
|
|
|
- {
|
|
|
- Element *unknown = new Element;
|
|
|
- unknown->type = childType;
|
|
|
- parser->parseElementAttributes(unknown);
|
|
|
- if (!isEmptyElement) {
|
|
|
- parser->parseEndElement();
|
|
|
- }
|
|
|
- switch (unknownParentType) {
|
|
|
- case XmlParser::elm_Outputs:
|
|
|
- outputs.push_back(unknown);
|
|
|
- break;
|
|
|
- case XmlParser::elm_Derivatives:
|
|
|
- derivatives.push_back(unknown);
|
|
|
- break;
|
|
|
- case XmlParser::elm_DiscreteStates:
|
|
|
- discreteStates.push_back(unknown);
|
|
|
- break;
|
|
|
- case XmlParser::elm_InitialUnknowns:
|
|
|
- initialUnknowns.push_back(unknown);
|
|
|
- break;
|
|
|
- default: {
|
|
|
- throw XmlParserException(
|
|
|
- "Element '%s' must be inside of '%s' | '%s' | '%s' | '%s'.",
|
|
|
- XmlParser::elmNames[XmlParser::elm_Unknown],
|
|
|
- XmlParser::elmNames[XmlParser::elm_Outputs],
|
|
|
- XmlParser::elmNames[XmlParser::elm_Derivatives],
|
|
|
- XmlParser::elmNames[XmlParser::elm_DiscreteStates],
|
|
|
- XmlParser::elmNames[XmlParser::elm_InitialUnknowns]);
|
|
|
-}
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- default:
|
|
|
- {
|
|
|
- throw XmlParserException(
|
|
|
- "Expected '%s' | '%s' | '%s' | '%s' | '%s' element inside '%s'. Found instead: '%s'.",
|
|
|
- XmlParser::elmNames[XmlParser::elm_Outputs],
|
|
|
- XmlParser::elmNames[XmlParser::elm_Derivatives],
|
|
|
- XmlParser::elmNames[XmlParser::elm_DiscreteStates],
|
|
|
- XmlParser::elmNames[XmlParser::elm_InitialUnknowns],
|
|
|
- XmlParser::elmNames[XmlParser::elm_Unknown],
|
|
|
- XmlParser::elmNames[type],
|
|
|
- childName);
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-void ModelStructure::printElement(int indent) {
|
|
|
- Element::printElement(indent);
|
|
|
- int childIndent = indent + 1;
|
|
|
- printListOfElements(childIndent, outputs);
|
|
|
- printListOfElements(childIndent, derivatives);
|
|
|
- printListOfElements(childIndent, discreteStates);
|
|
|
- printListOfElements(childIndent, initialUnknowns);
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-ModelDescription::ModelDescription() {
|
|
|
- modelExchange = NULL;
|
|
|
- coSimulation = NULL;
|
|
|
- defaultExperiment = NULL;
|
|
|
- modelStructure = NULL;
|
|
|
-}
|
|
|
-ModelDescription::~ModelDescription() {
|
|
|
- deleteListOfElements(unitDefinitions);
|
|
|
- deleteListOfElements(typeDefinitions);
|
|
|
- if (coSimulation) delete coSimulation;
|
|
|
- if (modelExchange) delete modelExchange;
|
|
|
- deleteListOfElements(logCategories);
|
|
|
- if (defaultExperiment) delete defaultExperiment;
|
|
|
- deleteListOfElements(vendorAnnotations);
|
|
|
- deleteListOfElements(modelVariables);
|
|
|
- if (modelStructure) delete modelStructure;
|
|
|
-}
|
|
|
-void ModelDescription::handleElement(XmlParser *parser, const char *childName, int isEmptyElement) {
|
|
|
- XmlParser::Elm childType = parser->checkElement(childName);
|
|
|
- switch (childType) {
|
|
|
- case XmlParser::elm_CoSimulation:
|
|
|
- {
|
|
|
- coSimulation = new Component;
|
|
|
- coSimulation->type = childType;
|
|
|
- parser->parseElementAttributes(coSimulation);
|
|
|
- if (!isEmptyElement) {
|
|
|
- parser->parseChildElements(coSimulation);
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- case XmlParser::elm_ModelExchange:
|
|
|
- {
|
|
|
- modelExchange = new Component;
|
|
|
- modelExchange->type = childType;
|
|
|
- parser->parseElementAttributes(modelExchange);
|
|
|
- if (!isEmptyElement) {
|
|
|
- parser->parseChildElements(modelExchange);
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- case XmlParser::elm_UnitDefinitions:
|
|
|
- {
|
|
|
- // no attributes expected; this class handles the Category
|
|
|
- if (!isEmptyElement) parser->parseChildElements(this);
|
|
|
- break;
|
|
|
- }
|
|
|
- case XmlParser::elm_Unit:
|
|
|
- {
|
|
|
- Unit *unit = new Unit;
|
|
|
- unit->type = childType;
|
|
|
- parser->parseElementAttributes(unit);
|
|
|
- if (!isEmptyElement) {
|
|
|
- parser->parseChildElements(unit);
|
|
|
- }
|
|
|
- unitDefinitions.push_back(unit);
|
|
|
- break;
|
|
|
- }
|
|
|
- case XmlParser::elm_TypeDefinitions:
|
|
|
- {
|
|
|
- // no attributes expected; this class handles also the SimpleType
|
|
|
- if (!isEmptyElement) parser->parseChildElements(this);
|
|
|
- break;
|
|
|
- }
|
|
|
- case XmlParser::elm_SimpleType:
|
|
|
- {
|
|
|
- SimpleType *type = new SimpleType;
|
|
|
- type->type = childType;
|
|
|
- parser->parseElementAttributes(type);
|
|
|
- if (!isEmptyElement) {
|
|
|
- parser->parseChildElements(type);
|
|
|
- }
|
|
|
- typeDefinitions.push_back(type);
|
|
|
- break;
|
|
|
- }
|
|
|
- case XmlParser::elm_DefaultExperiment:
|
|
|
- {
|
|
|
- defaultExperiment = new Element;
|
|
|
- defaultExperiment->type = childType;
|
|
|
- parser->parseElementAttributes(defaultExperiment);
|
|
|
- if (!isEmptyElement) {
|
|
|
- parser->parseEndElement();
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- case XmlParser::elm_LogCategories:
|
|
|
- {
|
|
|
- // no attributes expected; this class handles also the Category
|
|
|
- if (!isEmptyElement) parser->parseChildElements(this);
|
|
|
- break;
|
|
|
- }
|
|
|
- case XmlParser::elm_Category:
|
|
|
- {
|
|
|
- Element *category = new Element;
|
|
|
- category->type = childType;
|
|
|
- parser->parseElementAttributes(category);
|
|
|
- if (!isEmptyElement) {
|
|
|
- parser->parseEndElement();
|
|
|
- }
|
|
|
- logCategories.push_back(category);
|
|
|
- break;
|
|
|
- }
|
|
|
- case XmlParser::elm_VendorAnnotations:
|
|
|
- {
|
|
|
- // no attributes expected; this class handles also the Tool
|
|
|
- if (!isEmptyElement) parser->parseChildElements(this);
|
|
|
- break;
|
|
|
- }
|
|
|
- case XmlParser::elm_Tool:
|
|
|
- {
|
|
|
- Element *tool = new Element;
|
|
|
- tool->type = childType;
|
|
|
- parser->parseElementAttributes(tool, false);
|
|
|
- if (!isEmptyElement) {
|
|
|
- parser->parseSkipChildElement();
|
|
|
- }
|
|
|
- vendorAnnotations.push_back(tool);
|
|
|
- break;
|
|
|
- }
|
|
|
- case XmlParser::elm_ModelVariables:
|
|
|
- {
|
|
|
- // no attributes expected; this class handles also the ScalarVariable
|
|
|
- if (!isEmptyElement) parser->parseChildElements(this);
|
|
|
- break;
|
|
|
- }
|
|
|
- case XmlParser::elm_ScalarVariable:
|
|
|
- {
|
|
|
- ScalarVariable *variable = new ScalarVariable;
|
|
|
- variable->type = childType;
|
|
|
- parser->parseElementAttributes(variable);
|
|
|
- if (!isEmptyElement) {
|
|
|
- parser->parseChildElements(variable);
|
|
|
- }
|
|
|
- modelVariables.push_back(variable);
|
|
|
- break;
|
|
|
- }
|
|
|
- case XmlParser::elm_ModelStructure:
|
|
|
- {
|
|
|
- modelStructure = new ModelStructure;
|
|
|
- modelStructure->type = childType;
|
|
|
- parser->parseElementAttributes(modelStructure);
|
|
|
- if (!isEmptyElement) {
|
|
|
- parser->parseChildElements(modelStructure);
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- default:
|
|
|
- throw XmlParserException("Element '%s' is not expected inside of '%s' | '%s' | '%s' | '%s'.",
|
|
|
- childName,
|
|
|
- XmlParser::elmNames[type]);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void ModelDescription::printElement(int indent) {
|
|
|
- Element::printElement(indent);
|
|
|
- int childIndent = indent + 1;
|
|
|
-
|
|
|
- if (coSimulation) coSimulation->printElement(childIndent);
|
|
|
- if (modelExchange) modelExchange->printElement(childIndent);
|
|
|
- for (std::vector<Unit *>::const_iterator it = unitDefinitions.begin(); it != unitDefinitions.end(); ++it) {
|
|
|
- (*it)->printElement(childIndent);
|
|
|
- }
|
|
|
- for (std::vector<SimpleType *>::const_iterator it = typeDefinitions.begin(); it != typeDefinitions.end(); ++it) {
|
|
|
- (*it)->printElement(childIndent);
|
|
|
- }
|
|
|
- for (std::vector<Element *>::const_iterator it = logCategories.begin(); it != logCategories.end(); ++it) {
|
|
|
- (*it)->printElement(childIndent);
|
|
|
- }
|
|
|
- if (defaultExperiment) defaultExperiment->printElement(childIndent);
|
|
|
- for (std::vector<Element *>::const_iterator it = vendorAnnotations.begin(); it != vendorAnnotations.end(); ++it) {
|
|
|
- (*it)->printElement(childIndent);
|
|
|
- }
|
|
|
- for (std::vector<ScalarVariable *>::const_iterator it = modelVariables.begin(); it != modelVariables.end(); ++it) {
|
|
|
- (*it)->printElement(childIndent);
|
|
|
- }
|
|
|
- if (modelStructure) modelStructure->printElement(childIndent);
|
|
|
-}
|
|
|
-
|
|
|
-SimpleType *ModelDescription::getSimpleType(const char *name) {
|
|
|
- for (std::vector<SimpleType *>::const_iterator it = typeDefinitions.begin(); it != typeDefinitions.end(); ++it) {
|
|
|
- const char *typeName = (*it)->getAttributeValue(XmlParser::att_name);
|
|
|
- if (typeName && 0 == strcmp(typeName, name)) {
|
|
|
- return (*it);
|
|
|
- }
|
|
|
- }
|
|
|
- return NULL;
|
|
|
-}
|
|
|
-
|
|
|
-ScalarVariable *ModelDescription::getVariable(const char *name) {
|
|
|
- if (!name) return NULL;
|
|
|
- for (std::vector<ScalarVariable *>::const_iterator it = modelVariables.begin(); it != modelVariables.end(); ++it) {
|
|
|
- const char *varName = (*it)->getAttributeValue(XmlParser::att_name);
|
|
|
- if (varName && 0 == strcmp(name, varName)) {
|
|
|
- return (*it);
|
|
|
- }
|
|
|
- }
|
|
|
- return NULL;
|
|
|
-}
|
|
|
-
|
|
|
-// Enumeration and Integer have the same base type while
|
|
|
-// Real, String, Boolean define own base types.
|
|
|
-static int sameBaseType(XmlParser::Elm t1, XmlParser::Elm t2){
|
|
|
- return t1 == t2 ||
|
|
|
- t1 == XmlParser::elm_Enumeration && t2 == XmlParser::elm_Integer ||
|
|
|
- t2 == XmlParser::elm_Enumeration && t1 == XmlParser::elm_Integer;
|
|
|
-}
|
|
|
-
|
|
|
-ScalarVariable *ModelDescription::getVariable(fmi2ValueReference vr, XmlParser::Elm type) {
|
|
|
- for (std::vector<ScalarVariable *>::const_iterator it = modelVariables.begin(); it != modelVariables.end(); ++it) {
|
|
|
- if (vr == (*it)->getValueReference() && sameBaseType(type, (*it)->typeSpec->type)) {
|
|
|
- return (*it);
|
|
|
- }
|
|
|
- }
|
|
|
- return NULL;
|
|
|
-}
|
|
|
-
|
|
|
-const char *ModelDescription::getDescriptionForVariable(ScalarVariable *sv) {
|
|
|
- const char *desc = sv->getAttributeValue(XmlParser::att_description);
|
|
|
- // found description
|
|
|
- if (desc) return desc;
|
|
|
- // look for description of declared type:
|
|
|
- const char *typeName = sv->typeSpec->getAttributeValue(XmlParser::att_declaredType);
|
|
|
- if (typeName) {
|
|
|
- SimpleType *type = getSimpleType(typeName);
|
|
|
- if (type) return type->getAttributeValue(XmlParser::att_description);
|
|
|
- }
|
|
|
- return NULL;
|
|
|
-}
|
|
|
-
|
|
|
-const char *ModelDescription::getAttributeFromTypeOrDeclaredType(ScalarVariable *sv, XmlParser::Att a) {
|
|
|
- const char *stringValue = sv->typeSpec->getAttributeValue(a);
|
|
|
- if (stringValue) return stringValue;
|
|
|
- // look for stringValue inside declared type:
|
|
|
- const char *typeName = sv->typeSpec->getAttributeValue(XmlParser::att_declaredType);
|
|
|
- if (typeName) {
|
|
|
- SimpleType *type = getSimpleType(typeName);
|
|
|
- if (type) return type->getAttributeValue(a);
|
|
|
- }
|
|
|
- return NULL;
|
|
|
-}
|