diff options
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | libre2.symbols | 3 | ||||
-rw-r--r-- | libre2.symbols.darwin | 3 | ||||
-rw-r--r-- | re2/re2.cc | 201 | ||||
-rw-r--r-- | re2/re2.h | 248 | ||||
-rw-r--r-- | re2/testing/charclass_test.cc | 4 | ||||
-rw-r--r-- | re2/testing/re2_arg_test.cc | 25 | ||||
-rw-r--r-- | testinstall.cc | 35 | ||||
-rw-r--r-- | util/pcre.h | 6 |
9 files changed, 255 insertions, 274 deletions
@@ -44,7 +44,7 @@ endif # ABI version # http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html -SONAME=8 +SONAME=9 # To rebuild the Tables generated by Perl and Python scripts (requires Internet # access for Unicode data), uncomment the following line: @@ -203,7 +203,7 @@ obj/dbg/libre2.a: $(DOFILES) $(AR) $(ARFLAGS) obj/dbg/libre2.a $(DOFILES) .PRECIOUS: obj/so/libre2.$(SOEXT) -obj/so/libre2.$(SOEXT): $(SOFILES) +obj/so/libre2.$(SOEXT): $(SOFILES) libre2.symbols libre2.symbols.darwin @mkdir -p obj/so $(MAKE_SHARED_LIBRARY) -o obj/so/libre2.$(SOEXTVER) $(SOFILES) ln -sf libre2.$(SOEXTVER) $@ diff --git a/libre2.symbols b/libre2.symbols index 8308b64..93b71b4 100644 --- a/libre2.symbols +++ b/libre2.symbols @@ -11,6 +11,9 @@ # re2::FilteredRE2* _ZN3re211FilteredRE2*; _ZNK3re211FilteredRE2*; + # re2::re2_internal* + _ZN3re212re2_internal*; + _ZNK3re212re2_internal*; local: *; }; diff --git a/libre2.symbols.darwin b/libre2.symbols.darwin index 31e8c52..41ac96f 100644 --- a/libre2.symbols.darwin +++ b/libre2.symbols.darwin @@ -10,3 +10,6 @@ __ZN3re2ls* # re2::FilteredRE2* __ZN3re211FilteredRE2* __ZNK3re211FilteredRE2* +# re2::re2_internal* +__ZN3re212re2_internal* +__ZNK3re212re2_internal* @@ -1040,41 +1040,49 @@ bool RE2::Rewrite(std::string* out, /***** Parsers for various types *****/ -bool RE2::Arg::parse_null(const char* str, size_t n, void* dest) { +namespace re2_internal { + +template <> +bool Parse(const char* str, size_t n, void* dest) { // We fail if somebody asked us to store into a non-NULL void* pointer return (dest == NULL); } -bool RE2::Arg::parse_string(const char* str, size_t n, void* dest) { +template <> +bool Parse(const char* str, size_t n, std::string* dest) { if (dest == NULL) return true; - reinterpret_cast<std::string*>(dest)->assign(str, n); + dest->assign(str, n); return true; } -bool RE2::Arg::parse_stringpiece(const char* str, size_t n, void* dest) { +template <> +bool Parse(const char* str, size_t n, StringPiece* dest) { if (dest == NULL) return true; - *(reinterpret_cast<StringPiece*>(dest)) = StringPiece(str, n); + *dest = StringPiece(str, n); return true; } -bool RE2::Arg::parse_char(const char* str, size_t n, void* dest) { +template <> +bool Parse(const char* str, size_t n, char* dest) { if (n != 1) return false; if (dest == NULL) return true; - *(reinterpret_cast<char*>(dest)) = str[0]; + *dest = str[0]; return true; } -bool RE2::Arg::parse_schar(const char* str, size_t n, void* dest) { +template <> +bool Parse(const char* str, size_t n, signed char* dest) { if (n != 1) return false; if (dest == NULL) return true; - *(reinterpret_cast<signed char*>(dest)) = str[0]; + *dest = str[0]; return true; } -bool RE2::Arg::parse_uchar(const char* str, size_t n, void* dest) { +template <> +bool Parse(const char* str, size_t n, unsigned char* dest) { if (n != 1) return false; if (dest == NULL) return true; - *(reinterpret_cast<unsigned char*>(dest)) = str[0]; + *dest = str[0]; return true; } @@ -1138,10 +1146,40 @@ static const char* TerminateNumber(char* buf, size_t nbuf, const char* str, return buf; } -bool RE2::Arg::parse_long_radix(const char* str, - size_t n, - void* dest, - int radix) { +template <> +bool Parse(const char* str, size_t n, float* dest) { + if (n == 0) return false; + static const int kMaxLength = 200; + char buf[kMaxLength+1]; + str = TerminateNumber(buf, sizeof buf, str, &n, true); + char* end; + errno = 0; + float r = strtof(str, &end); + if (end != str + n) return false; // Leftover junk + if (errno) return false; + if (dest == NULL) return true; + *dest = r; + return true; +} + +template <> +bool Parse(const char* str, size_t n, double* dest) { + if (n == 0) return false; + static const int kMaxLength = 200; + char buf[kMaxLength+1]; + str = TerminateNumber(buf, sizeof buf, str, &n, true); + char* end; + errno = 0; + double r = strtod(str, &end); + if (end != str + n) return false; // Leftover junk + if (errno) return false; + if (dest == NULL) return true; + *dest = r; + return true; +} + +template <> +bool Parse(const char* str, size_t n, long* dest, int radix) { if (n == 0) return false; char buf[kMaxNumberLength+1]; str = TerminateNumber(buf, sizeof buf, str, &n, false); @@ -1151,14 +1189,12 @@ bool RE2::Arg::parse_long_radix(const char* str, if (end != str + n) return false; // Leftover junk if (errno) return false; if (dest == NULL) return true; - *(reinterpret_cast<long*>(dest)) = r; + *dest = r; return true; } -bool RE2::Arg::parse_ulong_radix(const char* str, - size_t n, - void* dest, - int radix) { +template <> +bool Parse(const char* str, size_t n, unsigned long* dest, int radix) { if (n == 0) return false; char buf[kMaxNumberLength+1]; str = TerminateNumber(buf, sizeof buf, str, &n, false); @@ -1174,62 +1210,52 @@ bool RE2::Arg::parse_ulong_radix(const char* str, if (end != str + n) return false; // Leftover junk if (errno) return false; if (dest == NULL) return true; - *(reinterpret_cast<unsigned long*>(dest)) = r; + *dest = r; return true; } -bool RE2::Arg::parse_short_radix(const char* str, - size_t n, - void* dest, - int radix) { +template <> +bool Parse(const char* str, size_t n, short* dest, int radix) { long r; - if (!parse_long_radix(str, n, &r, radix)) return false; // Could not parse - if ((short)r != r) return false; // Out of range + if (!Parse(str, n, &r, radix)) return false; // Could not parse + if ((short)r != r) return false; // Out of range if (dest == NULL) return true; - *(reinterpret_cast<short*>(dest)) = (short)r; + *dest = (short)r; return true; } -bool RE2::Arg::parse_ushort_radix(const char* str, - size_t n, - void* dest, - int radix) { +template <> +bool Parse(const char* str, size_t n, unsigned short* dest, int radix) { unsigned long r; - if (!parse_ulong_radix(str, n, &r, radix)) return false; // Could not parse - if ((unsigned short)r != r) return false; // Out of range + if (!Parse(str, n, &r, radix)) return false; // Could not parse + if ((unsigned short)r != r) return false; // Out of range if (dest == NULL) return true; - *(reinterpret_cast<unsigned short*>(dest)) = (unsigned short)r; + *dest = (unsigned short)r; return true; } -bool RE2::Arg::parse_int_radix(const char* str, - size_t n, - void* dest, - int radix) { +template <> +bool Parse(const char* str, size_t n, int* dest, int radix) { long r; - if (!parse_long_radix(str, n, &r, radix)) return false; // Could not parse - if ((int)r != r) return false; // Out of range + if (!Parse(str, n, &r, radix)) return false; // Could not parse + if ((int)r != r) return false; // Out of range if (dest == NULL) return true; - *(reinterpret_cast<int*>(dest)) = (int)r; + *dest = (int)r; return true; } -bool RE2::Arg::parse_uint_radix(const char* str, - size_t n, - void* dest, - int radix) { +template <> +bool Parse(const char* str, size_t n, unsigned int* dest, int radix) { unsigned long r; - if (!parse_ulong_radix(str, n, &r, radix)) return false; // Could not parse - if ((unsigned int)r != r) return false; // Out of range + if (!Parse(str, n, &r, radix)) return false; // Could not parse + if ((unsigned int)r != r) return false; // Out of range if (dest == NULL) return true; - *(reinterpret_cast<unsigned int*>(dest)) = (unsigned int)r; + *dest = (unsigned int)r; return true; } -bool RE2::Arg::parse_longlong_radix(const char* str, - size_t n, - void* dest, - int radix) { +template <> +bool Parse(const char* str, size_t n, long long* dest, int radix) { if (n == 0) return false; char buf[kMaxNumberLength+1]; str = TerminateNumber(buf, sizeof buf, str, &n, false); @@ -1239,14 +1265,12 @@ bool RE2::Arg::parse_longlong_radix(const char* str, if (end != str + n) return false; // Leftover junk if (errno) return false; if (dest == NULL) return true; - *(reinterpret_cast<long long*>(dest)) = r; + *dest = r; return true; } -bool RE2::Arg::parse_ulonglong_radix(const char* str, - size_t n, - void* dest, - int radix) { +template <> +bool Parse(const char* str, size_t n, unsigned long long* dest, int radix) { if (n == 0) return false; char buf[kMaxNumberLength+1]; str = TerminateNumber(buf, sizeof buf, str, &n, false); @@ -1261,68 +1285,11 @@ bool RE2::Arg::parse_ulonglong_radix(const char* str, if (end != str + n) return false; // Leftover junk if (errno) return false; if (dest == NULL) return true; - *(reinterpret_cast<unsigned long long*>(dest)) = r; - return true; -} - -static bool parse_double_float(const char* str, size_t n, bool isfloat, - void* dest) { - if (n == 0) return false; - static const int kMaxLength = 200; - char buf[kMaxLength+1]; - str = TerminateNumber(buf, sizeof buf, str, &n, true); - char* end; - errno = 0; - double r; - if (isfloat) { - r = strtof(str, &end); - } else { - r = strtod(str, &end); - } - if (end != str + n) return false; // Leftover junk - if (errno) return false; - if (dest == NULL) return true; - if (isfloat) { - *(reinterpret_cast<float*>(dest)) = (float)r; - } else { - *(reinterpret_cast<double*>(dest)) = r; - } + *dest = r; return true; } -bool RE2::Arg::parse_double(const char* str, size_t n, void* dest) { - return parse_double_float(str, n, false, dest); -} - -bool RE2::Arg::parse_float(const char* str, size_t n, void* dest) { - return parse_double_float(str, n, true, dest); -} - -#define DEFINE_INTEGER_PARSER(name) \ - bool RE2::Arg::parse_##name(const char* str, size_t n, void* dest) { \ - return parse_##name##_radix(str, n, dest, 10); \ - } \ - bool RE2::Arg::parse_##name##_hex(const char* str, size_t n, void* dest) { \ - return parse_##name##_radix(str, n, dest, 16); \ - } \ - bool RE2::Arg::parse_##name##_octal(const char* str, size_t n, void* dest) { \ - return parse_##name##_radix(str, n, dest, 8); \ - } \ - bool RE2::Arg::parse_##name##_cradix(const char* str, size_t n, \ - void* dest) { \ - return parse_##name##_radix(str, n, dest, 0); \ - } - -DEFINE_INTEGER_PARSER(short) -DEFINE_INTEGER_PARSER(ushort) -DEFINE_INTEGER_PARSER(int) -DEFINE_INTEGER_PARSER(uint) -DEFINE_INTEGER_PARSER(long) -DEFINE_INTEGER_PARSER(ulong) -DEFINE_INTEGER_PARSER(longlong) -DEFINE_INTEGER_PARSER(ulonglong) - -#undef DEFINE_INTEGER_PARSER +} // namespace re2_internal namespace hooks { @@ -208,6 +208,7 @@ #include <map> #include <mutex> #include <string> +#include <type_traits> #include <vector> #if defined(__APPLE__) @@ -734,32 +735,12 @@ class RE2 { const Options& options() const { return options_; } // Argument converters; see below. - static inline Arg CRadix(short* x); - static inline Arg CRadix(unsigned short* x); - static inline Arg CRadix(int* x); - static inline Arg CRadix(unsigned int* x); - static inline Arg CRadix(long* x); - static inline Arg CRadix(unsigned long* x); - static inline Arg CRadix(long long* x); - static inline Arg CRadix(unsigned long long* x); - - static inline Arg Hex(short* x); - static inline Arg Hex(unsigned short* x); - static inline Arg Hex(int* x); - static inline Arg Hex(unsigned int* x); - static inline Arg Hex(long* x); - static inline Arg Hex(unsigned long* x); - static inline Arg Hex(long long* x); - static inline Arg Hex(unsigned long long* x); - - static inline Arg Octal(short* x); - static inline Arg Octal(unsigned short* x); - static inline Arg Octal(int* x); - static inline Arg Octal(unsigned int* x); - static inline Arg Octal(long* x); - static inline Arg Octal(unsigned long* x); - static inline Arg Octal(long long* x); - static inline Arg Octal(unsigned long long* x); + template <typename T> + static Arg CRadix(T* ptr); + template <typename T> + static Arg Hex(T* ptr); + template <typename T> + static Arg Octal(T* ptr); private: void Init(const StringPiece& pattern, const Options& options); @@ -802,130 +783,129 @@ class RE2 { /***** Implementation details *****/ -// Hex/Octal/Binary? - -// Special class for parsing into objects that define a ParseFrom() method -template <class T> -class _RE2_MatchObject { - public: - static inline bool Parse(const char* str, size_t n, void* dest) { - if (dest == NULL) return true; - T* object = reinterpret_cast<T*>(dest); - return object->ParseFrom(str, n); - } -}; +namespace re2_internal { + +// Types for which the 3-ary Parse() function template has specializations. +template <typename T> struct Parse3ary : public std::false_type {}; +template <> struct Parse3ary<void> : public std::true_type {}; +template <> struct Parse3ary<std::string> : public std::true_type {}; +template <> struct Parse3ary<StringPiece> : public std::true_type {}; +template <> struct Parse3ary<char> : public std::true_type {}; +template <> struct Parse3ary<signed char> : public std::true_type {}; +template <> struct Parse3ary<unsigned char> : public std::true_type {}; +template <> struct Parse3ary<float> : public std::true_type {}; +template <> struct Parse3ary<double> : public std::true_type {}; + +template <typename T> +bool Parse(const char* str, size_t n, T* dest); + +// Types for which the 4-ary Parse() function template has specializations. +template <typename T> struct Parse4ary : public std::false_type {}; +template <> struct Parse4ary<long> : public std::true_type {}; +template <> struct Parse4ary<unsigned long> : public std::true_type {}; +template <> struct Parse4ary<short> : public std::true_type {}; +template <> struct Parse4ary<unsigned short> : public std::true_type {}; +template <> struct Parse4ary<int> : public std::true_type {}; +template <> struct Parse4ary<unsigned int> : public std::true_type {}; +template <> struct Parse4ary<long long> : public std::true_type {}; +template <> struct Parse4ary<unsigned long long> : public std::true_type {}; + +template <typename T> +bool Parse(const char* str, size_t n, T* dest, int radix); + +} // namespace re2_internal class RE2::Arg { + private: + template <typename T> + using CanParse3ary = typename std::enable_if< + re2_internal::Parse3ary<T>::value, + int>::type; + + template <typename T> + using CanParse4ary = typename std::enable_if< + re2_internal::Parse4ary<T>::value, + int>::type; + +#if !defined(_MSC_VER) + template <typename T> + using CanParseFrom = typename std::enable_if< + std::is_member_function_pointer<decltype( + (bool (T::*)(const char*, size_t))&T::ParseFrom)>::value, + int>::type; +#endif + public: - // Empty constructor so we can declare arrays of RE2::Arg - Arg(); + Arg() : Arg(nullptr) {} + Arg(std::nullptr_t ptr) : arg_(ptr), parser_(DoNothing) {} - // Constructor specially designed for NULL arguments - Arg(void*); - Arg(std::nullptr_t); + template <typename T, CanParse3ary<T> = 0> + Arg(T* ptr) : arg_(ptr), parser_(DoParse3ary<T>) {} + + template <typename T, CanParse4ary<T> = 0> + Arg(T* ptr) : arg_(ptr), parser_(DoParse4ary<T>) {} + +#if !defined(_MSC_VER) + template <typename T, CanParseFrom<T> = 0> + Arg(T* ptr) : arg_(ptr), parser_(DoParseFrom<T>) {} +#endif typedef bool (*Parser)(const char* str, size_t n, void* dest); -// Type-specific parsers -#define MAKE_PARSER(type, name) \ - Arg(type* p) : arg_(p), parser_(name) {} \ - Arg(type* p, Parser parser) : arg_(p), parser_(parser) {} - - MAKE_PARSER(char, parse_char) - MAKE_PARSER(signed char, parse_schar) - MAKE_PARSER(unsigned char, parse_uchar) - MAKE_PARSER(float, parse_float) - MAKE_PARSER(double, parse_double) - MAKE_PARSER(std::string, parse_string) - MAKE_PARSER(StringPiece, parse_stringpiece) - - MAKE_PARSER(short, parse_short) - MAKE_PARSER(unsigned short, parse_ushort) - MAKE_PARSER(int, parse_int) - MAKE_PARSER(unsigned int, parse_uint) - MAKE_PARSER(long, parse_long) - MAKE_PARSER(unsigned long, parse_ulong) - MAKE_PARSER(long long, parse_longlong) - MAKE_PARSER(unsigned long long, parse_ulonglong) - -#undef MAKE_PARSER - - // Generic constructor templates - template <class T> Arg(T* p) - : arg_(p), parser_(_RE2_MatchObject<T>::Parse) { } - template <class T> Arg(T* p, Parser parser) - : arg_(p), parser_(parser) { } - - // Parse the data - bool Parse(const char* str, size_t n) const; + template <typename T> + Arg(T* ptr, Parser parser) : arg_(ptr), parser_(parser) {} + + bool Parse(const char* str, size_t n) const { + return (*parser_)(str, n, arg_); + } private: - void* arg_; - Parser parser_; + static bool DoNothing(const char* /*str*/, size_t /*n*/, void* /*dest*/) { + return true; + } - static bool parse_null (const char* str, size_t n, void* dest); - static bool parse_char (const char* str, size_t n, void* dest); - static bool parse_schar (const char* str, size_t n, void* dest); - static bool parse_uchar (const char* str, size_t n, void* dest); - static bool parse_float (const char* str, size_t n, void* dest); - static bool parse_double (const char* str, size_t n, void* dest); - static bool parse_string (const char* str, size_t n, void* dest); - static bool parse_stringpiece (const char* str, size_t n, void* dest); - -#define DECLARE_INTEGER_PARSER(name) \ - private: \ - static bool parse_##name(const char* str, size_t n, void* dest); \ - static bool parse_##name##_radix(const char* str, size_t n, void* dest, \ - int radix); \ - \ - public: \ - static bool parse_##name##_hex(const char* str, size_t n, void* dest); \ - static bool parse_##name##_octal(const char* str, size_t n, void* dest); \ - static bool parse_##name##_cradix(const char* str, size_t n, void* dest); - - DECLARE_INTEGER_PARSER(short) - DECLARE_INTEGER_PARSER(ushort) - DECLARE_INTEGER_PARSER(int) - DECLARE_INTEGER_PARSER(uint) - DECLARE_INTEGER_PARSER(long) - DECLARE_INTEGER_PARSER(ulong) - DECLARE_INTEGER_PARSER(longlong) - DECLARE_INTEGER_PARSER(ulonglong) - -#undef DECLARE_INTEGER_PARSER + template <typename T> + static bool DoParse3ary(const char* str, size_t n, void* dest) { + return re2_internal::Parse(str, n, reinterpret_cast<T*>(dest)); + } -}; + template <typename T> + static bool DoParse4ary(const char* str, size_t n, void* dest) { + return re2_internal::Parse(str, n, reinterpret_cast<T*>(dest), 10); + } -inline RE2::Arg::Arg() : arg_(NULL), parser_(parse_null) { } -inline RE2::Arg::Arg(void* p) : arg_(p), parser_(parse_null) { } -inline RE2::Arg::Arg(std::nullptr_t p) : arg_(p), parser_(parse_null) { } +#if !defined(_MSC_VER) + template <typename T> + static bool DoParseFrom(const char* str, size_t n, void* dest) { + if (dest == NULL) return true; + return reinterpret_cast<T*>(dest)->ParseFrom(str, n); + } +#endif -inline bool RE2::Arg::Parse(const char* str, size_t n) const { - return (*parser_)(str, n, arg_); -} + void* arg_; + Parser parser_; +}; -// This part of the parser, appropriate only for ints, deals with bases -#define MAKE_INTEGER_PARSER(type, name) \ - inline RE2::Arg RE2::Hex(type* ptr) { \ - return RE2::Arg(ptr, RE2::Arg::parse_##name##_hex); \ - } \ - inline RE2::Arg RE2::Octal(type* ptr) { \ - return RE2::Arg(ptr, RE2::Arg::parse_##name##_octal); \ - } \ - inline RE2::Arg RE2::CRadix(type* ptr) { \ - return RE2::Arg(ptr, RE2::Arg::parse_##name##_cradix); \ - } +template <typename T> +inline RE2::Arg RE2::CRadix(T* ptr) { + return RE2::Arg(ptr, [](const char* str, size_t n, void* dest) -> bool { + return re2_internal::Parse(str, n, reinterpret_cast<T*>(dest), 0); + }); +} -MAKE_INTEGER_PARSER(short, short) -MAKE_INTEGER_PARSER(unsigned short, ushort) -MAKE_INTEGER_PARSER(int, int) -MAKE_INTEGER_PARSER(unsigned int, uint) -MAKE_INTEGER_PARSER(long, long) -MAKE_INTEGER_PARSER(unsigned long, ulong) -MAKE_INTEGER_PARSER(long long, longlong) -MAKE_INTEGER_PARSER(unsigned long long, ulonglong) +template <typename T> +inline RE2::Arg RE2::Hex(T* ptr) { + return RE2::Arg(ptr, [](const char* str, size_t n, void* dest) -> bool { + return re2_internal::Parse(str, n, reinterpret_cast<T*>(dest), 16); + }); +} -#undef MAKE_INTEGER_PARSER +template <typename T> +inline RE2::Arg RE2::Octal(T* ptr) { + return RE2::Arg(ptr, [](const char* str, size_t n, void* dest) -> bool { + return re2_internal::Parse(str, n, reinterpret_cast<T*>(dest), 8); + }); +} #ifndef SWIG // Silence warnings about missing initializers for members of LazyRE2. diff --git a/re2/testing/charclass_test.cc b/re2/testing/charclass_test.cc index a2837a6..9c2a32f 100644 --- a/re2/testing/charclass_test.cc +++ b/re2/testing/charclass_test.cc @@ -85,7 +85,7 @@ static CCTest tests[] = { { {-1} } }, }; -template<class CharClass> +template <typename CharClass> static void Broke(const char *desc, const CCTest* t, CharClass* cc) { if (t == NULL) { printf("\t%s:", desc); @@ -136,7 +136,7 @@ void Delete(CharClassBuilder* cc) { delete cc; } -template<class CharClass> +template <typename CharClass> bool CorrectCC(CharClass *cc, CCTest *t, const char *desc) { typename CharClass::iterator it = cc->begin(); int size = 0; diff --git a/re2/testing/re2_arg_test.cc b/re2/testing/re2_arg_test.cc index 7a38de7..f62e17c 100644 --- a/re2/testing/re2_arg_test.cc +++ b/re2/testing/re2_arg_test.cc @@ -11,6 +11,7 @@ #include <string.h> #include "util/test.h" +#include "util/logging.h" #include "re2/re2.h" namespace re2 { @@ -132,4 +133,28 @@ TEST(RE2ArgTest, Uint64Test) { PARSE_FOR_TYPE(uint64_t, 5); } +TEST(RE2ArgTest, ParseFromTest) { +#if !defined(_MSC_VER) + struct { + bool ParseFrom(const char* str, size_t n) { + LOG(INFO) << "str = " << str << ", n = " << n; + return true; + } + } obj1; + RE2::Arg arg1(&obj1); + EXPECT_TRUE(arg1.Parse("one", 3)); + + struct { + bool ParseFrom(const char* str, size_t n) { + LOG(INFO) << "str = " << str << ", n = " << n; + return false; + } + // Ensure that RE2::Arg works even with overloaded ParseFrom(). + void ParseFrom(const char* str) {} + } obj2; + RE2::Arg arg2(&obj2); + EXPECT_FALSE(arg2.Parse("two", 3)); +#endif +} + } // namespace re2 diff --git a/testinstall.cc b/testinstall.cc index 47db4e6..19cc900 100644 --- a/testinstall.cc +++ b/testinstall.cc @@ -2,23 +2,26 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -#include <re2/re2.h> -#include <re2/filtered_re2.h> #include <stdio.h> +#include <re2/filtered_re2.h> +#include <re2/re2.h> + +int main() { + re2::FilteredRE2 f; + int id; + f.Add("a.*b.*c", RE2::DefaultOptions, &id); + std::vector<std::string> v; + f.Compile(&v); + std::vector<int> ids; + f.FirstMatch("abbccc", ids); -int main(void) { - re2::FilteredRE2 f; - int id; - f.Add("a.*b.*c", RE2::DefaultOptions, &id); - std::vector<std::string> v; - f.Compile(&v); - std::vector<int> ids; - f.FirstMatch("abbccc", ids); + int n; + if (RE2::FullMatch("axbyc", "a.*b.*c") && + RE2::PartialMatch("foo123bar", "(\\d+)", &n) && n == 123) { + printf("PASS\n"); + return 0; + } - if(RE2::FullMatch("axbyc", "a.*b.*c")) { - printf("PASS\n"); - return 0; - } - printf("FAIL\n"); - return 2; + printf("FAIL\n"); + return 2; } diff --git a/util/pcre.h b/util/pcre.h index 644dce6..896b0bd 100644 --- a/util/pcre.h +++ b/util/pcre.h @@ -555,7 +555,7 @@ class PCRE_Options { // Hex/Octal/Binary? // Special class for parsing into objects that define a ParseFrom() method -template <class T> +template <typename T> class _PCRE_MatchObject { public: static inline bool Parse(const char* str, size_t n, void* dest) { @@ -600,9 +600,9 @@ class PCRE::Arg { #undef MAKE_PARSER // Generic constructor - template <class T> Arg(T*, Parser parser); + template <typename T> Arg(T*, Parser parser); // Generic constructor template - template <class T> Arg(T* p) + template <typename T> Arg(T* p) : arg_(p), parser_(_PCRE_MatchObject<T>::Parse) { } |