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