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