Commit 79216620 by Jeff Gilbert Committed by Commit Bot

Use stringstream with locale override.

Add test for compiling float literals in locales with comma decimal separators. Handle inexplicable test setlocale failure on Android,Linux. (Require success on other platforms) Skip setting the locale on Android, which is always C locale in C++, but for some reason std::locale::classic isn't implemented as a no-op. Bug: angleproject:2607 Test: angle_unittests Change-Id: I7c97cb56c01335db46f532fb8af3f9a4f2a30564 Reviewed-on: https://chromium-review.googlesource.com/1077789Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 47463d85
...@@ -51,10 +51,17 @@ bool numeric_lex_int(const std::string &str, IntType *value) ...@@ -51,10 +51,17 @@ bool numeric_lex_int(const std::string &str, IntType *value)
template <typename FloatType> template <typename FloatType>
bool numeric_lex_float(const std::string &str, FloatType *value) bool numeric_lex_float(const std::string &str, FloatType *value)
{ {
// Some platforms have issues with the usage of std::locale and std::stringstream and cause std::istringstream stream(str);
// crashes. Usage of strtod appears to be safe.
*value = static_cast<FloatType>(strtod(str.c_str(), nullptr)); // Android NDK forbids access to locales by always throwing instead of only accepting the C locale.
return errno != ERANGE && std::isfinite(*value); #if !defined(ANGLE_PLATFORM_ANDROID)
// Force "C" locale so that decimal character is always '.', and not dependent on the current
// locale.
stream.imbue(std::locale::classic());
#endif
stream >> (*value);
return !stream.fail() && std::isfinite(*value);
} }
} // namespace pp } // namespace pp
......
...@@ -7,9 +7,11 @@ ...@@ -7,9 +7,11 @@
// Test the sh::Compile interface with different parameters. // Test the sh::Compile interface with different parameters.
// //
#include <clocale>
#include "GLSLANG/ShaderLang.h"
#include "angle_gl.h" #include "angle_gl.h"
#include "common/platform.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "GLSLANG/ShaderLang.h"
class ShCompileTest : public testing::Test class ShCompileTest : public testing::Test
{ {
...@@ -36,13 +38,16 @@ class ShCompileTest : public testing::Test ...@@ -36,13 +38,16 @@ class ShCompileTest : public testing::Test
void testCompile(const char **shaderStrings, int stringCount, bool expectation) void testCompile(const char **shaderStrings, int stringCount, bool expectation)
{ {
bool success = sh::Compile(mCompiler, shaderStrings, stringCount, 0); ShCompileOptions options = SH_OBJECT_CODE;
bool success = sh::Compile(mCompiler, shaderStrings, stringCount, options);
const std::string &compileLog = sh::GetInfoLog(mCompiler); const std::string &compileLog = sh::GetInfoLog(mCompiler);
EXPECT_EQ(expectation, success) << compileLog; EXPECT_EQ(expectation, success) << compileLog;
} }
private: private:
ShBuiltInResources mResources; ShBuiltInResources mResources;
public:
ShHandle mCompiler; ShHandle mCompiler;
}; };
...@@ -81,3 +86,41 @@ TEST_F(ShCompileTest, TokensSplitInShaderStrings) ...@@ -81,3 +86,41 @@ TEST_F(ShCompileTest, TokensSplitInShaderStrings)
testCompile(shaderStrings, 3, true); testCompile(shaderStrings, 3, true);
} }
// Parsing floats in shaders can run afoul of locale settings.
// In de_DE, `strtof("1.9")` will yield `1.0f`. (It's expecting "1,9")
TEST_F(ShCompileTest, DecimalSepLocale)
{
const auto defaultLocale = setlocale(LC_NUMERIC, nullptr);
const auto fnSetLocale = [](const char *const name) {
return bool(setlocale(LC_NUMERIC, name));
};
const bool setLocaleToDe =
fnSetLocale("de_DE") || fnSetLocale("de-DE"); // Windows doesn't like de_DE.
// These configs don't support de_DE: android_angle_vk[32,64]_rel_ng, linux_angle_rel_ng
// Just allow those platforms to quietly fail, but require other platforms to succeed.
#if defined(ANGLE_PLATFORM_ANDROID) || defined(ANGLE_PLATFORM_LINUX)
if (!setLocaleToDe)
{
return;
}
#endif
ASSERT_TRUE(setLocaleToDe);
const char kSource[] = R"(
void main()
{
gl_FragColor = vec4(1.9);
})";
const char *parts[] = {kSource};
testCompile(parts, 1, true);
const auto &translated = sh::GetObjectCode(mCompiler);
// printf("%s\n", translated.data());
EXPECT_NE(translated.find("1.9"), std::string::npos);
fnSetLocale(defaultLocale);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment