Coverage Report

Created: 2025-06-09 06:44

/src/re2/re2/filtered_re2.cc
Line
Count
Source (jump to first uncovered line)
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
9
#include <string>
10
#include <utility>
11
#include <vector>
12
13
#include "absl/log/absl_log.h"
14
#include "absl/strings/string_view.h"
15
#include "re2/prefilter.h"
16
#include "re2/prefilter_tree.h"
17
18
namespace re2 {
19
20
FilteredRE2::FilteredRE2()
21
9.79k
    : compiled_(false),
22
9.79k
      prefilter_tree_(new PrefilterTree()) {
23
9.79k
}
24
25
FilteredRE2::FilteredRE2(int min_atom_len)
26
0
    : compiled_(false),
27
0
      prefilter_tree_(new PrefilterTree(min_atom_len)) {
28
0
}
29
30
9.79k
FilteredRE2::~FilteredRE2() {
31
19.5k
  for (size_t i = 0; i < re2_vec_.size(); i++)
32
9.79k
    delete re2_vec_[i];
33
9.79k
}
34
35
FilteredRE2::FilteredRE2(FilteredRE2&& other)
36
0
    : re2_vec_(std::move(other.re2_vec_)),
37
0
      compiled_(other.compiled_),
38
0
      prefilter_tree_(std::move(other.prefilter_tree_)) {
39
0
  other.re2_vec_.clear();
40
0
  other.re2_vec_.shrink_to_fit();
41
0
  other.compiled_ = false;
42
0
  other.prefilter_tree_.reset(new PrefilterTree());
43
0
}
44
45
0
FilteredRE2& FilteredRE2::operator=(FilteredRE2&& other) {
46
0
  this->~FilteredRE2();
47
0
  (void) new (this) FilteredRE2(std::move(other));
48
0
  return *this;
49
0
}
50
51
RE2::ErrorCode FilteredRE2::Add(absl::string_view pattern,
52
9.79k
                                const RE2::Options& options, int* id) {
53
9.79k
  RE2* re = new RE2(pattern, options);
54
9.79k
  RE2::ErrorCode code = re->error_code();
55
56
9.79k
  if (!re->ok()) {
57
0
    if (options.log_errors()) {
58
0
      ABSL_LOG(ERROR) << "Couldn't compile regular expression, skipping: "
59
0
                      << pattern << " due to error " << re->error();
60
0
    }
61
0
    delete re;
62
9.79k
  } else {
63
9.79k
    *id = static_cast<int>(re2_vec_.size());
64
9.79k
    re2_vec_.push_back(re);
65
9.79k
  }
66
67
9.79k
  return code;
68
9.79k
}
69
70
9.79k
void FilteredRE2::Compile(std::vector<std::string>* atoms) {
71
9.79k
  if (compiled_) {
72
0
    ABSL_LOG(ERROR) << "Compile called already.";
73
0
    return;
74
0
  }
75
76
  // Similarly to PrefilterTree::Compile(), make compiling
77
  // a no-op if it's attempted before adding any patterns.
78
9.79k
  if (re2_vec_.empty()) {
79
0
    return;
80
0
  }
81
82
19.5k
  for (size_t i = 0; i < re2_vec_.size(); i++) {
83
9.79k
    Prefilter* prefilter = Prefilter::FromRE2(re2_vec_[i]);
84
9.79k
    prefilter_tree_->Add(prefilter);
85
9.79k
  }
86
9.79k
  atoms->clear();
87
9.79k
  prefilter_tree_->Compile(atoms);
88
9.79k
  compiled_ = true;
89
9.79k
}
90
91
0
int FilteredRE2::SlowFirstMatch(absl::string_view text) const {
92
0
  for (size_t i = 0; i < re2_vec_.size(); i++)
93
0
    if (RE2::PartialMatch(text, *re2_vec_[i]))
94
0
      return static_cast<int>(i);
95
0
  return -1;
96
0
}
97
98
int FilteredRE2::FirstMatch(absl::string_view text,
99
0
                            const std::vector<int>& atoms) const {
100
0
  if (!compiled_) {
101
0
    ABSL_LOG(DFATAL) << "FirstMatch called before Compile.";
102
0
    return -1;
103
0
  }
104
0
  std::vector<int> regexps;
105
0
  prefilter_tree_->RegexpsGivenStrings(atoms, &regexps);
106
0
  for (size_t i = 0; i < regexps.size(); i++)
107
0
    if (RE2::PartialMatch(text, *re2_vec_[regexps[i]]))
108
0
      return regexps[i];
109
0
  return -1;
110
0
}
111
112
bool FilteredRE2::AllMatches(absl::string_view text,
113
                             const std::vector<int>& atoms,
114
9.79k
                             std::vector<int>* matching_regexps) const {
115
9.79k
  matching_regexps->clear();
116
9.79k
  std::vector<int> regexps;
117
9.79k
  prefilter_tree_->RegexpsGivenStrings(atoms, &regexps);
118
19.5k
  for (size_t i = 0; i < regexps.size(); i++)
119
9.79k
    if (RE2::PartialMatch(text, *re2_vec_[regexps[i]]))
120
3.65k
      matching_regexps->push_back(regexps[i]);
121
9.79k
  return !matching_regexps->empty();
122
9.79k
}
123
124
void FilteredRE2::AllPotentials(const std::vector<int>& atoms,
125
0
                                std::vector<int>* potential_regexps) const {
126
0
  prefilter_tree_->RegexpsGivenStrings(atoms, potential_regexps);
127
0
}
128
129
void FilteredRE2::RegexpsGivenStrings(const std::vector<int>& matched_atoms,
130
0
                                      std::vector<int>* passed_regexps) {
131
0
  prefilter_tree_->RegexpsGivenStrings(matched_atoms, passed_regexps);
132
0
}
133
134
0
void FilteredRE2::PrintPrefilter(int regexpid) {
135
0
  prefilter_tree_->PrintPrefilter(regexpid);
136
0
}
137
138
}  // namespace re2