From 139dee9874fca3d20e169b8ad0e206b475b34f27 Mon Sep 17 00:00:00 2001 From: Julius Michaelis Date: Thu, 1 Oct 2015 19:50:05 +0200 Subject: [PATCH] Replace strtod with strtof_l in C4ScriptGuiWindow::SetPositionStringProperties to avoid locale problems (That function could still use some more love, though: Error messages and not accepting ridiculous things when parsing.) --- CMakeLists.txt | 6 ++++++ config.h.cmake | 4 ++++ src/gui/C4ScriptGuiWindow.cpp | 10 ++++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e99cdc274..f3f036330 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,12 @@ REQUIRE_CXX_SOURCE_COMPILES("int main() { static_assert(true, \"\"); }" HAVE_STA CHECK_CXX_SOURCE_COMPILES("#include \nint main() { auto a = std::make_unique(0); }" HAVE_MAKE_UNIQUE) REQUIRE_CXX_SOURCE_COMPILES("template class C; int main() { return 0; }" HAVE_VARIADIC_TEMPLATES) +CHECK_CXX_SOURCE_COMPILES("#include\n#include\nint main() { locale_t l = newlocale(LC_ALL_MASK, \"C\", (locale_t)0); char *c; float f = strtof_l(c, &c, l);}" HAVE_STRTOF_L) +CHECK_CXX_SOURCE_COMPILES("#include\n#include\nint main() { locale_t l = newlocale(LC_ALL_MASK, \"C\", (locale_t)0); char *c; float f = _strtof_l(c, &c, l);}" HAVE__STRTOF_L) +if(NOT(HAVE_STRTOF_L OR HAVE__STRTOF_L)) + message(SEND_ERROR "newlocale and either strtof_l or _strtof_l is required. Or a rewrite of C4ScriptGuiWindow::SetPositionStringProperties") +endif() + # g++'s libstdc++ doesn't properly support until 4.9. # They ship a header that declares functions, but they don't ship an # implementation for some things (like std::regex_iterator). diff --git a/config.h.cmake b/config.h.cmake index 4f57bc7ee..c360dd890 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -194,3 +194,7 @@ /* Include OpenAL extensions (alext.h) for sound modifiers */ #cmakedefine HAVE_ALEXT 1 + +/* strtof_l is defined and usable */ +#cmakedefine HAVE_STRTOF_L 1 +#cmakedefine HAVE__STRTOF_L 2 diff --git a/src/gui/C4ScriptGuiWindow.cpp b/src/gui/C4ScriptGuiWindow.cpp index 9c84ecac8..bc75193e2 100644 --- a/src/gui/C4ScriptGuiWindow.cpp +++ b/src/gui/C4ScriptGuiWindow.cpp @@ -42,6 +42,11 @@ #include #include +#include +#include +#ifndef HAVE_STRTOF_L +#define strtof_l _strtof_l +#endif // Adds some helpful logs for hunting control & menu based desyncs. //#define MenuDebugLogF(...) DebugLogF(__VA_ARGS__) @@ -801,12 +806,13 @@ void C4ScriptGuiWindow::SetPositionStringProperties(const C4Value &property, C4S const char *currentPosition = trimmedString.data(); char *nextPosition; const char *lastPosition = trimmedString.data() + trimmedString.size(); + locale_t c_loc = newlocale(LC_ALL_MASK, "C", nullptr); while (currentPosition < lastPosition) { // look for next float nextPosition = 0; - float value = static_cast(strtod(currentPosition, &nextPosition)); + float value = strtof_l(currentPosition, &nextPosition, c_loc); // fail? exit right here (there must be some space left in the string for a unit, too) if (currentPosition == nextPosition || nextPosition == 0 || nextPosition >= lastPosition) break; @@ -1557,7 +1563,7 @@ void C4ScriptGuiWindow::RequestLayoutUpdate() return; } else // we are one of the multiple windows.. the root better do a full refresh - ; + {} } // propagate to parent window static_cast(GetParent())->RequestLayoutUpdate();