blob: 120e4c968279d75d8b8f341a96a1f6402a9c4e41 [file] [log] [blame]
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SRC_TRACE_PROCESSOR_UTIL_REGEX_H_
#define SRC_TRACE_PROCESSOR_UTIL_REGEX_H_
#include <optional>
#include "perfetto/base/compiler.h"
#include "perfetto/ext/base/scoped_file.h"
#include "perfetto/ext/base/status_or.h"
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <regex.h>
#endif
namespace perfetto {
namespace trace_processor {
namespace regex {
constexpr bool IsRegexSupported() {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
return false;
#else
return true;
#endif
}
// Implements regex parsing and regex search based on C library `regex.h`.
// Doesn't work on Windows.
class Regex {
public:
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
~Regex() {
if (regex_) {
regfree(&regex_.value());
}
}
Regex(Regex&) = delete;
Regex(Regex&& other) {
regex_ = std::move(other.regex_);
other.regex_ = std::nullopt;
}
Regex& operator=(Regex&& other) {
this->~Regex();
new (this) Regex(std::move(other));
return *this;
}
Regex& operator=(const Regex&) = delete;
#endif
// Parse regex pattern. Returns error if regex pattern is invalid.
static base::StatusOr<Regex> Create(const char* pattern) {
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
regex_t regex;
if (regcomp(&regex, pattern, 0)) {
return base::ErrStatus("Regex pattern '%s' is malformed.", pattern);
}
return Regex(std::move(regex));
#else
base::ignore_result(pattern);
PERFETTO_FATAL("Windows regex is not supported.");
#endif
}
// Returns true if string matches the regex.
bool Search(const char* s) const {
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
PERFETTO_CHECK(regex_);
return regexec(&regex_.value(), s, 0, nullptr, 0) == 0;
#else
base::ignore_result(s);
PERFETTO_FATAL("Windows regex is not supported.");
#endif
}
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
private:
explicit Regex(regex_t regex) : regex_(std::move(regex)) {}
std::optional<regex_t> regex_;
#endif
};
} // namespace regex
} // namespace trace_processor
} // namespace perfetto
#endif // SRC_TRACE_PROCESSOR_UTIL_REGEX_H_