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

Side by Side Diff: third_party/re2/util/pcre.cc

Issue 1516543002: Update re2 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: updated update instructions Created 5 years 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
« no previous file with comments | « third_party/re2/util/pcre.h ('k') | third_party/re2/util/rune.cc » ('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 2003-2009 Google Inc. All rights reserved. 1 // Copyright 2003-2009 Google Inc. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 // This is a variant of PCRE's pcrecpp.cc, originally written at Google. 5 // This is a variant of PCRE's pcrecpp.cc, originally written at Google.
6 // The main changes are the addition of the HitLimit method and 6 // The main changes are the addition of the HitLimit method and
7 // compilation as PCRE in namespace re2. 7 // compilation as PCRE in namespace re2.
8 8
9 #include <errno.h> 9 #include <errno.h>
10 #include <limits>
10 #include "util/util.h" 11 #include "util/util.h"
11 #include "util/flags.h" 12 #include "util/flags.h"
12 #include "util/pcre.h" 13 #include "util/pcre.h"
13 14
14 #ifdef WIN32
15 #define strtoll _strtoi64
16 #define strtoull _strtoui64
17 #endif
18
19 #define PCREPORT(level) LOG(level) 15 #define PCREPORT(level) LOG(level)
20 16
21 // Default PCRE limits. 17 // Default PCRE limits.
22 // Defaults chosen to allow a plausible amount of CPU and 18 // Defaults chosen to allow a plausible amount of CPU and
23 // not exceed main thread stacks. Note that other threads 19 // not exceed main thread stacks. Note that other threads
24 // often have smaller stacks, and therefore tightening 20 // often have smaller stacks, and therefore tightening
25 // regexp_stack_limit may frequently be necessary. 21 // regexp_stack_limit may frequently be necessary.
26 DEFINE_int32(regexp_stack_limit, 256<<10, "default PCRE stack limit (bytes)"); 22 DEFINE_int32(regexp_stack_limit, 256<<10, "default PCRE stack limit (bytes)");
27 DEFINE_int32(regexp_match_limit, 1000000, 23 DEFINE_int32(regexp_match_limit, 1000000,
28 "default PCRE match limit (function calls)"); 24 "default PCRE match limit (function calls)");
29 25
26 #ifndef USEPCRE
27
28 // Fake just enough of the PCRE API to allow this file to build. :)
29
30 struct pcre_extra {
31 int flags;
32 int match_limit;
33 int match_limit_recursion;
34 };
35
36 #define PCRE_EXTRA_MATCH_LIMIT 0
37 #define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0
38 #define PCRE_ANCHORED 0
39 #define PCRE_NOTEMPTY 0
40 #define PCRE_ERROR_NOMATCH 1
41 #define PCRE_ERROR_MATCHLIMIT 2
42 #define PCRE_ERROR_RECURSIONLIMIT 3
43 #define PCRE_INFO_CAPTURECOUNT 0
44
45 void pcre_free(void*) {
46 }
47
48 pcre* pcre_compile(const char*, int, const char**, int*, const unsigned char*) {
49 return NULL;
50 }
51
52 int pcre_exec(const pcre*, const pcre_extra*, const char*, int, int, int, int*, int) {
53 return 0;
54 }
55
56 int pcre_fullinfo(const pcre*, const pcre_extra*, int, void*) {
57 return 0;
58 }
59
60 #endif
61
30 namespace re2 { 62 namespace re2 {
31 63
32 // Maximum number of args we can set 64 // Maximum number of args we can set
33 static const int kMaxArgs = 16; 65 static const int kMaxArgs = 16;
34 static const int kVecSize = (1 + kMaxArgs) * 3; // results + PCRE workspace 66 static const int kVecSize = (1 + kMaxArgs) * 3; // results + PCRE workspace
35 67
36 // Approximate size of a recursive invocation of PCRE's 68 // Approximate size of a recursive invocation of PCRE's
37 // internal "match()" frame. This varies depending on the 69 // internal "match()" frame. This varies depending on the
38 // compiler and architecture, of course, so the constant is 70 // compiler and architecture, of course, so the constant is
39 // just a conservative estimate. To find the exact number, 71 // just a conservative estimate. To find the exact number,
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 // beginning of a string. 143 // beginning of a string.
112 // 144 //
113 // There are three types of anchoring we want: 145 // There are three types of anchoring we want:
114 // UNANCHORED Compile the original pattern, and use 146 // UNANCHORED Compile the original pattern, and use
115 // a pcre unanchored match. 147 // a pcre unanchored match.
116 // ANCHOR_START Compile the original pattern, and use 148 // ANCHOR_START Compile the original pattern, and use
117 // a pcre anchored match. 149 // a pcre anchored match.
118 // ANCHOR_BOTH Tack a "\z" to the end of the original pattern 150 // ANCHOR_BOTH Tack a "\z" to the end of the original pattern
119 // and use a pcre anchored match. 151 // and use a pcre anchored match.
120 152
121 const char* error; 153 const char* error = "";
122 int eoffset; 154 int eoffset;
123 pcre* re; 155 pcre* re;
124 if (anchor != ANCHOR_BOTH) { 156 if (anchor != ANCHOR_BOTH) {
125 re = pcre_compile(pattern_.c_str(), 157 re = pcre_compile(pattern_.c_str(),
126 (options_ & EnabledCompileOptions), 158 (options_ & EnabledCompileOptions),
127 &error, &eoffset, NULL); 159 &error, &eoffset, NULL);
128 } else { 160 } else {
129 // Tack a '\z' at the end of PCRE. Parenthesize it first so that 161 // Tack a '\z' at the end of PCRE. Parenthesize it first so that
130 // the '\z' applies to all top-level alternatives in the regexp. 162 // the '\z' applies to all top-level alternatives in the regexp.
131 string wrapped = "(?:"; // A non-counting grouping operator 163 string wrapped = "(?:"; // A non-counting grouping operator
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 if (&a9 == &no_more_args) goto done; args[n++] = &a9; 208 if (&a9 == &no_more_args) goto done; args[n++] = &a9;
177 if (&a10 == &no_more_args) goto done; args[n++] = &a10; 209 if (&a10 == &no_more_args) goto done; args[n++] = &a10;
178 if (&a11 == &no_more_args) goto done; args[n++] = &a11; 210 if (&a11 == &no_more_args) goto done; args[n++] = &a11;
179 if (&a12 == &no_more_args) goto done; args[n++] = &a12; 211 if (&a12 == &no_more_args) goto done; args[n++] = &a12;
180 if (&a13 == &no_more_args) goto done; args[n++] = &a13; 212 if (&a13 == &no_more_args) goto done; args[n++] = &a13;
181 if (&a14 == &no_more_args) goto done; args[n++] = &a14; 213 if (&a14 == &no_more_args) goto done; args[n++] = &a14;
182 if (&a15 == &no_more_args) goto done; args[n++] = &a15; 214 if (&a15 == &no_more_args) goto done; args[n++] = &a15;
183 done: 215 done:
184 216
185 int consumed; 217 int consumed;
186 int vec[kVecSize]; 218 int vec[kVecSize] = {};
187 return re.DoMatchImpl(text, ANCHOR_BOTH, &consumed, args, n, vec, kVecSize); 219 return re.DoMatchImpl(text, ANCHOR_BOTH, &consumed, args, n, vec, kVecSize);
188 } 220 }
189 221
190 bool PCRE::PartialMatchFunctor::operator ()(const StringPiece& text, 222 bool PCRE::PartialMatchFunctor::operator ()(const StringPiece& text,
191 const PCRE& re, 223 const PCRE& re,
192 const Arg& a0, 224 const Arg& a0,
193 const Arg& a1, 225 const Arg& a1,
194 const Arg& a2, 226 const Arg& a2,
195 const Arg& a3, 227 const Arg& a3,
196 const Arg& a4, 228 const Arg& a4,
(...skipping 22 matching lines...) Expand all
219 if (&a9 == &no_more_args) goto done; args[n++] = &a9; 251 if (&a9 == &no_more_args) goto done; args[n++] = &a9;
220 if (&a10 == &no_more_args) goto done; args[n++] = &a10; 252 if (&a10 == &no_more_args) goto done; args[n++] = &a10;
221 if (&a11 == &no_more_args) goto done; args[n++] = &a11; 253 if (&a11 == &no_more_args) goto done; args[n++] = &a11;
222 if (&a12 == &no_more_args) goto done; args[n++] = &a12; 254 if (&a12 == &no_more_args) goto done; args[n++] = &a12;
223 if (&a13 == &no_more_args) goto done; args[n++] = &a13; 255 if (&a13 == &no_more_args) goto done; args[n++] = &a13;
224 if (&a14 == &no_more_args) goto done; args[n++] = &a14; 256 if (&a14 == &no_more_args) goto done; args[n++] = &a14;
225 if (&a15 == &no_more_args) goto done; args[n++] = &a15; 257 if (&a15 == &no_more_args) goto done; args[n++] = &a15;
226 done: 258 done:
227 259
228 int consumed; 260 int consumed;
229 int vec[kVecSize]; 261 int vec[kVecSize] = {};
230 return re.DoMatchImpl(text, UNANCHORED, &consumed, args, n, vec, kVecSize); 262 return re.DoMatchImpl(text, UNANCHORED, &consumed, args, n, vec, kVecSize);
231 } 263 }
232 264
233 bool PCRE::ConsumeFunctor::operator ()(StringPiece* input, 265 bool PCRE::ConsumeFunctor::operator ()(StringPiece* input,
234 const PCRE& pattern, 266 const PCRE& pattern,
235 const Arg& a0, 267 const Arg& a0,
236 const Arg& a1, 268 const Arg& a1,
237 const Arg& a2, 269 const Arg& a2,
238 const Arg& a3, 270 const Arg& a3,
239 const Arg& a4, 271 const Arg& a4,
(...skipping 22 matching lines...) Expand all
262 if (&a9 == &no_more_args) goto done; args[n++] = &a9; 294 if (&a9 == &no_more_args) goto done; args[n++] = &a9;
263 if (&a10 == &no_more_args) goto done; args[n++] = &a10; 295 if (&a10 == &no_more_args) goto done; args[n++] = &a10;
264 if (&a11 == &no_more_args) goto done; args[n++] = &a11; 296 if (&a11 == &no_more_args) goto done; args[n++] = &a11;
265 if (&a12 == &no_more_args) goto done; args[n++] = &a12; 297 if (&a12 == &no_more_args) goto done; args[n++] = &a12;
266 if (&a13 == &no_more_args) goto done; args[n++] = &a13; 298 if (&a13 == &no_more_args) goto done; args[n++] = &a13;
267 if (&a14 == &no_more_args) goto done; args[n++] = &a14; 299 if (&a14 == &no_more_args) goto done; args[n++] = &a14;
268 if (&a15 == &no_more_args) goto done; args[n++] = &a15; 300 if (&a15 == &no_more_args) goto done; args[n++] = &a15;
269 done: 301 done:
270 302
271 int consumed; 303 int consumed;
272 int vec[kVecSize]; 304 int vec[kVecSize] = {};
273 if (pattern.DoMatchImpl(*input, ANCHOR_START, &consumed, 305 if (pattern.DoMatchImpl(*input, ANCHOR_START, &consumed,
274 args, n, vec, kVecSize)) { 306 args, n, vec, kVecSize)) {
275 input->remove_prefix(consumed); 307 input->remove_prefix(consumed);
276 return true; 308 return true;
277 } else { 309 } else {
278 return false; 310 return false;
279 } 311 }
280 } 312 }
281 313
282 bool PCRE::FindAndConsumeFunctor::operator ()(StringPiece* input, 314 bool PCRE::FindAndConsumeFunctor::operator ()(StringPiece* input,
(...skipping 28 matching lines...) Expand all
311 if (&a9 == &no_more_args) goto done; args[n++] = &a9; 343 if (&a9 == &no_more_args) goto done; args[n++] = &a9;
312 if (&a10 == &no_more_args) goto done; args[n++] = &a10; 344 if (&a10 == &no_more_args) goto done; args[n++] = &a10;
313 if (&a11 == &no_more_args) goto done; args[n++] = &a11; 345 if (&a11 == &no_more_args) goto done; args[n++] = &a11;
314 if (&a12 == &no_more_args) goto done; args[n++] = &a12; 346 if (&a12 == &no_more_args) goto done; args[n++] = &a12;
315 if (&a13 == &no_more_args) goto done; args[n++] = &a13; 347 if (&a13 == &no_more_args) goto done; args[n++] = &a13;
316 if (&a14 == &no_more_args) goto done; args[n++] = &a14; 348 if (&a14 == &no_more_args) goto done; args[n++] = &a14;
317 if (&a15 == &no_more_args) goto done; args[n++] = &a15; 349 if (&a15 == &no_more_args) goto done; args[n++] = &a15;
318 done: 350 done:
319 351
320 int consumed; 352 int consumed;
321 int vec[kVecSize]; 353 int vec[kVecSize] = {};
322 if (pattern.DoMatchImpl(*input, UNANCHORED, &consumed, 354 if (pattern.DoMatchImpl(*input, UNANCHORED, &consumed,
323 args, n, vec, kVecSize)) { 355 args, n, vec, kVecSize)) {
324 input->remove_prefix(consumed); 356 input->remove_prefix(consumed);
325 return true; 357 return true;
326 } else { 358 } else {
327 return false; 359 return false;
328 } 360 }
329 } 361 }
330 362
331 bool PCRE::Replace(string *str, 363 bool PCRE::Replace(string *str,
332 const PCRE& pattern, 364 const PCRE& pattern,
333 const StringPiece& rewrite) { 365 const StringPiece& rewrite) {
334 int vec[kVecSize]; 366 int vec[kVecSize] = {};
335 int matches = pattern.TryMatch(*str, 0, UNANCHORED, true, vec, kVecSize); 367 int matches = pattern.TryMatch(*str, 0, UNANCHORED, true, vec, kVecSize);
336 if (matches == 0) 368 if (matches == 0)
337 return false; 369 return false;
338 370
339 string s; 371 string s;
340 if (!pattern.Rewrite(&s, rewrite, *str, vec, matches)) 372 if (!pattern.Rewrite(&s, rewrite, *str, vec, matches))
341 return false; 373 return false;
342 374
343 assert(vec[0] >= 0); 375 assert(vec[0] >= 0);
344 assert(vec[1] >= 0); 376 assert(vec[1] >= 0);
345 str->replace(vec[0], vec[1] - vec[0], s); 377 str->replace(vec[0], vec[1] - vec[0], s);
346 return true; 378 return true;
347 } 379 }
348 380
349 int PCRE::GlobalReplace(string *str, 381 int PCRE::GlobalReplace(string *str,
350 const PCRE& pattern, 382 const PCRE& pattern,
351 const StringPiece& rewrite) { 383 const StringPiece& rewrite) {
352 int count = 0; 384 int count = 0;
353 int vec[kVecSize]; 385 int vec[kVecSize] = {};
354 string out; 386 string out;
355 int start = 0; 387 int start = 0;
356 bool last_match_was_empty_string = false; 388 bool last_match_was_empty_string = false;
357 389
358 for (; start <= str->length();) { 390 while (start <= static_cast<int>(str->size())) {
359 // If the previous match was for the empty string, we shouldn't 391 // If the previous match was for the empty string, we shouldn't
360 // just match again: we'll match in the same way and get an 392 // just match again: we'll match in the same way and get an
361 // infinite loop. Instead, we do the match in a special way: 393 // infinite loop. Instead, we do the match in a special way:
362 // anchored -- to force another try at the same position -- 394 // anchored -- to force another try at the same position --
363 // and with a flag saying that this time, ignore empty matches. 395 // and with a flag saying that this time, ignore empty matches.
364 // If this special match returns, that means there's a non-empty 396 // If this special match returns, that means there's a non-empty
365 // match at this position as well, and we can continue. If not, 397 // match at this position as well, and we can continue. If not,
366 // we do what perl does, and just advance by one. 398 // we do what perl does, and just advance by one.
367 // Notice that perl prints '@@@' for this; 399 // Notice that perl prints '@@@' for this;
368 // perl -le '$_ = "aa"; s/b*|aa/@/g; print' 400 // perl -le '$_ = "aa"; s/b*|aa/@/g; print'
369 int matches; 401 int matches;
370 if (last_match_was_empty_string) { 402 if (last_match_was_empty_string) {
371 matches = pattern.TryMatch(*str, start, ANCHOR_START, false, 403 matches = pattern.TryMatch(*str, start, ANCHOR_START, false,
372 vec, kVecSize); 404 vec, kVecSize);
373 if (matches <= 0) { 405 if (matches <= 0) {
374 if (start < str->length()) 406 if (start < static_cast<int>(str->size()))
375 out.push_back((*str)[start]); 407 out.push_back((*str)[start]);
376 start++; 408 start++;
377 last_match_was_empty_string = false; 409 last_match_was_empty_string = false;
378 continue; 410 continue;
379 } 411 }
380 } else { 412 } else {
381 matches = pattern.TryMatch(*str, start, UNANCHORED, true, vec, kVecSize); 413 matches = pattern.TryMatch(*str, start, UNANCHORED, true,
414 vec, kVecSize);
382 if (matches <= 0) 415 if (matches <= 0)
383 break; 416 break;
384 } 417 }
385 int matchstart = vec[0], matchend = vec[1]; 418 int matchstart = vec[0], matchend = vec[1];
386 assert(matchstart >= start); 419 assert(matchstart >= start);
387 assert(matchend >= matchstart); 420 assert(matchend >= matchstart);
388 421
389 out.append(*str, start, matchstart - start); 422 out.append(*str, start, matchstart - start);
390 pattern.Rewrite(&out, rewrite, *str, vec, matches); 423 pattern.Rewrite(&out, rewrite, *str, vec, matches);
391 start = matchend; 424 start = matchend;
392 count++; 425 count++;
393 last_match_was_empty_string = (matchstart == matchend); 426 last_match_was_empty_string = (matchstart == matchend);
394 } 427 }
395 428
396 if (count == 0) 429 if (count == 0)
397 return 0; 430 return 0;
398 431
399 if (start < str->length()) 432 if (start < static_cast<int>(str->size()))
400 out.append(*str, start, str->length() - start); 433 out.append(*str, start, static_cast<int>(str->size()) - start);
401 swap(out, *str); 434 swap(out, *str);
402 return count; 435 return count;
403 } 436 }
404 437
405 bool PCRE::Extract(const StringPiece &text, 438 bool PCRE::Extract(const StringPiece &text,
406 const PCRE& pattern, 439 const PCRE& pattern,
407 const StringPiece &rewrite, 440 const StringPiece &rewrite,
408 string *out) { 441 string *out) {
409 int vec[kVecSize]; 442 int vec[kVecSize] = {};
410 int matches = pattern.TryMatch(text, 0, UNANCHORED, true, vec, kVecSize); 443 int matches = pattern.TryMatch(text, 0, UNANCHORED, true, vec, kVecSize);
411 if (matches == 0) 444 if (matches == 0)
412 return false; 445 return false;
413 out->clear(); 446 out->clear();
414 return pattern.Rewrite(out, rewrite, text, vec, matches); 447 return pattern.Rewrite(out, rewrite, text, vec, matches);
415 } 448 }
416 449
417 string PCRE::QuoteMeta(const StringPiece& unquoted) { 450 string PCRE::QuoteMeta(const StringPiece& unquoted) {
418 string result; 451 string result;
419 result.reserve(unquoted.size() << 1); 452 result.reserve(unquoted.size() << 1);
(...skipping 25 matching lines...) Expand all
445 } 478 }
446 result += unquoted[ii]; 479 result += unquoted[ii];
447 } 480 }
448 481
449 return result; 482 return result;
450 } 483 }
451 484
452 /***** Actual matching and rewriting code *****/ 485 /***** Actual matching and rewriting code *****/
453 486
454 bool PCRE::HitLimit() { 487 bool PCRE::HitLimit() {
455 return hit_limit_; 488 return hit_limit_ != 0;
456 } 489 }
457 490
458 void PCRE::ClearHitLimit() { 491 void PCRE::ClearHitLimit() {
459 hit_limit_ = 0; 492 hit_limit_ = 0;
460 } 493 }
461 494
462 int PCRE::TryMatch(const StringPiece& text, 495 int PCRE::TryMatch(const StringPiece& text,
463 int startpos, 496 int startpos,
464 Anchor anchor, 497 Anchor anchor,
465 bool empty_ok, 498 bool empty_ok,
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 626
594 return true; 627 return true;
595 } 628 }
596 629
597 bool PCRE::DoMatch(const StringPiece& text, 630 bool PCRE::DoMatch(const StringPiece& text,
598 Anchor anchor, 631 Anchor anchor,
599 int* consumed, 632 int* consumed,
600 const Arg* const args[], 633 const Arg* const args[],
601 int n) const { 634 int n) const {
602 assert(n >= 0); 635 assert(n >= 0);
603 size_t const vecsize = (1 + n) * 3; // results + PCRE workspace 636 const int vecsize = (1 + n) * 3; // results + PCRE workspace
604 // (as for kVecSize) 637 // (as for kVecSize)
605 int *vec = new int[vecsize]; 638 int* vec = new int[vecsize];
606 bool b = DoMatchImpl(text, anchor, consumed, args, n, vec, vecsize); 639 bool b = DoMatchImpl(text, anchor, consumed, args, n, vec, vecsize);
607 delete[] vec; 640 delete[] vec;
608 return b; 641 return b;
609 } 642 }
610 643
611 bool PCRE::Rewrite(string *out, const StringPiece &rewrite, 644 bool PCRE::Rewrite(string *out, const StringPiece &rewrite,
612 const StringPiece &text, int *vec, int veclen) const { 645 const StringPiece &text, int *vec, int veclen) const {
613 int number_of_capturing_groups = NumberOfCapturingGroups(); 646 int number_of_capturing_groups = NumberOfCapturingGroups();
614 for (const char *s = rewrite.data(), *end = s + rewrite.size(); 647 for (const char *s = rewrite.data(), *end = s + rewrite.size();
615 s < end; s++) { 648 s < end; s++) {
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 } 834 }
802 835
803 bool PCRE::Arg::parse_short_radix(const char* str, 836 bool PCRE::Arg::parse_short_radix(const char* str,
804 int n, 837 int n,
805 void* dest, 838 void* dest,
806 int radix) { 839 int radix) {
807 long r; 840 long r;
808 if (!parse_long_radix(str, n, &r, radix)) return false; // Could not parse 841 if (!parse_long_radix(str, n, &r, radix)) return false; // Could not parse
809 if ((short)r != r) return false; // Out of range 842 if ((short)r != r) return false; // Out of range
810 if (dest == NULL) return true; 843 if (dest == NULL) return true;
811 *(reinterpret_cast<short*>(dest)) = r; 844 *(reinterpret_cast<short*>(dest)) = (short)r;
812 return true; 845 return true;
813 } 846 }
814 847
815 bool PCRE::Arg::parse_ushort_radix(const char* str, 848 bool PCRE::Arg::parse_ushort_radix(const char* str,
816 int n, 849 int n,
817 void* dest, 850 void* dest,
818 int radix) { 851 int radix) {
819 unsigned long r; 852 unsigned long r;
820 if (!parse_ulong_radix(str, n, &r, radix)) return false; // Could not parse 853 if (!parse_ulong_radix(str, n, &r, radix)) return false; // Could not parse
821 if ((ushort)r != r) return false; // Out of range 854 if ((ushort)r != r) return false; // Out of range
822 if (dest == NULL) return true; 855 if (dest == NULL) return true;
823 *(reinterpret_cast<unsigned short*>(dest)) = r; 856 *(reinterpret_cast<unsigned short*>(dest)) = (ushort)r;
824 return true; 857 return true;
825 } 858 }
826 859
827 bool PCRE::Arg::parse_int_radix(const char* str, 860 bool PCRE::Arg::parse_int_radix(const char* str,
828 int n, 861 int n,
829 void* dest, 862 void* dest,
830 int radix) { 863 int radix) {
831 long r; 864 long r;
832 if (!parse_long_radix(str, n, &r, radix)) return false; // Could not parse 865 if (!parse_long_radix(str, n, &r, radix)) return false; // Could not parse
833 if ((int)r != r) return false; // Out of range 866 if ((int)r != r) return false; // Out of range
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 if (n == 0) return false; 924 if (n == 0) return false;
892 static const int kMaxLength = 200; 925 static const int kMaxLength = 200;
893 char buf[kMaxLength]; 926 char buf[kMaxLength];
894 if (n >= kMaxLength) return false; 927 if (n >= kMaxLength) return false;
895 memcpy(buf, str, n); 928 memcpy(buf, str, n);
896 buf[n] = '\0'; 929 buf[n] = '\0';
897 errno = 0; 930 errno = 0;
898 char* end; 931 char* end;
899 double r = strtod(buf, &end); 932 double r = strtod(buf, &end);
900 if (end != buf + n) { 933 if (end != buf + n) {
901 #ifdef COMPILER_MSVC 934 #ifdef _WIN32
902 // Microsoft's strtod() doesn't handle inf and nan, so we have to 935 // Microsoft's strtod() doesn't handle inf and nan, so we have to
903 // handle it explicitly. Speed is not important here because this 936 // handle it explicitly. Speed is not important here because this
904 // code is only called in unit tests. 937 // code is only called in unit tests.
905 bool pos = true; 938 bool pos = true;
906 const char* i = buf; 939 const char* i = buf;
907 if ('-' == *i) { 940 if ('-' == *i) {
908 pos = false; 941 pos = false;
909 ++i; 942 ++i;
910 } else if ('+' == *i) { 943 } else if ('+' == *i) {
911 ++i; 944 ++i;
912 } 945 }
913 if (0 == stricmp(i, "inf") || 0 == stricmp(i, "infinity")) { 946 if (0 == stricmp(i, "inf") || 0 == stricmp(i, "infinity")) {
914 r = numeric_limits<double>::infinity(); 947 r = std::numeric_limits<double>::infinity();
915 if (!pos) 948 if (!pos)
916 r = -r; 949 r = -r;
917 } else if (0 == stricmp(i, "nan")) { 950 } else if (0 == stricmp(i, "nan")) {
918 r = numeric_limits<double>::quiet_NaN(); 951 r = std::numeric_limits<double>::quiet_NaN();
919 } else { 952 } else {
920 return false; 953 return false;
921 } 954 }
922 #else 955 #else
923 return false; // Leftover junk 956 return false; // Leftover junk
924 #endif 957 #endif
925 } 958 }
926 if (errno) return false; 959 if (errno) return false;
927 if (dest == NULL) return true; 960 if (dest == NULL) return true;
928 *(reinterpret_cast<double*>(dest)) = r; 961 *(reinterpret_cast<double*>(dest)) = r;
(...skipping 28 matching lines...) Expand all
957 DEFINE_INTEGER_PARSERS(int); 990 DEFINE_INTEGER_PARSERS(int);
958 DEFINE_INTEGER_PARSERS(uint); 991 DEFINE_INTEGER_PARSERS(uint);
959 DEFINE_INTEGER_PARSERS(long); 992 DEFINE_INTEGER_PARSERS(long);
960 DEFINE_INTEGER_PARSERS(ulong); 993 DEFINE_INTEGER_PARSERS(ulong);
961 DEFINE_INTEGER_PARSERS(longlong); 994 DEFINE_INTEGER_PARSERS(longlong);
962 DEFINE_INTEGER_PARSERS(ulonglong); 995 DEFINE_INTEGER_PARSERS(ulonglong);
963 996
964 #undef DEFINE_INTEGER_PARSERS 997 #undef DEFINE_INTEGER_PARSERS
965 998
966 } // namespace re2 999 } // namespace re2
OLDNEW
« no previous file with comments | « third_party/re2/util/pcre.h ('k') | third_party/re2/util/rune.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698