Skip to content

Commit

Permalink
refs #21: Do not error if cell/node/key is not found
Browse files Browse the repository at this point in the history
* Report validity by new Boolean output flag ''exist'' (on scalar get functions only)
* Use ModelicaMessage (and not ModelicaError) (Can be changed to ModelicaWarning once there is proper tool support).
  • Loading branch information
tbeu committed Sep 29, 2017
1 parent c3ec486 commit 54115a2
Show file tree
Hide file tree
Showing 14 changed files with 865 additions and 430 deletions.
66 changes: 58 additions & 8 deletions ExternData/Examples/package.mo
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// CP: 65001
/* package.mo - Modelica library for data I/O of CSV, INI, JSON, MATLAB MAT, Excel XLS/XLSX or XML files
/* package.mo - Modelica Examples library for data I/O of CSV, INI, JSON, MATLAB MAT, TIR, Excel XLS/XLSX or XML files
*
* Copyright (C) 2015-2017, tbeu
* All rights reserved.
Expand Down Expand Up @@ -30,15 +30,15 @@ package Examples "Test examples"
extends Modelica.Icons.ExamplesPackage;
model CSVTest "CSV file read test"
extends Modelica.Icons.Example;
inner CSVFile csvfile(fileName=Modelica.Utilities.Files.loadResource("modelica://ExternData/Resources/Examples/test.csv")) annotation(Placement(transformation(extent={{-80,60},{-60,80}})));
inner parameter CSVFile csvfile(fileName=Modelica.Utilities.Files.loadResource("modelica://ExternData/Resources/Examples/test.csv")) annotation(Placement(transformation(extent={{-80,60},{-60,80}})));
Modelica.Blocks.Sources.TimeTable timeTable(table=csvfile.getRealArray2D(3, 2)) annotation(Placement(transformation(extent={{-50,60},{-30,80}})));
annotation(experiment(StopTime=1),
Documentation(info="<html><p>This example model reads the table parameter from the CSV file <a href=\"modelica://ExternData/Resources/Examples/test.csv\">test.csv</a>. The table parameter is read as Real array of dimension 3x2 by function <a href=\"modelica://ExternData.CSVFile.getRealArray2D\">ExternData.CSVFile.getRealArray2D</a>. The read parameter is assigned by a parameter binding to the appropriate model parameter.</p></html>"));
end CSVTest;

model INITest "INI file read test"
extends Modelica.Icons.Example;
inner INIFile inifile(fileName=Modelica.Utilities.Files.loadResource("modelica://ExternData/Resources/Examples/test.ini")) annotation(Placement(transformation(extent={{-80,60},{-60,80}})));
inner parameter INIFile inifile(fileName=Modelica.Utilities.Files.loadResource("modelica://ExternData/Resources/Examples/test.ini")) annotation(Placement(transformation(extent={{-80,60},{-60,80}})));
Modelica.Blocks.Math.Gain gain1(k=inifile.getReal("gain.k", "set1")) annotation(Placement(transformation(extent={{-15,60},{5,80}})));
Modelica.Blocks.Math.Gain gain2(k=Modelica.Utilities.Strings.scanReal(inifile.getString("gain.k", "set2"))) annotation(Placement(transformation(extent={{-15,30},{5,50}})));
Modelica.Blocks.Sources.Clock clock annotation(Placement(transformation(extent={{-50,60},{-30,80}})));
Expand All @@ -51,7 +51,7 @@ package Examples "Test examples"

model JSONTest "JSON file read test"
extends Modelica.Icons.Example;
inner JSONFile jsonfile(fileName=Modelica.Utilities.Files.loadResource("modelica://ExternData/Resources/Examples/test.json")) annotation(Placement(transformation(extent={{-80,60},{-60,80}})));
inner parameter JSONFile jsonfile(fileName=Modelica.Utilities.Files.loadResource("modelica://ExternData/Resources/Examples/test.json")) annotation(Placement(transformation(extent={{-80,60},{-60,80}})));
Modelica.Blocks.Math.Gain gain1(k=jsonfile.getReal("set1.gain.k")) annotation(Placement(transformation(extent={{-15,60},{5,80}})));
Modelica.Blocks.Math.Gain gain2(k=Modelica.Utilities.Strings.scanReal(jsonfile.getString("set2.gain.k"))) annotation(Placement(transformation(extent={{-15,30},{5,50}})));
Modelica.Blocks.Sources.Clock clock annotation(Placement(transformation(extent={{-50,60},{-30,80}})));
Expand All @@ -65,19 +65,44 @@ package Examples "Test examples"

model MATTest "MAT-file read test"
extends Modelica.Icons.Example;
inner MATFile matfile(fileName=Modelica.Utilities.Files.loadResource("modelica://ExternData/Resources/Examples/test_v7.3.mat")) annotation(Placement(transformation(extent={{-80,60},{-60,80}})));
inner parameter MATFile matfile(fileName=Modelica.Utilities.Files.loadResource("modelica://ExternData/Resources/Examples/test_v7.3.mat")) annotation(Placement(transformation(extent={{-80,60},{-60,80}})));
Modelica.Blocks.Sources.TimeTable timeTable(table=matfile.getRealArray2D("table1", 3, 2)) annotation(Placement(transformation(extent={{-50,60},{-30,80}})));
annotation(experiment(StopTime=1),
Documentation(info="<html><p>This example model reads the table parameter from variable table1 of the HDF5-based MAT-file <a href=\"modelica://ExternData/Resources/Examples/test_v7.3.mat\">test_v7.3.mat</a>. The table parameter is read as Real array of dimension 3x2 by function <a href=\"modelica://ExternData.MATFile.getRealArray2D\">ExternData.MATFile.getRealArray2D</a>. The read parameter is assigned by a parameter binding to the appropriate model parameter.</p></html>"));
end MATTest;

model XLSTest "Excel XLS file read test"
extends Modelica.Icons.Example;
inner XLSFile xlsfile(fileName=Modelica.Utilities.Files.loadResource("modelica://ExternData/Resources/Examples/test.xls")) annotation(Placement(transformation(extent={{-80,60},{-60,80}})));
inner parameter XLSFile xlsfile(fileName=Modelica.Utilities.Files.loadResource("modelica://ExternData/Resources/Examples/test.xls")) annotation(Placement(transformation(extent={{-80,60},{-60,80}})));
Modelica.Blocks.Math.Gain gain1(k=xlsfile.getReal("B2", "set1")) annotation(Placement(transformation(extent={{-15,60},{5,80}})));
Modelica.Blocks.Math.Gain gain2(k=Modelica.Utilities.Strings.scanReal(xlsfile.getString("B2", "set2"))) annotation(Placement(transformation(extent={{-15,30},{5,50}})));
Modelica.Blocks.Sources.Clock clock annotation(Placement(transformation(extent={{-50,60},{-30,80}})));
Modelica.Blocks.Sources.TimeTable timeTable(table=xlsfile.getRealArray2D("A1", "table1", 3, 2)) annotation(Placement(transformation(extent={{-50,30},{-30,50}})));
parameter Real sumB = computeColSum(xlsfile, "B") "Sum of column B";
function computeColSum "Compute column sum"
extends Modelica.Icons.Function;
input XLSFile xlsfile "Excel XLS file record";
input String col = "A" "Column";
input String sheetName="" "Sheet name";
input Integer startRow = 2 "Start row";
output Real colSum "Column sum";
protected
Integer row;
Real val;
Boolean exist;
algorithm
colSum := 0.0;
row := startRow;
exist := true;
while exist loop
(val, exist) := Functions.XLS.getReal(cellAddress=col + String(row), sheetName=sheetName, xls=xlsfile.xls);
if exist then
colSum := colSum + val;
row := row + 1;
end if;
end while;
annotation(Documentation(info="<html><p>This function computes the column sum of a given column and sheet of an Excel XLS file.</p></html>"));
end computeColSum;
equation
connect(clock.y,gain1.u) annotation(Line(points={{-29,70},{-17,70}}, color={0,0,127}));
connect(clock.y,gain2.u) annotation(Line(points={{-29,70},{-22,70},{-22,40},{-17,40}}, color={0,0,127}));
Expand All @@ -87,11 +112,36 @@ package Examples "Test examples"

model XLSXTest "Excel XLSX file read test"
extends Modelica.Icons.Example;
inner XLSXFile xlsxfile(fileName=Modelica.Utilities.Files.loadResource("modelica://ExternData/Resources/Examples/test.xlsx")) annotation(Placement(transformation(extent={{-80,60},{-60,80}})));
inner parameter XLSXFile xlsxfile(fileName=Modelica.Utilities.Files.loadResource("modelica://ExternData/Resources/Examples/test.xlsx")) annotation(Placement(transformation(extent={{-80,60},{-60,80}})));
Modelica.Blocks.Math.Gain gain1(k=xlsxfile.getReal("B2", "set1")) annotation(Placement(transformation(extent={{-15,60},{5,80}})));
Modelica.Blocks.Math.Gain gain2(k=Modelica.Utilities.Strings.scanReal(xlsxfile.getString("B2", "set2"))) annotation(Placement(transformation(extent={{-15,30},{5,50}})));
Modelica.Blocks.Sources.Clock clock annotation(Placement(transformation(extent={{-50,60},{-30,80}})));
Modelica.Blocks.Sources.TimeTable timeTable(table=xlsxfile.getRealArray2D("A1", "table1", 3, 2)) annotation(Placement(transformation(extent={{-50,30},{-30,50}})));
parameter Real sumB = computeColSum(xlsxfile, "B") "Sum of column B";
function computeColSum "Compute column sum"
extends Modelica.Icons.Function;
input XLSXFile xlsxfile "Excel XLSX file record";
input String col = "A" "Column";
input String sheetName="" "Sheet name";
input Integer startRow = 2 "Start row";
output Real colSum "Column sum";
protected
Integer row;
Real val;
Boolean exist;
algorithm
colSum := 0.0;
row := startRow;
exist := true;
while exist loop
(val, exist) := Functions.XLSX.getReal(cellAddress=col + String(row), sheetName=sheetName, xlsx=xlsxfile.xlsx);
if exist then
colSum := colSum + val;
row := row + 1;
end if;
end while;
annotation(Documentation(info="<html><p>This function computes the column sum of a given column and sheet of an Excel XLSX file.</p></html>"));
end computeColSum;
equation
connect(clock.y,gain1.u) annotation(Line(points={{-29,70},{-17,70}}, color={0,0,127}));
connect(clock.y,gain2.u) annotation(Line(points={{-29,70},{-22,70},{-22,40},{-17,40}}, color={0,0,127}));
Expand All @@ -101,7 +151,7 @@ package Examples "Test examples"

model XMLTest "XML file read test"
extends Modelica.Icons.Example;
inner XMLFile xmlfile(fileName=Modelica.Utilities.Files.loadResource("modelica://ExternData/Resources/Examples/test.xml")) annotation(Placement(transformation(extent={{-80,60},{-60,80}})));
inner parameter XMLFile xmlfile(fileName=Modelica.Utilities.Files.loadResource("modelica://ExternData/Resources/Examples/test.xml")) annotation(Placement(transformation(extent={{-80,60},{-60,80}})));
Modelica.Blocks.Math.Gain gain1(k=xmlfile.getReal("set1.gain.k")) annotation(Placement(transformation(extent={{-15,60},{5,80}})));
Modelica.Blocks.Math.Gain gain2(k=Modelica.Utilities.Strings.scanReal(xmlfile.getString("set2.gain.k"))) annotation(Placement(transformation(extent={{-15,30},{5,50}})));
Modelica.Blocks.Sources.Clock clock annotation(Placement(transformation(extent={{-50,60},{-30,80}})));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ EXPORTS
ED_getDoubleFromJSON
ED_getStringFromJSON
ED_getIntFromJSON
ED_getBooleanFromJSON
ED_getArray1DDimensionFromJSON
ED_getArray2DDimensionsFromJSON
ED_getDoubleArray1DFromJSON
Expand Down
81 changes: 60 additions & 21 deletions ExternData/Resources/C-Sources/ED_INIFile.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,99 +160,138 @@ void ED_destroyINI(void* _ini)
}
}

double ED_getDoubleFromINI(void* _ini, const char* varName, const char* section, int strict)
double ED_getDoubleFromINI(void* _ini, const char* varName, const char* section, int strict, int* exist)
{
double ret = 0.;
INIFile* ini = (INIFile*)_ini;
if (ini != NULL) {
INISection* _section = findSection(ini, section);
if (_section != NULL) {
INIPair* pair = findKey(_section, varName);
*exist = 1;
if (pair != NULL) {
if (ED_strtod(pair->value, ini->loc, &ret, strict)) {
ModelicaFormatError("Cannot read double value \"%s\" from file \"%s\"\n",
pair->value, ini->fileName);
if (NULL != pair->value) {
if (ED_strtod(pair->value, ini->loc, &ret, strict)) {
ModelicaFormatError("Cannot read double value \"%s\" from file \"%s\"\n",
pair->value, ini->fileName);
}
}
else {
ModelicaFormatError("Cannot read value for key \"%s\" from file \"%s\"\n",
varName, ini->fileName);
*exist = 0;
}
}
else {
ModelicaFormatError("Cannot read key \"%s\" from file \"%s\"\n",
ModelicaFormatMessage("Cannot read key \"%s\" from file \"%s\"\n",
varName, ini->fileName);
*exist = 0;
}
}
else {
if (strlen(section) > 0) {
ModelicaFormatError("Cannot read section \"%s\" from file \"%s\"\n",
ModelicaFormatMessage("Cannot read section \"%s\" from file \"%s\"\n",
section, ini->fileName);
}
else {
ModelicaFormatError("Cannot read empty section from file \"%s\"\n",
ModelicaFormatMessage("Cannot read empty section from file \"%s\"\n",
ini->fileName);
}
*exist = 0;
}
}
else {
*exist = 0;
}
return ret;
}

const char* ED_getStringFromINI(void* _ini, const char* varName, const char* section)
const char* ED_getStringFromINI(void* _ini, const char* varName, const char* section, int* exist)
{
INIFile* ini = (INIFile*)_ini;
if (ini != NULL) {
INISection* _section = findSection(ini, section);
if (_section != NULL) {
INIPair* pair = findKey(_section, varName);
*exist = 1;
if (pair != NULL) {
char* ret = ModelicaAllocateString(strlen(pair->value));
strcpy(ret, pair->value);
return (const char*)ret;
if (NULL != pair->value) {
char* ret = ModelicaAllocateString(strlen(pair->value));
strcpy(ret, pair->value);
return (const char*)ret;
}
else {
ModelicaFormatError("Cannot read value for key \"%s\" from file \"%s\"\n",
varName, ini->fileName);
*exist = 0;
}
}
else {
ModelicaFormatError("Cannot read key \"%s\" from file \"%s\"\n",
ModelicaFormatMessage("Cannot read key \"%s\" from file \"%s\"\n",
varName, ini->fileName);
*exist = 0;
}
}
else {
if (strlen(section) > 0) {
ModelicaFormatError("Cannot read section \"%s\" from file \"%s\"\n",
ModelicaFormatMessage("Cannot read section \"%s\" from file \"%s\"\n",
section, ini->fileName);
}
else {
ModelicaFormatError("Cannot read empty section from file \"%s\"\n",
ModelicaFormatMessage("Cannot read empty section from file \"%s\"\n",
ini->fileName);
}
*exist = 0;
}
}
else {
*exist = 0;
}
return "";
}

int ED_getIntFromINI(void* _ini, const char* varName, const char* section, int strict)
int ED_getIntFromINI(void* _ini, const char* varName, const char* section, int strict, int* exist)
{
long ret = 0;
INIFile* ini = (INIFile*)_ini;
if (ini != NULL) {
INISection* _section = findSection(ini, section);
if (_section != NULL) {
INIPair* pair = findKey(_section, varName);
*exist = 1;
if (pair != NULL) {
if (ED_strtol(pair->value, ini->loc, &ret, strict)) {
ModelicaFormatError("Cannot read int value \"%s\" from file \"%s\"\n",
pair->value, ini->fileName);
if (NULL != pair->value) {
if (ED_strtol(pair->value, ini->loc, &ret, strict)) {
ModelicaFormatError("Cannot read int value \"%s\" from file \"%s\"\n",
pair->value, ini->fileName);
}
}
else {
ModelicaFormatError("Cannot read value for key \"%s\" from file \"%s\"\n",
varName, ini->fileName);
*exist = 0;
}
}
else {
ModelicaFormatError("Cannot read key \"%s\" from file \"%s\"\n",
ModelicaFormatMessage("Cannot read key \"%s\" from file \"%s\"\n",
varName, ini->fileName);
*exist = 0;
}
}
else {
if (strlen(section) > 0) {
ModelicaFormatError("Cannot read section \"%s\" from file \"%s\"\n",
ModelicaFormatMessage("Cannot read section \"%s\" from file \"%s\"\n",
section, ini->fileName);
}
else {
ModelicaFormatError("Cannot read empty section from file \"%s\"\n",
ModelicaFormatMessage("Cannot read empty section from file \"%s\"\n",
ini->fileName);
}
*exist = 0;
}
}
else {
*exist = 0;
}
return (int)ret;
}
Loading

0 comments on commit 54115a2

Please sign in to comment.