diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2024-10-28 12:52:11 +0200 |
---|---|---|
committer | Karen Arutyunov <karen@codesynthesis.com> | 2024-10-28 12:52:11 +0200 |
commit | 0e911d64e71a85d3958689debff0ccbee4c3891a (patch) | |
tree | c6883a7d44b48417956d98924f889a92daf29806 | |
parent | c10c90efd41294eca8dad0bd3a20abead33032c2 (diff) |
Make .*search() functions not to match empty substrings in non empty strings
-rw-r--r-- | libbuild2/functions-regex.cxx | 31 | ||||
-rw-r--r-- | tests/function/regex/testscript | 81 |
2 files changed, 108 insertions, 4 deletions
diff --git a/libbuild2/functions-regex.cxx b/libbuild2/functions-regex.cxx index c46f6f5..cac4e54 100644 --- a/libbuild2/functions-regex.cxx +++ b/libbuild2/functions-regex.cxx @@ -138,12 +138,19 @@ namespace build2 // string s (to_string (move (v))); + // Match flags. + // + regex_constants::match_flag_type mf (regex_constants::match_default); + + if (!s.empty ()) + mf |= regex_constants::match_not_null; + if (!match && !subs) - return value (regex_search (s, rge)); // Return boolean value. + return value (regex_search (s, rge, mf)); // Return boolean value. match_results<string::const_iterator> m; - if (regex_search (s, m, rge)) + if (regex_search (s, m, rge, mf)) { assert (!m.empty ()); @@ -483,7 +490,16 @@ namespace build2 for (auto& n: ns) { - if (regex_search (convert<string> (move (n)), rge)) + string s (convert<string> (move (n))); + + // Match flags. + // + regex_constants::match_flag_type mf (regex_constants::match_default); + + if (!s.empty ()) + mf |= regex_constants::match_not_null; + + if (regex_search (s, rge, mf)) return true; } @@ -516,7 +532,14 @@ namespace build2 bool s (n.simple ()); string v (convert<string> (s ? move (n) : name (n))); - if (regex_search (v, rge) == matching) + // Match flags. + // + regex_constants::match_flag_type mf (regex_constants::match_default); + + if (!v.empty ()) + mf |= regex_constants::match_not_null; + + if (regex_search (v, rge, mf) == matching) r.emplace_back (s ? name (move (v)) : move (n)); } diff --git a/tests/function/regex/testscript b/tests/function/regex/testscript index 538bdab..5564bbd 100644 --- a/tests/function/regex/testscript +++ b/tests/function/regex/testscript @@ -366,6 +366,33 @@ EOI } } + + : empty-substring + : + : Note that the regex search-based replacement with the match_not_null flag + : is broken for older versions of libstdc++ and libc++. + : + if (($cxx.id != 'gcc' || $cxx.version.major >= 7) && \ + ($cxx.id != 'clang' || $cxx.version.major >= 6)) + { + : empty + : + $* <<EOI >'true' + print $regex.search('', '.*') + EOI + + : match + : + $* <<EOI >'true' + print $regex.search('a', 'a*') + EOI + + : no-match + : + $* <<EOI >'false' + print $regex.search('aa', 'b*') + EOI + } } : split @@ -576,6 +603,33 @@ print $regex.find_search(Foo.cxx, 'f', icase) EOI } + + : empty-substring + : + : Note that the regex search-based replacement with the match_not_null flag + : is broken for older versions of libstdc++ and libc++. + : + if (($cxx.id != 'gcc' || $cxx.version.major >= 7) && \ + ($cxx.id != 'clang' || $cxx.version.major >= 6)) + { + : empty + : + $* <<EOI >'true' + print $regex.find_search('', '.*') + EOI + + : match + : + $* <<EOI >'true' + print $regex.find_search('a', 'a*') + EOI + + : no-match + : + $* <<EOI >'false' + print $regex.find_search('aa', 'b*') + EOI + } } : filter-search @@ -607,6 +661,33 @@ $* <<EOI >'' print $regex.filter_search(-g, '-O') EOI + + : empty-substring + : + : Note that the regex search-based replacement with the match_not_null flag + : is broken for older versions of libstdc++ and libc++. + : + if (($cxx.id != 'gcc' || $cxx.version.major >= 7) && \ + ($cxx.id != 'clang' || $cxx.version.major >= 6)) + { + : empty + : + $* <<EOI >'{}' + print $regex.filter_search('', '.*') + EOI + + : match + : + $* <<EOI >'a' + print $regex.filter_search('a', 'a*') + EOI + + : no-match + : + $* <<EOI >'' + print $regex.filter_search('aa', 'b*') + EOI + } } : filter-out |