Skip to content

Commit

Permalink
Improve handling of temporary XML string variables
Browse files Browse the repository at this point in the history
  • Loading branch information
robbr48 committed Nov 4, 2024
1 parent 1cae8b7 commit fb76952
Showing 1 changed file with 75 additions and 40 deletions.
115 changes: 75 additions & 40 deletions src/fmi4c.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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<var.numberOfClocks; ++i) {
if(i == 0) {
var.clocks[i] = atoi(strtok(nonConstClocks, delim));
//Allocate memory for clocks
if(var.numberOfClocks > 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<var.numberOfClocks; ++i) {
if(i == 0) {
var.clocks[i] = atoi(strtok(mutable_clocks, delim));
}
else {
var.clocks[i] = atoi(strtok(NULL, delim));
}
}
}

free(nonConstClocks);
freeDuplicatedConstChar(mutable_clocks);
freeDuplicatedConstChar(clocks);
}

var.hasStartValue = false;

Expand Down Expand Up @@ -1500,7 +1531,7 @@ bool parseModelDescriptionFmi3(fmiHandle *fmu)
}

var.causality = fmi3CausalityLocal;
const char* causality;
const char* causality = NULL;
if(parseStringAttributeEzXml(varElement, "causality", &causality)) {
if(!strcmp(causality, "parameter")) {
var.causality = fmi3CausalityParameter;
Expand Down Expand Up @@ -1528,12 +1559,14 @@ bool parseModelDescriptionFmi3(fmiHandle *fmu)
if(var.numberOfClocks > 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;
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -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.");
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit fb76952

Please sign in to comment.