diff --git a/INSTALL b/INSTALL index 1281bb9..b4e43a1 100644 --- a/INSTALL +++ b/INSTALL @@ -1,5 +1,5 @@ Requirements: - libcurl - libarchive - - pcre - pthreads + - re2 diff --git a/build-aux/ci-test b/build-aux/ci-test index cc66f22..f17e0dd 100755 --- a/build-aux/ci-test +++ b/build-aux/ci-test @@ -42,7 +42,7 @@ case $buildmode in ;; esac -pacman -Syu --noconfirm base-devel git gmock gtest python meson pcre perl +pacman -Syu --noconfirm base-devel git gmock gtest python meson perl re2 # Needed to ensure PATH is properly set for perl, etc. source /etc/profile diff --git a/man/pkgfile.pod b/man/pkgfile.pod index ad9a8ad..a6017c6 100644 --- a/man/pkgfile.pod +++ b/man/pkgfile.pod @@ -63,7 +63,9 @@ Disable case sensitivity in matching. =item B<-r>, B<--regex> -Enable regular expression matching. See B(3). +Enable regular expression matching. The matching is partial meaning it will +match a substring of an entry. See https://github.com/google/re2/wiki/Syntax +for supported syntax. =item B<-R> I, B<--repo=>I @@ -177,7 +179,7 @@ systemd support, this can be enabled with: =head1 SEE ALSO -B(1), B(8), B(3), B(7), B(5) +B(1), B(8), B(7), B(5) =head1 AUTHOR diff --git a/meson.build b/meson.build index ea68406..979ca07 100644 --- a/meson.build +++ b/meson.build @@ -28,7 +28,7 @@ add_project_arguments( language: 'cpp', ) -libpcre = dependency('libpcre', version: '>= 8.30') +re2 = dependency('re2') libarchive = dependency('libarchive', version: '>= 3.2.0') libcurl = dependency('libcurl') libsystemd = dependency('libsystemd') @@ -57,7 +57,7 @@ libcommon = static_library( src/queue.hh '''.split(), ), - dependencies: [libpcre, libarchive, libcurl, pthreads, stdcppfs], + dependencies: [re2, libarchive, libcurl, pthreads, stdcppfs], install: false, ) @@ -191,7 +191,7 @@ if gtest.found() and gmock.found() '''.split(), ), link_with: [libcommon, gtest_main], - dependencies: [gmock, gtest, libpcre], + dependencies: [gmock, gtest, re2], ), protocol: 'gtest', ) diff --git a/src/filter.cc b/src/filter.cc index 72aa41b..8013e15 100644 --- a/src/filter.cc +++ b/src/filter.cc @@ -5,6 +5,7 @@ #include #include +#include namespace pkgfile { namespace filter { @@ -40,38 +41,25 @@ bool Glob::Matches(std::string_view line) const { return fnmatch(glob_pattern_.c_str(), std::string(line).c_str(), flags_) == 0; } -Regex::~Regex() { - pcre_free_study(re_extra_); - pcre_free(re_); -} - // static std::unique_ptr Regex::Compile(const std::string& pattern, bool case_sensitive) { - const int options = case_sensitive ? 0 : PCRE_CASELESS; - const char* err; - int offset; - - pcre* re = pcre_compile(pattern.c_str(), options, &err, &offset, nullptr); - if (re == nullptr) { - std::cerr << std::format("error: failed to compile regex at char {}: {}\n", - offset, err); - return nullptr; - } - - pcre_extra* re_extra = pcre_study(re, PCRE_STUDY_JIT_COMPILE, &err); - if (err) { - std::cerr << std::format("error: failed to study regex: {}\n", err); - pcre_free(re); + re2::RE2::Options re2_options; + re2_options.set_case_sensitive(case_sensitive); + re2_options.set_log_errors(false); + + auto re = std::make_unique(pattern, re2_options); + if (!re->ok()) { + std::cerr << std::format("error: failed to compile regex: {}\n", + re->error()); return nullptr; } - return std::make_unique(re, re_extra); + return std::make_unique(std::move(re)); } bool Regex::Matches(std::string_view line) const { - return pcre_exec(re_, re_extra_, line.data(), line.size(), 0, - PCRE_NO_UTF16_CHECK, nullptr, 0) >= 0; + return re2::RE2::PartialMatch(line, *re_); } Exact::Exact(std::string match, bool case_sensitive) { diff --git a/src/filter.hh b/src/filter.hh index 5a9e85f..6149674 100644 --- a/src/filter.hh +++ b/src/filter.hh @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -66,8 +66,7 @@ class Bin : public Filter { class Regex : public Filter { public: - Regex(pcre* re, pcre_extra* re_extra) : re_(re), re_extra_(re_extra) {} - ~Regex(); + Regex(std::unique_ptr re) : re_(std::move(re)) {} static std::unique_ptr Compile(const std::string& pattern, bool case_sensitive); @@ -75,8 +74,7 @@ class Regex : public Filter { bool Matches(std::string_view line) const override; private: - pcre* re_; - pcre_extra* re_extra_; + std::unique_ptr re_; }; class Glob : public Filter {