diff --git a/src/fmi4c.c b/src/fmi4c.c index e03e7bd..a9dce5e 100644 --- a/src/fmi4c.c +++ b/src/fmi4c.c @@ -72,6 +72,12 @@ const char* fmi4c_getErrorMessages() return fmi4cErrorMessage; } +void freeDuplicatedConstChar(const char* ptr) { + if(ptr == NULL) { + free((void*)ptr); + } +} + //! @brief Parses modelDescription.xml for FMI 1 //! @param fmu FMU handle @@ -236,7 +242,7 @@ bool parseModelDescriptionFmi1(fmiHandle *fmu) parseStringAttributeEzXml(varElement, "description", &var.description); var.causality = fmi1CausalityInternal; - const char* causality; + const char* causality = NULL; if(parseStringAttributeEzXml(varElement, "causality", &causality)) { if(!strcmp(causality, "input")) { var.causality = fmi1CausalityInput; @@ -252,12 +258,14 @@ bool parseModelDescriptionFmi1(fmiHandle *fmu) } else { printf("Unknown causality: %s\n", causality); + freeDuplicatedConstChar(causality); return false; } + freeDuplicatedConstChar(causality); } var.variability = fmi1VariabilityContinuous; - const char* variability; + const char* variability = NULL; if(parseStringAttributeEzXml(varElement, "variability", &variability)) { if(!strcmp(variability, "parameter")) { var.variability = fmi1VariabilityParameter; @@ -273,12 +281,14 @@ bool parseModelDescriptionFmi1(fmiHandle *fmu) } else { printf("Unknown variability: %s\n", variability); + freeDuplicatedConstChar(variability); return false; } + freeDuplicatedConstChar(variability); } var.alias = fmi1AliasNoAlias; - const char* alias; + const char* alias = NULL; if(parseStringAttributeEzXml(varElement, "alias", &alias)) { if(!strcmp(alias, "alias")) { var.alias = fmi1AliasAlias; @@ -289,6 +299,12 @@ bool parseModelDescriptionFmi1(fmiHandle *fmu) else if(!strcmp(alias, "noAlias")) { var.alias = fmi1AliasNoAlias; } + else { + printf("Unknown alias: %s\n", alias); + freeDuplicatedConstChar(alias); + return false; + } + freeDuplicatedConstChar(alias); } var.hasStartValue = false; @@ -578,7 +594,7 @@ bool parseModelDescriptionFmi2(fmiHandle *fmu) parseBooleanAttributeEzXml(varElement, "canHandleMultipleSetPerTimeInstant", &var.canHandleMultipleSetPerTimeInstant); var.causality = fmi2CausalityLocal; - const char* causality; + const char* causality = NULL; if(parseStringAttributeEzXml(varElement, "causality", &causality)) { if(!strcmp(causality, "input")) { var.causality = fmi2CausalityInput; @@ -600,12 +616,14 @@ bool parseModelDescriptionFmi2(fmiHandle *fmu) } else { printf("Unknown causality: %s\n", causality); + freeDuplicatedConstChar(causality); return false; } + freeDuplicatedConstChar(causality); } var.variability = fmi2VariabilityContinuous; - const char* variability; + const char* variability = NULL; if(parseStringAttributeEzXml(varElement, "variability", &variability)) { if(variability && !strcmp(variability, "fixed")) { var.variability = fmi2VariabilityFixed; @@ -624,12 +642,14 @@ bool parseModelDescriptionFmi2(fmiHandle *fmu) } else if(variability) { printf("Unknown variability: %s\n", variability); + freeDuplicatedConstChar(variability); return false; } + freeDuplicatedConstChar(variability); } var.initial = fmi2InitialUnknown; - const char* initial; + const char* initial = NULL; if(parseStringAttributeEzXml(varElement, "initial", &initial)) { if(initial && !strcmp(initial, "approx")) { var.initial = fmi2InitialApprox; @@ -641,9 +661,15 @@ bool parseModelDescriptionFmi2(fmiHandle *fmu) var.initial = fmi2InitialExact; } else { - // calculate the initial value according to fmi specification 2.2 table page 51 - var.initial = initialDefaultTable[mapVariabilityIndex[var.variability]][mapCausalityIndex[var.causality]]; + printf("Unknown intial: %s\n", initial); + freeDuplicatedConstChar(initial); + return false; } + freeDuplicatedConstChar(variability); + } + else { + // calculate the initial value according to fmi specification 2.2 table page 51 + var.initial = initialDefaultTable[mapVariabilityIndex[var.variability]][mapCausalityIndex[var.causality]]; } var.hasStartValue = false; @@ -1269,7 +1295,7 @@ bool parseModelDescriptionFmi3(fmiHandle *fmu) parseStringAttributeEzXml(typeElement, "description", &fmu->fmi3.clockTypes[iClock].description); parseBooleanAttributeEzXml(typeElement, "canBeDeactivated", &fmu->fmi3.clockTypes[iClock].canBeDeactivated); parseUInt32AttributeEzXml(typeElement, "priority", &fmu->fmi3.clockTypes[iClock].priority); - const char* intervalVariability; + const char* intervalVariability = NULL; parseStringAttributeEzXml(typeElement, "intervalVariability", &intervalVariability); if(intervalVariability && !strcmp(intervalVariability, "calculated")) { fmu->fmi3.clockTypes[iClock].intervalVariability = fmi3IntervalVariabilityCalculated; @@ -1294,8 +1320,10 @@ bool parseModelDescriptionFmi3(fmiHandle *fmu) } else if(intervalVariability) { printf("Unknown interval variability: %s\n", intervalVariability); + freeDuplicatedConstChar(intervalVariability); return false; } + freeDuplicatedConstChar(intervalVariability); parseFloat32AttributeEzXml(typeElement, "intervalDecimal", &fmu->fmi3.clockTypes[iClock].intervalDecimal); parseFloat32AttributeEzXml(typeElement, "shiftDecimal", &fmu->fmi3.clockTypes[iClock].shiftDecimal); parseBooleanAttributeEzXml(typeElement, "supportsFraction", &fmu->fmi3.clockTypes[iClock].supportsFraction); @@ -1356,38 +1384,41 @@ bool parseModelDescriptionFmi3(fmiHandle *fmu) parseBooleanAttributeEzXml(varElement, "intermediateUpdate", &var.intermediateUpdate); parseUInt32AttributeEzXml(varElement, "previous", &var.previous); parseStringAttributeEzXml(varElement, "declaredType", &var.declaredType); - const char* clocks = ""; - parseStringAttributeEzXml(varElement, "clocks", &clocks); - char* nonConstClocks = _strdup(clocks); - //Count number of clocks var.numberOfClocks = 0; - if(nonConstClocks[0]) { - var.numberOfClocks = 1; - } - for(int i=0; nonConstClocks[i]; ++i) { - if(nonConstClocks[i] == ' ') { - ++var.numberOfClocks; + const char* clocks = NULL; + if (parseStringAttributeEzXml(varElement, "clocks", &clocks)) { + // Count number of clocks + if(clocks[0]) { + var.numberOfClocks = 1; + } + for(int i=0; clocks[i]; ++i) { + if(clocks[i] == ' ') { + ++var.numberOfClocks; + } } - } - //Allocate memory for clocks - if(var.numberOfClocks > 0) { - var.clocks = malloc(var.numberOfClocks*sizeof(int)); - } - //Read clocks - const char* delim = " "; - for(int i=0; i 0) { + var.clocks = malloc(var.numberOfClocks*sizeof(int)); } - else { - var.clocks[i] = atoi(strtok(NULL, delim)); + + //Read clocks + char* mutable_clocks = _strdup(clocks); + const char* delim = " "; + for(int i=0; i 0) { free(var.clocks); } + freeDuplicatedConstChar(causality); return false; } + freeDuplicatedConstChar(causality); } - const char* variability; + const char* variability = NULL; if(var.datatype == fmi3DataTypeFloat64 || var.datatype == fmi3DataTypeFloat32) { var.variability = fmi3VariabilityContinuous; } @@ -1589,8 +1622,10 @@ bool parseModelDescriptionFmi3(fmiHandle *fmu) } else if(initial) { printf("Unknown initial: %s\n", initial); + freeDuplicatedConstChar(initial); return false; } + freeDuplicatedConstChar(initial); } //Parse arguments common to float, int and enumeration @@ -1637,7 +1672,7 @@ bool parseModelDescriptionFmi3(fmiHandle *fmu) parseInt64AttributeEzXml(varElement, "resolution", &var.resolution); parseInt64AttributeEzXml(varElement, "intervalCounter", &var.intervalCounter); parseInt64AttributeEzXml(varElement, "shiftCounter", &var.shiftCounter); - const char* intervalVariability; + const char* intervalVariability = NULL; parseStringAttributeEzXml(varElement, "intervalVariability", &intervalVariability); if(intervalVariability && !strcmp(intervalVariability, "calculated")) { var.intervalVariability = fmi3IntervalVariabilityCalculated; @@ -1662,8 +1697,10 @@ bool parseModelDescriptionFmi3(fmiHandle *fmu) } else if(intervalVariability) { printf("Unknown interval variability: %s\n", intervalVariability); + freeDuplicatedConstChar(intervalVariability); return false; } + freeDuplicatedConstChar(intervalVariability); } if(fmu->fmi3.numberOfVariables >= fmu->fmi3.variablesSize) { @@ -4230,9 +4267,11 @@ fmiHandle *fmi4c_loadFmu(const char *fmufile, const char* instanceName) } else { printf("Unsupported FMI version: %s\n", version); + freeDuplicatedConstChar(version); free(fmu); return NULL; } + freeDuplicatedConstChar(version); } else { printf("FMI version not specified."); @@ -4463,10 +4502,6 @@ fmiHandle *fmi4c_loadFmu(const char *fmufile, const char* instanceName) } -void freeDuplicatedConstChar(const char* ptr) { - free((void*)ptr); -} - //! @brief Free FMU dll //! @param fmu FMU handle void fmi4c_freeFmu(fmiHandle *fmu)