1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "RegEx.h"
18 
19 #include <regex>
20 
21 #include <android-base/logging.h>
22 
23 namespace simpleperf {
24 
~RegExMatch()25 RegExMatch::~RegExMatch() {}
26 
27 class RegExMatchImpl : public RegExMatch {
28  public:
RegExMatchImpl(std::string_view s,const std::regex & re)29   RegExMatchImpl(std::string_view s, const std::regex& re)
30       : match_it_(s.data(), s.data() + s.size(), re) {}
31 
IsValid() const32   bool IsValid() const override { return match_it_ != std::cregex_iterator(); }
33 
GetField(size_t index) const34   std::string GetField(size_t index) const override { return match_it_->str(index); }
35 
MoveToNextMatch()36   void MoveToNextMatch() override { ++match_it_; }
37 
38  private:
39   std::cregex_iterator match_it_;
40 };
41 
42 class RegExImpl : public RegEx {
43  public:
RegExImpl(std::string_view pattern)44   RegExImpl(std::string_view pattern)
45       : RegEx(pattern), re_(pattern_, std::regex::ECMAScript | std::regex::optimize) {}
46 
Match(std::string_view s) const47   bool Match(std::string_view s) const override {
48     return std::regex_match(s.begin(), s.end(), re_);
49   }
Search(std::string_view s) const50   bool Search(std::string_view s) const override {
51     return std::regex_search(s.begin(), s.end(), re_);
52   }
SearchAll(std::string_view s) const53   std::unique_ptr<RegExMatch> SearchAll(std::string_view s) const override {
54     return std::unique_ptr<RegExMatch>(new RegExMatchImpl(s, re_));
55   }
Replace(const std::string & s,const std::string & format) const56   std::optional<std::string> Replace(const std::string& s,
57                                      const std::string& format) const override {
58     try {
59       return {std::regex_replace(s, re_, format)};
60     } catch (std::regex_error& e) {
61       LOG(ERROR) << "regex_error: " << e.what() << ", pattern " << pattern_ << ", format "
62                  << format;
63       return std::nullopt;
64     }
65   }
66 
67  private:
68   std::regex re_;
69 };
70 
Create(std::string_view pattern)71 std::unique_ptr<RegEx> RegEx::Create(std::string_view pattern) {
72   try {
73     return std::make_unique<RegExImpl>(pattern);
74   } catch (std::regex_error& e) {
75     LOG(ERROR) << "regex_error: " << e.what() << ", pattern " << pattern;
76     return nullptr;
77   }
78 }
79 
SearchInRegs(std::string_view s,const std::vector<std::unique_ptr<RegEx>> & regs)80 bool SearchInRegs(std::string_view s, const std::vector<std::unique_ptr<RegEx>>& regs) {
81   for (auto& reg : regs) {
82     if (reg->Search(s)) {
83       return true;
84     }
85   }
86   return false;
87 }
88 
89 }  // namespace simpleperf
90