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 <string> 6 #include "util/util.h" 7 #include "re2/filtered_re2.h" 8 #include "re2/prefilter.h" 9 #include "re2/prefilter_tree.h" 10 11 namespace re2 { 12 13 FilteredRE2::FilteredRE2() 14 : compiled_(false), 15 prefilter_tree_(new PrefilterTree()) { 16 } 17 18 FilteredRE2::~FilteredRE2() { 19 for (int i = 0; i < re2_vec_.size(); i++) 20 delete re2_vec_[i]; 21 delete prefilter_tree_; 22 } 23 24 RE2::ErrorCode FilteredRE2::Add(const StringPiece& pattern, 25 const RE2::Options& options, int* id) { 26 RE2* re = new RE2(pattern, options); 27 RE2::ErrorCode code = re->error_code(); 28 29 if (!re->ok()) { 30 if (options.log_errors()) { 31 LOG(ERROR) << "Couldn't compile regular expression, skipping: " 32 << re << " due to error " << re->error(); 33 } 34 delete re; 35 } else { 36 *id = re2_vec_.size(); 37 re2_vec_.push_back(re); 38 } 39 40 return code; 41 } 42 43 void FilteredRE2::Compile(vector<string>* atoms) { 44 if (compiled_ || re2_vec_.size() == 0) { 45 LOG(INFO) << "C: " << compiled_ << " S:" << re2_vec_.size(); 46 return; 47 } 48 49 for (int i = 0; i < re2_vec_.size(); i++) { 50 Prefilter* prefilter = Prefilter::FromRE2(re2_vec_[i]); 51 prefilter_tree_->Add(prefilter); 52 } 53 atoms->clear(); 54 prefilter_tree_->Compile(atoms); 55 compiled_ = true; 56 } 57 58 int FilteredRE2::SlowFirstMatch(const StringPiece& text) const { 59 for (int i = 0; i < re2_vec_.size(); i++) 60 if (RE2::PartialMatch(text, *re2_vec_[i])) 61 return i; 62 return -1; 63 } 64 65 int FilteredRE2::FirstMatch(const StringPiece& text, 66 const vector<int>& atoms) const { 67 if (!compiled_) { 68 LOG(DFATAL) << "FirstMatch called before Compile"; 69 return -1; 70 } 71 vector<int> regexps; 72 prefilter_tree_->RegexpsGivenStrings(atoms, ®exps); 73 for (int i = 0; i < regexps.size(); i++) 74 if (RE2::PartialMatch(text, *re2_vec_[regexps[i]])) 75 return regexps[i]; 76 return -1; 77 } 78 79 bool FilteredRE2::AllMatches( 80 const StringPiece& text, 81 const vector<int>& atoms, 82 vector<int>* matching_regexps) const { 83 matching_regexps->clear(); 84 vector<int> regexps; 85 prefilter_tree_->RegexpsGivenStrings(atoms, ®exps); 86 for (int i = 0; i < regexps.size(); i++) 87 if (RE2::PartialMatch(text, *re2_vec_[regexps[i]])) 88 matching_regexps->push_back(regexps[i]); 89 return !matching_regexps->empty(); 90 } 91 92 void FilteredRE2::RegexpsGivenStrings(const vector<int>& matched_atoms, 93 vector<int>* passed_regexps) { 94 prefilter_tree_->RegexpsGivenStrings(matched_atoms, passed_regexps); 95 } 96 97 98 void FilteredRE2::PrintPrefilter(int regexpid) { 99 prefilter_tree_->PrintPrefilter(regexpid); 100 } 101 102 } // namespace re2 103