| 30 |
// Author: Sanjay Ghemawat |
// Author: Sanjay Ghemawat |
| 31 |
|
|
| 32 |
#ifdef HAVE_CONFIG_H |
#ifdef HAVE_CONFIG_H |
| 33 |
#include <config.h> |
#include "config.h" |
| 34 |
#endif |
#endif |
| 35 |
|
|
| 36 |
#include <stdlib.h> |
#include <stdlib.h> |
| 43 |
#include <algorithm> |
#include <algorithm> |
| 44 |
|
|
| 45 |
#include "pcrecpp_internal.h" |
#include "pcrecpp_internal.h" |
| 46 |
#include <pcre.h> |
#include "pcre.h" |
| 47 |
#include "pcrecpp.h" |
#include "pcrecpp.h" |
| 48 |
#include "pcre_stringpiece.h" |
#include "pcre_stringpiece.h" |
| 49 |
|
|
| 331 |
|
|
| 332 |
// Returns PCRE_NEWLINE_CRLF, PCRE_NEWLINE_CR, or PCRE_NEWLINE_LF. |
// Returns PCRE_NEWLINE_CRLF, PCRE_NEWLINE_CR, or PCRE_NEWLINE_LF. |
| 333 |
// Note that PCRE_NEWLINE_CRLF is defined to be P_N_CR | P_N_LF. |
// Note that PCRE_NEWLINE_CRLF is defined to be P_N_CR | P_N_LF. |
| 334 |
|
// Modified by PH to add PCRE_NEWLINE_ANY and PCRE_NEWLINE_ANYCRLF. |
| 335 |
|
|
| 336 |
static int NewlineMode(int pcre_options) { |
static int NewlineMode(int pcre_options) { |
| 337 |
// TODO: if we can make it threadsafe, cache this var |
// TODO: if we can make it threadsafe, cache this var |
| 338 |
int newline_mode = 0; |
int newline_mode = 0; |
| 339 |
/* if (newline_mode) return newline_mode; */ // do this once it's cached |
/* if (newline_mode) return newline_mode; */ // do this once it's cached |
| 340 |
if (pcre_options & (PCRE_NEWLINE_CRLF|PCRE_NEWLINE_CR|PCRE_NEWLINE_LF)) { |
if (pcre_options & (PCRE_NEWLINE_CRLF|PCRE_NEWLINE_CR|PCRE_NEWLINE_LF| |
| 341 |
|
PCRE_NEWLINE_ANY|PCRE_NEWLINE_ANYCRLF)) { |
| 342 |
newline_mode = (pcre_options & |
newline_mode = (pcre_options & |
| 343 |
(PCRE_NEWLINE_CRLF|PCRE_NEWLINE_CR|PCRE_NEWLINE_LF)); |
(PCRE_NEWLINE_CRLF|PCRE_NEWLINE_CR|PCRE_NEWLINE_LF| |
| 344 |
|
PCRE_NEWLINE_ANY|PCRE_NEWLINE_ANYCRLF)); |
| 345 |
} else { |
} else { |
| 346 |
int newline; |
int newline; |
| 347 |
pcre_config(PCRE_CONFIG_NEWLINE, &newline); |
pcre_config(PCRE_CONFIG_NEWLINE, &newline); |
| 351 |
newline_mode = PCRE_NEWLINE_CR; |
newline_mode = PCRE_NEWLINE_CR; |
| 352 |
else if (newline == 3338) |
else if (newline == 3338) |
| 353 |
newline_mode = PCRE_NEWLINE_CRLF; |
newline_mode = PCRE_NEWLINE_CRLF; |
| 354 |
|
else if (newline == -1) |
| 355 |
|
newline_mode = PCRE_NEWLINE_ANY; |
| 356 |
|
else if (newline == -2) |
| 357 |
|
newline_mode = PCRE_NEWLINE_ANYCRLF; |
| 358 |
else |
else |
| 359 |
assert("" == "Unexpected return value from pcre_config(NEWLINE)"); |
assert("" == "Unexpected return value from pcre_config(NEWLINE)"); |
| 360 |
} |
} |
| 384 |
// Note it's better to call pcre_fullinfo() than to examine |
// Note it's better to call pcre_fullinfo() than to examine |
| 385 |
// all_options(), since options_ could have changed bewteen |
// all_options(), since options_ could have changed bewteen |
| 386 |
// compile-time and now, but this is simpler and safe enough. |
// compile-time and now, but this is simpler and safe enough. |
| 387 |
|
// Modified by PH to add ANY and ANYCRLF. |
| 388 |
if (start+1 < static_cast<int>(str->length()) && |
if (start+1 < static_cast<int>(str->length()) && |
| 389 |
(*str)[start] == '\r' && (*str)[start+1] == '\n' && |
(*str)[start] == '\r' && (*str)[start+1] == '\n' && |
| 390 |
NewlineMode(options_.all_options()) == PCRE_NEWLINE_CRLF) { |
(NewlineMode(options_.all_options()) == PCRE_NEWLINE_CRLF || |
| 391 |
|
NewlineMode(options_.all_options()) == PCRE_NEWLINE_ANY || |
| 392 |
|
NewlineMode(options_.all_options()) == PCRE_NEWLINE_ANYCRLF) |
| 393 |
|
) { |
| 394 |
matchend++; |
matchend++; |
| 395 |
} |
} |
| 396 |
// We also need to advance more than one char if we're in utf8 mode. |
// We also need to advance more than one char if we're in utf8 mode. |
| 409 |
Rewrite(&out, rewrite, *str, vec, matches); |
Rewrite(&out, rewrite, *str, vec, matches); |
| 410 |
start = matchend; |
start = matchend; |
| 411 |
lastend = matchend; |
lastend = matchend; |
| 412 |
count++; |
// count++; // Removed by PH 19-Dec-2007: duplicate count increment |
| 413 |
} |
} |
| 414 |
} |
} |
| 415 |
|
|
| 618 |
} |
} |
| 619 |
|
|
| 620 |
bool Arg::parse_string(const char* str, int n, void* dest) { |
bool Arg::parse_string(const char* str, int n, void* dest) { |
| 621 |
|
if (dest == NULL) return true; |
| 622 |
reinterpret_cast<string*>(dest)->assign(str, n); |
reinterpret_cast<string*>(dest)->assign(str, n); |
| 623 |
return true; |
return true; |
| 624 |
} |
} |
| 625 |
|
|
| 626 |
bool Arg::parse_stringpiece(const char* str, int n, void* dest) { |
bool Arg::parse_stringpiece(const char* str, int n, void* dest) { |
| 627 |
|
if (dest == NULL) return true; |
| 628 |
reinterpret_cast<StringPiece*>(dest)->set(str, n); |
reinterpret_cast<StringPiece*>(dest)->set(str, n); |
| 629 |
return true; |
return true; |
| 630 |
} |
} |
| 631 |
|
|
| 632 |
bool Arg::parse_char(const char* str, int n, void* dest) { |
bool Arg::parse_char(const char* str, int n, void* dest) { |
| 633 |
if (n != 1) return false; |
if (n != 1) return false; |
| 634 |
|
if (dest == NULL) return true; |
| 635 |
*(reinterpret_cast<char*>(dest)) = str[0]; |
*(reinterpret_cast<char*>(dest)) = str[0]; |
| 636 |
return true; |
return true; |
| 637 |
} |
} |
| 638 |
|
|
| 639 |
bool Arg::parse_uchar(const char* str, int n, void* dest) { |
bool Arg::parse_uchar(const char* str, int n, void* dest) { |
| 640 |
if (n != 1) return false; |
if (n != 1) return false; |
| 641 |
|
if (dest == NULL) return true; |
| 642 |
*(reinterpret_cast<unsigned char*>(dest)) = str[0]; |
*(reinterpret_cast<unsigned char*>(dest)) = str[0]; |
| 643 |
return true; |
return true; |
| 644 |
} |
} |
| 687 |
long r = strtol(str, &end, radix); |
long r = strtol(str, &end, radix); |
| 688 |
if (end != str + n) return false; // Leftover junk |
if (end != str + n) return false; // Leftover junk |
| 689 |
if (errno) return false; |
if (errno) return false; |
| 690 |
|
if (dest == NULL) return true; |
| 691 |
*(reinterpret_cast<long*>(dest)) = r; |
*(reinterpret_cast<long*>(dest)) = r; |
| 692 |
return true; |
return true; |
| 693 |
} |
} |
| 705 |
unsigned long r = strtoul(str, &end, radix); |
unsigned long r = strtoul(str, &end, radix); |
| 706 |
if (end != str + n) return false; // Leftover junk |
if (end != str + n) return false; // Leftover junk |
| 707 |
if (errno) return false; |
if (errno) return false; |
| 708 |
|
if (dest == NULL) return true; |
| 709 |
*(reinterpret_cast<unsigned long*>(dest)) = r; |
*(reinterpret_cast<unsigned long*>(dest)) = r; |
| 710 |
return true; |
return true; |
| 711 |
} |
} |
| 717 |
long r; |
long r; |
| 718 |
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 |
| 719 |
if (r < SHRT_MIN || r > SHRT_MAX) return false; // Out of range |
if (r < SHRT_MIN || r > SHRT_MAX) return false; // Out of range |
| 720 |
*(reinterpret_cast<short*>(dest)) = r; |
if (dest == NULL) return true; |
| 721 |
|
*(reinterpret_cast<short*>(dest)) = static_cast<short>(r); |
| 722 |
return true; |
return true; |
| 723 |
} |
} |
| 724 |
|
|
| 729 |
unsigned long r; |
unsigned long r; |
| 730 |
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 |
| 731 |
if (r > USHRT_MAX) return false; // Out of range |
if (r > USHRT_MAX) return false; // Out of range |
| 732 |
*(reinterpret_cast<unsigned short*>(dest)) = r; |
if (dest == NULL) return true; |
| 733 |
|
*(reinterpret_cast<unsigned short*>(dest)) = static_cast<unsigned short>(r); |
| 734 |
return true; |
return true; |
| 735 |
} |
} |
| 736 |
|
|
| 741 |
long r; |
long r; |
| 742 |
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 |
| 743 |
if (r < INT_MIN || r > INT_MAX) return false; // Out of range |
if (r < INT_MIN || r > INT_MAX) return false; // Out of range |
| 744 |
|
if (dest == NULL) return true; |
| 745 |
*(reinterpret_cast<int*>(dest)) = r; |
*(reinterpret_cast<int*>(dest)) = r; |
| 746 |
return true; |
return true; |
| 747 |
} |
} |
| 753 |
unsigned long r; |
unsigned long r; |
| 754 |
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 |
| 755 |
if (r > UINT_MAX) return false; // Out of range |
if (r > UINT_MAX) return false; // Out of range |
| 756 |
|
if (dest == NULL) return true; |
| 757 |
*(reinterpret_cast<unsigned int*>(dest)) = r; |
*(reinterpret_cast<unsigned int*>(dest)) = r; |
| 758 |
return true; |
return true; |
| 759 |
} |
} |
| 774 |
long long r = strtoq(str, &end, radix); |
long long r = strtoq(str, &end, radix); |
| 775 |
#elif defined HAVE_STRTOLL |
#elif defined HAVE_STRTOLL |
| 776 |
long long r = strtoll(str, &end, radix); |
long long r = strtoll(str, &end, radix); |
| 777 |
|
#elif defined HAVE__STRTOI64 |
| 778 |
|
long long r = _strtoi64(str, &end, radix); |
| 779 |
#else |
#else |
| 780 |
#error parse_longlong_radix: cannot convert input to a long-long |
#error parse_longlong_radix: cannot convert input to a long-long |
| 781 |
#endif |
#endif |
| 782 |
if (end != str + n) return false; // Leftover junk |
if (end != str + n) return false; // Leftover junk |
| 783 |
if (errno) return false; |
if (errno) return false; |
| 784 |
|
if (dest == NULL) return true; |
| 785 |
*(reinterpret_cast<long long*>(dest)) = r; |
*(reinterpret_cast<long long*>(dest)) = r; |
| 786 |
return true; |
return true; |
| 787 |
#endif /* HAVE_LONG_LONG */ |
#endif /* HAVE_LONG_LONG */ |
| 804 |
unsigned long long r = strtouq(str, &end, radix); |
unsigned long long r = strtouq(str, &end, radix); |
| 805 |
#elif defined HAVE_STRTOLL |
#elif defined HAVE_STRTOLL |
| 806 |
unsigned long long r = strtoull(str, &end, radix); |
unsigned long long r = strtoull(str, &end, radix); |
| 807 |
|
#elif defined HAVE__STRTOI64 |
| 808 |
|
unsigned long long r = _strtoui64(str, &end, radix); |
| 809 |
#else |
#else |
| 810 |
#error parse_ulonglong_radix: cannot convert input to a long-long |
#error parse_ulonglong_radix: cannot convert input to a long-long |
| 811 |
#endif |
#endif |
| 812 |
if (end != str + n) return false; // Leftover junk |
if (end != str + n) return false; // Leftover junk |
| 813 |
if (errno) return false; |
if (errno) return false; |
| 814 |
|
if (dest == NULL) return true; |
| 815 |
*(reinterpret_cast<unsigned long long*>(dest)) = r; |
*(reinterpret_cast<unsigned long long*>(dest)) = r; |
| 816 |
return true; |
return true; |
| 817 |
#endif /* HAVE_UNSIGNED_LONG_LONG */ |
#endif /* HAVE_UNSIGNED_LONG_LONG */ |
| 829 |
double r = strtod(buf, &end); |
double r = strtod(buf, &end); |
| 830 |
if (end != buf + n) return false; // Leftover junk |
if (end != buf + n) return false; // Leftover junk |
| 831 |
if (errno) return false; |
if (errno) return false; |
| 832 |
|
if (dest == NULL) return true; |
| 833 |
*(reinterpret_cast<double*>(dest)) = r; |
*(reinterpret_cast<double*>(dest)) = r; |
| 834 |
return true; |
return true; |
| 835 |
} |
} |
| 837 |
bool Arg::parse_float(const char* str, int n, void* dest) { |
bool Arg::parse_float(const char* str, int n, void* dest) { |
| 838 |
double r; |
double r; |
| 839 |
if (!parse_double(str, n, &r)) return false; |
if (!parse_double(str, n, &r)) return false; |
| 840 |
|
if (dest == NULL) return true; |
| 841 |
*(reinterpret_cast<float*>(dest)) = static_cast<float>(r); |
*(reinterpret_cast<float*>(dest)) = static_cast<float>(r); |
| 842 |
return true; |
return true; |
| 843 |
} |
} |