Index: third_party/re2/re2/re2.cc |
diff --git a/third_party/re2/re2/re2.cc b/third_party/re2/re2/re2.cc |
index b3e582f0580e97a80a69287d12a9e58e8183fd04..b9e44fcdef04db5cc4f31cd441818562f2d37243 100644 |
--- a/third_party/re2/re2/re2.cc |
+++ b/third_party/re2/re2/re2.cc |
@@ -11,10 +11,16 @@ |
#include <stdio.h> |
#include <string> |
+#ifdef WIN32 |
+#define strtoll _strtoi64 |
+#define strtoull _strtoui64 |
+#define strtof strtod |
+#else |
+#include <pthread.h> |
+#endif |
#include <errno.h> |
#include "util/util.h" |
#include "util/flags.h" |
-#include "util/sparse_array.h" |
#include "re2/prog.h" |
#include "re2/regexp.h" |
@@ -31,10 +37,22 @@ |
const VariadicFunction2<bool, StringPiece*, const RE2&, RE2::Arg, RE2::ConsumeN> RE2::Consume = {}; |
const VariadicFunction2<bool, StringPiece*, const RE2&, RE2::Arg, RE2::FindAndConsumeN> RE2::FindAndConsume = {}; |
-// This will trigger LNK2005 error in MSVC. |
-#ifndef _MSC_VER |
-const int RE2::Options::kDefaultMaxMem; // initialized in re2.h |
-#endif |
+#define kDefaultMaxMem (8<<20) |
+ |
+RE2::Options::Options() |
+ : encoding_(EncodingUTF8), |
+ posix_syntax_(false), |
+ longest_match_(false), |
+ log_errors_(true), |
+ max_mem_(kDefaultMaxMem), |
+ literal_(false), |
+ never_nl_(false), |
+ never_capture_(false), |
+ case_sensitive_(true), |
+ perl_classes_(false), |
+ word_boundary_(false), |
+ one_line_(false) { |
+} |
RE2::Options::Options(RE2::CannedOptions opt) |
: encoding_(opt == RE2::Latin1 ? EncodingLatin1 : EncodingUTF8), |
@@ -44,7 +62,6 @@ |
max_mem_(kDefaultMaxMem), |
literal_(false), |
never_nl_(false), |
- dot_nl_(false), |
never_capture_(false), |
case_sensitive_(true), |
perl_classes_(false), |
@@ -152,9 +169,6 @@ |
if (never_nl()) |
flags |= Regexp::NeverNL; |
- if (dot_nl()) |
- flags |= Regexp::DotNL; |
- |
if (never_capture()) |
flags |= Regexp::NeverCapture; |
@@ -271,36 +285,8 @@ |
return prog_->size(); |
} |
-int RE2::ProgramFanout(map<int, int>* histogram) const { |
- if (prog_ == NULL) |
- return -1; |
- SparseArray<int> fanout(prog_->size()); |
- prog_->Fanout(&fanout); |
- histogram->clear(); |
- for (SparseArray<int>::iterator i = fanout.begin(); i != fanout.end(); ++i) { |
- // TODO(junyer): Optimise this? |
- int bucket = 0; |
- while (1 << bucket < i->second) { |
- bucket++; |
- } |
- (*histogram)[bucket]++; |
- } |
- return histogram->rbegin()->first; |
-} |
- |
-// Returns num_captures_, computing it if needed, or -1 if the |
-// regexp wasn't valid on construction. |
-int RE2::NumberOfCapturingGroups() const { |
- MutexLock l(mutex_); |
- if (suffix_regexp_ == NULL) |
- return -1; |
- if (num_captures_ == -1) |
- num_captures_ = suffix_regexp_->NumCaptures(); |
- return num_captures_; |
-} |
- |
// Returns named_groups_, computing it if needed. |
-const map<string, int>& RE2::NamedCapturingGroups() const { |
+const map<string, int>& RE2::NamedCapturingGroups() const { |
MutexLock l(mutex_); |
if (!ok()) |
return *empty_named_groups; |
@@ -313,7 +299,7 @@ |
} |
// Returns group_names_, computing it if needed. |
-const map<int, string>& RE2::CapturingGroupNames() const { |
+const map<int, string>& RE2::CapturingGroupNames() const { |
MutexLock l(mutex_); |
if (!ok()) |
return *empty_group_names; |
@@ -385,7 +371,7 @@ |
int nvec = 1 + MaxSubmatch(rewrite); |
if (nvec > arraysize(vec)) |
return false; |
- if (!re.Match(*str, 0, static_cast<int>(str->size()), UNANCHORED, vec, nvec)) |
+ if (!re.Match(*str, 0, str->size(), UNANCHORED, vec, nvec)) |
return false; |
string s; |
@@ -412,8 +398,7 @@ |
string out; |
int count = 0; |
while (p <= ep) { |
- if (!re.Match(*str, static_cast<int>(p - str->data()), |
- static_cast<int>(str->size()), UNANCHORED, vec, nvec)) |
+ if (!re.Match(*str, p - str->data(), str->size(), UNANCHORED, vec, nvec)) |
break; |
if (p < vec[0].begin()) |
out.append(p, vec[0].begin() - p); |
@@ -497,7 +482,7 @@ |
if (prog_ == NULL) |
return false; |
- int n = static_cast<int>(prefix_.size()); |
+ int n = prefix_.size(); |
if (n > maxlen) |
n = maxlen; |
@@ -569,10 +554,7 @@ |
if (startpos < 0 || startpos > endpos || endpos > text.size()) { |
if (options_.log_errors()) |
- LOG(ERROR) << "RE2: invalid startpos, endpos pair. [" |
- << "startpos: " << startpos << ", " |
- << "endpos: " << endpos << ", " |
- << "text size: " << text.size() << "]"; |
+ LOG(ERROR) << "RE2: invalid startpos, endpos pair."; |
return false; |
} |
@@ -609,7 +591,7 @@ |
if (!prefix_.empty()) { |
if (startpos != 0) |
return false; |
- prefixlen = static_cast<int>(prefix_.size()); |
+ prefixlen = prefix_.size(); |
if (prefixlen > subtext.size()) |
return false; |
if (prefix_foldcase_) { |
@@ -850,8 +832,8 @@ |
return false; |
} |
- if (consumed != NULL) |
- *consumed = static_cast<int>(vec[0].end() - text.begin()); |
+ if(consumed != NULL) |
+ *consumed = vec[0].end() - text.begin(); |
if (n == 0 || args == NULL) { |
// We are not interested in results |
@@ -873,7 +855,7 @@ |
if (!args[i]->Parse(s.data(), s.size())) { |
// TODO: Should we indicate what the error was? |
VLOG(1) << "Parse error on #" << i << " " << s << " " |
- << (void*)s.data() << "/" << s.size(); |
+ << (void*)s.data() << "/" << s.size(); |
delete[] heapvec; |
return false; |
} |
@@ -889,33 +871,46 @@ |
const StringPiece *vec, int veclen) const { |
for (const char *s = rewrite.data(), *end = s + rewrite.size(); |
s < end; s++) { |
- if (*s != '\\') { |
- out->push_back(*s); |
- continue; |
- } |
- s++; |
- int c = (s < end) ? *s : -1; |
- if (isdigit(c)) { |
- int n = (c - '0'); |
- if (n >= veclen) { |
- if (options_.log_errors()) { |
- LOG(ERROR) << "requested group " << n |
- << " in regexp " << rewrite.data(); |
+ int c = *s; |
+ if (c == '\\') { |
+ s++; |
+ c = (s < end) ? *s : -1; |
+ if (isdigit(c)) { |
+ int n = (c - '0'); |
+ if (n >= veclen) { |
+ if (options_.log_errors()) { |
+ LOG(ERROR) << "requested group " << n |
+ << " in regexp " << rewrite.data(); |
+ } |
+ return false; |
} |
+ StringPiece snip = vec[n]; |
+ if (snip.size() > 0) |
+ out->append(snip.data(), snip.size()); |
+ } else if (c == '\\') { |
+ out->push_back('\\'); |
+ } else { |
+ if (options_.log_errors()) |
+ LOG(ERROR) << "invalid rewrite pattern: " << rewrite.data(); |
return false; |
} |
- StringPiece snip = vec[n]; |
- if (snip.size() > 0) |
- out->append(snip.data(), snip.size()); |
- } else if (c == '\\') { |
- out->push_back('\\'); |
} else { |
- if (options_.log_errors()) |
- LOG(ERROR) << "invalid rewrite pattern: " << rewrite.data(); |
- return false; |
- } |
- } |
- return true; |
+ out->push_back(c); |
+ } |
+ } |
+ return true; |
+} |
+ |
+// Return the number of capturing subpatterns, or -1 if the |
+// regexp wasn't valid on construction. |
+int RE2::NumberOfCapturingGroups() const { |
+ if (suffix_regexp_ == NULL) |
+ return -1; |
+ ANNOTATE_BENIGN_RACE(&num_captures_, "benign race: in the worst case" |
+ " multiple threads end up doing the same work in parallel."); |
+ if (num_captures_ == -1) |
+ num_captures_ = suffix_regexp_->NumCaptures(); |
+ return num_captures_; |
} |
// Checks that the rewrite string is well-formed with respect to this |
@@ -992,23 +987,16 @@ |
// Largest number spec that we are willing to parse |
static const int kMaxNumberLength = 32; |
-// REQUIRES "buf" must have length at least nbuf. |
+// REQUIRES "buf" must have length at least kMaxNumberLength+1 |
// Copies "str" into "buf" and null-terminates. |
// Overwrites *np with the new length. |
-static const char* TerminateNumber(char* buf, int nbuf, const char* str, int* np, |
- bool accept_spaces) { |
+static const char* TerminateNumber(char* buf, const char* str, int* np) { |
int n = *np; |
if (n <= 0) return ""; |
if (n > 0 && isspace(*str)) { |
// We are less forgiving than the strtoxxx() routines and do not |
- // allow leading spaces. We do allow leading spaces for floats. |
- if (!accept_spaces) { |
- return ""; |
- } |
- while (n > 0 && isspace(*str)) { |
- n--; |
- str++; |
- } |
+ // allow leading spaces. |
+ return ""; |
} |
// Although buf has a fixed maximum size, we can still handle |
@@ -1038,7 +1026,7 @@ |
str--; |
} |
- if (n > nbuf-1) return ""; |
+ if (n > kMaxNumberLength) return ""; |
memmove(buf, str, n); |
if (neg) { |
@@ -1055,7 +1043,7 @@ |
int radix) { |
if (n == 0) return false; |
char buf[kMaxNumberLength+1]; |
- str = TerminateNumber(buf, sizeof buf, str, &n, false); |
+ str = TerminateNumber(buf, str, &n); |
char* end; |
errno = 0; |
long r = strtol(str, &end, radix); |
@@ -1072,7 +1060,7 @@ |
int radix) { |
if (n == 0) return false; |
char buf[kMaxNumberLength+1]; |
- str = TerminateNumber(buf, sizeof buf, str, &n, false); |
+ str = TerminateNumber(buf, str, &n); |
if (str[0] == '-') { |
// strtoul() will silently accept negative numbers and parse |
// them. This module is more strict and treats them as errors. |
@@ -1097,7 +1085,7 @@ |
if (!parse_long_radix(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; |
+ *(reinterpret_cast<short*>(dest)) = r; |
return true; |
} |
@@ -1109,7 +1097,7 @@ |
if (!parse_ulong_radix(str, n, &r, radix)) return false; // Could not parse |
if ((ushort)r != r) return false; // Out of range |
if (dest == NULL) return true; |
- *(reinterpret_cast<unsigned short*>(dest)) = (ushort)r; |
+ *(reinterpret_cast<unsigned short*>(dest)) = r; |
return true; |
} |
@@ -1137,14 +1125,13 @@ |
return true; |
} |
-#if RE2_HAVE_LONGLONG |
bool RE2::Arg::parse_longlong_radix(const char* str, |
int n, |
void* dest, |
int radix) { |
if (n == 0) return false; |
char buf[kMaxNumberLength+1]; |
- str = TerminateNumber(buf, sizeof buf, str, &n, false); |
+ str = TerminateNumber(buf, str, &n); |
char* end; |
errno = 0; |
int64 r = strtoll(str, &end, radix); |
@@ -1161,7 +1148,7 @@ |
int radix) { |
if (n == 0) return false; |
char buf[kMaxNumberLength+1]; |
- str = TerminateNumber(buf, sizeof buf, str, &n, false); |
+ str = TerminateNumber(buf, str, &n); |
if (str[0] == '-') { |
// strtoull() will silently accept negative numbers and parse |
// them. This module is more strict and treats them as errors. |
@@ -1176,26 +1163,27 @@ |
*(reinterpret_cast<uint64*>(dest)) = r; |
return true; |
} |
-#endif |
static bool parse_double_float(const char* str, int 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 buf[kMaxLength]; |
+ if (n >= kMaxLength) return false; |
+ memcpy(buf, str, n); |
+ buf[n] = '\0'; |
+ errno = 0; |
char* end; |
- errno = 0; |
double r; |
if (isfloat) { |
- r = strtof(str, &end); |
+ r = strtof(buf, &end); |
} else { |
- r = strtod(str, &end); |
- } |
- if (end != str + n) return false; // Leftover junk |
+ r = strtod(buf, &end); |
+ } |
+ if (end != buf + n) return false; // Leftover junk |
if (errno) return false; |
if (dest == NULL) return true; |
if (isfloat) { |
- *(reinterpret_cast<float*>(dest)) = (float)r; |
+ *(reinterpret_cast<float*>(dest)) = r; |
} else { |
*(reinterpret_cast<double*>(dest)) = r; |
} |