re2 1.19.2 → 1.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/actions/linux-alpine-node-16/Dockerfile +1 -1
- package/.github/actions/linux-alpine-node-18/Dockerfile +1 -1
- package/.github/actions/linux-alpine-node-20/Dockerfile +1 -1
- package/.gitmodules +5 -2
- package/README.md +1 -0
- package/binding.gyp +82 -25
- package/lib/replace.cc +4 -4
- package/package.json +1 -1
- package/tsconfig.json +2 -1
- package/vendor/re2/.bazelrc +16 -0
- package/vendor/re2/.github/bazel.sh +24 -0
- package/vendor/re2/.github/cmake.sh +12 -0
- package/vendor/re2/.github/workflows/ci-bazel.yml +17 -0
- package/vendor/re2/.github/workflows/ci-cmake.yml +108 -0
- package/vendor/re2/.github/workflows/ci.yml +89 -0
- package/vendor/re2/.github/workflows/pr.yml +26 -0
- package/vendor/re2/.github/workflows/python.yml +185 -0
- package/vendor/re2/AUTHORS +13 -0
- package/vendor/re2/BUILD.bazel +280 -0
- package/vendor/re2/CMakeLists.txt +268 -0
- package/vendor/re2/CONTRIBUTING.md +2 -0
- package/vendor/re2/CONTRIBUTORS +41 -0
- package/vendor/re2/Makefile +400 -0
- package/vendor/{README → re2/README} +5 -0
- package/vendor/re2/SECURITY.md +4 -0
- package/vendor/re2/WORKSPACE.bazel +62 -0
- package/vendor/re2/app/BUILD.bazel +19 -0
- package/vendor/re2/app/_re2.cc +94 -0
- package/vendor/re2/app/_re2.d.ts +23 -0
- package/vendor/re2/app/app.ts +111 -0
- package/vendor/re2/app/build.sh +50 -0
- package/vendor/re2/app/index.html +5 -0
- package/vendor/re2/app/package.json +14 -0
- package/vendor/re2/app/rollup.config.js +28 -0
- package/vendor/re2/app/tsconfig.json +17 -0
- package/vendor/re2/benchlog/benchplot.py +98 -0
- package/vendor/re2/benchlog/mktable +155 -0
- package/vendor/re2/doc/mksyntaxgo +42 -0
- package/vendor/re2/doc/mksyntaxhtml +42 -0
- package/vendor/re2/doc/mksyntaxwiki +36 -0
- package/vendor/re2/doc/syntax.html +477 -0
- package/vendor/re2/doc/syntax.txt +463 -0
- package/vendor/re2/lib/git/commit-msg.hook +104 -0
- package/vendor/re2/libre2.symbols +19 -0
- package/vendor/re2/libre2.symbols.darwin +15 -0
- package/vendor/re2/python/BUILD.bazel +36 -0
- package/vendor/re2/python/README +1 -0
- package/vendor/re2/python/_re2.cc +338 -0
- package/vendor/re2/python/re2.py +582 -0
- package/vendor/re2/python/re2_test.py +482 -0
- package/vendor/re2/python/setup.py +105 -0
- package/vendor/re2/{bitmap256.cc → re2/bitmap256.cc} +4 -4
- package/vendor/re2/{bitstate.cc → re2/bitstate.cc} +21 -25
- package/vendor/re2/{compile.cc → re2/compile.cc} +5 -4
- package/vendor/re2/{dfa.cc → re2/dfa.cc} +120 -101
- package/vendor/re2/{filtered_re2.cc → re2/filtered_re2.cc} +8 -11
- package/vendor/re2/{filtered_re2.h → re2/filtered_re2.h} +5 -4
- package/vendor/re2/{fuzzing → re2/fuzzing}/re2_fuzzer.cc +4 -6
- package/vendor/re2/{mimics_pcre.cc → re2/mimics_pcre.cc} +0 -1
- package/vendor/re2/{nfa.cc → re2/nfa.cc} +34 -37
- package/vendor/re2/{onepass.cc → re2/onepass.cc} +25 -27
- package/vendor/re2/{parse.cc → re2/parse.cc} +118 -121
- package/vendor/re2/{prefilter.cc → re2/prefilter.cc} +2 -3
- package/vendor/re2/{prefilter.h → re2/prefilter.h} +0 -1
- package/vendor/re2/{prefilter_tree.cc → re2/prefilter_tree.cc} +4 -5
- package/vendor/re2/{prefilter_tree.h → re2/prefilter_tree.h} +1 -2
- package/vendor/re2/{prog.cc → re2/prog.cc} +20 -21
- package/vendor/re2/{prog.h → re2/prog.h} +21 -22
- package/vendor/re2/{re2.cc → re2/re2.cc} +51 -62
- package/vendor/re2/{re2.h → re2/re2.h} +78 -40
- package/vendor/re2/{regexp.cc → re2/regexp.cc} +11 -12
- package/vendor/re2/{regexp.h → re2/regexp.h} +9 -10
- package/vendor/re2/{set.cc → re2/set.cc} +3 -5
- package/vendor/re2/{set.h → re2/set.h} +4 -3
- package/vendor/re2/{simplify.cc → re2/simplify.cc} +1 -2
- package/vendor/re2/re2/stringpiece.h +24 -0
- package/vendor/re2/{testing → re2/testing}/backtrack.cc +22 -25
- package/vendor/re2/{testing → re2/testing}/charclass_test.cc +23 -21
- package/vendor/re2/{testing → re2/testing}/compile_test.cc +5 -4
- package/vendor/re2/{testing → re2/testing}/dfa_test.cc +36 -30
- package/vendor/re2/{testing → re2/testing}/dump.cc +8 -8
- package/vendor/re2/{testing → re2/testing}/exhaustive1_test.cc +1 -1
- package/vendor/re2/{testing → re2/testing}/exhaustive2_test.cc +1 -1
- package/vendor/re2/{testing → re2/testing}/exhaustive3_test.cc +1 -1
- package/vendor/re2/{testing → re2/testing}/exhaustive_test.cc +1 -1
- package/vendor/re2/{testing → re2/testing}/exhaustive_tester.cc +36 -32
- package/vendor/re2/{testing → re2/testing}/exhaustive_tester.h +0 -1
- package/vendor/re2/{testing → re2/testing}/filtered_re2_test.cc +9 -8
- package/vendor/re2/{testing → re2/testing}/mimics_pcre_test.cc +3 -2
- package/vendor/re2/{testing → re2/testing}/null_walker.cc +1 -1
- package/vendor/re2/{testing → re2/testing}/parse_test.cc +13 -12
- package/vendor/re2/{testing → re2/testing}/possible_match_test.cc +15 -14
- package/vendor/re2/{testing → re2/testing}/random_test.cc +13 -12
- package/vendor/re2/{testing → re2/testing}/re2_arg_test.cc +25 -2
- package/vendor/re2/{testing → re2/testing}/re2_test.cc +49 -47
- package/vendor/re2/{testing → re2/testing}/regexp_benchmark.cc +144 -145
- package/vendor/re2/{testing → re2/testing}/regexp_generator.cc +18 -14
- package/vendor/re2/{testing → re2/testing}/regexp_generator.h +3 -4
- package/vendor/re2/{testing → re2/testing}/regexp_test.cc +1 -1
- package/vendor/re2/{testing → re2/testing}/required_prefix_test.cc +5 -4
- package/vendor/re2/{testing → re2/testing}/search_test.cc +3 -2
- package/vendor/re2/{testing → re2/testing}/set_test.cc +1 -1
- package/vendor/re2/{testing → re2/testing}/simplify_test.cc +3 -2
- package/vendor/re2/{testing → re2/testing}/string_generator.cc +3 -3
- package/vendor/re2/{testing → re2/testing}/string_generator.h +5 -6
- package/vendor/re2/{testing → re2/testing}/string_generator_test.cc +2 -2
- package/vendor/re2/{testing → re2/testing}/tester.cc +77 -78
- package/vendor/re2/{testing → re2/testing}/tester.h +13 -15
- package/vendor/re2/{tostring.cc → re2/tostring.cc} +7 -8
- package/vendor/re2/{unicode_casefold.h → re2/unicode_casefold.h} +0 -1
- package/vendor/re2/{unicode_groups.h → re2/unicode_groups.h} +0 -1
- package/vendor/re2/{walker-inl.h → re2/walker-inl.h} +2 -1
- package/vendor/re2/re2.pc.in +9 -0
- package/vendor/re2/re2Config.cmake.in +28 -0
- package/vendor/re2/runtests +33 -0
- package/vendor/re2/testinstall.cc +27 -0
- package/vendor/re2/ucs2.diff +567 -0
- package/vendor/{util → re2/util}/logging.h +2 -2
- package/vendor/{util → re2/util}/pcre.cc +47 -116
- package/vendor/{util → re2/util}/pcre.h +53 -63
- package/vendor/re2/util/strutil.cc +26 -0
- package/vendor/{util → re2/util}/strutil.h +0 -5
- package/vendor/re2/stringpiece.cc +0 -65
- package/vendor/re2/stringpiece.h +0 -213
- package/vendor/util/benchmark.cc +0 -131
- package/vendor/util/benchmark.h +0 -156
- package/vendor/util/flags.h +0 -26
- package/vendor/util/mix.h +0 -41
- package/vendor/util/mutex.h +0 -164
- package/vendor/util/strutil.cc +0 -149
- package/vendor/util/test.cc +0 -34
- package/vendor/util/test.h +0 -50
- package/vendor/util/util.h +0 -42
- /package/vendor/{LICENSE → re2/LICENSE} +0 -0
- /package/vendor/re2/{bitmap256.h → re2/bitmap256.h} +0 -0
- /package/vendor/re2/{fuzzing → re2/fuzzing}/compiler-rt/LICENSE +0 -0
- /package/vendor/re2/{fuzzing → re2/fuzzing}/compiler-rt/include/fuzzer/FuzzedDataProvider.h +0 -0
- /package/vendor/re2/{make_perl_groups.pl → re2/make_perl_groups.pl} +0 -0
- /package/vendor/re2/{make_unicode_casefold.py → re2/make_unicode_casefold.py} +0 -0
- /package/vendor/re2/{make_unicode_groups.py → re2/make_unicode_groups.py} +0 -0
- /package/vendor/re2/{perl_groups.cc → re2/perl_groups.cc} +0 -0
- /package/vendor/re2/{pod_array.h → re2/pod_array.h} +0 -0
- /package/vendor/re2/{sparse_array.h → re2/sparse_array.h} +0 -0
- /package/vendor/re2/{sparse_set.h → re2/sparse_set.h} +0 -0
- /package/vendor/re2/{unicode.py → re2/unicode.py} +0 -0
- /package/vendor/re2/{unicode_casefold.cc → re2/unicode_casefold.cc} +0 -0
- /package/vendor/re2/{unicode_groups.cc → re2/unicode_groups.cc} +0 -0
- /package/vendor/{util → re2/util}/fuzz.cc +0 -0
- /package/vendor/{util → re2/util}/malloc_counter.h +0 -0
- /package/vendor/{util → re2/util}/rune.cc +0 -0
- /package/vendor/{util → re2/util}/utf.h +0 -0
|
@@ -28,23 +28,25 @@
|
|
|
28
28
|
#include <algorithm>
|
|
29
29
|
#include <atomic>
|
|
30
30
|
#include <deque>
|
|
31
|
-
#include <mutex>
|
|
32
31
|
#include <new>
|
|
33
32
|
#include <string>
|
|
34
|
-
#include <unordered_map>
|
|
35
|
-
#include <unordered_set>
|
|
36
33
|
#include <utility>
|
|
37
34
|
#include <vector>
|
|
38
35
|
|
|
36
|
+
#include "absl/base/call_once.h"
|
|
37
|
+
#include "absl/base/macros.h"
|
|
38
|
+
#include "absl/base/thread_annotations.h"
|
|
39
|
+
#include "absl/container/flat_hash_map.h"
|
|
40
|
+
#include "absl/container/flat_hash_set.h"
|
|
41
|
+
#include "absl/strings/str_format.h"
|
|
42
|
+
#include "absl/synchronization/mutex.h"
|
|
43
|
+
#include "absl/types/span.h"
|
|
39
44
|
#include "util/logging.h"
|
|
40
|
-
#include "util/mix.h"
|
|
41
|
-
#include "util/mutex.h"
|
|
42
45
|
#include "util/strutil.h"
|
|
43
46
|
#include "re2/pod_array.h"
|
|
44
47
|
#include "re2/prog.h"
|
|
45
48
|
#include "re2/re2.h"
|
|
46
49
|
#include "re2/sparse_set.h"
|
|
47
|
-
#include "re2/stringpiece.h"
|
|
48
50
|
|
|
49
51
|
// Silence "zero-sized array in struct/union" warning for DFA::State::next_.
|
|
50
52
|
#ifdef _MSC_VER
|
|
@@ -88,9 +90,9 @@ class DFA {
|
|
|
88
90
|
// returning the leftmost end of the match instead of the rightmost one.
|
|
89
91
|
// If the DFA cannot complete the search (for example, if it is out of
|
|
90
92
|
// memory), it sets *failed and returns false.
|
|
91
|
-
bool Search(
|
|
92
|
-
bool
|
|
93
|
-
|
|
93
|
+
bool Search(absl::string_view text, absl::string_view context, bool anchored,
|
|
94
|
+
bool want_earliest_match, bool run_forward, bool* failed,
|
|
95
|
+
const char** ep, SparseSet* matches);
|
|
94
96
|
|
|
95
97
|
// Builds out all states for the entire DFA.
|
|
96
98
|
// If cb is not empty, it receives one callback per state built.
|
|
@@ -114,6 +116,18 @@ class DFA {
|
|
|
114
116
|
struct State {
|
|
115
117
|
inline bool IsMatch() const { return (flag_ & kFlagMatch) != 0; }
|
|
116
118
|
|
|
119
|
+
template <typename H>
|
|
120
|
+
friend H AbslHashValue(H h, const State& a) {
|
|
121
|
+
const absl::Span<const int> ainst(a.inst_, a.ninst_);
|
|
122
|
+
return H::combine(std::move(h), a.flag_, ainst);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
friend bool operator==(const State& a, const State& b) {
|
|
126
|
+
const absl::Span<const int> ainst(a.inst_, a.ninst_);
|
|
127
|
+
const absl::Span<const int> binst(b.inst_, b.ninst_);
|
|
128
|
+
return &a == &b || (a.flag_ == b.flag_ && ainst == binst);
|
|
129
|
+
}
|
|
130
|
+
|
|
117
131
|
int* inst_; // Instruction pointers in the state.
|
|
118
132
|
int ninst_; // # of inst_ pointers.
|
|
119
133
|
uint32_t flag_; // Empty string bitfield flags in effect on the way
|
|
@@ -124,11 +138,11 @@ class DFA {
|
|
|
124
138
|
// (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70932)
|
|
125
139
|
#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ == 6 && __GNUC_MINOR__ >= 1
|
|
126
140
|
std::atomic<State*> next_[0]; // Outgoing arrows from State,
|
|
141
|
+
// one per input byte class
|
|
127
142
|
#else
|
|
128
143
|
std::atomic<State*> next_[]; // Outgoing arrows from State,
|
|
144
|
+
// one per input byte class
|
|
129
145
|
#endif
|
|
130
|
-
|
|
131
|
-
// one per input byte class
|
|
132
146
|
};
|
|
133
147
|
|
|
134
148
|
enum {
|
|
@@ -143,11 +157,7 @@ class DFA {
|
|
|
143
157
|
struct StateHash {
|
|
144
158
|
size_t operator()(const State* a) const {
|
|
145
159
|
DCHECK(a != NULL);
|
|
146
|
-
|
|
147
|
-
for (int i = 0; i < a->ninst_; i++)
|
|
148
|
-
mix.Mix(a->inst_[i]);
|
|
149
|
-
mix.Mix(0);
|
|
150
|
-
return mix.get();
|
|
160
|
+
return absl::Hash<State>()(*a);
|
|
151
161
|
}
|
|
152
162
|
};
|
|
153
163
|
|
|
@@ -155,24 +165,15 @@ class DFA {
|
|
|
155
165
|
bool operator()(const State* a, const State* b) const {
|
|
156
166
|
DCHECK(a != NULL);
|
|
157
167
|
DCHECK(b != NULL);
|
|
158
|
-
|
|
159
|
-
return true;
|
|
160
|
-
if (a->flag_ != b->flag_)
|
|
161
|
-
return false;
|
|
162
|
-
if (a->ninst_ != b->ninst_)
|
|
163
|
-
return false;
|
|
164
|
-
for (int i = 0; i < a->ninst_; i++)
|
|
165
|
-
if (a->inst_[i] != b->inst_[i])
|
|
166
|
-
return false;
|
|
167
|
-
return true;
|
|
168
|
+
return *a == *b;
|
|
168
169
|
}
|
|
169
170
|
};
|
|
170
171
|
|
|
171
|
-
typedef
|
|
172
|
+
typedef absl::flat_hash_set<State*, StateHash, StateEqual> StateSet;
|
|
172
173
|
|
|
173
174
|
private:
|
|
174
175
|
// Make it easier to swap in a scalable reader-writer mutex.
|
|
175
|
-
using CacheMutex = Mutex;
|
|
176
|
+
using CacheMutex = absl::Mutex;
|
|
176
177
|
|
|
177
178
|
enum {
|
|
178
179
|
// Indices into start_ for unanchored searches.
|
|
@@ -238,7 +239,7 @@ class DFA {
|
|
|
238
239
|
|
|
239
240
|
// Search parameters
|
|
240
241
|
struct SearchParams {
|
|
241
|
-
SearchParams(
|
|
242
|
+
SearchParams(absl::string_view text, absl::string_view context,
|
|
242
243
|
RWLocker* cache_lock)
|
|
243
244
|
: text(text),
|
|
244
245
|
context(context),
|
|
@@ -252,8 +253,8 @@ class DFA {
|
|
|
252
253
|
ep(NULL),
|
|
253
254
|
matches(NULL) {}
|
|
254
255
|
|
|
255
|
-
|
|
256
|
-
|
|
256
|
+
absl::string_view text;
|
|
257
|
+
absl::string_view context;
|
|
257
258
|
bool anchored;
|
|
258
259
|
bool can_prefix_accel;
|
|
259
260
|
bool want_earliest_match;
|
|
@@ -325,7 +326,7 @@ class DFA {
|
|
|
325
326
|
Prog::MatchKind kind_; // The kind of DFA.
|
|
326
327
|
bool init_failed_; // initialization failed (out of memory)
|
|
327
328
|
|
|
328
|
-
Mutex mutex_; // mutex_ >= cache_mutex_.r
|
|
329
|
+
absl::Mutex mutex_; // mutex_ >= cache_mutex_.r
|
|
329
330
|
|
|
330
331
|
// Scratch areas, protected by mutex_.
|
|
331
332
|
Workq* q0_; // Two pre-allocated work queues.
|
|
@@ -428,7 +429,7 @@ DFA::DFA(Prog* prog, Prog::MatchKind kind, int64_t max_mem)
|
|
|
428
429
|
q1_(NULL),
|
|
429
430
|
mem_budget_(max_mem) {
|
|
430
431
|
if (ExtraDebug)
|
|
431
|
-
|
|
432
|
+
absl::FPrintF(stderr, "\nkind %d\n%s\n", kind_, prog_->DumpUnanchored());
|
|
432
433
|
int nmark = 0;
|
|
433
434
|
if (kind_ == Prog::kLongestMatch)
|
|
434
435
|
nmark = prog_->size();
|
|
@@ -498,7 +499,7 @@ std::string DFA::DumpWorkq(Workq* q) {
|
|
|
498
499
|
s += "|";
|
|
499
500
|
sep = "";
|
|
500
501
|
} else {
|
|
501
|
-
s +=
|
|
502
|
+
s += absl::StrFormat("%s%d", sep, *it);
|
|
502
503
|
sep = ",";
|
|
503
504
|
}
|
|
504
505
|
}
|
|
@@ -515,7 +516,7 @@ std::string DFA::DumpState(State* state) {
|
|
|
515
516
|
return "*";
|
|
516
517
|
std::string s;
|
|
517
518
|
const char* sep = "";
|
|
518
|
-
s +=
|
|
519
|
+
s += absl::StrFormat("(%p)", state);
|
|
519
520
|
for (int i = 0; i < state->ninst_; i++) {
|
|
520
521
|
if (state->inst_[i] == Mark) {
|
|
521
522
|
s += "|";
|
|
@@ -524,11 +525,11 @@ std::string DFA::DumpState(State* state) {
|
|
|
524
525
|
s += "||";
|
|
525
526
|
sep = "";
|
|
526
527
|
} else {
|
|
527
|
-
s +=
|
|
528
|
+
s += absl::StrFormat("%s%d", sep, state->inst_[i]);
|
|
528
529
|
sep = ",";
|
|
529
530
|
}
|
|
530
531
|
}
|
|
531
|
-
s +=
|
|
532
|
+
s += absl::StrFormat(" flag=%#x", state->flag_);
|
|
532
533
|
return s;
|
|
533
534
|
}
|
|
534
535
|
|
|
@@ -596,16 +597,35 @@ DFA::State* DFA::WorkqToCachedState(Workq* q, Workq* mq, uint32_t flag) {
|
|
|
596
597
|
//mutex_.AssertHeld();
|
|
597
598
|
|
|
598
599
|
// Construct array of instruction ids for the new state.
|
|
599
|
-
//
|
|
600
|
-
//
|
|
601
|
-
//
|
|
600
|
+
// In some cases, kInstAltMatch may trigger an upgrade to FullMatchState.
|
|
601
|
+
// Otherwise, "compress" q down to list heads for storage; StateToWorkq()
|
|
602
|
+
// will "decompress" it for computation by exploring from each list head.
|
|
603
|
+
//
|
|
604
|
+
// Historically, only kInstByteRange, kInstEmptyWidth and kInstMatch were
|
|
605
|
+
// useful to keep, but it turned out that kInstAlt was necessary to keep:
|
|
606
|
+
//
|
|
607
|
+
// > [*] kInstAlt would seem useless to record in a state, since
|
|
608
|
+
// > we've already followed both its arrows and saved all the
|
|
609
|
+
// > interesting states we can reach from there. The problem
|
|
610
|
+
// > is that one of the empty-width instructions might lead
|
|
611
|
+
// > back to the same kInstAlt (if an empty-width operator is starred),
|
|
612
|
+
// > producing a different evaluation order depending on whether
|
|
613
|
+
// > we keep the kInstAlt to begin with. Sigh.
|
|
614
|
+
// > A specific case that this affects is /(^|a)+/ matching "a".
|
|
615
|
+
// > If we don't save the kInstAlt, we will match the whole "a" (0,1)
|
|
616
|
+
// > but in fact the correct leftmost-first match is the leading "" (0,0).
|
|
617
|
+
//
|
|
618
|
+
// Recall that flattening transformed the Prog from "tree" form to "list"
|
|
619
|
+
// form: in the former, kInstAlt existed explicitly... and abundantly; in
|
|
620
|
+
// the latter, it's implied between the instructions that compose a list.
|
|
621
|
+
// Thus, because the information wasn't lost, the bug doesn't remanifest.
|
|
602
622
|
PODArray<int> inst(q->size());
|
|
603
623
|
int n = 0;
|
|
604
624
|
uint32_t needflags = 0; // flags needed by kInstEmptyWidth instructions
|
|
605
625
|
bool sawmatch = false; // whether queue contains guaranteed kInstMatch
|
|
606
626
|
bool sawmark = false; // whether queue contains a Mark
|
|
607
627
|
if (ExtraDebug)
|
|
608
|
-
|
|
628
|
+
absl::FPrintF(stderr, "WorkqToCachedState %s [%#x]", DumpWorkq(q), flag);
|
|
609
629
|
for (Workq::iterator it = q->begin(); it != q->end(); ++it) {
|
|
610
630
|
int id = *it;
|
|
611
631
|
if (sawmatch && (kind_ == Prog::kFirstMatch || q->is_mark(id)))
|
|
@@ -630,10 +650,10 @@ DFA::State* DFA::WorkqToCachedState(Workq* q, Workq* mq, uint32_t flag) {
|
|
|
630
650
|
(kind_ != Prog::kLongestMatch || !sawmark) &&
|
|
631
651
|
(flag & kFlagMatch)) {
|
|
632
652
|
if (ExtraDebug)
|
|
633
|
-
|
|
653
|
+
absl::FPrintF(stderr, " -> FullMatchState\n");
|
|
634
654
|
return FullMatchState;
|
|
635
655
|
}
|
|
636
|
-
|
|
656
|
+
ABSL_FALLTHROUGH_INTENDED;
|
|
637
657
|
default:
|
|
638
658
|
// Record iff id is the head of its list, which must
|
|
639
659
|
// be the case if id-1 is the last of *its* list. :)
|
|
@@ -676,7 +696,7 @@ DFA::State* DFA::WorkqToCachedState(Workq* q, Workq* mq, uint32_t flag) {
|
|
|
676
696
|
// if the state is *not* a matching state.
|
|
677
697
|
if (n == 0 && flag == 0) {
|
|
678
698
|
if (ExtraDebug)
|
|
679
|
-
|
|
699
|
+
absl::FPrintF(stderr, " -> DeadState\n");
|
|
680
700
|
return DeadState;
|
|
681
701
|
}
|
|
682
702
|
|
|
@@ -740,25 +760,29 @@ DFA::State* DFA::CachedState(int* inst, int ninst, uint32_t flag) {
|
|
|
740
760
|
StateSet::iterator it = state_cache_.find(&state);
|
|
741
761
|
if (it != state_cache_.end()) {
|
|
742
762
|
if (ExtraDebug)
|
|
743
|
-
|
|
763
|
+
absl::FPrintF(stderr, " -cached-> %s\n", DumpState(*it));
|
|
744
764
|
return *it;
|
|
745
765
|
}
|
|
746
766
|
|
|
747
767
|
// Must have enough memory for new state.
|
|
748
768
|
// In addition to what we're going to allocate,
|
|
749
|
-
// the state cache hash table seems to incur about
|
|
750
|
-
// State
|
|
751
|
-
|
|
769
|
+
// the state cache hash table seems to incur about 18 bytes per
|
|
770
|
+
// State*. Worst case for non-small sets is it being half full, where each
|
|
771
|
+
// value present takes up 1 byte hash sample plus the pointer itself.
|
|
772
|
+
const int kStateCacheOverhead = 18;
|
|
752
773
|
int nnext = prog_->bytemap_range() + 1; // + 1 for kByteEndText slot
|
|
753
|
-
int mem = sizeof(State) + nnext*sizeof(std::atomic<State*>)
|
|
754
|
-
|
|
755
|
-
if (mem_budget_ < mem + kStateCacheOverhead) {
|
|
774
|
+
int mem = sizeof(State) + nnext*sizeof(std::atomic<State*>);
|
|
775
|
+
int instmem = ninst*sizeof(int);
|
|
776
|
+
if (mem_budget_ < mem + instmem + kStateCacheOverhead) {
|
|
756
777
|
mem_budget_ = -1;
|
|
757
778
|
return NULL;
|
|
758
779
|
}
|
|
759
|
-
mem_budget_ -= mem + kStateCacheOverhead;
|
|
780
|
+
mem_budget_ -= mem + instmem + kStateCacheOverhead;
|
|
760
781
|
|
|
761
782
|
// Allocate new state along with room for next_ and inst_.
|
|
783
|
+
// inst_ is stored separately since it's colder; this also
|
|
784
|
+
// means that the States for a given DFA are the same size
|
|
785
|
+
// class, so the allocator can hopefully pack them better.
|
|
762
786
|
char* space = std::allocator<char>().allocate(mem);
|
|
763
787
|
State* s = new (space) State;
|
|
764
788
|
(void) new (s->next_) std::atomic<State*>[nnext];
|
|
@@ -766,12 +790,13 @@ DFA::State* DFA::CachedState(int* inst, int ninst, uint32_t flag) {
|
|
|
766
790
|
// (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64658)
|
|
767
791
|
for (int i = 0; i < nnext; i++)
|
|
768
792
|
(void) new (s->next_ + i) std::atomic<State*>(NULL);
|
|
769
|
-
s->inst_ =
|
|
770
|
-
|
|
793
|
+
s->inst_ = std::allocator<int>().allocate(ninst);
|
|
794
|
+
(void) new (s->inst_) int[ninst];
|
|
795
|
+
memmove(s->inst_, inst, instmem);
|
|
771
796
|
s->ninst_ = ninst;
|
|
772
797
|
s->flag_ = flag;
|
|
773
798
|
if (ExtraDebug)
|
|
774
|
-
|
|
799
|
+
absl::FPrintF(stderr, " -> %s\n", DumpState(s));
|
|
775
800
|
|
|
776
801
|
// Put state in cache and return it.
|
|
777
802
|
state_cache_.insert(s);
|
|
@@ -785,12 +810,12 @@ void DFA::ClearCache() {
|
|
|
785
810
|
while (begin != end) {
|
|
786
811
|
StateSet::iterator tmp = begin;
|
|
787
812
|
++begin;
|
|
813
|
+
// Deallocate the instruction array, which is stored separately as above.
|
|
814
|
+
std::allocator<int>().deallocate((*tmp)->inst_, (*tmp)->ninst_);
|
|
788
815
|
// Deallocate the blob of memory that we allocated in DFA::CachedState().
|
|
789
816
|
// We recompute mem in order to benefit from sized delete where possible.
|
|
790
|
-
int ninst = (*tmp)->ninst_;
|
|
791
817
|
int nnext = prog_->bytemap_range() + 1; // + 1 for kByteEndText slot
|
|
792
|
-
int mem = sizeof(State) + nnext*sizeof(std::atomic<State*>)
|
|
793
|
-
ninst*sizeof(int);
|
|
818
|
+
int mem = sizeof(State) + nnext*sizeof(std::atomic<State*>);
|
|
794
819
|
std::allocator<char>().deallocate(reinterpret_cast<char*>(*tmp), mem);
|
|
795
820
|
}
|
|
796
821
|
state_cache_.clear();
|
|
@@ -985,8 +1010,8 @@ void DFA::RunWorkqOnByte(Workq* oldq, Workq* newq,
|
|
|
985
1010
|
}
|
|
986
1011
|
|
|
987
1012
|
if (ExtraDebug)
|
|
988
|
-
|
|
989
|
-
|
|
1013
|
+
absl::FPrintF(stderr, "%s on %d[%#x] -> %s [%d]\n",
|
|
1014
|
+
DumpWorkq(oldq), c, flag, DumpWorkq(newq), *ismatch);
|
|
990
1015
|
}
|
|
991
1016
|
|
|
992
1017
|
// Processes input byte c in state, returning new state.
|
|
@@ -994,7 +1019,7 @@ void DFA::RunWorkqOnByte(Workq* oldq, Workq* newq,
|
|
|
994
1019
|
DFA::State* DFA::RunStateOnByteUnlocked(State* state, int c) {
|
|
995
1020
|
// Keep only one RunStateOnByte going
|
|
996
1021
|
// even if the DFA is being run by multiple threads.
|
|
997
|
-
MutexLock l(&mutex_);
|
|
1022
|
+
absl::MutexLock l(&mutex_);
|
|
998
1023
|
return RunStateOnByte(state, c);
|
|
999
1024
|
}
|
|
1000
1025
|
|
|
@@ -1134,9 +1159,9 @@ DFA::RWLocker::RWLocker(CacheMutex* mu) : mu_(mu), writing_(false) {
|
|
|
1134
1159
|
mu_->ReaderLock();
|
|
1135
1160
|
}
|
|
1136
1161
|
|
|
1137
|
-
// This function is marked as
|
|
1162
|
+
// This function is marked as ABSL_NO_THREAD_SAFETY_ANALYSIS because
|
|
1138
1163
|
// the annotations don't support lock upgrade.
|
|
1139
|
-
void DFA::RWLocker::LockForWriting()
|
|
1164
|
+
void DFA::RWLocker::LockForWriting() ABSL_NO_THREAD_SAFETY_ANALYSIS {
|
|
1140
1165
|
if (!writing_) {
|
|
1141
1166
|
mu_->ReaderUnlock();
|
|
1142
1167
|
mu_->WriterLock();
|
|
@@ -1246,7 +1271,7 @@ DFA::StateSaver::~StateSaver() {
|
|
|
1246
1271
|
DFA::State* DFA::StateSaver::Restore() {
|
|
1247
1272
|
if (is_special_)
|
|
1248
1273
|
return special_;
|
|
1249
|
-
MutexLock l(&dfa_->mutex_);
|
|
1274
|
+
absl::MutexLock l(&dfa_->mutex_);
|
|
1250
1275
|
State* s = dfa_->CachedState(inst_, ninst_, flag_);
|
|
1251
1276
|
if (s == NULL)
|
|
1252
1277
|
LOG(DFATAL) << "StateSaver failed to restore state.";
|
|
@@ -1342,13 +1367,13 @@ inline bool DFA::InlinedSearchLoop(SearchParams* params) {
|
|
|
1342
1367
|
|
|
1343
1368
|
State* s = start;
|
|
1344
1369
|
if (ExtraDebug)
|
|
1345
|
-
|
|
1370
|
+
absl::FPrintF(stderr, "@stx: %s\n", DumpState(s));
|
|
1346
1371
|
|
|
1347
1372
|
if (s->IsMatch()) {
|
|
1348
1373
|
matched = true;
|
|
1349
1374
|
lastmatch = p;
|
|
1350
1375
|
if (ExtraDebug)
|
|
1351
|
-
|
|
1376
|
+
absl::FPrintF(stderr, "match @stx! [%s]\n", DumpState(s));
|
|
1352
1377
|
if (params->matches != NULL && kind_ == Prog::kManyMatch) {
|
|
1353
1378
|
for (int i = s->ninst_ - 1; i >= 0; i--) {
|
|
1354
1379
|
int id = s->inst_[i];
|
|
@@ -1365,7 +1390,7 @@ inline bool DFA::InlinedSearchLoop(SearchParams* params) {
|
|
|
1365
1390
|
|
|
1366
1391
|
while (p != ep) {
|
|
1367
1392
|
if (ExtraDebug)
|
|
1368
|
-
|
|
1393
|
+
absl::FPrintF(stderr, "@%d: %s\n", p - bp, DumpState(s));
|
|
1369
1394
|
|
|
1370
1395
|
if (can_prefix_accel && s == start) {
|
|
1371
1396
|
// In start state, only way out is to find the prefix,
|
|
@@ -1465,7 +1490,7 @@ inline bool DFA::InlinedSearchLoop(SearchParams* params) {
|
|
|
1465
1490
|
else
|
|
1466
1491
|
lastmatch = p + 1;
|
|
1467
1492
|
if (ExtraDebug)
|
|
1468
|
-
|
|
1493
|
+
absl::FPrintF(stderr, "match @%d! [%s]\n", lastmatch - bp, DumpState(s));
|
|
1469
1494
|
if (params->matches != NULL && kind_ == Prog::kManyMatch) {
|
|
1470
1495
|
for (int i = s->ninst_ - 1; i >= 0; i--) {
|
|
1471
1496
|
int id = s->inst_[i];
|
|
@@ -1484,7 +1509,7 @@ inline bool DFA::InlinedSearchLoop(SearchParams* params) {
|
|
|
1484
1509
|
// Process one more byte to see if it triggers a match.
|
|
1485
1510
|
// (Remember, matches are delayed one byte.)
|
|
1486
1511
|
if (ExtraDebug)
|
|
1487
|
-
|
|
1512
|
+
absl::FPrintF(stderr, "@etx: %s\n", DumpState(s));
|
|
1488
1513
|
|
|
1489
1514
|
int lastbyte;
|
|
1490
1515
|
if (run_forward) {
|
|
@@ -1532,7 +1557,7 @@ inline bool DFA::InlinedSearchLoop(SearchParams* params) {
|
|
|
1532
1557
|
matched = true;
|
|
1533
1558
|
lastmatch = p;
|
|
1534
1559
|
if (ExtraDebug)
|
|
1535
|
-
|
|
1560
|
+
absl::FPrintF(stderr, "match @etx! [%s]\n", DumpState(s));
|
|
1536
1561
|
if (params->matches != NULL && kind_ == Prog::kManyMatch) {
|
|
1537
1562
|
for (int i = s->ninst_ - 1; i >= 0; i--) {
|
|
1538
1563
|
int id = s->inst_[i];
|
|
@@ -1623,8 +1648,8 @@ bool DFA::FastSearchLoop(SearchParams* params) {
|
|
|
1623
1648
|
// state for the DFA search loop. Fills in params and returns true on success.
|
|
1624
1649
|
// Returns false on failure.
|
|
1625
1650
|
bool DFA::AnalyzeSearch(SearchParams* params) {
|
|
1626
|
-
|
|
1627
|
-
|
|
1651
|
+
absl::string_view text = params->text;
|
|
1652
|
+
absl::string_view context = params->context;
|
|
1628
1653
|
|
|
1629
1654
|
// Sanity check: make sure that text lies within context.
|
|
1630
1655
|
if (BeginPtr(text) < BeginPtr(context) || EndPtr(text) > EndPtr(context)) {
|
|
@@ -1694,9 +1719,9 @@ bool DFA::AnalyzeSearch(SearchParams* params) {
|
|
|
1694
1719
|
params->can_prefix_accel = true;
|
|
1695
1720
|
|
|
1696
1721
|
if (ExtraDebug)
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1722
|
+
absl::FPrintF(stderr, "anchored=%d fwd=%d flags=%#x state=%s can_prefix_accel=%d\n",
|
|
1723
|
+
params->anchored, params->run_forward, flags,
|
|
1724
|
+
DumpState(params->start), params->can_prefix_accel);
|
|
1700
1725
|
|
|
1701
1726
|
return true;
|
|
1702
1727
|
}
|
|
@@ -1709,7 +1734,7 @@ bool DFA::AnalyzeSearchHelper(SearchParams* params, StartInfo* info,
|
|
|
1709
1734
|
if (start != NULL)
|
|
1710
1735
|
return true;
|
|
1711
1736
|
|
|
1712
|
-
MutexLock l(&mutex_);
|
|
1737
|
+
absl::MutexLock l(&mutex_);
|
|
1713
1738
|
start = info->start.load(std::memory_order_relaxed);
|
|
1714
1739
|
if (start != NULL)
|
|
1715
1740
|
return true;
|
|
@@ -1728,14 +1753,9 @@ bool DFA::AnalyzeSearchHelper(SearchParams* params, StartInfo* info,
|
|
|
1728
1753
|
}
|
|
1729
1754
|
|
|
1730
1755
|
// The actual DFA search: calls AnalyzeSearch and then FastSearchLoop.
|
|
1731
|
-
bool DFA::Search(
|
|
1732
|
-
|
|
1733
|
-
bool
|
|
1734
|
-
bool want_earliest_match,
|
|
1735
|
-
bool run_forward,
|
|
1736
|
-
bool* failed,
|
|
1737
|
-
const char** epp,
|
|
1738
|
-
SparseSet* matches) {
|
|
1756
|
+
bool DFA::Search(absl::string_view text, absl::string_view context,
|
|
1757
|
+
bool anchored, bool want_earliest_match, bool run_forward,
|
|
1758
|
+
bool* failed, const char** epp, SparseSet* matches) {
|
|
1739
1759
|
*epp = NULL;
|
|
1740
1760
|
if (!ok()) {
|
|
1741
1761
|
*failed = true;
|
|
@@ -1744,9 +1764,9 @@ bool DFA::Search(const StringPiece& text,
|
|
|
1744
1764
|
*failed = false;
|
|
1745
1765
|
|
|
1746
1766
|
if (ExtraDebug) {
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1767
|
+
absl::FPrintF(stderr, "\nprogram:\n%s\n", prog_->DumpUnanchored());
|
|
1768
|
+
absl::FPrintF(stderr, "text %s anchored=%d earliest=%d fwd=%d kind %d\n",
|
|
1769
|
+
text, anchored, want_earliest_match, run_forward, kind_);
|
|
1750
1770
|
}
|
|
1751
1771
|
|
|
1752
1772
|
RWLocker l(&cache_mutex_);
|
|
@@ -1770,7 +1790,7 @@ bool DFA::Search(const StringPiece& text,
|
|
|
1770
1790
|
return true;
|
|
1771
1791
|
}
|
|
1772
1792
|
if (ExtraDebug)
|
|
1773
|
-
|
|
1793
|
+
absl::FPrintF(stderr, "start %s\n", DumpState(params.start));
|
|
1774
1794
|
bool ret = FastSearchLoop(¶ms);
|
|
1775
1795
|
if (params.failed) {
|
|
1776
1796
|
*failed = true;
|
|
@@ -1789,17 +1809,17 @@ DFA* Prog::GetDFA(MatchKind kind) {
|
|
|
1789
1809
|
// "longest match" DFA, because RE2 never does reverse
|
|
1790
1810
|
// "first match" searches.
|
|
1791
1811
|
if (kind == kFirstMatch) {
|
|
1792
|
-
|
|
1812
|
+
absl::call_once(dfa_first_once_, [](Prog* prog) {
|
|
1793
1813
|
prog->dfa_first_ = new DFA(prog, kFirstMatch, prog->dfa_mem_ / 2);
|
|
1794
1814
|
}, this);
|
|
1795
1815
|
return dfa_first_;
|
|
1796
1816
|
} else if (kind == kManyMatch) {
|
|
1797
|
-
|
|
1817
|
+
absl::call_once(dfa_first_once_, [](Prog* prog) {
|
|
1798
1818
|
prog->dfa_first_ = new DFA(prog, kManyMatch, prog->dfa_mem_);
|
|
1799
1819
|
}, this);
|
|
1800
1820
|
return dfa_first_;
|
|
1801
1821
|
} else {
|
|
1802
|
-
|
|
1822
|
+
absl::call_once(dfa_longest_once_, [](Prog* prog) {
|
|
1803
1823
|
if (!prog->reversed_)
|
|
1804
1824
|
prog->dfa_longest_ = new DFA(prog, kLongestMatch, prog->dfa_mem_ / 2);
|
|
1805
1825
|
else
|
|
@@ -1823,12 +1843,11 @@ void Prog::DeleteDFA(DFA* dfa) {
|
|
|
1823
1843
|
//
|
|
1824
1844
|
// This is the only external interface (class DFA only exists in this file).
|
|
1825
1845
|
//
|
|
1826
|
-
bool Prog::SearchDFA(
|
|
1827
|
-
Anchor anchor, MatchKind kind,
|
|
1846
|
+
bool Prog::SearchDFA(absl::string_view text, absl::string_view context,
|
|
1847
|
+
Anchor anchor, MatchKind kind, absl::string_view* match0,
|
|
1828
1848
|
bool* failed, SparseSet* matches) {
|
|
1829
1849
|
*failed = false;
|
|
1830
1850
|
|
|
1831
|
-
StringPiece context = const_context;
|
|
1832
1851
|
if (context.data() == NULL)
|
|
1833
1852
|
context = text;
|
|
1834
1853
|
bool caret = anchor_start();
|
|
@@ -1889,10 +1908,10 @@ bool Prog::SearchDFA(const StringPiece& text, const StringPiece& const_context,
|
|
|
1889
1908
|
if (match0) {
|
|
1890
1909
|
if (reversed_)
|
|
1891
1910
|
*match0 =
|
|
1892
|
-
|
|
1911
|
+
absl::string_view(ep, static_cast<size_t>(text.data() + text.size() - ep));
|
|
1893
1912
|
else
|
|
1894
1913
|
*match0 =
|
|
1895
|
-
|
|
1914
|
+
absl::string_view(text.data(), static_cast<size_t>(ep - text.data()));
|
|
1896
1915
|
}
|
|
1897
1916
|
return true;
|
|
1898
1917
|
}
|
|
@@ -1905,7 +1924,7 @@ int DFA::BuildAllStates(const Prog::DFAStateCallback& cb) {
|
|
|
1905
1924
|
// Pick out start state for unanchored search
|
|
1906
1925
|
// at beginning of text.
|
|
1907
1926
|
RWLocker l(&cache_mutex_);
|
|
1908
|
-
SearchParams params(
|
|
1927
|
+
SearchParams params(absl::string_view(), absl::string_view(), &l);
|
|
1909
1928
|
params.anchored = false;
|
|
1910
1929
|
if (!AnalyzeSearch(¶ms) ||
|
|
1911
1930
|
params.start == NULL ||
|
|
@@ -1915,7 +1934,7 @@ int DFA::BuildAllStates(const Prog::DFAStateCallback& cb) {
|
|
|
1915
1934
|
// Add start state to work queue.
|
|
1916
1935
|
// Note that any State* that we handle here must point into the cache,
|
|
1917
1936
|
// so we can simply depend on pointer-as-a-number hashing and equality.
|
|
1918
|
-
|
|
1937
|
+
absl::flat_hash_map<State*, int> m;
|
|
1919
1938
|
std::deque<State*> q;
|
|
1920
1939
|
m.emplace(params.start, static_cast<int>(m.size()));
|
|
1921
1940
|
q.push_back(params.start);
|
|
@@ -1989,11 +2008,11 @@ bool DFA::PossibleMatchRange(std::string* min, std::string* max, int maxlen) {
|
|
|
1989
2008
|
// Also note that previously_visited_states[UnseenStatePtr] will, in the STL
|
|
1990
2009
|
// tradition, implicitly insert a '0' value at first use. We take advantage
|
|
1991
2010
|
// of that property below.
|
|
1992
|
-
|
|
2011
|
+
absl::flat_hash_map<State*, int> previously_visited_states;
|
|
1993
2012
|
|
|
1994
2013
|
// Pick out start state for anchored search at beginning of text.
|
|
1995
2014
|
RWLocker l(&cache_mutex_);
|
|
1996
|
-
SearchParams params(
|
|
2015
|
+
SearchParams params(absl::string_view(), absl::string_view(), &l);
|
|
1997
2016
|
params.anchored = true;
|
|
1998
2017
|
if (!AnalyzeSearch(¶ms))
|
|
1999
2018
|
return false;
|
|
@@ -2033,7 +2052,7 @@ bool DFA::PossibleMatchRange(std::string* min, std::string* max, int maxlen) {
|
|
|
2033
2052
|
// Build minimum prefix.
|
|
2034
2053
|
State* s = params.start;
|
|
2035
2054
|
min->clear();
|
|
2036
|
-
MutexLock lock(&mutex_);
|
|
2055
|
+
absl::MutexLock lock(&mutex_);
|
|
2037
2056
|
for (int i = 0; i < maxlen; i++) {
|
|
2038
2057
|
if (previously_visited_states[s] > kMaxEltRepetitions)
|
|
2039
2058
|
break;
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
#include <string>
|
|
9
9
|
#include <utility>
|
|
10
10
|
|
|
11
|
-
#include "util/util.h"
|
|
12
11
|
#include "util/logging.h"
|
|
13
12
|
#include "re2/prefilter.h"
|
|
14
13
|
#include "re2/prefilter_tree.h"
|
|
@@ -46,7 +45,7 @@ FilteredRE2& FilteredRE2::operator=(FilteredRE2&& other) {
|
|
|
46
45
|
return *this;
|
|
47
46
|
}
|
|
48
47
|
|
|
49
|
-
RE2::ErrorCode FilteredRE2::Add(
|
|
48
|
+
RE2::ErrorCode FilteredRE2::Add(absl::string_view pattern,
|
|
50
49
|
const RE2::Options& options, int* id) {
|
|
51
50
|
RE2* re = new RE2(pattern, options);
|
|
52
51
|
RE2::ErrorCode code = re->error_code();
|
|
@@ -85,14 +84,14 @@ void FilteredRE2::Compile(std::vector<std::string>* atoms) {
|
|
|
85
84
|
compiled_ = true;
|
|
86
85
|
}
|
|
87
86
|
|
|
88
|
-
int FilteredRE2::SlowFirstMatch(
|
|
87
|
+
int FilteredRE2::SlowFirstMatch(absl::string_view text) const {
|
|
89
88
|
for (size_t i = 0; i < re2_vec_.size(); i++)
|
|
90
89
|
if (RE2::PartialMatch(text, *re2_vec_[i]))
|
|
91
90
|
return static_cast<int>(i);
|
|
92
91
|
return -1;
|
|
93
92
|
}
|
|
94
93
|
|
|
95
|
-
int FilteredRE2::FirstMatch(
|
|
94
|
+
int FilteredRE2::FirstMatch(absl::string_view text,
|
|
96
95
|
const std::vector<int>& atoms) const {
|
|
97
96
|
if (!compiled_) {
|
|
98
97
|
LOG(DFATAL) << "FirstMatch called before Compile.";
|
|
@@ -106,10 +105,9 @@ int FilteredRE2::FirstMatch(const StringPiece& text,
|
|
|
106
105
|
return -1;
|
|
107
106
|
}
|
|
108
107
|
|
|
109
|
-
bool FilteredRE2::AllMatches(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
std::vector<int>* matching_regexps) const {
|
|
108
|
+
bool FilteredRE2::AllMatches(absl::string_view text,
|
|
109
|
+
const std::vector<int>& atoms,
|
|
110
|
+
std::vector<int>* matching_regexps) const {
|
|
113
111
|
matching_regexps->clear();
|
|
114
112
|
std::vector<int> regexps;
|
|
115
113
|
prefilter_tree_->RegexpsGivenStrings(atoms, ®exps);
|
|
@@ -119,9 +117,8 @@ bool FilteredRE2::AllMatches(
|
|
|
119
117
|
return !matching_regexps->empty();
|
|
120
118
|
}
|
|
121
119
|
|
|
122
|
-
void FilteredRE2::AllPotentials(
|
|
123
|
-
|
|
124
|
-
std::vector<int>* potential_regexps) const {
|
|
120
|
+
void FilteredRE2::AllPotentials(const std::vector<int>& atoms,
|
|
121
|
+
std::vector<int>* potential_regexps) const {
|
|
125
122
|
prefilter_tree_->RegexpsGivenStrings(atoms, potential_regexps);
|
|
126
123
|
}
|
|
127
124
|
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
#include <string>
|
|
26
26
|
#include <vector>
|
|
27
27
|
|
|
28
|
+
#include "absl/strings/string_view.h"
|
|
28
29
|
#include "re2/re2.h"
|
|
29
30
|
|
|
30
31
|
namespace re2 {
|
|
@@ -47,7 +48,7 @@ class FilteredRE2 {
|
|
|
47
48
|
// Uses RE2 constructor to create a RE2 object (re). Returns
|
|
48
49
|
// re->error_code(). If error_code is other than NoError, then re is
|
|
49
50
|
// deleted and not added to re2_vec_.
|
|
50
|
-
RE2::ErrorCode Add(
|
|
51
|
+
RE2::ErrorCode Add(absl::string_view pattern,
|
|
51
52
|
const RE2::Options& options,
|
|
52
53
|
int* id);
|
|
53
54
|
|
|
@@ -63,17 +64,17 @@ class FilteredRE2 {
|
|
|
63
64
|
// Returns -1 on no match. Can be called prior to Compile.
|
|
64
65
|
// Does not do any filtering: simply tries to Match the
|
|
65
66
|
// regexps in a loop.
|
|
66
|
-
int SlowFirstMatch(
|
|
67
|
+
int SlowFirstMatch(absl::string_view text) const;
|
|
67
68
|
|
|
68
69
|
// Returns the index of the first matching regexp.
|
|
69
70
|
// Returns -1 on no match. Compile has to be called before
|
|
70
71
|
// calling this.
|
|
71
|
-
int FirstMatch(
|
|
72
|
+
int FirstMatch(absl::string_view text,
|
|
72
73
|
const std::vector<int>& atoms) const;
|
|
73
74
|
|
|
74
75
|
// Returns the indices of all matching regexps, after first clearing
|
|
75
76
|
// matched_regexps.
|
|
76
|
-
bool AllMatches(
|
|
77
|
+
bool AllMatches(absl::string_view text,
|
|
77
78
|
const std::vector<int>& atoms,
|
|
78
79
|
std::vector<int>* matching_regexps) const;
|
|
79
80
|
|