summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authortc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-12 23:19:30 +0000
committertc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-12 23:19:30 +0000
commit4f2ad3f5ab8550a404d4c70c29938c19110b3ecb (patch)
treeca8af381337293f5a3b1221b6e5a53849af02450 /base
parentb377d9cd5c2a3e723dd55b797f52de8d2d41a032 (diff)
downloadchromium_src-4f2ad3f5ab8550a404d4c70c29938c19110b3ecb.zip
chromium_src-4f2ad3f5ab8550a404d4c70c29938c19110b3ecb.tar.gz
chromium_src-4f2ad3f5ab8550a404d4c70c29938c19110b3ecb.tar.bz2
Make unit_tests pass with pt_BR.UTF-8 locale.
BUG=3675 Patch from Paweł Hajdan jr <phajdan.jr@gmail.com> original issue: http://codereview.chromium.org/9509 Review URL: http://codereview.chromium.org/11002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5319 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/base.sln61
-rw-r--r--base/base.xcodeproj/project.pbxproj43
-rw-r--r--base/base_unittests.scons1
-rw-r--r--base/json_reader.cc3
-rw-r--r--base/json_writer.cc2
-rw-r--r--base/string_util.cc147
-rw-r--r--base/string_util.h21
7 files changed, 232 insertions, 46 deletions
diff --git a/base/base.sln b/base/base.sln
index caae7c3..2a52486 100644
--- a/base/base.sln
+++ b/base/base.sln
@@ -1,11 +1,20 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base", "build\base.vcproj", "{1832A374-8A74-4F9E-B536-69A699B3E165}"
+ ProjectSection(WebsiteProperties) = preProject
+ Debug.AspNetCompiler.Debug = "True"
+ Release.AspNetCompiler.Debug = "False"
+ EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{0E5474AC-5996-4B13-87C0-4AE931EE0815} = {0E5474AC-5996-4B13-87C0-4AE931EE0815}
+ {CA6CE3BB-B746-4D91-85A0-6944DD273E2A} = {CA6CE3BB-B746-4D91-85A0-6944DD273E2A}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base_unittests", "build\base_unittests.vcproj", "{27A30967-4BBA-48D1-8522-CDE95F7B1CEC}"
+ ProjectSection(WebsiteProperties) = preProject
+ Debug.AspNetCompiler.Debug = "True"
+ Release.AspNetCompiler.Debug = "False"
+ EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{1832A374-8A74-4F9E-B536-69A699B3E165} = {1832A374-8A74-4F9E-B536-69A699B3E165}
{8423AF0D-4B88-4EBF-94E1-E4D00D00E21C} = {8423AF0D-4B88-4EBF-94E1-E4D00D00E21C}
@@ -14,29 +23,70 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base_unittests", "build\bas
{BFE8E2A7-3B3B-43B0-A994-3058B852DB8B} = {BFE8E2A7-3B3B-43B0-A994-3058B852DB8B}
{C564F145-9172-42C3-BFCB-6014CA97DBCD} = {C564F145-9172-42C3-BFCB-6014CA97DBCD}
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D} = {CD9CA56E-4E94-444C-87D4-58CA1E6F300D}
- {E457F2FB-4708-4001-9B1C-275D7BD7F2A8} = {E457F2FB-4708-4001-9B1C-275D7BD7F2A8}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "debug_message", "build\debug_message.vcproj", "{0E5474AC-5996-4B13-87C0-4AE931EE0815}"
+ ProjectSection(WebsiteProperties) = preProject
+ Debug.AspNetCompiler.Debug = "True"
+ Release.AspNetCompiler.Debug = "False"
+ EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dependencies", "dependencies", "{F216062D-F9C4-4883-A52C-2BE9ECADEEA0}"
+ ProjectSection(WebsiteProperties) = preProject
+ Debug.AspNetCompiler.Debug = "True"
+ Release.AspNetCompiler.Debug = "False"
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "icu", "..\third_party\icu38\build\icu.vcproj", "{8C27D792-2648-4F5E-9ED0-374276327308}"
+ ProjectSection(WebsiteProperties) = preProject
+ Debug.AspNetCompiler.Debug = "True"
+ Release.AspNetCompiler.Debug = "False"
+ EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{A0D94973-D355-47A5-A1E2-3456F321F010} = {A0D94973-D355-47A5-A1E2-3456F321F010}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "icudt", "..\third_party\icu38\build\icudt.vcproj", "{A0D94973-D355-47A5-A1E2-3456F321F010}"
+ ProjectSection(WebsiteProperties) = preProject
+ Debug.AspNetCompiler.Debug = "True"
+ Release.AspNetCompiler.Debug = "False"
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base_gfx", "build\base_gfx.vcproj", "{A508ADD3-CECE-4E0F-8448-2F5E454DF551}"
+ ProjectSection(WebsiteProperties) = preProject
+ Debug.AspNetCompiler.Debug = "True"
+ Release.AspNetCompiler.Debug = "False"
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "skia", "..\skia\skia.vcproj", "{CD9CA56E-4E94-444C-87D4-58CA1E6F300D}"
+ ProjectSection(WebsiteProperties) = preProject
+ Debug.AspNetCompiler.Debug = "True"
+ Release.AspNetCompiler.Debug = "False"
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "..\third_party\libpng\libpng.vcproj", "{C564F145-9172-42C3-BFCB-6014CA97DBCD}"
+ ProjectSection(WebsiteProperties) = preProject
+ Debug.AspNetCompiler.Debug = "True"
+ Release.AspNetCompiler.Debug = "False"
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\third_party\zlib\zlib.vcproj", "{8423AF0D-4B88-4EBF-94E1-E4D00D00E21C}"
+ ProjectSection(WebsiteProperties) = preProject
+ Debug.AspNetCompiler.Debug = "True"
+ Release.AspNetCompiler.Debug = "False"
+ EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "..\testing\gtest.vcproj", "{BFE8E2A7-3B3B-43B0-A994-3058B852DB8B}"
+ ProjectSection(WebsiteProperties) = preProject
+ Debug.AspNetCompiler.Debug = "True"
+ Release.AspNetCompiler.Debug = "False"
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dmg_fp", "..\third_party\dmg_fp\dmg_fp.vcproj", "{CA6CE3BB-B746-4D91-85A0-6944DD273E2A}"
+ ProjectSection(WebsiteProperties) = preProject
+ Debug.AspNetCompiler.Debug = "True"
+ Release.AspNetCompiler.Debug = "False"
+ EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -80,14 +130,14 @@ Global
{C564F145-9172-42C3-BFCB-6014CA97DBCD}.Debug|Win32.Build.0 = Debug|Win32
{C564F145-9172-42C3-BFCB-6014CA97DBCD}.Release|Win32.ActiveCfg = Release|Win32
{C564F145-9172-42C3-BFCB-6014CA97DBCD}.Release|Win32.Build.0 = Release|Win32
+ {CA6CE3BB-B746-4D91-85A0-6944DD273E2A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {CA6CE3BB-B746-4D91-85A0-6944DD273E2A}.Debug|Win32.Build.0 = Debug|Win32
+ {CA6CE3BB-B746-4D91-85A0-6944DD273E2A}.Release|Win32.ActiveCfg = Release|Win32
+ {CA6CE3BB-B746-4D91-85A0-6944DD273E2A}.Release|Win32.Build.0 = Release|Win32
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D}.Debug|Win32.ActiveCfg = Debug|Win32
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D}.Debug|Win32.Build.0 = Debug|Win32
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D}.Release|Win32.ActiveCfg = Release|Win32
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D}.Release|Win32.Build.0 = Release|Win32
- {E457F2FB-4708-4001-9B1C-275D7BD7F2A8}.Debug|Win32.ActiveCfg = Debug|Win32
- {E457F2FB-4708-4001-9B1C-275D7BD7F2A8}.Debug|Win32.Build.0 = Debug|Win32
- {E457F2FB-4708-4001-9B1C-275D7BD7F2A8}.Release|Win32.ActiveCfg = Release|Win32
- {E457F2FB-4708-4001-9B1C-275D7BD7F2A8}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -98,6 +148,7 @@ Global
{A0D94973-D355-47A5-A1E2-3456F321F010} = {F216062D-F9C4-4883-A52C-2BE9ECADEEA0}
{BFE8E2A7-3B3B-43B0-A994-3058B852DB8B} = {F216062D-F9C4-4883-A52C-2BE9ECADEEA0}
{C564F145-9172-42C3-BFCB-6014CA97DBCD} = {F216062D-F9C4-4883-A52C-2BE9ECADEEA0}
+ {CA6CE3BB-B746-4D91-85A0-6944DD273E2A} = {F216062D-F9C4-4883-A52C-2BE9ECADEEA0}
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D} = {F216062D-F9C4-4883-A52C-2BE9ECADEEA0}
EndGlobalSection
EndGlobal
diff --git a/base/base.xcodeproj/project.pbxproj b/base/base.xcodeproj/project.pbxproj
index 02cef59..adb444a 100644
--- a/base/base.xcodeproj/project.pbxproj
+++ b/base/base.xcodeproj/project.pbxproj
@@ -40,6 +40,7 @@
4D11B59C0E91730500EF7617 /* rand_util_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D11B5970E9172F800EF7617 /* rand_util_unittest.cc */; };
4D11B89E0E929F0400EF7617 /* file_path.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D11B89B0E929EFF00EF7617 /* file_path.cc */; };
4D11B89F0E929F0700EF7617 /* file_path_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D11B89D0E929EFF00EF7617 /* file_path_unittest.cc */; };
+ 531CBD4F0ECB69180084F32D /* libdmg_fp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 531CBD370ECB67090084F32D /* libdmg_fp.a */; };
7B26302F0E82F218001CE27F /* message_pump_libevent.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7B26302D0E82F218001CE27F /* message_pump_libevent.cc */; };
7B2630330E82F258001CE27F /* libevent.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B2630240E82F1E6001CE27F /* libevent.a */; };
7B4C5F4A0E4B6BF900679E8F /* sys_string_conversions_mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7B4C5F480E4B6BF900679E8F /* sys_string_conversions_mac.mm */; };
@@ -191,6 +192,20 @@
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
+ 531CBD360ECB67090084F32D /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 531CBD320ECB67090084F32D /* dmg_fp.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = D2AAC046055464E500DB518D /* libdmg_fp.a */;
+ remoteInfo = dmg_fp;
+ };
+ 531CBE300ECB86E90084F32D /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 531CBD320ECB67090084F32D /* dmg_fp.xcodeproj */;
+ proxyType = 1;
+ remoteGlobalIDString = D2AAC045055464E500DB518D /* dmg_fp */;
+ remoteInfo = dmg_fp;
+ };
7B165D2F0E55081000185273 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = E45A2C680E47AEFF00DB1196 /* gtest.xcodeproj */;
@@ -384,6 +399,7 @@
4D11B89C0E929EFF00EF7617 /* file_path.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = file_path.h; sourceTree = "<group>"; };
4D11B89D0E929EFF00EF7617 /* file_path_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_path_unittest.cc; sourceTree = "<group>"; };
4D7BF2B20E9D3CDC009A6919 /* foundation_utils_mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = foundation_utils_mac.h; sourceTree = "<group>"; };
+ 531CBD320ECB67090084F32D /* dmg_fp.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = dmg_fp.xcodeproj; path = third_party/dmg_fp/dmg_fp.xcodeproj; sourceTree = "<group>"; };
7B1435DE0E78416400901940 /* skia_utils_mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = skia_utils_mac.h; sourceTree = "<group>"; };
7B1435DF0E78419700901940 /* native_widget_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = native_widget_types.h; sourceTree = "<group>"; };
7B26301F0E82F1E6001CE27F /* libevent.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libevent.xcodeproj; path = third_party/libevent/libevent.xcodeproj; sourceTree = "<group>"; };
@@ -713,6 +729,7 @@
7B78D40E0E54FE8000609465 /* Foundation.framework in Frameworks */,
7B78D38C0E54FDEC00609465 /* libbase.a in Frameworks */,
7B8505D90E5B445100730B43 /* libbase_gfx.a in Frameworks */,
+ 531CBD4F0ECB69180084F32D /* libdmg_fp.a in Frameworks */,
7B2630330E82F258001CE27F /* libevent.a in Frameworks */,
7B836AE30E5509A900F6AD31 /* libgtest.a in Frameworks */,
7B836E180E55CE5B00F6AD31 /* libicudata.a in Frameworks */,
@@ -727,6 +744,14 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ 531CBD330ECB67090084F32D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 531CBD370ECB67090084F32D /* libdmg_fp.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
7B165D2C0E55081000185273 /* Products */ = {
isa = PBXGroup;
children = (
@@ -784,6 +809,7 @@
7B78D40F0E54FE8D00609465 /* Projects */ = {
isa = PBXGroup;
children = (
+ 531CBD320ECB67090084F32D /* dmg_fp.xcodeproj */,
E45A2C680E47AEFF00DB1196 /* gtest.xcodeproj */,
E4562AF30E27E428005E4685 /* icu.xcodeproj */,
7B26301F0E82F1E6001CE27F /* libevent.xcodeproj */,
@@ -1196,6 +1222,7 @@
dependencies = (
7B78D38B0E54FDDE00609465 /* PBXTargetDependency */,
7B8505D80E5B444100730B43 /* PBXTargetDependency */,
+ 531CBE310ECB86E90084F32D /* PBXTargetDependency */,
7B836AD60E55094000F6AD31 /* PBXTargetDependency */,
7B836ADC0E55094000F6AD31 /* PBXTargetDependency */,
7B836AD80E55094000F6AD31 /* PBXTargetDependency */,
@@ -1223,6 +1250,10 @@
projectDirPath = "";
projectReferences = (
{
+ ProductGroup = 531CBD330ECB67090084F32D /* Products */;
+ ProjectRef = 531CBD320ECB67090084F32D /* dmg_fp.xcodeproj */;
+ },
+ {
ProductGroup = 7B165D2C0E55081000185273 /* Products */;
ProjectRef = E45A2C680E47AEFF00DB1196 /* gtest.xcodeproj */;
},
@@ -1259,6 +1290,13 @@
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
+ 531CBD370ECB67090084F32D /* libdmg_fp.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libdmg_fp.a;
+ remoteRef = 531CBD360ECB67090084F32D /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
7B165D300E55081000185273 /* libgtest.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
@@ -1541,6 +1579,11 @@
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
+ 531CBE310ECB86E90084F32D /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ name = dmg_fp;
+ targetProxy = 531CBE300ECB86E90084F32D /* PBXContainerItemProxy */;
+ };
7B2630260E82F1EF001CE27F /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = libevent;
diff --git a/base/base_unittests.scons b/base/base_unittests.scons
index 7b1cc28..496a12c 100644
--- a/base/base_unittests.scons
+++ b/base/base_unittests.scons
@@ -13,6 +13,7 @@ env = env.Clone()
env.SConscript([
'$BASE_DIR/using_base.scons',
'$BASE_DIR/gfx/using_base_gfx.scons',
+ '$DMG_FP_DIR/using_dmg_fp.scons',
'$GTEST_DIR/../using_gtest.scons',
'$ICU38_DIR/using_icu38.scons',
'$LIBPNG_DIR/using_libpng.scons',
diff --git a/base/json_reader.cc b/base/json_reader.cc
index c0e019b..15d43cc 100644
--- a/base/json_reader.cc
+++ b/base/json_reader.cc
@@ -329,7 +329,8 @@ bool JSONReader::DecodeNumber(const Token& token, Value** node) {
}
double num_double;
- if (StringToDouble(num_string, &num_double) && base::IsFinite(num_double)) {
+ if (base::StringToDouble(num_string, &num_double, base::LOCALE_INDEPENDENT) &&
+ base::IsFinite(num_double)) {
*node = Value::CreateRealValue(num_double);
return true;
}
diff --git a/base/json_writer.cc b/base/json_writer.cc
index 10dd39f..4782eb55b 100644
--- a/base/json_writer.cc
+++ b/base/json_writer.cc
@@ -58,7 +58,7 @@ void JSONWriter::BuildJSONString(const Value* const node, int depth) {
double value;
bool result = node->GetAsReal(&value);
DCHECK(result);
- std::string real = StringPrintf("%g", value);
+ std::string real = base::DoubleToString(value, base::LOCALE_INDEPENDENT);
// Ensure that the number has a .0 if there's no decimal or 'e'. This
// makes sure that when we read the JSON back, it's interpreted as a
// real rather than an int.
diff --git a/base/string_util.cc b/base/string_util.cc
index 4c27693..4897f85 100644
--- a/base/string_util.cc
+++ b/base/string_util.cc
@@ -4,6 +4,8 @@
#include "base/string_util.h"
+#include "build/build_config.h"
+
#include <ctype.h>
#include <errno.h>
#include <math.h>
@@ -21,6 +23,7 @@
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/singleton.h"
+#include "third_party/dmg_fp/dmg_fp.h"
namespace {
@@ -86,13 +89,14 @@ static bool CompareParameter(const ReplacementOffset& elem1,
// should check for leading whitespace.
template<typename StringToNumberTraits>
bool StringToNumber(const typename StringToNumberTraits::string_type& input,
- typename StringToNumberTraits::value_type* output) {
+ typename StringToNumberTraits::value_type* output,
+ base::LocaleDependence locale_dependent) {
typedef StringToNumberTraits traits;
errno = 0; // Thread-safe? It is on at least Mac, Linux, and Windows.
typename traits::string_type::value_type* endptr = NULL;
typename traits::value_type value = traits::convert_func(input.c_str(),
- &endptr);
+ &endptr, locale_dependent == base::LOCALE_DEPENDENT);
*output = value;
// Cases to return false:
@@ -116,7 +120,8 @@ class StringToLongTraits {
typedef long value_type;
static const int kBase = 10;
static inline value_type convert_func(const string_type::value_type* str,
- string_type::value_type** endptr) {
+ string_type::value_type** endptr,
+ bool locale_dependent) {
return strtol(str, endptr, kBase);
}
static inline bool valid_func(const string_type& str) {
@@ -130,7 +135,8 @@ class WStringToLongTraits {
typedef long value_type;
static const int kBase = 10;
static inline value_type convert_func(const string_type::value_type* str,
- string_type::value_type** endptr) {
+ string_type::value_type** endptr,
+ bool locale_dependent) {
return wcstol(str, endptr, kBase);
}
static inline bool valid_func(const string_type& str) {
@@ -144,7 +150,8 @@ class StringToInt64Traits {
typedef int64 value_type;
static const int kBase = 10;
static inline value_type convert_func(const string_type::value_type* str,
- string_type::value_type** endptr) {
+ string_type::value_type** endptr,
+ bool locale_dependent) {
#ifdef OS_WIN
return _strtoi64(str, endptr, kBase);
#else // assume OS_POSIX
@@ -162,7 +169,8 @@ class WStringToInt64Traits {
typedef int64 value_type;
static const int kBase = 10;
static inline value_type convert_func(const string_type::value_type* str,
- string_type::value_type** endptr) {
+ string_type::value_type** endptr,
+ bool locale_dependent) {
#ifdef OS_WIN
return _wcstoi64(str, endptr, kBase);
#else // assume OS_POSIX
@@ -183,7 +191,8 @@ class HexStringToLongTraits {
typedef long value_type;
static const int kBase = 16;
static inline value_type convert_func(const string_type::value_type* str,
- string_type::value_type** endptr) {
+ string_type::value_type** endptr,
+ bool locale_dependent) {
return strtoul(str, endptr, kBase);
}
static inline bool valid_func(const string_type& str) {
@@ -197,7 +206,8 @@ class HexWStringToLongTraits {
typedef long value_type;
static const int kBase = 16;
static inline value_type convert_func(const string_type::value_type* str,
- string_type::value_type** endptr) {
+ string_type::value_type** endptr,
+ bool locale_dependent) {
return wcstoul(str, endptr, kBase);
}
static inline bool valid_func(const string_type& str) {
@@ -210,8 +220,13 @@ class StringToDoubleTraits {
typedef std::string string_type;
typedef double value_type;
static inline value_type convert_func(const string_type::value_type* str,
- string_type::value_type** endptr) {
- return strtod(str, endptr);
+ string_type::value_type** endptr,
+ bool locale_dependent) {
+ if (locale_dependent) {
+ return strtod(str, endptr);
+ } else {
+ return dmg_fp::strtod(str, endptr);
+ }
}
static inline bool valid_func(const string_type& str) {
return !str.empty() && !isspace(str[0]);
@@ -223,8 +238,25 @@ class WStringToDoubleTraits {
typedef std::wstring string_type;
typedef double value_type;
static inline value_type convert_func(const string_type::value_type* str,
- string_type::value_type** endptr) {
- return wcstod(str, endptr);
+ string_type::value_type** endptr,
+ bool locale_dependent) {
+ if (base::LOCALE_DEPENDENT == locale_dependent) {
+ return wcstod(str, endptr);
+ } else {
+ // Because dmg_fp::strtod does not like wchar_t, we convert it to ASCII.
+ // In theory, this should be safe, but it's possible that wide chars
+ // might get ignored by accident causing something to be parsed when it
+ // shouldn't.
+ std::string ascii_string = WideToASCII(std::wstring(str));
+ char* ascii_end = NULL;
+ value_type ret = dmg_fp::strtod(ascii_string.c_str(), &ascii_end);
+ if (ascii_string.c_str() + ascii_string.length() == ascii_end) {
+ // Put endptr at end of input string, so it's not recognized as an error.
+ *endptr = const_cast<string_type::value_type*>(str) + wcslen(str);
+ }
+
+ return ret;
+ }
}
static inline bool valid_func(const string_type& str) {
return !str.empty() && !iswspace(str[0]);
@@ -273,6 +305,46 @@ bool IsWprintfFormatPortable(const wchar_t* format) {
return true;
}
+std::string DoubleToString(double value, LocaleDependence locale_dependent) {
+ if (LOCALE_DEPENDENT == locale_dependent) {
+ return StringPrintf("%g", value);
+ } else {
+ char buffer[32];
+ dmg_fp::g_fmt(buffer, value);
+ return std::string(buffer);
+ }
+}
+
+std::wstring DoubleToWString(double value, LocaleDependence locale_dependent) {
+ return ASCIIToWide(DoubleToString(value, locale_dependent));
+}
+
+bool StringToDouble(const std::string& input, double* output,
+ LocaleDependence locale_dependent) {
+ return StringToNumber<StringToDoubleTraits>(input, output,
+ locale_dependent);
+}
+
+bool StringToDouble(const std::wstring& input, double* output,
+ LocaleDependence locale_dependent) {
+ return StringToNumber<WStringToDoubleTraits>(input, output,
+ locale_dependent);
+}
+
+double StringToDouble(const std::string& value,
+ LocaleDependence locale_dependent) {
+ double result;
+ StringToDouble(value, &result, locale_dependent);
+ return result;
+}
+
+double StringToDouble(const std::wstring& value,
+ LocaleDependence locale_dependent) {
+ double result;
+ StringToDouble(value, &result, locale_dependent);
+ return result;
+}
+
} // namespace base
@@ -992,6 +1064,22 @@ inline void StringAppendV(std::wstring* dst,
StringAppendVT<wchar_t>(dst, format, ap);
}
+bool StringToDouble(const std::string& input, double* output) {
+ return StringToDouble(input, output, base::LOCALE_DEPENDENT);
+}
+
+bool StringToDouble(const std::wstring& input, double* output) {
+ return StringToDouble(input, output, base::LOCALE_DEPENDENT);
+}
+
+double StringToDouble(const std::string& value) {
+ return StringToDouble(value, base::LOCALE_DEPENDENT);
+}
+
+double StringToDouble(const std::wstring& value) {
+ return StringToDouble(value, base::LOCALE_DEPENDENT);
+}
+
std::string StringPrintf(const char* format, ...) {
va_list ap;
va_start(ap, format);
@@ -1331,41 +1419,36 @@ bool MatchPattern(const std::string& eval, const std::string& pattern) {
bool StringToInt(const std::string& input, int* output) {
COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int);
return StringToNumber<StringToLongTraits>(input,
- reinterpret_cast<long*>(output));
+ reinterpret_cast<long*>(output),
+ base::LOCALE_DEPENDENT);
}
bool StringToInt(const std::wstring& input, int* output) {
COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int);
return StringToNumber<WStringToLongTraits>(input,
- reinterpret_cast<long*>(output));
+ reinterpret_cast<long*>(output),
+ base::LOCALE_DEPENDENT);
}
bool StringToInt64(const std::string& input, int64* output) {
- return StringToNumber<StringToInt64Traits>(input, output);
+ return StringToNumber<StringToInt64Traits>(input, output, base::LOCALE_DEPENDENT);
}
bool StringToInt64(const std::wstring& input, int64* output) {
- return StringToNumber<WStringToInt64Traits>(input, output);
+ return StringToNumber<WStringToInt64Traits>(input, output, base::LOCALE_DEPENDENT);
}
bool HexStringToInt(const std::string& input, int* output) {
COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int);
return StringToNumber<HexStringToLongTraits>(input,
- reinterpret_cast<long*>(output));
+ reinterpret_cast<long*>(output),
+ base::LOCALE_DEPENDENT);
}
bool HexStringToInt(const std::wstring& input, int* output) {
COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int);
return StringToNumber<HexWStringToLongTraits>(
- input, reinterpret_cast<long*>(output));
-}
-
-bool StringToDouble(const std::string& input, double* output) {
- return StringToNumber<StringToDoubleTraits>(input, output);
-}
-
-bool StringToDouble(const std::wstring& input, double* output) {
- return StringToNumber<WStringToDoubleTraits>(input, output);
+ input, reinterpret_cast<long*>(output), base::LOCALE_DEPENDENT);
}
int StringToInt(const std::string& value) {
@@ -1404,18 +1487,6 @@ int HexStringToInt(const std::wstring& value) {
return result;
}
-double StringToDouble(const std::string& value) {
- double result;
- StringToDouble(value, &result);
- return result;
-}
-
-double StringToDouble(const std::wstring& value) {
- double result;
- StringToDouble(value, &result);
- return result;
-}
-
// The following code is compatible with the OpenBSD lcpy interface. See:
// http://www.gratisoft.us/todd/papers/strlcpy.html
// ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/{wcs,str}lcpy.c
diff --git a/base/string_util.h b/base/string_util.h
index d62e9b0..488d4a2 100644
--- a/base/string_util.h
+++ b/base/string_util.h
@@ -95,6 +95,23 @@ size_t wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size);
// This function is intended to be called from base::vswprintf.
bool IsWprintfFormatPortable(const wchar_t* format);
+enum LocaleDependence {
+ LOCALE_DEPENDENT,
+ LOCALE_INDEPENDENT
+};
+
+std::string DoubleToString(double value, LocaleDependence locale_dependent);
+std::wstring DoubleToWString(double value, LocaleDependence locale_dependent);
+
+bool StringToDouble(const std::string& input, double* output,
+ LocaleDependence locale_dependent);
+bool StringToDouble(const std::wstring& input, double* output,
+ LocaleDependence locale_dependent);
+double StringToDouble(const std::string& value,
+ LocaleDependence locale_dependent);
+double StringToDouble(const std::wstring& value,
+ LocaleDependence locale_dependent);
+
} // namespace base
#if defined(OS_WIN)
@@ -354,6 +371,7 @@ std::wstring Int64ToWString(int64 value);
std::string Uint64ToString(uint64 value);
std::wstring Uint64ToWString(uint64 value);
+
// Perform a best-effort conversion of the input string to a numeric type,
// setting |*output| to the result of the conversion. Returns true for
// "perfect" conversions; returns false in the following cases:
@@ -375,7 +393,7 @@ bool HexStringToInt(const std::wstring& input, int* output);
// form are defined to work. Behavior with strings representing floating-point
// numbers in hexadecimal, and strings representing non-fininte values (such
// as NaN and inf) is undefined. Otherwise, these behave the same as the
-// integral variants above.
+// integral variants above. By default, locale-dependent variant is used.
bool StringToDouble(const std::string& input, double* output);
bool StringToDouble(const std::wstring& input, double* output);
@@ -388,6 +406,7 @@ int64 StringToInt64(const std::string& value);
int64 StringToInt64(const std::wstring& value);
int HexStringToInt(const std::string& value);
int HexStringToInt(const std::wstring& value);
+// By default, locale-dependent variant is used.
double StringToDouble(const std::string& value);
double StringToDouble(const std::wstring& value);