(CFACT-65) Replace RE2 with boost::regex
Removes dependency on RE2. Uses an adapter class and function to abstract
regular expression calls so it's easier to modify or switch packages if
necessary (for speed or Unicode support), and simplify the call interface.
Michael Smith
9 years ago
20 | 20 | - wget https://github.com/doxygen/doxygen/archive/Release_1_8_7.tar.gz -O $HOME/doxygen-1.8.7.tgz |
21 | 21 | - pushd $HOME && tar xzf doxygen-1.8.7.tgz && cd $HOME/doxygen-Release_1_8_7 && ./configure > /dev/null && make > /dev/null && sudo make install > /dev/null && popd |
22 | 22 | # Install dependencies of cfacter |
23 | - sudo apt-get -y install libboost-filesystem1.48-dev libboost-program-options1.48-dev liblog4cxx10-dev | |
24 | - wget https://re2.googlecode.com/files/re2-20140304.tgz -O $HOME/re2-20140304.tgz | |
25 | - pushd $HOME && tar xzf re2-20140304.tgz && cd $HOME/re2 && make > /dev/null && sudo make install > /dev/null && popd | |
23 | - sudo apt-get -y install libboost-filesystem1.48-dev libboost-program-options1.48-dev libboost-regex1.48-dev liblog4cxx10-dev | |
26 | 24 | - wget https://yaml-cpp.googlecode.com/files/yaml-cpp-0.5.1.tar.gz -O $HOME/yaml-cpp-0.5.1.tgz |
27 | 25 | - pushd $HOME && tar xzf yaml-cpp-0.5.1.tgz && cd $HOME/yaml-cpp-0.5.1 && cmake -DBUILD_SHARED_LIBS=ON . && make > /dev/null && sudo make install > /dev/null && popd |
28 | 26 |
17 | 17 | endif() |
18 | 18 | |
19 | 19 | # Find our dependency packages |
20 | find_package(Boost 1.48 REQUIRED COMPONENTS program_options system filesystem) | |
20 | find_package(Boost 1.48 REQUIRED COMPONENTS program_options system filesystem regex) | |
21 | 21 | find_package(LOG4CXX REQUIRED) |
22 | find_package(RE2 REQUIRED) | |
23 | 22 | find_package(OPENSSL REQUIRED) |
24 | 23 | find_package(YAMLCPP REQUIRED) |
25 | 24 | |
65 | 64 | "-readability/todo" # Seriously? todo comments need to identify an owner? pffft |
66 | 65 | "-whitespace/empty_loop_body" # Can't handle do { ... } while(expr); |
67 | 66 | "-runtime/int" # Some C types are needed for library interop |
67 | "-runtime/explicit" # Using implicit conversion from string to regex for regex calls. | |
68 | 68 | ) |
69 | 69 | |
70 | 70 | file(GLOB_RECURSE ALL_SOURCES lib/*.cc lib/*.h lib/*.hpp exe/*.cc exe/*.h exe/*.hpp) |
14 | 14 | * Apache log4cxx >= 10.0 |
15 | 15 | * OpenSSL >= 1.0.1.g |
16 | 16 | * yaml-cpp >= 0.5.1 |
17 | * Google's RE2 library | |
18 | 17 | |
19 | 18 | ### Setup on Fedora 20 |
20 | 19 | |
21 | 20 | The following will install all required tools and libraries: |
22 | 21 | |
23 | yum install cmake boost-devel log4cxx-devel openssl-devel yaml-cpp-devel re2-devel | |
22 | yum install cmake boost-devel log4cxx-devel openssl-devel yaml-cpp-devel | |
24 | 23 | |
25 | 24 | ### Setup on Mac OSX Mavericks (homebrew) |
26 | 25 | |
28 | 27 | |
29 | 28 | The following will install all required libraries: |
30 | 29 | |
31 | brew install cmake boost log4cxx yaml-cpp re2 | |
30 | brew install cmake boost log4cxx yaml-cpp | |
32 | 31 | |
33 | 32 | ### Setup on Ubuntu 14.04 (Trusty) |
34 | 33 | |
36 | 35 | |
37 | 36 | apt-get install build-essential cmake libboost-all-dev liblog4cxx10-dev libssl-dev libyaml-cpp-dev |
38 | 37 | |
39 | Google's RE2 library will need to be installed from source. | |
40 | 38 | |
41 | 39 | Pre-Build |
42 | 40 | --------- |
0 | ################################################################################ | |
1 | # | |
2 | # CMake script for finding RE2. | |
3 | # The default CMake search process is used to locate files. | |
4 | # | |
5 | # This script creates the following variables: | |
6 | # RE2_FOUND: Boolean that indicates if the package was found | |
7 | # RE2_INCLUDE_DIRS: Paths to the necessary header files | |
8 | # RE2_LIBRARIES: Package libraries | |
9 | # RE2_LIBRARY_DIRS: Path to package libraries | |
10 | # | |
11 | ################################################################################ | |
12 | ||
13 | include(FindPackageHandleStandardArgs) | |
14 | ||
15 | # See if RE2_ROOT is not already set in CMake | |
16 | if (NOT RE2_ROOT) | |
17 | # See if RE2_ROOT is set in process environment | |
18 | if (NOT $ENV{RE2_ROOT} STREQUAL "") | |
19 | set(RE2_ROOT "$ENV{RE2_ROOT}") | |
20 | message(STATUS "Detected RE2_ROOT set to '${RE2_ROOT}'") | |
21 | endif() | |
22 | endif() | |
23 | ||
24 | # If RE2_ROOT is available, set up our hints | |
25 | if (RE2_ROOT) | |
26 | set(RE2_INCLUDE_HINTS HINTS "${RE2_ROOT}/include" "${RE2_ROOT}") | |
27 | set(RE2_LIBRARY_HINTS HINTS "${RE2_ROOT}/lib") | |
28 | endif() | |
29 | ||
30 | # Find headers and libraries | |
31 | find_path(RE2_INCLUDE_DIR NAMES re2/re2.h ${RE2_INCLUDE_HINTS}) | |
32 | find_library(RE2_LIBRARY NAMES re2 ${RE2_LIBRARY_HINTS}) | |
33 | ||
34 | # Set RE2_FOUND honoring the QUIET and REQUIRED arguments | |
35 | find_package_handle_standard_args(RE2 DEFAULT_MSG RE2_LIBRARY RE2_INCLUDE_DIR) | |
36 | ||
37 | # Output variables | |
38 | if (RE2_FOUND) | |
39 | # Include dirs | |
40 | set(RE2_INCLUDE_DIRS ${RE2_INCLUDE_DIR}) | |
41 | ||
42 | # Libraries | |
43 | if(RE2_LIBRARY) | |
44 | set(RE2_LIBRARIES ${RE2_LIBRARY}) | |
45 | else() | |
46 | set(RE2_LIBRARIES "") | |
47 | endif() | |
48 | ||
49 | # Link dirs | |
50 | get_filename_component(RE2_LIBRARY_DIRS ${RE2_LIBRARY} PATH) | |
51 | endif() | |
52 | ||
53 | # Advanced options for not cluttering the cmake UIs | |
54 | mark_as_advanced(RE2_INCLUDE_DIR RE2_LIBRARY)⏎ |
20 | 20 | depends_on "log4cxx" |
21 | 21 | depends_on "openssl" |
22 | 22 | depends_on "yaml-cpp" |
23 | depends_on "re2" | |
24 | 23 | |
25 | 24 | def install |
26 | 25 | system "cmake", ".", *std_cmake_args |
97 | 97 | # Set include directories |
98 | 98 | include_directories( |
99 | 99 | inc |
100 | ${RE2_INCLUDE_DIRS} | |
101 | 100 | ${RAPIDJSON_INCLUDE_DIRS} |
102 | 101 | ${LOG4CXX_INCLUDE_DIRS} |
103 | 102 | ${Boost_INCLUDE_DIRS} |
119 | 118 | # Link in additional libraries |
120 | 119 | target_link_libraries(libfacter |
121 | 120 | ${THREAD_LIBS} |
122 | ${RE2_LIBRARIES} | |
123 | 121 | ${LOG4CXX_LIBRARIES} |
124 | 122 | ${Boost_LIBRARIES} |
125 | 123 | ${OPENSSL_LIBRARIES} |
8 | 8 | #include <memory> |
9 | 9 | #include <stdexcept> |
10 | 10 | #include <string> |
11 | ||
12 | // Forward declare RE2 so users of this header don't have to include re2 | |
13 | namespace re2 { | |
14 | class RE2; | |
15 | } | |
11 | #include <facter/util/regex.hpp> | |
16 | 12 | |
17 | 13 | namespace facter { namespace facts { |
18 | 14 | |
129 | 125 | private: |
130 | 126 | std::string _name; |
131 | 127 | std::vector<std::string> _names; |
132 | std::vector<std::unique_ptr<re2::RE2>> _regexes; | |
128 | std::vector<std::unique_ptr<facter::util::re_adapter>> _regexes; | |
133 | 129 | bool _resolving; |
134 | 130 | }; |
135 | 131 |
0 | /** | |
1 | * @file | |
2 | * Defines an abstraction for using regular expression calls. | |
3 | * It should be extended when new match methods are needed, and allows easily | |
4 | * switching between regex libraries. | |
5 | */ | |
6 | #ifndef FACTER_UTIL_REGEX_HPP_ | |
7 | #define FACTER_UTIL_REGEX_HPP_ | |
8 | ||
9 | #ifdef USE_RE2 | |
10 | #include <re2/re2.h> | |
11 | #else | |
12 | #include <boost/regex.hpp> | |
13 | #include <boost/lexical_cast.hpp> | |
14 | #endif | |
15 | ||
16 | namespace facter { namespace util { | |
17 | #ifdef USE_RE2 | |
18 | using re_adapter = re2::RE2; | |
19 | ||
20 | template <typename... Args> | |
21 | inline bool re_search(const re2::StringPiece &txt, const re2::RE2 &r, Args&&... args) | |
22 | { | |
23 | return re2::RE2::PartialMatch(txt, r, std::forward<Args>(args)...); | |
24 | } | |
25 | #else | |
26 | class re_adapter : public boost::regex { | |
27 | std::string _err; | |
28 | public: | |
29 | re_adapter(const char* pattern) try : boost::regex(pattern) | |
30 | { | |
31 | } catch (const boost::regex_error &e) { | |
32 | _err = e.what(); | |
33 | } | |
34 | ||
35 | re_adapter(const std::string &pattern) try : boost::regex(pattern) | |
36 | { | |
37 | } catch (const boost::regex_error &e) { | |
38 | _err = e.what(); | |
39 | } | |
40 | ||
41 | const std::string& error() const { return _err; } | |
42 | bool ok() const { return error().empty(); } | |
43 | }; | |
44 | ||
45 | template <typename Text> | |
46 | inline bool re_search_helper(Text &txt, const boost::smatch &what, size_t depth) | |
47 | { | |
48 | return true; | |
49 | } | |
50 | ||
51 | template <typename Text, typename Arg, typename... Args> | |
52 | inline bool re_search_helper(Text &txt, const boost::smatch &what, size_t depth, Arg arg, Args&&... args) | |
53 | { | |
54 | if (depth >= what.size()) { | |
55 | return false; | |
56 | } | |
57 | ||
58 | try { | |
59 | using ArgType = typename std::pointer_traits<Arg>::element_type; | |
60 | auto val = boost::lexical_cast<ArgType>(what[depth]); | |
61 | *arg = val; | |
62 | } catch (const boost::bad_lexical_cast &e) { | |
63 | return false; | |
64 | } | |
65 | ||
66 | return re_search_helper(txt, what, depth+1, std::forward<Args>(args)...); | |
67 | } | |
68 | ||
69 | template <typename Text, typename... Args> | |
70 | inline bool re_search(Text &txt, const re_adapter &r, Args&&... args) | |
71 | { | |
72 | if (!r.ok()) { | |
73 | return false; | |
74 | } | |
75 | ||
76 | boost::smatch what; | |
77 | if (!boost::regex_search(txt, what, r)) { | |
78 | return false; | |
79 | } | |
80 | ||
81 | return re_search_helper(txt, what, 1, std::forward<Args>(args)...); | |
82 | } | |
83 | #endif | |
84 | ||
85 | }} // namespace facter::util | |
86 | ||
87 | #endif // FACTER_UTIL_REGEX_HPP_ | |
88 |
3 | 3 | #include <facter/facts/scalar_value.hpp> |
4 | 4 | #include <facter/execution/execution.hpp> |
5 | 5 | #include <facter/util/string.hpp> |
6 | #include <re2/re2.h> | |
6 | #include <facter/util/regex.hpp> | |
7 | 7 | |
8 | 8 | using namespace std; |
9 | 9 | using namespace facter::util; |
83 | 83 | } |
84 | 84 | string major; |
85 | 85 | string minor; |
86 | if (!RE2::PartialMatch(dist_release->value(), "(\\d+)\\.(\\d*)", &major, &minor)) { | |
86 | if (!re_search(dist_release->value(), "(\\d+)\\.(\\d*)", &major, &minor)) { | |
87 | 87 | major = dist_release->value(); |
88 | 88 | } |
89 | 89 | facts.add(fact::lsb_dist_major_release, make_value<string_value>(move(major))); |
7 | 7 | #include <facter/execution/execution.hpp> |
8 | 8 | #include <facter/util/string.hpp> |
9 | 9 | #include <facter/util/file.hpp> |
10 | #include <re2/re2.h> | |
10 | #include <facter/util/regex.hpp> | |
11 | 11 | #include <boost/filesystem.hpp> |
12 | 12 | #include <map> |
13 | 13 | #include <vector> |
97 | 97 | if (ends_with(contents, "(Rawhide)")) { |
98 | 98 | value = "Rawhide"; |
99 | 99 | } else { |
100 | RE2::PartialMatch(contents, "release (\\d[\\d.]*)", &value); | |
100 | re_search(contents, "release (\\d[\\d.]*)", &value); | |
101 | 101 | } |
102 | 102 | } |
103 | 103 | |
120 | 120 | string contents = file::read(release_file::suse); |
121 | 121 | string major; |
122 | 122 | string minor; |
123 | if (RE2::PartialMatch(contents, "(?m)^VERSION\\s*=\\s*(\\d+)\\.?(\\d+)?", &major, &minor)) { | |
123 | if (re_search(contents, "(?m)^VERSION\\s*=\\s*(\\d+)\\.?(\\d+)?", &major, &minor)) { | |
124 | 124 | // Check that we have a minor version; if not, use the patch level |
125 | 125 | if (minor.empty()) { |
126 | if (!RE2::PartialMatch(contents, "(?m)^PATCHLEVEL\\s*=\\s*(\\d+)", &minor)) { | |
126 | if (!re_search(contents, "(?m)^PATCHLEVEL\\s*=\\s*(\\d+)", &minor)) { | |
127 | 127 | minor = "0"; |
128 | 128 | } |
129 | 129 | } |
164 | 164 | } |
165 | 165 | if (file) { |
166 | 166 | string contents = file::read(file); |
167 | RE2::PartialMatch(contents, regex, &value); | |
167 | re_search(contents, regex, &value); | |
168 | 168 | } |
169 | 169 | } |
170 | 170 | |
172 | 172 | if (value.empty() && operating_system->value() == os::vmware_esx) { |
173 | 173 | auto result = execute("vmware", { "-v" }); |
174 | 174 | if (result.first) { |
175 | RE2::PartialMatch(result.second, "VMware ESX .*?(\\d.*)", &value); | |
175 | re_search(result.second, "VMware ESX .*?(\\d.*)", &value); | |
176 | 176 | } |
177 | 177 | } |
178 | 178 | |
232 | 232 | if (is_regular_file(release_file::os, ec)) { |
233 | 233 | string contents = trim(file::read(release_file::os)); |
234 | 234 | string release; |
235 | if (RE2::PartialMatch(contents, "(?m)^NAME=[\"']?(.+?)[\"']?$", &release)) { | |
235 | if (re_search(contents, "(?m)^NAME=[\"']?(.+?)[\"']?$", &release)) { | |
236 | 236 | if (release == "Cumulus Linux") { |
237 | 237 | return os::cumulus; |
238 | 238 | } |
286 | 286 | |
287 | 287 | string contents = trim(file::read(release_file::redhat)); |
288 | 288 | for (auto const& regex : regexs) { |
289 | if (RE2::PartialMatch(contents, get<0>(regex))) { | |
289 | if (re_search(contents, get<0>(regex))) { | |
290 | 290 | return get<1>(regex); |
291 | 291 | } |
292 | 292 | } |
307 | 307 | |
308 | 308 | string contents = trim(file::read(release_file::suse)); |
309 | 309 | for (auto const& regex : regexs) { |
310 | if (RE2::PartialMatch(contents, get<0>(regex))) { | |
310 | if (re_search(contents, get<0>(regex))) { | |
311 | 311 | return get<1>(regex); |
312 | 312 | } |
313 | 313 | } |
7 | 7 | #include <facter/util/file.hpp> |
8 | 8 | #include <facter/util/directory.hpp> |
9 | 9 | #include <boost/filesystem.hpp> |
10 | #include <re2/re2.h> | |
10 | #include <facter/util/regex.hpp> | |
11 | 11 | #include <unordered_set> |
12 | 12 | |
13 | 13 | using namespace std; |
14 | using namespace re2; | |
15 | 14 | using namespace facter::facts; |
16 | 15 | using namespace facter::facts::posix; |
17 | 16 | using namespace facter::util; |
47 | 46 | value = "amd64"; |
48 | 47 | } |
49 | 48 | // For 32-bit, use "x86" for Gentoo and "i386" for everyone else |
50 | } else if (RE2::PartialMatch(model->value(), "i[3456]86|pentium")) { | |
49 | } else if (re_search(model->value(), "i[3456]86|pentium")) { | |
51 | 50 | if (os->value() == os::gentoo) { |
52 | 51 | value = "x86"; |
53 | 52 | } else { |
2 | 2 | #include <facter/facts/fact.hpp> |
3 | 3 | #include <facter/facts/scalar_value.hpp> |
4 | 4 | #include <facter/util/file.hpp> |
5 | #include <re2/re2.h> | |
5 | #include <facter/util/regex.hpp> | |
6 | 6 | |
7 | 7 | using namespace std; |
8 | 8 | using namespace facter::util; |
81 | 81 | } |
82 | 82 | |
83 | 83 | string mode; |
84 | if (RE2::PartialMatch(buffer, "(?m)^SELINUX=(\\w+)$" , &mode)) { | |
84 | if (re_search(buffer, "(?m)^SELINUX=(\\w+)$", &mode)) { | |
85 | 85 | facts.add(fact::selinux_config_mode, make_value<string_value>(move(mode))); |
86 | 86 | } |
87 | 87 | |
88 | 88 | string type; |
89 | if (RE2::PartialMatch(buffer, "(?m)^SELINUXTYPE=(\\w+)$" , &type)) { | |
89 | if (re_search(buffer, "(?m)^SELINUXTYPE=(\\w+)$", &type)) { | |
90 | 90 | facts.add(fact::selinux_config_policy, make_value<string_value>(move(type))); |
91 | 91 | } |
92 | 92 | } |
93 | 93 | |
94 | 94 | bool selinux_resolver::get_selinux_mountpoint(string& selinux_mount) |
95 | 95 | { |
96 | RE2 regexp("\\S+ (\\S+) selinuxfs"); | |
96 | re_adapter regexp("\\S+ (\\S+) selinuxfs"); | |
97 | 97 | bool is_mounted = false; |
98 | 98 | file::each_line("/proc/self/mounts", [&](string& line) { |
99 | 99 | string mountpoint; |
100 | if (RE2::PartialMatch(line, regexp, &mountpoint)) { | |
100 | if (re_search(line, regexp, &mountpoint)) { | |
101 | 101 | selinux_mount = mountpoint; |
102 | 102 | is_mounted = true; |
103 | 103 | return false; |
6 | 6 | #include <facter/facts/posix/uptime_resolver.hpp> |
7 | 7 | #include <facter/util/file.hpp> |
8 | 8 | #include <facter/util/string.hpp> |
9 | #include <re2/re2.h> | |
9 | #include <facter/util/regex.hpp> | |
10 | 10 | |
11 | 11 | using namespace std; |
12 | 12 | using namespace facter::util; |
119 | 119 | |
120 | 120 | int days, hours, minutes; |
121 | 121 | |
122 | if (RE2::PartialMatch(output, "(\\d+) day(?:s|\\(s\\))?,\\s+(\\d+):(\\d+)", &days, &hours, &minutes)) { | |
122 | if (re_search(output, "(\\d+) day(?:s|\\(s\\))?,\\s+(\\d+):(\\d+)", &days, &hours, &minutes)) { | |
123 | 123 | return 86400 * days + 3600 * hours + 60 * minutes; |
124 | } else if (RE2::PartialMatch(output, "(\\d+) day(?:s|\\(s\\))?,\\s+(\\d+) hr(?:s|\\(s\\))?,", &days, &hours)) { | |
124 | } else if (re_search(output, "(\\d+) day(?:s|\\(s\\))?,\\s+(\\d+) hr(?:s|\\(s\\))?,", &days, &hours)) { | |
125 | 125 | return 86400 * days + 3600 * hours; |
126 | } else if (RE2::PartialMatch(output, "(\\d+) day(?:s|\\(s\\))?,\\s+(\\d+) min(?:s|\\(s\\))?,", &days, &minutes)) { | |
126 | } else if (re_search(output, "(\\d+) day(?:s|\\(s\\))?,\\s+(\\d+) min(?:s|\\(s\\))?,", &days, &minutes)) { | |
127 | 127 | return 86400 * days + 60 * minutes; |
128 | } else if (RE2::PartialMatch(output, "(\\d+) day(?:s|\\(s\\))?,", &days)) { | |
128 | } else if (re_search(output, "(\\d+) day(?:s|\\(s\\))?,", &days)) { | |
129 | 129 | return 86400 * days; |
130 | } else if (RE2::PartialMatch(output, "up\\s+(\\d+):(\\d+),", &hours, &minutes)) { | |
130 | } else if (re_search(output, "up\\s+(\\d+):(\\d+),", &hours, &minutes)) { | |
131 | 131 | return 3600 * hours + 60 * minutes; |
132 | } else if (RE2::PartialMatch(output, "(\\d+) hr(?:s|\\(s\\))?,", &hours)) { | |
132 | } else if (re_search(output, "(\\d+) hr(?:s|\\(s\\))?,", &hours)) { | |
133 | 133 | return 3600 * hours; |
134 | } else if (RE2::PartialMatch(output, "(\\d+) min(?:s|\\(s\\))?,", &minutes)) { | |
134 | } else if (re_search(output, "(\\d+) min(?:s|\\(s\\))?,", &minutes)) { | |
135 | 135 | return 60 * minutes; |
136 | 136 | } else { |
137 | 137 | return 0; |
0 | 0 | #include <facter/facts/resolver.hpp> |
1 | 1 | #include <facter/facts/collection.hpp> |
2 | 2 | #include <facter/logging/logging.hpp> |
3 | #include <re2/re2.h> | |
3 | #include <facter/util/regex.hpp> | |
4 | 4 | |
5 | 5 | using namespace std; |
6 | using namespace re2; | |
7 | 6 | |
8 | 7 | LOG_DECLARE_NAMESPACE("facts.resolver"); |
9 | 8 | |
42 | 41 | _resolving(false) |
43 | 42 | { |
44 | 43 | for (auto const& pattern : patterns) { |
45 | auto regex = unique_ptr<RE2>(new RE2(pattern)); | |
44 | auto regex = unique_ptr<util::re_adapter>(new util::re_adapter(pattern)); | |
46 | 45 | if (!regex->error().empty()) { |
47 | 46 | throw invalid_name_pattern_exception(regex->error()); |
48 | 47 | } |
90 | 89 | { |
91 | 90 | // Check to see if any of our regexes match |
92 | 91 | for (auto const& regex : _regexes) { |
93 | if (RE2::PartialMatch(name, *regex)) { | |
92 | if (re_search(name, *regex)) { | |
94 | 93 | return true; |
95 | 94 | } |
96 | 95 | } |
0 | 0 | #include <facter/util/directory.hpp> |
1 | 1 | #include <boost/filesystem.hpp> |
2 | #include <re2/re2.h> | |
2 | #include <facter/util/regex.hpp> | |
3 | 3 | |
4 | 4 | using namespace std; |
5 | using namespace re2; | |
6 | 5 | using namespace boost::filesystem; |
7 | 6 | |
8 | 7 | namespace facter { namespace util { |
9 | 8 | |
10 | 9 | void directory::each_file(string const& directory, function<bool(string const&)> callback, string const& pattern) |
11 | 10 | { |
12 | RE2 regex(pattern); | |
11 | re_adapter regex(pattern); | |
13 | 12 | if (!regex.ok()) { |
14 | 13 | return; |
15 | 14 | } |
28 | 27 | if (!is_regular_file(it->status(ec))) { |
29 | 28 | continue; |
30 | 29 | } |
31 | if (RE2::PartialMatch(it->path().filename().string(), regex)) { | |
30 | if (re_search(it->path().filename().string(), regex)) { | |
32 | 31 | if (!callback(it->path().string())) { |
33 | 32 | break; |
34 | 33 | } |
38 | 37 | |
39 | 38 | void directory::each_subdirectory(string const& directory, function<bool(string const&)> callback, string const& pattern) |
40 | 39 | { |
41 | RE2 regex(pattern); | |
40 | re_adapter regex(pattern); | |
42 | 41 | if (!regex.ok()) { |
43 | 42 | return; |
44 | 43 | } |
57 | 56 | if (!is_directory(it->status(ec))) { |
58 | 57 | continue; |
59 | 58 | } |
60 | if (RE2::PartialMatch(it->path().filename().string(), regex)) { | |
59 | if (re_search(it->path().filename().string(), regex)) { | |
61 | 60 | if (!callback(it->path().string())) { |
62 | 61 | break; |
63 | 62 | } |
5 | 5 | #include <facter/util/string.hpp> |
6 | 6 | #include <log4cxx/logger.h> |
7 | 7 | #include <log4cxx/appenderskeleton.h> |
8 | #include <re2/re2.h> | |
8 | #include <facter/util/regex.hpp> | |
9 | 9 | #include <boost/algorithm/string/replace.hpp> |
10 | 10 | #include <memory> |
11 | 11 | #include <tuple> |
21 | 21 | using namespace facter::util; |
22 | 22 | using namespace facter::testing; |
23 | 23 | using namespace log4cxx; |
24 | using namespace re2; | |
25 | 24 | using testing::ElementsAre; |
26 | 25 | |
27 | 26 | struct ruby_log_appender : AppenderSkeleton |
236 | 235 | ASSERT_EQ(expected_messages.size(), messages.size()); |
237 | 236 | for (size_t i = 0; i < expected_messages.size(); ++i) { |
238 | 237 | ASSERT_EQ(expected_messages[i].first, messages[i].first); |
239 | ASSERT_TRUE(RE2::PartialMatch(messages[i].second, expected_messages[i].second)); | |
238 | ASSERT_TRUE(re_search(messages[i].second, expected_messages[i].second)); | |
240 | 239 | } |
241 | 240 | return; |
242 | 241 | } |