Skip to content

Commit

Permalink
Use a locale-independent strtod
Browse files Browse the repository at this point in the history
This resolves ticket:4020
  • Loading branch information
sjoelund committed May 15, 2020
1 parent 85d0e45 commit ad22570
Show file tree
Hide file tree
Showing 16 changed files with 106 additions and 38 deletions.
3 changes: 2 additions & 1 deletion OMCompiler/Compiler/runtime/ptolemyio.cpp
Expand Up @@ -36,6 +36,7 @@
#include <fstream>
#include <string>

#include "util/omc_numbers.h"


using namespace std;
Expand Down Expand Up @@ -117,7 +118,7 @@ void * read_ptolemy_dataset(const char*filename, void* vars,int datasize)
int commapos=values.find(",");

buf1 = values.substr(commapos+1).c_str();
val = strtod(buf1,&buf2); // Second value after comma
val = om_strtod(buf1,&buf2); // Second value after comma

if (buf1 == buf2) {
// We may be trying to parse Infinity on a Windows platform.
Expand Down
1 change: 1 addition & 0 deletions OMCompiler/SimulationRuntime/c/Makefile.common
Expand Up @@ -111,6 +111,7 @@ RUNTIMEUTIL_HEADERS = \
./util/omc_file.h \
./util/omc_mmap.h \
./util/omc_msvc.h \
./util/omc_numbers.h \
./util/omc_spinlock.h \
./util/parallel_helper.h \
./util/read_matlab4.c \
Expand Down
4 changes: 2 additions & 2 deletions OMCompiler/SimulationRuntime/c/Makefile.objs
Expand Up @@ -28,7 +28,7 @@ else
UTIL_OBJS_NO_FMI=
endif

UTIL_OBJS_MINIMAL=base_array$(OBJ_EXT) boolean_array$(OBJ_EXT) omc_error$(OBJ_EXT) omc_file$(OBJ_EXT) division$(OBJ_EXT) generic_array$(OBJ_EXT) index_spec$(OBJ_EXT) integer_array$(OBJ_EXT) list$(OBJ_EXT) modelica_string$(OBJ_EXT) real_array$(OBJ_EXT) ringbuffer$(OBJ_EXT) string_array$(OBJ_EXT) utility$(OBJ_EXT) varinfo$(OBJ_EXT) ModelicaUtilities$(OBJ_EXT) omc_msvc$(OBJ_EXT) parallel_helper$(OBJ_EXT) simulation_options$(OBJ_EXT) rational$(OBJ_EXT) modelica_string_lit$(OBJ_EXT) omc_init$(OBJ_EXT) omc_mmap$(OBJ_EXT) jacobian_util$(OBJ_EXT) $(UTIL_OBJS_NO_FMI)
UTIL_OBJS_MINIMAL=base_array$(OBJ_EXT) boolean_array$(OBJ_EXT) omc_error$(OBJ_EXT) omc_file$(OBJ_EXT) division$(OBJ_EXT) generic_array$(OBJ_EXT) index_spec$(OBJ_EXT) integer_array$(OBJ_EXT) list$(OBJ_EXT) modelica_string$(OBJ_EXT) real_array$(OBJ_EXT) ringbuffer$(OBJ_EXT) string_array$(OBJ_EXT) utility$(OBJ_EXT) varinfo$(OBJ_EXT) ModelicaUtilities$(OBJ_EXT) omc_msvc$(OBJ_EXT) omc_numbers$(OBJ_EXT) parallel_helper$(OBJ_EXT) simulation_options$(OBJ_EXT) rational$(OBJ_EXT) modelica_string_lit$(OBJ_EXT) omc_init$(OBJ_EXT) omc_mmap$(OBJ_EXT) jacobian_util$(OBJ_EXT) $(UTIL_OBJS_NO_FMI)
UTIL_HFILES_MINIMAL=base_array.h boolean_array.h division.h generic_array.h omc_error.h omc_file.h index_spec.h integer_array.h list.h modelica.h modelica_string.h read_write.h real_array.h ringbuffer.h rtclock.h string_array.h utility.h varinfo.h simulation_options.h omc_mmap.h modelica_string_lit.h omc_init.h

ifeq ($(OMC_MINIMAL_RUNTIME),)
Expand Down Expand Up @@ -193,4 +193,4 @@ ALL_PATHS_CLEAN_OBJS = $(ALL_PATHS:%=%*$(OBJ_EXT)) $(ALL_PATHS:%=%*.a) meta/gc/*

BASE_OBJS = $(GCOBJSPATH) $(METAOBJSPATH) $(UTILOBJSPATH) ./meta/meta_modelica_catch$(OBJ_EXT)

COMMON_HEADERS = util/omc_msvc.h openmodelica.h openmodelica_types.h ModelicaUtilities.h omc_inline.h openmodelica_func.h simulation_data.h omc_simulation_settings.h
COMMON_HEADERS = util/omc_msvc.h ./util/omc_numbers.h openmodelica.h openmodelica_types.h ModelicaUtilities.h omc_inline.h openmodelica_func.h simulation_data.h omc_simulation_settings.h
3 changes: 2 additions & 1 deletion OMCompiler/SimulationRuntime/c/meta/meta_modelica_builtin.c
Expand Up @@ -40,6 +40,7 @@

#define GEN_META_MODELICA_BUILTIN_BOXPTR
#include "meta_modelica_builtin_boxptr.h"
#include "../util/omc_numbers.h"

metamodelica_string intString(modelica_integer i)
{
Expand Down Expand Up @@ -99,7 +100,7 @@ modelica_real nobox_stringReal(threadData_t *threadData,metamodelica_string s)
char *endptr,*str=MMC_STRINGDATA(s);
MMC_CHECK_STRING(s);
errno = 0;
res = strtod(str,&endptr);
res = om_strtod(str,&endptr);
if (errno != 0 || str == endptr)
MMC_THROW_INTERNAL();
if (*endptr != '\0')
Expand Down
Expand Up @@ -36,6 +36,7 @@
#include <stdio.h>
#include "../util/rtclock.h"
#include "../util/omc_mmap.h"
#include "../util/omc_numbers.h"
#include "solver/model_help.h"

static inline const char* skipSpace(const char* str)
Expand Down Expand Up @@ -135,7 +136,7 @@ static const char* skipValue(const char* str)
case '9':
{
char *endptr = NULL;
strtod(str,&endptr);
om_strtod(str,&endptr);
if (str == endptr) {
fprintf(stderr, "Not a number, got %.20s\n", str);
abort();
Expand Down Expand Up @@ -175,7 +176,7 @@ static inline const char* assertNumber(const char *str, double expected)
char *endptr = NULL;
double d;
str = skipSpace(str);
d = strtod(str, &endptr);
d = om_strtod(str, &endptr);
if (str == endptr) {
fprintf(stderr, "Expected number, got: %.20s\n", str);
abort();
Expand Down
15 changes: 8 additions & 7 deletions OMCompiler/SimulationRuntime/c/simulation/simulation_runtime.cpp
Expand Up @@ -60,6 +60,7 @@

#include "util/omc_error.h"
#include "util/omc_file.h"
#include "util/omc_numbers.h"
#include "simulation_data.h"
#include "openmodelica_func.h"
#include "meta/meta_modelica.h"
Expand Down Expand Up @@ -253,10 +254,10 @@ void setGlobalLoggingTime(int argc, char**argv, SIMULATION_INFO *simulationInfo)
}

/* Parse flagStr */
loggingStartTime = strtod(flagStr, &endptr);
loggingStartTime = om_strtod(flagStr, &endptr);
endptr = endptr+1;
secondPart = endptr;
loggingStopTime = strtod(secondPart, &endptr);
loggingStopTime = om_strtod(secondPart, &endptr);
if (*endptr)
{
throwStreamPrint(NULL, "Simulation flag %s expects two real numbers, seperated by a comata. Got: %s", FLAG_NAME[FLAG_LV_TIME], flagStr);
Expand Down Expand Up @@ -308,7 +309,7 @@ static double getFlagReal(enum _FLAG flag, double res)
if (flagStr==NULL || *flagStr=='\0') {
return res;
}
res = strtod(flagStr, &endptr);
res = om_strtod(flagStr, &endptr);
if (*endptr) {
throwStreamPrint(NULL, "Simulation flag %s expects a real number, got: %s", FLAG_NAME[flag], flagStr);
}
Expand Down Expand Up @@ -587,10 +588,10 @@ int startNonInteractiveSimulation(int argc, char**argv, DATA* data, threadData_t

if(0 == retVal && omc_flag[FLAG_DATA_RECONCILE])
{
infoStreamPrint(LOG_STDOUT, 0, "DataReconciliation Starting!");
infoStreamPrint(LOG_STDOUT, 0, "%s", data->modelData->modelName);
retVal = dataReconciliation(data, threadData);
infoStreamPrint(LOG_STDOUT, 0, "DataReconciliation Completed!");
infoStreamPrint(LOG_STDOUT, 0, "DataReconciliation Starting!");
infoStreamPrint(LOG_STDOUT, 0, "%s", data->modelData->modelName);
retVal = dataReconciliation(data, threadData);
infoStreamPrint(LOG_STDOUT, 0, "DataReconciliation Completed!");
}

if(0 == retVal && create_linearmodel) {
Expand Down
5 changes: 3 additions & 2 deletions OMCompiler/SimulationRuntime/c/util/OldModelicaTables.c
Expand Up @@ -39,6 +39,7 @@
#ifdef _MSC_VER
#include "omc_msvc.h"
#endif
#include "omc_numbers.h"

/* Definition to get some Debug information if interface is called */
/* #define INFOS */
Expand Down Expand Up @@ -530,7 +531,7 @@ static void Text_readTable(TEXT_FILE *f, double *buf, size_t rows, size_t cols)
for(j = 0; j < cols; ++j)
{
/* remove sufix whitespaces */
buf[i*cols+j] = strtod(number,&entp);
buf[i*cols+j] = om_strtod(number,&entp);
/* move to next number */
number = entp;
}
Expand Down Expand Up @@ -920,7 +921,7 @@ static void csv_readTable(CSV_FILE *f, const char *tableName, double *data, size
number = strLn;
for(col=0;col<cols;col++)
{
data[row*cols+col] = strtod(number,&entp);
data[row*cols+col] = om_strtod(number,&entp);
trim((const char**)&entp,&lh);
number = entp+1;
}
Expand Down
61 changes: 61 additions & 0 deletions OMCompiler/SimulationRuntime/c/util/omc_numbers.c
@@ -0,0 +1,61 @@
/* strtod_l is considered a GNU extension.
* It will fail if the correct prototype does not exist. */
#define _GNU_SOURCE 1

#include <stdlib.h>

#if (defined(_MSC_VER) && _MSC_VER >= 1400)

#include <locale.h>


_locale_t getCLocale()
{
static int init = 0;
static _locale_t loc;
if (!init) {
loc = _create_locale(LC_NUMERIC, "C");
init = 1;
}
return loc;
}

double om_strtod(const char *nptr, char **endptr)
{
return _strtod_l(nptr, endptr, getCLocale());
}

#elif (defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3)) || defined(__APPLE_CC__)

#if defined(__GLIBC__)
#include <locale.h>
#elif defined(__APPLE_CC__)
#include <xlocale.h>
#include <locale.h>
#endif

locale_t getCLocale()
{
static int init = 0;
static locale_t loc;
if (!init) {
loc = newlocale(LC_NUMERIC, "C", NULL);
init = 1;
}
return loc;
}

double om_strtod(const char *nptr, char **endptr)
{
return strtod_l(nptr, endptr, getCLocale());
}

#else

double om_strtod(const char *nptr, char **endptr)
{
/* Default to just assuming we have the correct locale */
return strtod(nptr, endptr);
}

#endif
14 changes: 14 additions & 0 deletions OMCompiler/SimulationRuntime/c/util/omc_numbers.h
@@ -0,0 +1,14 @@
#ifndef __OMC_STRTOD
#define __OMC_STRTOD

#if defined(__cplusplus)
extern "C" {
#endif

double om_strtod(const char *nptr, char **endptr);

#if defined(__cplusplus)
}
#endif

#endif
16 changes: 2 additions & 14 deletions OMCompiler/SimulationRuntime/c/util/read_csv.c
Expand Up @@ -35,10 +35,7 @@
#include "read_matlab4.h"
#include "libcsv.h"
#include "omc_file.h"

#if defined(__cplusplus)
#include <sstream>
#endif
#include "omc_numbers.h"

struct cell_row_count
{
Expand Down Expand Up @@ -182,20 +179,11 @@ static void add_cell(void *data, size_t len, void *t)
body->res[body->size++] = 0.0;
return;
}
#if !defined(__cplusplus)
body->res[body->size++] = data ? strtod((const char*)data,&endptr) : 0;
body->res[body->size++] = data ? om_strtod((const char*)data,&endptr) : 0;
if (*endptr) {
fprintf(stderr,"Found non-double data in csv result-file: %s\n", (char*) data);
body->error = 1;
}
#else
std::istringstream str((const char*)data);
str >> body->res[body->size++];
if (!str.eof()) {
fprintf(stderr,"Found non-double data in csv result-file: %s\n", (char*) data);
body->error = 1;
}
#endif
}

static void add_row(int c, void *t)
Expand Down
6 changes: 0 additions & 6 deletions OMCompiler/SimulationRuntime/c/util/read_csv.cpp

This file was deleted.

1 change: 1 addition & 0 deletions OMPlot/OMPlot/OMPlotGUI/PlotWindow.cpp
Expand Up @@ -2247,3 +2247,4 @@ void SetupDialog::applySetup()
#include "util/read_matlab4.c"
#include "util/libcsv.c"
#include "util/read_csv.c"
#include "util/omc_numbers.c"
3 changes: 2 additions & 1 deletion testsuite/openmodelica/fmi/ModelExchange/2.0/testBug2764.mos
Expand Up @@ -91,6 +91,7 @@ readFile("modelDescription.tmp.xml");
// <File name=\"./util/varinfo.c\" />
// <File name=\"./util/ModelicaUtilities.c\" />
// <File name=\"./util/omc_msvc.c\" />
// <File name=\"./util/omc_numbers.c\" />
// <File name=\"./util/parallel_helper.c\" />
// <File name=\"./util/simulation_options.c\" />
// <File name=\"./util/rational.c\" />
Expand Down Expand Up @@ -126,7 +127,7 @@ readFile("modelDescription.tmp.xml");
// <Category name=\"logAll\" />
// <Category name=\"logFmi2Call\" />
// </LogCategories>
// <DefaultExperiment startTime=\"0.0\" stopTime=\"1.0\" tolerance=\"1e-006\"/>
// <DefaultExperiment startTime=\"0.0\" stopTime=\"1.0\" tolerance=\"1e-06\"/>
// <ModelVariables>
// <!-- Index of variable = \"1\" -->
// <ScalarVariable
Expand Down
3 changes: 2 additions & 1 deletion testsuite/openmodelica/fmi/ModelExchange/2.0/testBug3049.mos
Expand Up @@ -82,6 +82,7 @@ readFile("modelDescription.tmp.xml");
// <File name=\"./util/varinfo.c\" />
// <File name=\"./util/ModelicaUtilities.c\" />
// <File name=\"./util/omc_msvc.c\" />
// <File name=\"./util/omc_numbers.c\" />
// <File name=\"./util/parallel_helper.c\" />
// <File name=\"./util/simulation_options.c\" />
// <File name=\"./util/rational.c\" />
Expand Down Expand Up @@ -117,7 +118,7 @@ readFile("modelDescription.tmp.xml");
// <Category name=\"logAll\" />
// <Category name=\"logFmi2Call\" />
// </LogCategories>
// <DefaultExperiment startTime=\"0.0\" stopTime=\"1.0\" tolerance=\"1e-006\"/>
// <DefaultExperiment startTime=\"0.0\" stopTime=\"1.0\" tolerance=\"1e-06\"/>
// <ModelVariables>
// <!-- Index of variable = \"1\" -->
// <ScalarVariable
Expand Down
Expand Up @@ -96,6 +96,7 @@ readFile("modelDescription.tmp.xml");
// <File name=\"./util/varinfo.c\" />
// <File name=\"./util/ModelicaUtilities.c\" />
// <File name=\"./util/omc_msvc.c\" />
// <File name=\"./util/omc_numbers.c\" />
// <File name=\"./util/parallel_helper.c\" />
// <File name=\"./util/simulation_options.c\" />
// <File name=\"./util/rational.c\" />
Expand Down
Expand Up @@ -92,6 +92,7 @@ readFile("modelDescription.tmp.xml");
// <File name=\"./util/varinfo.c\" />
// <File name=\"./util/ModelicaUtilities.c\" />
// <File name=\"./util/omc_msvc.c\" />
// <File name=\"./util/omc_numbers.c\" />
// <File name=\"./util/parallel_helper.c\" />
// <File name=\"./util/simulation_options.c\" />
// <File name=\"./util/rational.c\" />
Expand Down Expand Up @@ -132,7 +133,7 @@ readFile("modelDescription.tmp.xml");
// <Category name=\"logAll\" />
// <Category name=\"logFmi2Call\" />
// </LogCategories>
// <DefaultExperiment startTime=\"0.0\" stopTime=\"1.0\" tolerance=\"1e-006\"/>
// <DefaultExperiment startTime=\"0.0\" stopTime=\"1.0\" tolerance=\"1e-06\"/>
// <ModelVariables>
// <!-- Index of variable = \"1\" -->
// <ScalarVariable
Expand Down

0 comments on commit ad22570

Please sign in to comment.