Home | History | Annotate | Download | only in re2
      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, &regexps);
     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, &regexps);
     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