Imported Upstream version 20170501 64/170464/1 upstream/20170501
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 20 Feb 2018 06:35:04 +0000 (15:35 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 20 Feb 2018 06:35:04 +0000 (15:35 +0900)
Change-Id: Ic0dcb93fc88c16c072f122fa58fa429037714897
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
12 files changed:
CMakeLists.txt
re2/prefilter.cc
re2/re2.cc
re2/regexp.h
re2/testing/exhaustive_tester.h
re2/testing/re2_test.cc
re2/testing/regexp_generator.cc
re2/testing/string_generator.cc
re2/testing/string_generator_test.cc
re2/tostring.cc
util/sparse_array.h
util/sparse_set.h

index 23e3a2b..cfb946c 100644 (file)
@@ -11,6 +11,10 @@ include(CTest)
 option(BUILD_SHARED_LIBS "build shared libraries" OFF)
 option(USEPCRE "use PCRE in tests and benchmarks" OFF)
 
+# CMake seems to have no way to enable/disable testing per subproject,
+# so we provide an option similar to BUILD_TESTING, but just for RE2.
+option(RE2_BUILD_TESTING "enable testing for RE2" ON)
+
 set(EXTRA_TARGET_LINK_LIBRARIES)
 
 if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
@@ -112,7 +116,9 @@ set(BENCHMARK_TARGETS
 foreach(target ${TEST_TARGETS})
   add_executable(${target} re2/testing/${target}.cc util/test.cc)
   target_link_libraries(${target} testing re2 ${EXTRA_TARGET_LINK_LIBRARIES})
-  add_test(NAME ${target} COMMAND ${target})
+  if(RE2_BUILD_TESTING)
+    add_test(NAME ${target} COMMAND ${target})
+  endif()
 endforeach(target)
 
 foreach(target ${BENCHMARK_TARGETS})
index dbbbc97..e34aaf0 100644 (file)
@@ -49,7 +49,7 @@ Prefilter* Prefilter::Simplify() {
   }
 
   // Nothing left in the AND/OR.
-  if (subs_->size() == 0) {
+  if (subs_->empty()) {
     if (op_ == AND)
       op_ = ALL;  // AND of nothing is true
     else
index 84cf992..de63183 100644 (file)
@@ -538,7 +538,7 @@ bool RE2::PossibleMatchRange(string* min, string* max, int maxlen) const {
   if (maxlen > 0 && prog_->PossibleMatchRange(&dmin, &dmax, maxlen)) {
     pmin += dmin;
     pmax += dmax;
-  } else if (pmax.size() > 0) {
+  } else if (!pmax.empty()) {
     // prog_->PossibleMatchRange has failed us,
     // but we still have useful information from prefix_.
     // Round up pmax to allow any possible suffix.
index 9b5d98d..f0e3faa 100644 (file)
@@ -276,44 +276,45 @@ class Regexp {
 
   // Flags for parsing.  Can be ORed together.
   enum ParseFlags {
-    NoParseFlags = 0,
-    FoldCase     = 1<<0,   // Fold case during matching (case-insensitive).
-    Literal      = 1<<1,   // Treat s as literal string instead of a regexp.
-    ClassNL      = 1<<2,   // Allow char classes like [^a-z] and \D and \s
-                           // and [[:space:]] to match newline.
-    DotNL        = 1<<3,   // Allow . to match newline.
-    MatchNL      = ClassNL | DotNL,
-    OneLine      = 1<<4,   // Treat ^ and $ as only matching at beginning and
-                           // end of text, not around embedded newlines.
-                           // (Perl's default)
-    Latin1       = 1<<5,   // Regexp and text are in Latin1, not UTF-8.
-    NonGreedy    = 1<<6,   // Repetition operators are non-greedy by default.
-    PerlClasses  = 1<<7,   // Allow Perl character classes like \d.
-    PerlB        = 1<<8,   // Allow Perl's \b and \B.
-    PerlX        = 1<<9,   // Perl extensions:
-                           //   non-capturing parens - (?: )
-                           //   non-greedy operators - *? +? ?? {}?
-                           //   flag edits - (?i) (?-i) (?i: )
-                           //     i - FoldCase
-                           //     m - !OneLine
-                           //     s - DotNL
-                           //     U - NonGreedy
-                           //   line ends: \A \z
-                           //   \Q and \E to disable/enable metacharacters
-                           //   (?P<name>expr) for named captures
-                           //   \C to match any single byte
-    UnicodeGroups = 1<<10, // Allow \p{Han} for Unicode Han group
-                           //   and \P{Han} for its negation.
-    NeverNL      = 1<<11,  // Never match NL, even if the regexp mentions
-                           //   it explicitly.
-    NeverCapture = 1<<12,  // Parse all parens as non-capturing.
+    NoParseFlags  = 0,
+    FoldCase      = 1<<0,   // Fold case during matching (case-insensitive).
+    Literal       = 1<<1,   // Treat s as literal string instead of a regexp.
+    ClassNL       = 1<<2,   // Allow char classes like [^a-z] and \D and \s
+                            // and [[:space:]] to match newline.
+    DotNL         = 1<<3,   // Allow . to match newline.
+    MatchNL       = ClassNL | DotNL,
+    OneLine       = 1<<4,   // Treat ^ and $ as only matching at beginning and
+                            // end of text, not around embedded newlines.
+                            // (Perl's default)
+    Latin1        = 1<<5,   // Regexp and text are in Latin1, not UTF-8.
+    NonGreedy     = 1<<6,   // Repetition operators are non-greedy by default.
+    PerlClasses   = 1<<7,   // Allow Perl character classes like \d.
+    PerlB         = 1<<8,   // Allow Perl's \b and \B.
+    PerlX         = 1<<9,   // Perl extensions:
+                            //   non-capturing parens - (?: )
+                            //   non-greedy operators - *? +? ?? {}?
+                            //   flag edits - (?i) (?-i) (?i: )
+                            //     i - FoldCase
+                            //     m - !OneLine
+                            //     s - DotNL
+                            //     U - NonGreedy
+                            //   line ends: \A \z
+                            //   \Q and \E to disable/enable metacharacters
+                            //   (?P<name>expr) for named captures
+                            //   \C to match any single byte
+    UnicodeGroups = 1<<10,  // Allow \p{Han} for Unicode Han group
+                            //   and \P{Han} for its negation.
+    NeverNL       = 1<<11,  // Never match NL, even if the regexp mentions
+                            //   it explicitly.
+    NeverCapture  = 1<<12,  // Parse all parens as non-capturing.
 
     // As close to Perl as we can get.
-    LikePerl     = ClassNL | OneLine | PerlClasses | PerlB | PerlX |
-                   UnicodeGroups,
+    LikePerl      = ClassNL | OneLine | PerlClasses | PerlB | PerlX |
+                    UnicodeGroups,
 
     // Internal use only.
-    WasDollar    = 1<<15,  // on kRegexpEndText: was $ in regexp text
+    WasDollar     = 1<<13,  // on kRegexpEndText: was $ in regexp text
+    AllParseFlags = (1<<14)-1,
   };
 
   // Get.  No set, Regexps are logically immutable once created.
@@ -620,25 +621,29 @@ class CharClassBuilder {
   CharClassBuilder& operator=(const CharClassBuilder&) = delete;
 };
 
-// Tell g++ that bitwise ops on ParseFlags produce ParseFlags.
-inline Regexp::ParseFlags operator|(Regexp::ParseFlags a, Regexp::ParseFlags b)
-{
-  return static_cast<Regexp::ParseFlags>(static_cast<int>(a) | static_cast<int>(b));
+// Bitwise ops on ParseFlags produce ParseFlags.
+inline Regexp::ParseFlags operator|(Regexp::ParseFlags a,
+                                    Regexp::ParseFlags b) {
+  return static_cast<Regexp::ParseFlags>(
+      static_cast<int>(a) | static_cast<int>(b));
 }
 
-inline Regexp::ParseFlags operator^(Regexp::ParseFlags a, Regexp::ParseFlags b)
-{
-  return static_cast<Regexp::ParseFlags>(static_cast<int>(a) ^ static_cast<int>(b));
+inline Regexp::ParseFlags operator^(Regexp::ParseFlags a,
+                                    Regexp::ParseFlags b) {
+  return static_cast<Regexp::ParseFlags>(
+      static_cast<int>(a) ^ static_cast<int>(b));
 }
 
-inline Regexp::ParseFlags operator&(Regexp::ParseFlags a, Regexp::ParseFlags b)
-{
-  return static_cast<Regexp::ParseFlags>(static_cast<int>(a) & static_cast<int>(b));
+inline Regexp::ParseFlags operator&(Regexp::ParseFlags a,
+                                    Regexp::ParseFlags b) {
+  return static_cast<Regexp::ParseFlags>(
+      static_cast<int>(a) & static_cast<int>(b));
 }
 
-inline Regexp::ParseFlags operator~(Regexp::ParseFlags a)
-{
-  return static_cast<Regexp::ParseFlags>(~static_cast<int>(a));
+inline Regexp::ParseFlags operator~(Regexp::ParseFlags a) {
+  // Attempting to produce a value out of enum's range has undefined behaviour.
+  return static_cast<Regexp::ParseFlags>(
+      ~static_cast<int>(a) & static_cast<int>(Regexp::AllParseFlags));
 }
 
 }  // namespace re2
index 7c966cf..769d8b5 100644 (file)
 
 namespace re2 {
 
+// Doing this simplifies the logic below.
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+
 #if !defined(NDEBUG)
 // We are in a debug build.
 const bool RE2_DEBUG_MODE = true;
-#elif ADDRESS_SANITIZER || MEMORY_SANITIZER || THREAD_SANITIZER
+#elif __has_feature(address_sanitizer) || __has_feature(memory_sanitizer) || __has_feature(thread_sanitizer)
 // Not a debug build, but still under sanitizers.
 const bool RE2_DEBUG_MODE = true;
 #else
index 2b05333..d71dce7 100644 (file)
@@ -388,7 +388,7 @@ static void TestRecursion(int size, const char* pattern) {
 
 // A meta-quoted string, interpreted as a pattern, should always match
 // the original unquoted string.
-static void TestQuoteMeta(string unquoted,
+static void TestQuoteMeta(const string& unquoted,
                           const RE2::Options& options = RE2::DefaultOptions) {
   string quoted = RE2::QuoteMeta(unquoted);
   RE2 re(quoted, options);
@@ -398,8 +398,9 @@ static void TestQuoteMeta(string unquoted,
 
 // A meta-quoted string, interpreted as a pattern, should always match
 // the original unquoted string.
-static void NegativeTestQuoteMeta(string unquoted, string should_not_match,
-                                  const RE2::Options& options = RE2::DefaultOptions) {
+static void NegativeTestQuoteMeta(
+    const string& unquoted, const string& should_not_match,
+    const RE2::Options& options = RE2::DefaultOptions) {
   string quoted = RE2::QuoteMeta(unquoted);
   RE2 re(quoted, options);
   EXPECT_FALSE(RE2::FullMatch(should_not_match, re))
index c2f3400..c0f26fe 100644 (file)
@@ -56,9 +56,9 @@ RegexpGenerator::RegexpGenerator(int maxatoms, int maxops,
                                  const std::vector<string>& ops)
     : maxatoms_(maxatoms), maxops_(maxops), atoms_(atoms), ops_(ops) {
   // Degenerate case.
-  if (atoms_.size() == 0)
+  if (atoms_.empty())
     maxatoms_ = 0;
-  if (ops_.size() == 0)
+  if (ops_.empty())
     maxops_ = 0;
 }
 
index b659d34..feef200 100644 (file)
@@ -24,7 +24,7 @@ StringGenerator::StringGenerator(int maxlen,
       random_(false), nrandom_(0) {
 
   // Degenerate case: no letters, no non-empty strings.
-  if (alphabet_.size() == 0)
+  if (alphabet_.empty())
     maxlen_ = 0;
 
   // Next() will return empty string (digits_ is empty).
index dcdc68a..1f10a80 100644 (file)
@@ -31,7 +31,7 @@ static int64_t IntegerPower(int i, int e) {
 // If all of these hold, the StringGenerator is behaving.
 // Assumes that the alphabet is sorted, so that the generated
 // strings can just be compared lexicographically.
-static void RunTest(int len, string alphabet, bool donull) {
+static void RunTest(int len, const string& alphabet, bool donull) {
   StringGenerator g(len, Explode(alphabet));
 
   int n = 0;
index fc9faca..278c310 100644 (file)
@@ -131,8 +131,7 @@ static void AppendLiteral(string *t, Rune r, bool foldcase) {
     t->append(1, '\\');
     t->append(1, static_cast<char>(r));
   } else if (foldcase && 'a' <= r && r <= 'z') {
-    if ('a' <= r && r <= 'z')
-      r += 'A' - 'a';
+    r -= 'a' - 'A';
     t->append(1, '[');
     t->append(1, static_cast<char>(r));
     t->append(1, static_cast<char>(r) + 'a' - 'A');
index eb0498e..1c3edef 100644 (file)
@@ -415,12 +415,14 @@ void SparseArray<Value>::resize(int max_size) {
 
     dense_.resize(max_size);
 
-#ifdef MEMORY_SANITIZER
+#if defined(__has_feature)
+#if __has_feature(memory_sanitizer)
     for (int i = max_size_; i < max_size; i++) {
       sparse_to_dense_[i] = 0xababababU;
       dense_[i].index_ = 0xababababU;
     }
 #endif
+#endif
   }
   max_size_ = max_size;
   if (size_ > max_size_)
@@ -483,12 +485,14 @@ template<typename Value> SparseArray<Value>::SparseArray(int max_size) {
   dense_.resize(max_size);
   size_ = 0;
 
-#ifdef MEMORY_SANITIZER
+#if defined(__has_feature)
+#if __has_feature(memory_sanitizer)
   for (int i = 0; i < max_size; i++) {
     sparse_to_dense_[i] = 0xababababU;
     dense_[i].index_ = 0xababababU;
   }
 #endif
+#endif
 
   DebugCheckInvariants();
 }
index 191ac7c..6764cc7 100644 (file)
@@ -183,12 +183,14 @@ void SparseSetT<Value>::resize(int max_size) {
 
     dense_.resize(max_size);
 
-#ifdef MEMORY_SANITIZER
+#if defined(__has_feature)
+#if __has_feature(memory_sanitizer)
     for (int i = max_size_; i < max_size; i++) {
       sparse_to_dense_[i] = 0xababababU;
       dense_[i] = 0xababababU;
     }
 #endif
+#endif
   }
   max_size_ = max_size;
   if (size_ > max_size_)
@@ -224,12 +226,14 @@ template<typename Value> SparseSetT<Value>::SparseSetT(int max_size) {
   dense_.resize(max_size);
   size_ = 0;
 
-#ifdef MEMORY_SANITIZER
+#if defined(__has_feature)
+#if __has_feature(memory_sanitizer)
   for (int i = 0; i < max_size; i++) {
     sparse_to_dense_[i] = 0xababababU;
     dense_[i] = 0xababababU;
   }
 #endif
+#endif
 
   DebugCheckInvariants();
 }