diff --git a/compiler2/PredefFunc.cc b/compiler2/PredefFunc.cc index 71c58cd753491a40cce738d400a159754359a9bc..b4592322e098085afcb52c4a28b46ff304721ef6 100644 --- a/compiler2/PredefFunc.cc +++ b/compiler2/PredefFunc.cc @@ -30,6 +30,7 @@ #include "../common/pattern.hh" #include "../common/UnicharPattern.hh" #include <iostream> +#include <locale.h> // used by regex #define ERRMSG_BUFSIZE 512 @@ -607,11 +608,13 @@ namespace Common { return new string("not_a_number"); } char str_buf[64]; - if ( (value > -MAX_DECIMAL_FLOAT && value <= -MIN_DECIMAL_FLOAT) + bool f = (value > -MAX_DECIMAL_FLOAT && value <= -MIN_DECIMAL_FLOAT) || (value >= MIN_DECIMAL_FLOAT && value < MAX_DECIMAL_FLOAT) - || (value == 0.0)) - snprintf(str_buf,64,"%f",value); - else snprintf(str_buf,64,"%e",value); + || (value == 0.0); + const char* loc = setlocale(LC_ALL, NULL); + setlocale(LC_NUMERIC, "C"); // use default locale for displaying numbers + snprintf(str_buf, 64, f ? "%f" : "%e", value); + setlocale(LC_NUMERIC, loc); return new string(str_buf); } diff --git a/core/Addfunc.cc b/core/Addfunc.cc index 3c7722ebc8e00a13217f8d820e53f14c2be41d11..1952b4326f95193cf34bbdfed420c18b60751bee 100644 --- a/core/Addfunc.cc +++ b/core/Addfunc.cc @@ -45,6 +45,7 @@ #include <string.h> #include <sys/types.h> #include <regex.h> +#include <locale.h> #define ERRMSG_BUFSIZE 512 @@ -2876,7 +2877,10 @@ CHARSTRING float2str(double value) || (value >= MIN_DECIMAL_FLOAT && value < MAX_DECIMAL_FLOAT); // true if decimal representation possible (use %f format) char str_buf[64]; + const char* loc = setlocale(LC_ALL, NULL); + setlocale(LC_NUMERIC, "C"); // use default locale for displaying numbers int str_len = snprintf(str_buf, sizeof(str_buf), f ? "%f" : "%e", value); + setlocale(LC_NUMERIC, loc); if (str_len < 0 || str_len >= (int)sizeof(str_buf)) { TTCN_error("Internal error: system call snprintf() returned " "unexpected status code %d when converting value %g in function " diff --git a/core/Float.cc b/core/Float.cc index c9c04d4540647c001f5f5214b5722d9d82b65f18..53f18f3427ceaad1c94c4b43d41bb523af5cefe6 100644 --- a/core/Float.cc +++ b/core/Float.cc @@ -25,6 +25,7 @@ #include <string.h> #include <math.h> #include <float.h> +#include <locale.h> #include "../common/memory.h" #include "Float.hh" @@ -60,17 +61,21 @@ const FLOAT NOT_A_NUMBER((double)PLUS_INFINITY+(double)MINUS_INFINITY); static inline void log_float(double float_val) { - if ( (float_val > -MAX_DECIMAL_FLOAT && float_val <= -MIN_DECIMAL_FLOAT) - || (float_val >= MIN_DECIMAL_FLOAT && float_val < MAX_DECIMAL_FLOAT) - || (float_val == 0.0)) - TTCN_Logger::log_event("%f", float_val); - else if(float_val==INFINITY) + if(float_val==INFINITY) TTCN_Logger::log_event_str("infinity"); else if(float_val==-INFINITY) TTCN_Logger::log_event_str("-infinity"); else if(float_val!=float_val) TTCN_Logger::log_event_str("not_a_number"); - else TTCN_Logger::log_event("%e", float_val); + else { + boolean f = (float_val > -MAX_DECIMAL_FLOAT && float_val <= -MIN_DECIMAL_FLOAT) + || (float_val >= MIN_DECIMAL_FLOAT && float_val < MAX_DECIMAL_FLOAT) + || (float_val == 0.0); + const char* loc = setlocale(LC_ALL, NULL); + setlocale(LC_NUMERIC, "C"); // use default locale for displaying numbers + TTCN_Logger::log_event(f ? "%f" : "%e", float_val); + setlocale(LC_NUMERIC, loc); + } } // float value class diff --git a/regression_test/Makefile b/regression_test/Makefile index 8ab5ba4f2f6499c6011530d4260bc4b05d64aca2..114053ac721078c2a6f8101965d8ea40ef59932f 100644 --- a/regression_test/Makefile +++ b/regression_test/Makefile @@ -49,7 +49,8 @@ all_from lazyEval tryCatch text2ttcn json ttcn2json profiler templateOmit \ customEncoding makefilegen uidChars checkstate hostid templateIstemplatekind \ selectUnion templateExclusiveRange any_from templatePatternRef indexWithRecofArray \ connectMapOperTest fuzzy portTranslation ischosen OER functionSubref done \ -nondeterministicDefaultParam predefFunction2 realtime portTranslationCentralStorage +nondeterministicDefaultParam predefFunction2 realtime portTranslationCentralStorage \ +locale ifdef DYN DIRS += loggerplugin junitlogger diff --git a/regression_test/locale/.gitignore b/regression_test/locale/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..62c4d845ca0352094c76e27fa7f3bd562e2b7c54 --- /dev/null +++ b/regression_test/locale/.gitignore @@ -0,0 +1,6 @@ +locale +locale.exe +locale*.cc +locale*.hh +compile +locale*.log diff --git a/regression_test/locale/Makefile b/regression_test/locale/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..2c209e8ac1b7ed82b70d7a5761a6abd9db4f2fae --- /dev/null +++ b/regression_test/locale/Makefile @@ -0,0 +1,60 @@ +############################################################################## +# Copyright (c) 2000-2019 Ericsson Telecom AB +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v2.0 +# which accompanies this distribution, and is available at +# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html +# +# Contributors: +# Baranyi, Botond +# +############################################################################## +TOPDIR := .. +include $(TOPDIR)/Makefile.regression + +.SUFFIXES: .ttcn .hh +.PHONY: all clean dep run + +TTCN3_LIB = ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX) + +TTCN3_MODULES = locale.ttcn + +USER_SOURCES = ext_func.cc + +GENERATED_SOURCES = $(TTCN3_MODULES:.ttcn=.cc) +GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh) +ifdef CODE_SPLIT +GENERATED_SOURCES := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), .cc _seq.cc _set.cc _seqof.cc _setof.cc _union.cc)) +else ifdef SPLIT_TO_SLICES +POSTFIXES := $(foreach file, $(SPLIT_TO_SLICES), $(addsuffix $(file), _part_)) +POSTFIXES := $(foreach file, $(POSTFIXES), $(addprefix $(file), .cc)) +GENERATED_SOURCES2 := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), $(POSTFIXES))) +GENERATED_SOURCES += $(GENERATED_SOURCES2) +endif + +OBJECTS = $(GENERATED_SOURCES:.cc=.o) $(USER_SOURCES:.cc=.o) + +TARGET = locale + +all: $(TARGET) ; + +$(TARGET): $(GENERATED_SOURCES) $(USER_SOURCES) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@ $^ -L$(TTCN3_DIR)/lib -l$(TTCN3_LIB) \ + -L$(OPENSSL_DIR)/lib -lcrypto $($(PLATFORM)_LIBS) + +$(GENERATED_SOURCES) $(GENERATED_HEADERS): compile + @if [ ! -f $@ ]; then $(RM) compile; $(MAKE) compile; fi + +compile: $(TTCN3_MODULES) $(ASN1_MODULES) + $(TTCN3_COMPILER) $(COMPILER_FLAGS) $^ + touch $@ + +clean distclean: + $(RM) $(TARGET) $(OBJECTS) $(GENERATED_HEADERS) \ + $(GENERATED_SOURCES) compile *.log + +dep: $(GENERATED_SOURCES) + makedepend $(CPPFLAGS) $(USER_SOURCES) $(GENERATED_SOURCES) + +run: $(TARGET) locale.cfg + ./$^ diff --git a/regression_test/locale/ext_func.cc b/regression_test/locale/ext_func.cc new file mode 100644 index 0000000000000000000000000000000000000000..ae3f521d41b84bb266c2fe1805efde50745d02cb --- /dev/null +++ b/regression_test/locale/ext_func.cc @@ -0,0 +1,22 @@ +/****************************************************************************** + * Copyright (c) 2000-2019 Ericsson Telecom AB + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html + * + * Contributors: + * Baranyi, Botond + * + ******************************************************************************/ + +#include <locale.h> +#include "locale.hh" + +namespace locale { + +void ef__simulate__library__with__locale() { + setlocale(LC_ALL,"sv_SE.utf8"); +} + +} diff --git a/regression_test/locale/locale.cfg b/regression_test/locale/locale.cfg new file mode 100644 index 0000000000000000000000000000000000000000..664ae04d8a7efba7de377f41a5f6743586af8f57 --- /dev/null +++ b/regression_test/locale/locale.cfg @@ -0,0 +1,20 @@ +############################################################################### +# Copyright (c) 2000-2019 Ericsson Telecom AB +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v2.0 +# which accompanies this distribution, and is available at +# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html +# +# Contributors: +# Baranyi, Botond +# +############################################################################### +[LOGGING] +FileMask := TTCN_ERROR | TTCN_TESTCASE | TTCN_STATISTICS | TTCN_VERDICTOP |USER +ConsoleMask := TTCN_ERROR | TTCN_TESTCASE | TTCN_STATISTICS | TTCN_VERDICTOP | USER +SourceInfoFormat := Stack +LogEventTypes := Detailed +MatchingHints := Detailed + +[EXECUTE] +locale.control diff --git a/regression_test/locale/locale.ttcn b/regression_test/locale/locale.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..c6379d8d66e7340f6875cde3793678347d6ee4f4 --- /dev/null +++ b/regression_test/locale/locale.ttcn @@ -0,0 +1,56 @@ +/****************************************************************************** + * Copyright (c) 2000-2019 Ericsson Telecom AB + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html + * + * Contributors: + * Baranyi, Botond + * + ******************************************************************************/ + +// this module contains tests for conversions and logging with certain locale settings +// (converting to strings or logging must not be affected by locale settings) +module locale { + +type component CT {} + +// simulates the initialization of an external +// library, which uses a Swedish locale setting +external function ef_simulate_library_with_locale(); + +function f_test_float(in float val, in charstring exp) runs on CT { + ef_simulate_library_with_locale(); + + var charstring log_res := log2str(val); + if (log_res != exp) { + setverdict(fail, "invalid log() result: ", log_res); + } + + var charstring conv_res := float2str(val); + if (conv_res != exp) { + setverdict(fail, "invalid flaot2str() result: ", conv_res); + } + setverdict(pass); +} + +testcase tc_locale_float_zero() runs on CT { + f_test_float(0.0, "0.000000"); +} + +testcase tc_locale_float_regular() runs on CT { + f_test_float(1.23, "1.230000"); +} + +testcase tc_locale_float_exponent() runs on CT { + f_test_float(-123.456e78, "-1.234560e+80"); +} + +control { + execute(tc_locale_float_zero()); + execute(tc_locale_float_regular()); + execute(tc_locale_float_exponent()); +} + +}