• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2009 The RE2 Authors.  All Rights Reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 
5 #include "re2/filtered_re2.h"
6 
7 #include <stddef.h>
8 #include <string>
9 #include <utility>
10 
11 #include "util/logging.h"
12 #include "re2/prefilter.h"
13 #include "re2/prefilter_tree.h"
14 
15 namespace re2 {
16 
FilteredRE2()17 FilteredRE2::FilteredRE2()
18     : compiled_(false),
19       prefilter_tree_(new PrefilterTree()) {
20 }
21 
FilteredRE2(int min_atom_len)22 FilteredRE2::FilteredRE2(int min_atom_len)
23     : compiled_(false),
24       prefilter_tree_(new PrefilterTree(min_atom_len)) {
25 }
26 
~FilteredRE2()27 FilteredRE2::~FilteredRE2() {
28   for (size_t i = 0; i < re2_vec_.size(); i++)
29     delete re2_vec_[i];
30 }
31 
FilteredRE2(FilteredRE2 && other)32 FilteredRE2::FilteredRE2(FilteredRE2&& other)
33     : re2_vec_(std::move(other.re2_vec_)),
34       compiled_(other.compiled_),
35       prefilter_tree_(std::move(other.prefilter_tree_)) {
36   other.re2_vec_.clear();
37   other.re2_vec_.shrink_to_fit();
38   other.compiled_ = false;
39   other.prefilter_tree_.reset(new PrefilterTree());
40 }
41 
operator =(FilteredRE2 && other)42 FilteredRE2& FilteredRE2::operator=(FilteredRE2&& other) {
43   this->~FilteredRE2();
44   (void) new (this) FilteredRE2(std::move(other));
45   return *this;
46 }
47 
Add(absl::string_view pattern,const RE2::Options & options,int * id)48 RE2::ErrorCode FilteredRE2::Add(absl::string_view pattern,
49                                 const RE2::Options& options, int* id) {
50   RE2* re = new RE2(pattern, options);
51   RE2::ErrorCode code = re->error_code();
52 
53   if (!re->ok()) {
54     if (options.log_errors()) {
55       LOG(ERROR) << "Couldn't compile regular expression, skipping: "
56                  << pattern << " due to error " << re->error();
57     }
58     delete re;
59   } else {
60     *id = static_cast<int>(re2_vec_.size());
61     re2_vec_.push_back(re);
62   }
63 
64   return code;
65 }
66 
Compile(std::vector<std::string> * atoms)67 void FilteredRE2::Compile(std::vector<std::string>* atoms) {
68   if (compiled_) {
69     LOG(ERROR) << "Compile called already.";
70     return;
71   }
72 
73   if (re2_vec_.empty()) {
74     LOG(ERROR) << "Compile called before Add.";
75     return;
76   }
77 
78   for (size_t i = 0; i < re2_vec_.size(); i++) {
79     Prefilter* prefilter = Prefilter::FromRE2(re2_vec_[i]);
80     prefilter_tree_->Add(prefilter);
81   }
82   atoms->clear();
83   prefilter_tree_->Compile(atoms);
84   compiled_ = true;
85 }
86 
SlowFirstMatch(absl::string_view text) const87 int FilteredRE2::SlowFirstMatch(absl::string_view text) const {
88   for (size_t i = 0; i < re2_vec_.size(); i++)
89     if (RE2::PartialMatch(text, *re2_vec_[i]))
90       return static_cast<int>(i);
91   return -1;
92 }
93 
FirstMatch(absl::string_view text,const std::vector<int> & atoms) const94 int FilteredRE2::FirstMatch(absl::string_view text,
95                             const std::vector<int>& atoms) const {
96   if (!compiled_) {
97     LOG(DFATAL) << "FirstMatch called before Compile.";
98     return -1;
99   }
100   std::vector<int> regexps;
101   prefilter_tree_->RegexpsGivenStrings(atoms, &regexps);
102   for (size_t i = 0; i < regexps.size(); i++)
103     if (RE2::PartialMatch(text, *re2_vec_[regexps[i]]))
104       return regexps[i];
105   return -1;
106 }
107 
AllMatches(absl::string_view text,const std::vector<int> & atoms,std::vector<int> * matching_regexps) const108 bool FilteredRE2::AllMatches(absl::string_view text,
109                              const std::vector<int>& atoms,
110                              std::vector<int>* matching_regexps) const {
111   matching_regexps->clear();
112   std::vector<int> regexps;
113   prefilter_tree_->RegexpsGivenStrings(atoms, &regexps);
114   for (size_t i = 0; i < regexps.size(); i++)
115     if (RE2::PartialMatch(text, *re2_vec_[regexps[i]]))
116       matching_regexps->push_back(regexps[i]);
117   return !matching_regexps->empty();
118 }
119 
AllPotentials(const std::vector<int> & atoms,std::vector<int> * potential_regexps) const120 void FilteredRE2::AllPotentials(const std::vector<int>& atoms,
121                                 std::vector<int>* potential_regexps) const {
122   prefilter_tree_->RegexpsGivenStrings(atoms, potential_regexps);
123 }
124 
RegexpsGivenStrings(const std::vector<int> & matched_atoms,std::vector<int> * passed_regexps)125 void FilteredRE2::RegexpsGivenStrings(const std::vector<int>& matched_atoms,
126                                       std::vector<int>* passed_regexps) {
127   prefilter_tree_->RegexpsGivenStrings(matched_atoms, passed_regexps);
128 }
129 
PrintPrefilter(int regexpid)130 void FilteredRE2::PrintPrefilter(int regexpid) {
131   prefilter_tree_->PrintPrefilter(regexpid);
132 }
133 
134 }  // namespace re2
135