Use C locale for atof to ensure using a dot as decimal mark.
TRAC #14055
Signed-off-by: Daniel Koch
Author: Nicolas Capens
git-svn-id: https://angleproject.googlecode.com/svn/trunk@470 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/compiler/glslang.l b/src/compiler/glslang.l
index d0c96b8..acec131 100644
--- a/src/compiler/glslang.l
+++ b/src/compiler/glslang.l
@@ -32,6 +32,7 @@
#include <stdlib.h>
#include "compiler/ParseHelper.h"
+#include "compiler/util.h"
#include "glslang_tab.h"
/* windows only pragma */
@@ -176,9 +177,9 @@
0{D}+ { pyylval->lex.line = yylineno; parseContext.error(yylineno, "Invalid Octal number.", yytext, "", ""); parseContext.recover(); return 0;}
{D}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
-{D}+{E} { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
-{D}+"."{D}*({E})? { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
-"."{D}+({E})? { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
+{D}+{E} { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
+{D}+"."{D}*({E})? { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
+"."{D}+({E})? { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
"/*" { int ret = PaParseComment(pyylval->lex.line, parseContext); if (!ret) return ret; }
diff --git a/src/compiler/preprocessor/scanner.c b/src/compiler/preprocessor/scanner.c
index b6b9820..f4bfef9 100644
--- a/src/compiler/preprocessor/scanner.c
+++ b/src/compiler/preprocessor/scanner.c
@@ -59,7 +59,7 @@
#endif
#include "compiler/preprocessor/slglobals.h"
-
+#include "compiler/util.h"
typedef struct StringInputSrc {
InputSrc base;
@@ -244,7 +244,7 @@
assert(len <= MAX_SYMBOL_NAME_LEN);
yylvalpp->symbol_name[len] = '\0';
- yylvalpp->sc_fval = (float) atof(yylvalpp->symbol_name);
+ yylvalpp->sc_fval = (float) atof_dot(yylvalpp->symbol_name);
if (isinff(yylvalpp->sc_fval)) {
CPPErrorToInfoLog("FLOAT CONSTANT OVERFLOW");
}
diff --git a/src/compiler/preprocessor/tokens.c b/src/compiler/preprocessor/tokens.c
index fbf89ae..aa83d2f 100644
--- a/src/compiler/preprocessor/tokens.c
+++ b/src/compiler/preprocessor/tokens.c
@@ -52,6 +52,7 @@
#include "compiler/debug.h"
#include "compiler/preprocessor/slglobals.h"
+#include "compiler/util.h"
///////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////// Preprocessor and Token Recorder and Playback: ////////////////////////
@@ -305,7 +306,7 @@
symbol_name[len] = '\0';
assert(ch == '\0');
strcpy(yylvalpp->symbol_name,symbol_name);
- yylvalpp->sc_fval=(float)atof(yylvalpp->symbol_name);
+ yylvalpp->sc_fval=(float)atof_dot(yylvalpp->symbol_name);
break;
case CPP_INTCONSTANT:
len = 0;
diff --git a/src/compiler/translator_common.vcproj b/src/compiler/translator_common.vcproj
index 477a824..2e089f9 100644
--- a/src/compiler/translator_common.vcproj
+++ b/src/compiler/translator_common.vcproj
@@ -266,6 +266,10 @@
>
</File>
<File
+ RelativePath=".\util.cpp"
+ >
+ </File>
+ <File
RelativePath=".\VariableInfo.cpp"
>
</File>
@@ -412,6 +416,10 @@
>
</File>
<File
+ RelativePath=".\util.h"
+ >
+ </File>
+ <File
RelativePath=".\VariableInfo.h"
>
</File>
diff --git a/src/compiler/util.cpp b/src/compiler/util.cpp
new file mode 100644
index 0000000..a45fe83
--- /dev/null
+++ b/src/compiler/util.cpp
@@ -0,0 +1,30 @@
+//
+// Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include <math.h>
+#include <stdlib.h>
+
+#include "util.h"
+
+#ifdef _MSC_VER
+ #include <locale.h>
+#else
+ #include <sstream>
+#endif
+
+double atof_dot(const char *str)
+{
+#ifdef _MSC_VER
+ return _atof_l(str, _create_locale(LC_NUMERIC, "C"));
+#else
+ double result;
+ std::istringstream s(str);
+ std::locale l("C");
+ s.imbue(l);
+ s >> result;
+ return result;
+#endif
+}
diff --git a/src/compiler/util.h b/src/compiler/util.h
new file mode 100644
index 0000000..35288b7
--- /dev/null
+++ b/src/compiler/util.h
@@ -0,0 +1,21 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_UTIL_H
+#define COMPILER_UTIL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// atof_dot is like atof but forcing C locale, i.e. forcing '.' as decimal point.
+double atof_dot(const char *str);
+
+#ifdef __cplusplus
+} // end extern "C"
+#endif
+
+#endif // COMPILER_UTIL_H