From 6bcf4f25c898f40a83c365f36c09326a340eb54e Mon Sep 17 00:00:00 2001 From: Ykkrosh Date: Thu, 30 Sep 2010 23:17:41 +0000 Subject: [PATCH] Fix CStr parsing to be independent of locale, so that it doesn't break when GTK+ changes the locale. This was SVN commit r8218. --- source/ps/CStr.cpp | 38 ++++++++++++++++++++++++------------- source/ps/tests/test_CStr.h | 38 ++++++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 14 deletions(-) diff --git a/source/ps/CStr.cpp b/source/ps/CStr.cpp index cbc6910290..682ec88403 100644 --- a/source/ps/CStr.cpp +++ b/source/ps/CStr.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2010 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -75,17 +75,11 @@ CStrW CStr8::FromUTF8() const #ifdef _UNICODE #define tstringstream wstringstream - #define _tstod wcstod - #define _ttoi(a) wcstol(a, NULL, 0) - #define _ttol(a) wcstol(a, NULL, 0) #define _istspace iswspace #define _totlower towlower #define _totupper towupper #else #define tstringstream stringstream - #define _tstod strtod - #define _ttoi atoi - #define _ttol atol #define _istspace isspace #define _totlower tolower #define _totupper toupper @@ -130,32 +124,50 @@ NUM_TYPE(double) int CStr::ToInt() const { - return _ttoi(c_str()); + int ret = 0; + std::tstringstream str(*this); + str >> ret; + return ret; } unsigned int CStr::ToUInt() const { - return (unsigned int)_ttoi(c_str()); + unsigned int ret = 0; + std::tstringstream str(*this); + str >> ret; + return ret; } long CStr::ToLong() const { - return _ttol(c_str()); + long ret = 0; + std::tstringstream str(*this); + str >> ret; + return ret; } unsigned long CStr::ToULong() const { - return (unsigned long)_ttol(c_str()); + unsigned long ret = 0; + std::tstringstream str(*this); + str >> ret; + return ret; } float CStr::ToFloat() const { - return (float)_tstod(c_str(), NULL); + float ret = 0; + std::tstringstream str(*this); + str >> ret; + return ret; } double CStr::ToDouble() const { - return _tstod(c_str(), NULL); + double ret = 0; + std::tstringstream str(*this); + str >> ret; + return ret; } diff --git a/source/ps/tests/test_CStr.h b/source/ps/tests/test_CStr.h index 04bafcad95..55fafb3f9c 100644 --- a/source/ps/tests/test_CStr.h +++ b/source/ps/tests/test_CStr.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2010 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -106,4 +106,40 @@ public: str2[3] = '\0'; roundtrip(str2); } + + void test_parse() + { + // Parsing should be independent of locale ("," vs "."), + // because GTK+ can change the locale when we're running Atlas. + // (If the host system doesn't have the locale we're using for this test + // then it'll just stick with the default, which is fine) + char* old = setlocale(LC_NUMERIC, NULL); + setlocale(LC_NUMERIC, "fr_FR.UTF-8"); + + CStr8 str1("1.234"); + TS_ASSERT_DELTA(str1.ToFloat(), 1.234f, 0.0001f); + TS_ASSERT_DELTA(str1.ToDouble(), 1.234, 0.0001); + TS_ASSERT_EQUALS(str1.ToInt(), 1); + TS_ASSERT_EQUALS(str1.ToUInt(), 1u); + TS_ASSERT_EQUALS(str1.ToLong(), 1); + TS_ASSERT_EQUALS(str1.ToULong(), 1u); + + CStr8 str2("bogus"); + TS_ASSERT_EQUALS(str2.ToFloat(), 0.0f); + TS_ASSERT_EQUALS(str2.ToDouble(), 0.0); + TS_ASSERT_EQUALS(str2.ToInt(), 0); + TS_ASSERT_EQUALS(str2.ToUInt(), 0u); + TS_ASSERT_EQUALS(str2.ToLong(), 0); + TS_ASSERT_EQUALS(str2.ToULong(), 0u); + + CStr8 str3("3bogus"); + TS_ASSERT_EQUALS(str3.ToFloat(), 3.0f); + TS_ASSERT_EQUALS(str3.ToDouble(), 3.0); + TS_ASSERT_EQUALS(str3.ToInt(), 3); + TS_ASSERT_EQUALS(str3.ToUInt(), 3u); + TS_ASSERT_EQUALS(str3.ToLong(), 3); + TS_ASSERT_EQUALS(str3.ToULong(), 3u); + + setlocale(LC_NUMERIC, old); + } };