Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: base/string_util.cc

Issue 9509: Make unit_tests pass with pt_BR.UTF-8 locale. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 12 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/string_util.h ('k') | build/SConscript.main » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « base/string_util.h ('k') | build/SConscript.main » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698