summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2020-12-17 12:44:20 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2020-12-17 12:44:20 +0900
commitf5bfdaca23d30f84008fcc894001f37ab08b3956 (patch)
treec676ab38441d67e3b9297b7fb452dd2dd3202811
parentdad0443cd91defa753312ce49bef2093591e64d9 (diff)
downloadre2-f5bfdaca23d30f84008fcc894001f37ab08b3956.tar.gz
re2-f5bfdaca23d30f84008fcc894001f37ab08b3956.tar.bz2
re2-f5bfdaca23d30f84008fcc894001f37ab08b3956.zip
Imported Upstream version 20201101upstream/20201101
-rw-r--r--Makefile4
-rw-r--r--libre2.symbols3
-rw-r--r--libre2.symbols.darwin3
-rw-r--r--re2/re2.cc201
-rw-r--r--re2/re2.h248
-rw-r--r--re2/testing/charclass_test.cc4
-rw-r--r--re2/testing/re2_arg_test.cc25
-rw-r--r--testinstall.cc35
-rw-r--r--util/pcre.h6
9 files changed, 255 insertions, 274 deletions
diff --git a/Makefile b/Makefile
index fe766d2..44cedee 100644
--- a/Makefile
+++ b/Makefile
@@ -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*
diff --git a/re2/re2.cc b/re2/re2.cc
index 7ec193c..85ba1f4 100644
--- a/re2/re2.cc
+++ b/re2/re2.cc
@@ -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 {
diff --git a/re2/re2.h b/re2/re2.h
index 6593ce8..15ef0b3 100644
--- a/re2/re2.h
+++ b/re2/re2.h
@@ -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) {
}