OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/string_util.h" | 5 #include "base/string_util.h" |
6 | 6 |
| 7 #include "build/build_config.h" |
| 8 |
7 #include <ctype.h> | 9 #include <ctype.h> |
8 #include <errno.h> | 10 #include <errno.h> |
9 #include <math.h> | 11 #include <math.h> |
10 #include <stdarg.h> | 12 #include <stdarg.h> |
11 #include <stdio.h> | 13 #include <stdio.h> |
12 #include <stdlib.h> | 14 #include <stdlib.h> |
13 #include <string.h> | 15 #include <string.h> |
14 #include <time.h> | 16 #include <time.h> |
15 #include <wchar.h> | 17 #include <wchar.h> |
16 #include <wctype.h> | 18 #include <wctype.h> |
17 | 19 |
18 #include <algorithm> | 20 #include <algorithm> |
19 #include <vector> | 21 #include <vector> |
20 | 22 |
21 #include "base/basictypes.h" | 23 #include "base/basictypes.h" |
22 #include "base/logging.h" | 24 #include "base/logging.h" |
23 #include "base/singleton.h" | 25 #include "base/singleton.h" |
| 26 #include "third_party/dmg_fp/dmg_fp.h" |
24 | 27 |
25 namespace { | 28 namespace { |
26 | 29 |
27 // Hack to convert any char-like type to its unsigned counterpart. | 30 // Hack to convert any char-like type to its unsigned counterpart. |
28 // For example, it will convert char, signed char and unsigned char to unsigned | 31 // For example, it will convert char, signed char and unsigned char to unsigned |
29 // char. | 32 // char. |
30 template<typename T> | 33 template<typename T> |
31 struct ToUnsigned { | 34 struct ToUnsigned { |
32 typedef T Unsigned; | 35 typedef T Unsigned; |
33 }; | 36 }; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 // - a typedef for value_type, the target numeric type. | 82 // - a typedef for value_type, the target numeric type. |
80 // - a static function, convert_func, which dispatches to an appropriate | 83 // - a static function, convert_func, which dispatches to an appropriate |
81 // strtol-like function and returns type value_type. | 84 // strtol-like function and returns type value_type. |
82 // - a static function, valid_func, which validates |input| and returns a bool | 85 // - a static function, valid_func, which validates |input| and returns a bool |
83 // indicating whether it is in proper form. This is used to check for | 86 // indicating whether it is in proper form. This is used to check for |
84 // conditions that convert_func tolerates but should result in | 87 // conditions that convert_func tolerates but should result in |
85 // StringToNumber returning false. For strtol-like funtions, valid_func | 88 // StringToNumber returning false. For strtol-like funtions, valid_func |
86 // should check for leading whitespace. | 89 // should check for leading whitespace. |
87 template<typename StringToNumberTraits> | 90 template<typename StringToNumberTraits> |
88 bool StringToNumber(const typename StringToNumberTraits::string_type& input, | 91 bool StringToNumber(const typename StringToNumberTraits::string_type& input, |
89 typename StringToNumberTraits::value_type* output) { | 92 typename StringToNumberTraits::value_type* output, |
| 93 LocaleDependence locale_dependent) { |
90 typedef StringToNumberTraits traits; | 94 typedef StringToNumberTraits traits; |
91 | 95 |
92 errno = 0; // Thread-safe? It is on at least Mac, Linux, and Windows. | 96 errno = 0; // Thread-safe? It is on at least Mac, Linux, and Windows. |
93 typename traits::string_type::value_type* endptr = NULL; | 97 typename traits::string_type::value_type* endptr = NULL; |
94 typename traits::value_type value = traits::convert_func(input.c_str(), | 98 typename traits::value_type value = traits::convert_func(input.c_str(), |
95 &endptr); | 99 &endptr, |
| 100 locale_dependent); |
96 *output = value; | 101 *output = value; |
97 | 102 |
98 // Cases to return false: | 103 // Cases to return false: |
99 // - If errno is ERANGE, there was an overflow or underflow. | 104 // - If errno is ERANGE, there was an overflow or underflow. |
100 // - If the input string is empty, there was nothing to parse. | 105 // - If the input string is empty, there was nothing to parse. |
101 // - If endptr does not point to the end of the string, there are either | 106 // - If endptr does not point to the end of the string, there are either |
102 // characters remaining in the string after a parsed number, or the string | 107 // characters remaining in the string after a parsed number, or the string |
103 // does not begin with a parseable number. endptr is compared to the | 108 // does not begin with a parseable number. endptr is compared to the |
104 // expected end given the string's stated length to correctly catch cases | 109 // expected end given the string's stated length to correctly catch cases |
105 // where the string contains embedded NUL characters. | 110 // where the string contains embedded NUL characters. |
106 // - valid_func determines that the input is not in preferred form. | 111 // - valid_func determines that the input is not in preferred form. |
107 return errno == 0 && | 112 return errno == 0 && |
108 !input.empty() && | 113 !input.empty() && |
109 input.c_str() + input.length() == endptr && | 114 input.c_str() + input.length() == endptr && |
110 traits::valid_func(input); | 115 traits::valid_func(input); |
111 } | 116 } |
112 | 117 |
113 class StringToLongTraits { | 118 class StringToLongTraits { |
114 public: | 119 public: |
115 typedef std::string string_type; | 120 typedef std::string string_type; |
116 typedef long value_type; | 121 typedef long value_type; |
117 static const int kBase = 10; | 122 static const int kBase = 10; |
118 static inline value_type convert_func(const string_type::value_type* str, | 123 static inline value_type convert_func(const string_type::value_type* str, |
119 string_type::value_type** endptr) { | 124 string_type::value_type** endptr, |
| 125 bool locale_dependent) { |
120 return strtol(str, endptr, kBase); | 126 return strtol(str, endptr, kBase); |
121 } | 127 } |
122 static inline bool valid_func(const string_type& str) { | 128 static inline bool valid_func(const string_type& str) { |
123 return !str.empty() && !isspace(str[0]); | 129 return !str.empty() && !isspace(str[0]); |
124 } | 130 } |
125 }; | 131 }; |
126 | 132 |
127 class WStringToLongTraits { | 133 class WStringToLongTraits { |
128 public: | 134 public: |
129 typedef std::wstring string_type; | 135 typedef std::wstring string_type; |
130 typedef long value_type; | 136 typedef long value_type; |
131 static const int kBase = 10; | 137 static const int kBase = 10; |
132 static inline value_type convert_func(const string_type::value_type* str, | 138 static inline value_type convert_func(const string_type::value_type* str, |
133 string_type::value_type** endptr) { | 139 string_type::value_type** endptr, |
| 140 bool locale_dependent) { |
134 return wcstol(str, endptr, kBase); | 141 return wcstol(str, endptr, kBase); |
135 } | 142 } |
136 static inline bool valid_func(const string_type& str) { | 143 static inline bool valid_func(const string_type& str) { |
137 return !str.empty() && !iswspace(str[0]); | 144 return !str.empty() && !iswspace(str[0]); |
138 } | 145 } |
139 }; | 146 }; |
140 | 147 |
141 class StringToInt64Traits { | 148 class StringToInt64Traits { |
142 public: | 149 public: |
143 typedef std::string string_type; | 150 typedef std::string string_type; |
144 typedef int64 value_type; | 151 typedef int64 value_type; |
145 static const int kBase = 10; | 152 static const int kBase = 10; |
146 static inline value_type convert_func(const string_type::value_type* str, | 153 static inline value_type convert_func(const string_type::value_type* str, |
147 string_type::value_type** endptr) { | 154 string_type::value_type** endptr, |
| 155 bool locale_dependent) { |
148 #ifdef OS_WIN | 156 #ifdef OS_WIN |
149 return _strtoi64(str, endptr, kBase); | 157 return _strtoi64(str, endptr, kBase); |
150 #else // assume OS_POSIX | 158 #else // assume OS_POSIX |
151 return strtoll(str, endptr, kBase); | 159 return strtoll(str, endptr, kBase); |
152 #endif | 160 #endif |
153 } | 161 } |
154 static inline bool valid_func(const string_type& str) { | 162 static inline bool valid_func(const string_type& str) { |
155 return !str.empty() && !isspace(str[0]); | 163 return !str.empty() && !isspace(str[0]); |
156 } | 164 } |
157 }; | 165 }; |
158 | 166 |
159 class WStringToInt64Traits { | 167 class WStringToInt64Traits { |
160 public: | 168 public: |
161 typedef std::wstring string_type; | 169 typedef std::wstring string_type; |
162 typedef int64 value_type; | 170 typedef int64 value_type; |
163 static const int kBase = 10; | 171 static const int kBase = 10; |
164 static inline value_type convert_func(const string_type::value_type* str, | 172 static inline value_type convert_func(const string_type::value_type* str, |
165 string_type::value_type** endptr) { | 173 string_type::value_type** endptr, |
| 174 bool locale_dependent) { |
166 #ifdef OS_WIN | 175 #ifdef OS_WIN |
167 return _wcstoi64(str, endptr, kBase); | 176 return _wcstoi64(str, endptr, kBase); |
168 #else // assume OS_POSIX | 177 #else // assume OS_POSIX |
169 return wcstoll(str, endptr, kBase); | 178 return wcstoll(str, endptr, kBase); |
170 #endif | 179 #endif |
171 } | 180 } |
172 static inline bool valid_func(const string_type& str) { | 181 static inline bool valid_func(const string_type& str) { |
173 return !str.empty() && !iswspace(str[0]); | 182 return !str.empty() && !iswspace(str[0]); |
174 } | 183 } |
175 }; | 184 }; |
176 | 185 |
177 // For the HexString variants, use the unsigned variants like strtoul for | 186 // For the HexString variants, use the unsigned variants like strtoul for |
178 // convert_func so that input like "0x80000000" doesn't result in an overflow. | 187 // convert_func so that input like "0x80000000" doesn't result in an overflow. |
179 | 188 |
180 class HexStringToLongTraits { | 189 class HexStringToLongTraits { |
181 public: | 190 public: |
182 typedef std::string string_type; | 191 typedef std::string string_type; |
183 typedef long value_type; | 192 typedef long value_type; |
184 static const int kBase = 16; | 193 static const int kBase = 16; |
185 static inline value_type convert_func(const string_type::value_type* str, | 194 static inline value_type convert_func(const string_type::value_type* str, |
186 string_type::value_type** endptr) { | 195 string_type::value_type** endptr, |
| 196 bool locale_dependent) { |
187 return strtoul(str, endptr, kBase); | 197 return strtoul(str, endptr, kBase); |
188 } | 198 } |
189 static inline bool valid_func(const string_type& str) { | 199 static inline bool valid_func(const string_type& str) { |
190 return !str.empty() && !isspace(str[0]); | 200 return !str.empty() && !isspace(str[0]); |
191 } | 201 } |
192 }; | 202 }; |
193 | 203 |
194 class HexWStringToLongTraits { | 204 class HexWStringToLongTraits { |
195 public: | 205 public: |
196 typedef std::wstring string_type; | 206 typedef std::wstring string_type; |
197 typedef long value_type; | 207 typedef long value_type; |
198 static const int kBase = 16; | 208 static const int kBase = 16; |
199 static inline value_type convert_func(const string_type::value_type* str, | 209 static inline value_type convert_func(const string_type::value_type* str, |
200 string_type::value_type** endptr) { | 210 string_type::value_type** endptr, |
| 211 bool locale_dependent) { |
201 return wcstoul(str, endptr, kBase); | 212 return wcstoul(str, endptr, kBase); |
202 } | 213 } |
203 static inline bool valid_func(const string_type& str) { | 214 static inline bool valid_func(const string_type& str) { |
204 return !str.empty() && !iswspace(str[0]); | 215 return !str.empty() && !iswspace(str[0]); |
205 } | 216 } |
206 }; | 217 }; |
207 | 218 |
208 class StringToDoubleTraits { | 219 class StringToDoubleTraits { |
209 public: | 220 public: |
210 typedef std::string string_type; | 221 typedef std::string string_type; |
211 typedef double value_type; | 222 typedef double value_type; |
212 static inline value_type convert_func(const string_type::value_type* str, | 223 static inline value_type convert_func(const string_type::value_type* str, |
213 string_type::value_type** endptr) { | 224 string_type::value_type** endptr, |
214 return strtod(str, endptr); | 225 bool locale_dependent) { |
| 226 if (locale_dependent) { |
| 227 return strtod(str, endptr); |
| 228 } else { |
| 229 return dmg_fp::strtod(str, endptr); |
| 230 } |
215 } | 231 } |
216 static inline bool valid_func(const string_type& str) { | 232 static inline bool valid_func(const string_type& str) { |
217 return !str.empty() && !isspace(str[0]); | 233 return !str.empty() && !isspace(str[0]); |
218 } | 234 } |
219 }; | 235 }; |
220 | 236 |
221 class WStringToDoubleTraits { | 237 class WStringToDoubleTraits { |
222 public: | 238 public: |
223 typedef std::wstring string_type; | 239 typedef std::wstring string_type; |
224 typedef double value_type; | 240 typedef double value_type; |
225 static inline value_type convert_func(const string_type::value_type* str, | 241 static inline value_type convert_func(const string_type::value_type* str, |
226 string_type::value_type** endptr) { | 242 string_type::value_type** endptr, |
227 return wcstod(str, endptr); | 243 bool locale_dependent) { |
| 244 if (locale_dependent) { |
| 245 return wcstod(str, endptr); |
| 246 } else { |
| 247 // We are going to do some interesting things here, just because |
| 248 // dmg_fp::strtod does not like wchar_t. Converting to ASCII should |
| 249 // be fine. |
| 250 |
| 251 // Put endptr at end of input string, so it's not recognized as an error. |
| 252 *endptr = const_cast<string_type::value_type*>(str) + wcslen(str); |
| 253 |
| 254 std::string ascii_string = WideToASCII(std::wstring(str)); |
| 255 return StringToDouble(ascii_string, LOCALE_INDEPENDENT); |
| 256 } |
228 } | 257 } |
229 static inline bool valid_func(const string_type& str) { | 258 static inline bool valid_func(const string_type& str) { |
230 return !str.empty() && !iswspace(str[0]); | 259 return !str.empty() && !iswspace(str[0]); |
231 } | 260 } |
232 }; | 261 }; |
233 | 262 |
234 } // namespace | 263 } // namespace |
235 | 264 |
236 | 265 |
237 namespace base { | 266 namespace base { |
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
975 } | 1004 } |
976 std::string Uint64ToString(uint64 value) { | 1005 std::string Uint64ToString(uint64 value) { |
977 return IntToStringT<std::string, uint64, uint64, false>:: | 1006 return IntToStringT<std::string, uint64, uint64, false>:: |
978 IntToString(value); | 1007 IntToString(value); |
979 } | 1008 } |
980 std::wstring Uint64ToWString(uint64 value) { | 1009 std::wstring Uint64ToWString(uint64 value) { |
981 return IntToStringT<std::wstring, uint64, uint64, false>:: | 1010 return IntToStringT<std::wstring, uint64, uint64, false>:: |
982 IntToString(value); | 1011 IntToString(value); |
983 } | 1012 } |
984 | 1013 |
| 1014 std::string DoubleToString(double value, LocaleDependence locale_dependent) { |
| 1015 if (locale_dependent) { |
| 1016 return StringPrintf("%g", value); |
| 1017 } else { |
| 1018 char buffer[32]; |
| 1019 dmg_fp::g_fmt(buffer, value); |
| 1020 return std::string(buffer); |
| 1021 } |
| 1022 } |
| 1023 |
| 1024 std::wstring DoubleToWString(double value, LocaleDependence locale_dependent) { |
| 1025 return ASCIIToWide(DoubleToString(value, locale_dependent)); |
| 1026 } |
| 1027 |
985 inline void StringAppendV(std::string* dst, const char* format, va_list ap) { | 1028 inline void StringAppendV(std::string* dst, const char* format, va_list ap) { |
986 StringAppendVT<char>(dst, format, ap); | 1029 StringAppendVT<char>(dst, format, ap); |
987 } | 1030 } |
988 | 1031 |
989 inline void StringAppendV(std::wstring* dst, | 1032 inline void StringAppendV(std::wstring* dst, |
990 const wchar_t* format, | 1033 const wchar_t* format, |
991 va_list ap) { | 1034 va_list ap) { |
992 StringAppendVT<wchar_t>(dst, format, ap); | 1035 StringAppendVT<wchar_t>(dst, format, ap); |
993 } | 1036 } |
994 | 1037 |
| 1038 bool StringToDouble(const std::string& input, double* output) { |
| 1039 return StringToDouble(input, output, LOCALE_DEPENDENT); |
| 1040 } |
| 1041 |
| 1042 bool StringToDouble(const std::wstring& input, double* output) { |
| 1043 return StringToDouble(input, output, LOCALE_DEPENDENT); |
| 1044 } |
| 1045 |
| 1046 double StringToDouble(const std::string& value) { |
| 1047 return StringToDouble(value, LOCALE_DEPENDENT); |
| 1048 } |
| 1049 |
| 1050 double StringToDouble(const std::wstring& value) { |
| 1051 return StringToDouble(value, LOCALE_DEPENDENT); |
| 1052 } |
| 1053 |
995 std::string StringPrintf(const char* format, ...) { | 1054 std::string StringPrintf(const char* format, ...) { |
996 va_list ap; | 1055 va_list ap; |
997 va_start(ap, format); | 1056 va_start(ap, format); |
998 std::string result; | 1057 std::string result; |
999 StringAppendV(&result, format, ap); | 1058 StringAppendV(&result, format, ap); |
1000 va_end(ap); | 1059 va_end(ap); |
1001 return result; | 1060 return result; |
1002 } | 1061 } |
1003 | 1062 |
1004 std::wstring StringPrintf(const wchar_t* format, ...) { | 1063 std::wstring StringPrintf(const wchar_t* format, ...) { |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1324 } | 1383 } |
1325 | 1384 |
1326 // For the various *ToInt conversions, there are no *ToIntTraits classes to use | 1385 // For the various *ToInt conversions, there are no *ToIntTraits classes to use |
1327 // because there's no such thing as strtoi. Use *ToLongTraits through a cast | 1386 // because there's no such thing as strtoi. Use *ToLongTraits through a cast |
1328 // instead, requiring that long and int are compatible and equal-width. They | 1387 // instead, requiring that long and int are compatible and equal-width. They |
1329 // are on our target platforms. | 1388 // are on our target platforms. |
1330 | 1389 |
1331 bool StringToInt(const std::string& input, int* output) { | 1390 bool StringToInt(const std::string& input, int* output) { |
1332 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int); | 1391 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int); |
1333 return StringToNumber<StringToLongTraits>(input, | 1392 return StringToNumber<StringToLongTraits>(input, |
1334 reinterpret_cast<long*>(output)); | 1393 reinterpret_cast<long*>(output), |
| 1394 LOCALE_DEPENDENT); |
1335 } | 1395 } |
1336 | 1396 |
1337 bool StringToInt(const std::wstring& input, int* output) { | 1397 bool StringToInt(const std::wstring& input, int* output) { |
1338 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int); | 1398 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int); |
1339 return StringToNumber<WStringToLongTraits>(input, | 1399 return StringToNumber<WStringToLongTraits>(input, |
1340 reinterpret_cast<long*>(output)); | 1400 reinterpret_cast<long*>(output), |
| 1401 LOCALE_DEPENDENT); |
1341 } | 1402 } |
1342 | 1403 |
1343 bool StringToInt64(const std::string& input, int64* output) { | 1404 bool StringToInt64(const std::string& input, int64* output) { |
1344 return StringToNumber<StringToInt64Traits>(input, output); | 1405 return StringToNumber<StringToInt64Traits>(input, output, LOCALE_DEPENDENT); |
1345 } | 1406 } |
1346 | 1407 |
1347 bool StringToInt64(const std::wstring& input, int64* output) { | 1408 bool StringToInt64(const std::wstring& input, int64* output) { |
1348 return StringToNumber<WStringToInt64Traits>(input, output); | 1409 return StringToNumber<WStringToInt64Traits>(input, output, LOCALE_DEPENDENT); |
1349 } | 1410 } |
1350 | 1411 |
1351 bool HexStringToInt(const std::string& input, int* output) { | 1412 bool HexStringToInt(const std::string& input, int* output) { |
1352 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int); | 1413 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_strtol_to_int); |
1353 return StringToNumber<HexStringToLongTraits>(input, | 1414 return StringToNumber<HexStringToLongTraits>(input, |
1354 reinterpret_cast<long*>(output)); | 1415 reinterpret_cast<long*>(output), |
| 1416 LOCALE_DEPENDENT); |
1355 } | 1417 } |
1356 | 1418 |
1357 bool HexStringToInt(const std::wstring& input, int* output) { | 1419 bool HexStringToInt(const std::wstring& input, int* output) { |
1358 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int); | 1420 COMPILE_ASSERT(sizeof(int) == sizeof(long), cannot_wcstol_to_int); |
1359 return StringToNumber<HexWStringToLongTraits>( | 1421 return StringToNumber<HexWStringToLongTraits>( |
1360 input, reinterpret_cast<long*>(output)); | 1422 input, reinterpret_cast<long*>(output), LOCALE_DEPENDENT); |
1361 } | 1423 } |
1362 | 1424 |
1363 bool StringToDouble(const std::string& input, double* output) { | 1425 bool StringToDouble(const std::string& input, double* output, |
1364 return StringToNumber<StringToDoubleTraits>(input, output); | 1426 LocaleDependence locale_dependent) { |
| 1427 return StringToNumber<StringToDoubleTraits>(input, output, |
| 1428 locale_dependent); |
1365 } | 1429 } |
1366 | 1430 |
1367 bool StringToDouble(const std::wstring& input, double* output) { | 1431 bool StringToDouble(const std::wstring& input, double* output, |
1368 return StringToNumber<WStringToDoubleTraits>(input, output); | 1432 LocaleDependence locale_dependent) { |
| 1433 return StringToNumber<WStringToDoubleTraits>(input, output, |
| 1434 locale_dependent); |
1369 } | 1435 } |
1370 | 1436 |
1371 int StringToInt(const std::string& value) { | 1437 int StringToInt(const std::string& value) { |
1372 int result; | 1438 int result; |
1373 StringToInt(value, &result); | 1439 StringToInt(value, &result); |
1374 return result; | 1440 return result; |
1375 } | 1441 } |
1376 | 1442 |
1377 int StringToInt(const std::wstring& value) { | 1443 int StringToInt(const std::wstring& value) { |
1378 int result; | 1444 int result; |
(...skipping 18 matching lines...) Expand all Loading... |
1397 HexStringToInt(value, &result); | 1463 HexStringToInt(value, &result); |
1398 return result; | 1464 return result; |
1399 } | 1465 } |
1400 | 1466 |
1401 int HexStringToInt(const std::wstring& value) { | 1467 int HexStringToInt(const std::wstring& value) { |
1402 int result; | 1468 int result; |
1403 HexStringToInt(value, &result); | 1469 HexStringToInt(value, &result); |
1404 return result; | 1470 return result; |
1405 } | 1471 } |
1406 | 1472 |
1407 double StringToDouble(const std::string& value) { | 1473 double StringToDouble(const std::string& value, |
| 1474 LocaleDependence locale_dependent) { |
1408 double result; | 1475 double result; |
1409 StringToDouble(value, &result); | 1476 StringToDouble(value, &result, locale_dependent); |
1410 return result; | 1477 return result; |
1411 } | 1478 } |
1412 | 1479 |
1413 double StringToDouble(const std::wstring& value) { | 1480 double StringToDouble(const std::wstring& value, |
| 1481 LocaleDependence locale_dependent) { |
1414 double result; | 1482 double result; |
1415 StringToDouble(value, &result); | 1483 StringToDouble(value, &result, locale_dependent); |
1416 return result; | 1484 return result; |
1417 } | 1485 } |
1418 | 1486 |
1419 // The following code is compatible with the OpenBSD lcpy interface. See: | 1487 // The following code is compatible with the OpenBSD lcpy interface. See: |
1420 // http://www.gratisoft.us/todd/papers/strlcpy.html | 1488 // http://www.gratisoft.us/todd/papers/strlcpy.html |
1421 // ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/{wcs,str}lcpy.c | 1489 // ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/{wcs,str}lcpy.c |
1422 | 1490 |
1423 namespace { | 1491 namespace { |
1424 | 1492 |
1425 template <typename CHAR> | 1493 template <typename CHAR> |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1476 int rstr_len = (max_len - 3) / 2; | 1544 int rstr_len = (max_len - 3) / 2; |
1477 int lstr_len = rstr_len + ((max_len - 3) % 2); | 1545 int lstr_len = rstr_len + ((max_len - 3) % 2); |
1478 output->assign(input.substr(0, lstr_len) + L"..." + | 1546 output->assign(input.substr(0, lstr_len) + L"..." + |
1479 input.substr(input.length() - rstr_len)); | 1547 input.substr(input.length() - rstr_len)); |
1480 break; | 1548 break; |
1481 } | 1549 } |
1482 } | 1550 } |
1483 | 1551 |
1484 return true; | 1552 return true; |
1485 } | 1553 } |
OLD | NEW |