From 6dc01f74431a40dac698417d2947f0d8ddbd8c8c Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Mon, 28 Oct 2024 12:52:11 +0200 Subject: Make $regex.*search() functions not to match empty substrings in non empty strings --- libbuild2/functions-regex.cxx | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) (limited to 'libbuild2') diff --git a/libbuild2/functions-regex.cxx b/libbuild2/functions-regex.cxx index c46f6f5..de34d63 100644 --- a/libbuild2/functions-regex.cxx +++ b/libbuild2/functions-regex.cxx @@ -138,12 +138,24 @@ namespace build2 // string s (to_string (move (v))); + // Match flags. + // + // Note that by default std::regex_search() matches the empty substrings + // in non-empty strings for all the major implementations. We suppress + // such a counter-intuitive behavior with the match_not_null flag (see the + // butl::regex_replace_search() function implementation for details). + // + 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 m; - if (regex_search (s, m, rge)) + if (regex_search (s, m, rge, mf)) { assert (!m.empty ()); @@ -483,7 +495,19 @@ namespace build2 for (auto& n: ns) { - if (regex_search (convert (move (n)), rge)) + string s (convert (move (n))); + + // Match flags. + // + // Suppress matching of empty substrings in non-empty strings (see above + // for details). + // + 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 +540,17 @@ namespace build2 bool s (n.simple ()); string v (convert (s ? move (n) : name (n))); - if (regex_search (v, rge) == matching) + // Match flags. + // + // Suppress matching of empty substrings in non-empty strings (see above + // for details). + // + 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)); } -- cgit v1.1