| 55 |
static const int kVecSize = (1 + kMaxArgs) * 3; // results + PCRE workspace |
static const int kVecSize = (1 + kMaxArgs) * 3; // results + PCRE workspace |
| 56 |
|
|
| 57 |
// Special object that stands-in for no argument |
// Special object that stands-in for no argument |
| 58 |
PCRECPP_EXP_DEFN Arg no_arg((void*)NULL); |
Arg RE::no_arg((void*)NULL); |
| 59 |
|
|
| 60 |
|
// This is for ABI compatibility with old versions of pcre (pre-7.6), |
| 61 |
|
// which defined a global no_arg variable instead of putting it in the |
| 62 |
|
// RE class. This works on GCC >= 3, at least. We could probably have |
| 63 |
|
// a more inclusive test if we ever needed it. |
| 64 |
|
#if defined(__GNUC__) && __GNUC__ >= 3 |
| 65 |
|
extern Arg no_arg __attribute__((alias("_ZN7pcrecpp2RE6no_argE"))); |
| 66 |
|
#endif |
| 67 |
|
|
| 68 |
// If a regular expression has no error, its error_ field points here |
// If a regular expression has no error, its error_ field points here |
| 69 |
static const string empty_string; |
static const string empty_string; |
| 377 |
int start = 0; |
int start = 0; |
| 378 |
int lastend = -1; |
int lastend = -1; |
| 379 |
|
|
| 380 |
for (; start <= static_cast<int>(str->length()); count++) { |
while (start <= static_cast<int>(str->length())) { |
| 381 |
int matches = TryMatch(*str, start, UNANCHORED, vec, kVecSize); |
int matches = TryMatch(*str, start, UNANCHORED, vec, kVecSize); |
| 382 |
if (matches <= 0) |
if (matches <= 0) |
| 383 |
break; |
break; |
| 449 |
// Note that it's legal to escape a character even if it has no |
// Note that it's legal to escape a character even if it has no |
| 450 |
// special meaning in a regular expression -- so this function does |
// special meaning in a regular expression -- so this function does |
| 451 |
// that. (This also makes it identical to the perl function of the |
// that. (This also makes it identical to the perl function of the |
| 452 |
// same name; see `perldoc -f quotemeta`.) |
// same name; see `perldoc -f quotemeta`.) The one exception is |
| 453 |
|
// escaping NUL: rather than doing backslash + NUL, like perl does, |
| 454 |
|
// we do '\0', because pcre itself doesn't take embedded NUL chars. |
| 455 |
for (int ii = 0; ii < unquoted.size(); ++ii) { |
for (int ii = 0; ii < unquoted.size(); ++ii) { |
| 456 |
// Note that using 'isalnum' here raises the benchmark time from |
// Note that using 'isalnum' here raises the benchmark time from |
| 457 |
// 32ns to 58ns: |
// 32ns to 58ns: |
| 458 |
if ((unquoted[ii] < 'a' || unquoted[ii] > 'z') && |
if (unquoted[ii] == '\0') { |
| 459 |
(unquoted[ii] < 'A' || unquoted[ii] > 'Z') && |
result += "\\0"; |
| 460 |
(unquoted[ii] < '0' || unquoted[ii] > '9') && |
} else if ((unquoted[ii] < 'a' || unquoted[ii] > 'z') && |
| 461 |
unquoted[ii] != '_' && |
(unquoted[ii] < 'A' || unquoted[ii] > 'Z') && |
| 462 |
// If this is the part of a UTF8 or Latin1 character, we need |
(unquoted[ii] < '0' || unquoted[ii] > '9') && |
| 463 |
// to copy this byte without escaping. Experimentally this is |
unquoted[ii] != '_' && |
| 464 |
// what works correctly with the regexp library. |
// If this is the part of a UTF8 or Latin1 character, we need |
| 465 |
!(unquoted[ii] & 128)) { |
// to copy this byte without escaping. Experimentally this is |
| 466 |
|
// what works correctly with the regexp library. |
| 467 |
|
!(unquoted[ii] & 128)) { |
| 468 |
result += '\\'; |
result += '\\'; |
| 469 |
|
result += unquoted[ii]; |
| 470 |
|
} else { |
| 471 |
|
result += unquoted[ii]; |
| 472 |
} |
} |
|
result += unquoted[ii]; |
|
| 473 |
} |
} |
| 474 |
|
|
| 475 |
return result; |
return result; |
| 632 |
} |
} |
| 633 |
|
|
| 634 |
bool Arg::parse_string(const char* str, int n, void* dest) { |
bool Arg::parse_string(const char* str, int n, void* dest) { |
| 635 |
|
if (dest == NULL) return true; |
| 636 |
reinterpret_cast<string*>(dest)->assign(str, n); |
reinterpret_cast<string*>(dest)->assign(str, n); |
| 637 |
return true; |
return true; |
| 638 |
} |
} |
| 639 |
|
|
| 640 |
bool Arg::parse_stringpiece(const char* str, int n, void* dest) { |
bool Arg::parse_stringpiece(const char* str, int n, void* dest) { |
| 641 |
|
if (dest == NULL) return true; |
| 642 |
reinterpret_cast<StringPiece*>(dest)->set(str, n); |
reinterpret_cast<StringPiece*>(dest)->set(str, n); |
| 643 |
return true; |
return true; |
| 644 |
} |
} |
| 645 |
|
|
| 646 |
bool Arg::parse_char(const char* str, int n, void* dest) { |
bool Arg::parse_char(const char* str, int n, void* dest) { |
| 647 |
if (n != 1) return false; |
if (n != 1) return false; |
| 648 |
|
if (dest == NULL) return true; |
| 649 |
*(reinterpret_cast<char*>(dest)) = str[0]; |
*(reinterpret_cast<char*>(dest)) = str[0]; |
| 650 |
return true; |
return true; |
| 651 |
} |
} |
| 652 |
|
|
| 653 |
bool Arg::parse_uchar(const char* str, int n, void* dest) { |
bool Arg::parse_uchar(const char* str, int n, void* dest) { |
| 654 |
if (n != 1) return false; |
if (n != 1) return false; |
| 655 |
|
if (dest == NULL) return true; |
| 656 |
*(reinterpret_cast<unsigned char*>(dest)) = str[0]; |
*(reinterpret_cast<unsigned char*>(dest)) = str[0]; |
| 657 |
return true; |
return true; |
| 658 |
} |
} |
| 701 |
long r = strtol(str, &end, radix); |
long r = strtol(str, &end, radix); |
| 702 |
if (end != str + n) return false; // Leftover junk |
if (end != str + n) return false; // Leftover junk |
| 703 |
if (errno) return false; |
if (errno) return false; |
| 704 |
|
if (dest == NULL) return true; |
| 705 |
*(reinterpret_cast<long*>(dest)) = r; |
*(reinterpret_cast<long*>(dest)) = r; |
| 706 |
return true; |
return true; |
| 707 |
} |
} |
| 719 |
unsigned long r = strtoul(str, &end, radix); |
unsigned long r = strtoul(str, &end, radix); |
| 720 |
if (end != str + n) return false; // Leftover junk |
if (end != str + n) return false; // Leftover junk |
| 721 |
if (errno) return false; |
if (errno) return false; |
| 722 |
|
if (dest == NULL) return true; |
| 723 |
*(reinterpret_cast<unsigned long*>(dest)) = r; |
*(reinterpret_cast<unsigned long*>(dest)) = r; |
| 724 |
return true; |
return true; |
| 725 |
} |
} |
| 731 |
long r; |
long r; |
| 732 |
if (!parse_long_radix(str, n, &r, radix)) return false; // Could not parse |
if (!parse_long_radix(str, n, &r, radix)) return false; // Could not parse |
| 733 |
if (r < SHRT_MIN || r > SHRT_MAX) return false; // Out of range |
if (r < SHRT_MIN || r > SHRT_MAX) return false; // Out of range |
| 734 |
|
if (dest == NULL) return true; |
| 735 |
*(reinterpret_cast<short*>(dest)) = static_cast<short>(r); |
*(reinterpret_cast<short*>(dest)) = static_cast<short>(r); |
| 736 |
return true; |
return true; |
| 737 |
} |
} |
| 743 |
unsigned long r; |
unsigned long r; |
| 744 |
if (!parse_ulong_radix(str, n, &r, radix)) return false; // Could not parse |
if (!parse_ulong_radix(str, n, &r, radix)) return false; // Could not parse |
| 745 |
if (r > USHRT_MAX) return false; // Out of range |
if (r > USHRT_MAX) return false; // Out of range |
| 746 |
|
if (dest == NULL) return true; |
| 747 |
*(reinterpret_cast<unsigned short*>(dest)) = static_cast<unsigned short>(r); |
*(reinterpret_cast<unsigned short*>(dest)) = static_cast<unsigned short>(r); |
| 748 |
return true; |
return true; |
| 749 |
} |
} |
| 755 |
long r; |
long r; |
| 756 |
if (!parse_long_radix(str, n, &r, radix)) return false; // Could not parse |
if (!parse_long_radix(str, n, &r, radix)) return false; // Could not parse |
| 757 |
if (r < INT_MIN || r > INT_MAX) return false; // Out of range |
if (r < INT_MIN || r > INT_MAX) return false; // Out of range |
| 758 |
|
if (dest == NULL) return true; |
| 759 |
*(reinterpret_cast<int*>(dest)) = r; |
*(reinterpret_cast<int*>(dest)) = r; |
| 760 |
return true; |
return true; |
| 761 |
} |
} |
| 767 |
unsigned long r; |
unsigned long r; |
| 768 |
if (!parse_ulong_radix(str, n, &r, radix)) return false; // Could not parse |
if (!parse_ulong_radix(str, n, &r, radix)) return false; // Could not parse |
| 769 |
if (r > UINT_MAX) return false; // Out of range |
if (r > UINT_MAX) return false; // Out of range |
| 770 |
|
if (dest == NULL) return true; |
| 771 |
*(reinterpret_cast<unsigned int*>(dest)) = r; |
*(reinterpret_cast<unsigned int*>(dest)) = r; |
| 772 |
return true; |
return true; |
| 773 |
} |
} |
| 795 |
#endif |
#endif |
| 796 |
if (end != str + n) return false; // Leftover junk |
if (end != str + n) return false; // Leftover junk |
| 797 |
if (errno) return false; |
if (errno) return false; |
| 798 |
|
if (dest == NULL) return true; |
| 799 |
*(reinterpret_cast<long long*>(dest)) = r; |
*(reinterpret_cast<long long*>(dest)) = r; |
| 800 |
return true; |
return true; |
| 801 |
#endif /* HAVE_LONG_LONG */ |
#endif /* HAVE_LONG_LONG */ |
| 825 |
#endif |
#endif |
| 826 |
if (end != str + n) return false; // Leftover junk |
if (end != str + n) return false; // Leftover junk |
| 827 |
if (errno) return false; |
if (errno) return false; |
| 828 |
|
if (dest == NULL) return true; |
| 829 |
*(reinterpret_cast<unsigned long long*>(dest)) = r; |
*(reinterpret_cast<unsigned long long*>(dest)) = r; |
| 830 |
return true; |
return true; |
| 831 |
#endif /* HAVE_UNSIGNED_LONG_LONG */ |
#endif /* HAVE_UNSIGNED_LONG_LONG */ |
| 843 |
double r = strtod(buf, &end); |
double r = strtod(buf, &end); |
| 844 |
if (end != buf + n) return false; // Leftover junk |
if (end != buf + n) return false; // Leftover junk |
| 845 |
if (errno) return false; |
if (errno) return false; |
| 846 |
|
if (dest == NULL) return true; |
| 847 |
*(reinterpret_cast<double*>(dest)) = r; |
*(reinterpret_cast<double*>(dest)) = r; |
| 848 |
return true; |
return true; |
| 849 |
} |
} |
| 851 |
bool Arg::parse_float(const char* str, int n, void* dest) { |
bool Arg::parse_float(const char* str, int n, void* dest) { |
| 852 |
double r; |
double r; |
| 853 |
if (!parse_double(str, n, &r)) return false; |
if (!parse_double(str, n, &r)) return false; |
| 854 |
|
if (dest == NULL) return true; |
| 855 |
*(reinterpret_cast<float*>(dest)) = static_cast<float>(r); |
*(reinterpret_cast<float*>(dest)) = static_cast<float>(r); |
| 856 |
return true; |
return true; |
| 857 |
} |
} |