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