xref: /aosp_15_r20/external/perfetto/src/trace_processor/util/regex.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2023 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 #ifndef SRC_TRACE_PROCESSOR_UTIL_REGEX_H_
18 #define SRC_TRACE_PROCESSOR_UTIL_REGEX_H_
19 
20 #include <optional>
21 #include "perfetto/base/compiler.h"
22 #include "perfetto/ext/base/scoped_file.h"
23 #include "perfetto/ext/base/status_or.h"
24 
25 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
26 #include <regex.h>
27 #endif
28 
29 namespace perfetto {
30 namespace trace_processor {
31 namespace regex {
32 
IsRegexSupported()33 constexpr bool IsRegexSupported() {
34 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
35   return false;
36 #else
37   return true;
38 #endif
39 }
40 
41 // Implements regex parsing and regex search based on C library `regex.h`.
42 // Doesn't work on Windows.
43 class Regex {
44  public:
45 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
~Regex()46   ~Regex() {
47     if (regex_) {
48       regfree(&regex_.value());
49     }
50   }
51   Regex(Regex&) = delete;
Regex(Regex && other)52   Regex(Regex&& other) {
53     regex_ = std::move(other.regex_);
54     other.regex_ = std::nullopt;
55   }
56   Regex& operator=(Regex&& other) {
57     this->~Regex();
58     new (this) Regex(std::move(other));
59     return *this;
60   }
61   Regex& operator=(const Regex&) = delete;
62 #endif
63 
64   // Parse regex pattern. Returns error if regex pattern is invalid.
Create(const char * pattern)65   static base::StatusOr<Regex> Create(const char* pattern) {
66 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
67     regex_t regex;
68     if (regcomp(&regex, pattern, 0)) {
69       return base::ErrStatus("Regex pattern '%s' is malformed.", pattern);
70     }
71     return Regex(std::move(regex));
72 #else
73     base::ignore_result(pattern);
74     PERFETTO_FATAL("Windows regex is not supported.");
75 #endif
76   }
77 
78   // Returns true if string matches the regex.
Search(const char * s)79   bool Search(const char* s) const {
80 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
81     PERFETTO_CHECK(regex_);
82     return regexec(&regex_.value(), s, 0, nullptr, 0) == 0;
83 #else
84     base::ignore_result(s);
85     PERFETTO_FATAL("Windows regex is not supported.");
86 #endif
87   }
88 
89 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
90  private:
Regex(regex_t regex)91   explicit Regex(regex_t regex) : regex_(std::move(regex)) {}
92 
93   std::optional<regex_t> regex_;
94 #endif
95 };
96 }  // namespace regex
97 
98 }  // namespace trace_processor
99 }  // namespace perfetto
100 
101 #endif  // SRC_TRACE_PROCESSOR_UTIL_REGEX_H_
102