diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2020-07-18 12:34:52 +0300 |
---|---|---|
committer | Karen Arutyunov <karen@codesynthesis.com> | 2020-07-18 12:54:55 +0300 |
commit | 47d5b304235c5b1f409b01cab95a2191eac5a230 (patch) | |
tree | dc82e4971e7c0124a5953b6ab75ec017c6124c83 | |
parent | ef81695c5fa356529bac6f8aa7d9bfe1f1c84473 (diff) |
Add $regex.find_match() and $regex.find_search() functions
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | libbuild2/functions-regex.cxx | 98 | ||||
-rw-r--r-- | tests/function/regex/testscript | 84 |
3 files changed, 184 insertions, 0 deletions
@@ -187,6 +187,8 @@ Version 0.13.0 See the "Install Module" chapter in the manual for details. + * New $regex.find_{match,search}() functions that operate on lists. + * The $process.run*() functions now recognize a number of portable builtins. Refer to the Testscript manual for the list and details. diff --git a/libbuild2/functions-regex.cxx b/libbuild2/functions-regex.cxx index 10067a4..a59d808 100644 --- a/libbuild2/functions-regex.cxx +++ b/libbuild2/functions-regex.cxx @@ -397,6 +397,63 @@ namespace build2 return r; } + static regex::flag_type + parse_find_flags (optional<names>&& flags) + { + regex::flag_type r (regex::ECMAScript); + + if (flags) + { + for (auto& f: *flags) + { + string s (convert<string> (move (f))); + + if (s == "icase") + r |= regex::icase; + else + throw invalid_argument ("invalid flag '" + s + "'"); + } + } + + return r; + } + + // Return true if any of the list elements match the regular expression. + // See find_match() overloads (below) for details. + // + static bool + find_match (names&& s, const string& re, optional<names>&& flags) + { + regex::flag_type fl (parse_find_flags (move (flags))); + regex rge (parse_regex (re, fl)); + + for (auto& v: s) + { + if (regex_match (convert<string> (move (v)), rge)) + return true; + } + + return false; + } + + // Return true if a part of any of the list elements matches the regular + // expression. See find_search() overloads (below) for details. + // + static bool + find_search (names&& s, const string& re, optional<names>&& flags) + { + regex::flag_type fl (parse_find_flags (move (flags))); + regex rge (parse_regex (re, fl)); + + for (auto& v: s) + { + if (regex_search (convert<string> (move (v)), rge)) + return true; + } + + return false; + } + // Replace matched parts of list elements using the format string and // concatenate the transformed elements. See merge() overloads (below) for // details. @@ -474,6 +531,25 @@ namespace build2 return match (move (s), convert<string> (move (re)), move (flags)); }; + // $regex.find_match(<vals>, <pat> [, <flags>]) + // + // Match list elements against the regular expression and return true if + // the match is found. Convert the elements to string prior to matching. + // + // The following flags are supported: + // + // icase - match ignoring case + // + f[".find_match"] = [](names s, string re, optional<names> flags) + { + return find_match (move (s), re, move (flags)); + }; + + f[".find_match"] = [](names s, names re, optional<names> flags) + { + return find_match (move (s), convert<string> (move (re)), move (flags)); + }; + // $regex.search(<val>, <pat> [, <flags>]) // // Determine if there is a match between the regular expression and some @@ -507,6 +583,28 @@ namespace build2 return search (move (s), convert<string> (move (re)), move (flags)); }; + // $regex.find_search(<vals>, <pat> [, <flags>]) + // + // Determine if there is a match between the regular expression and some + // part of any of the list elements. Convert the elements to string prior + // to matching. + // + // The following flags are supported: + // + // icase - match ignoring case + // + f[".find_search"] = [](names s, string re, optional<names> flags) + { + return find_search (move (s), re, move (flags)); + }; + + f[".find_search"] = [](names s, names re, optional<names> flags) + { + return find_search (move (s), + convert<string> (move (re)), + move (flags)); + }; + // $regex.replace(<val>, <pat>, <fmt> [, <flags>]) // // Replace matched parts in a value of an arbitrary type, using the format diff --git a/tests/function/regex/testscript b/tests/function/regex/testscript index 95dfbb8..5167390 100644 --- a/tests/function/regex/testscript +++ b/tests/function/regex/testscript @@ -436,6 +436,90 @@ EOI } +: find-match +: +{ + : match + : + { + : string + : + $* <<EOI >'true' + print $regex.find_match(-g -O3, [string] '-O[23]') + EOI + + : untyped + : + $* <<EOI >'true' + print $regex.find_match(-g -O3, '-O[23]') + EOI + + : strings + : + $* <<EOI >'true' + print $regex.find_match([strings] -g -O3, '-O[23]') + EOI + + : nomatch + : + $* <<EOI >'false' + print $regex.find_match(-g -O1, '-O[23]') + EOI + } + + : flags + : + { + : icase + : + $* <<EOI >'true' + print $regex.find_match(Foo.cxx, 'f[^.]+.*', icase) + EOI + } +} + +: find-search +: +{ + : match + : + { + : string + : + $* <<EOI >'true' + print $regex.find_search(-g -O3, [string] '-O') + EOI + + : untyped + : + $* <<EOI >'true' + print $regex.find_search(-g -O3, '-O') + EOI + + : strings + : + $* <<EOI >'true' + print $regex.find_search([strings] -g -O3, '-O') + EOI + + : nomatch + : + $* <<EOI >'false' + print $regex.find_search(-g, '-O') + EOI + } + + : flags + : + { + : icase + : + $* <<EOI >'true' + print $regex.find_search(Foo.cxx, 'f', icase) + EOI + } +} + : merge : { |