From 2ccb11e55e1301e476e044abcfda6887971c518e Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Mon, 30 Dec 2024 23:34:08 +0200 Subject: Fix parser::parse_names() not to fail on pattern inclusion groups for some corner cases Specifically, fix the function for the case when the pattern inclusion group is specified first in the pattern group in a directory. For example, before the fix, compiling the following buildfile: fs = hello exe{hello}: foo/{hxx ixx txx cxx}{+{$fs}} would fail with the following error: invalid 'foo/hello' in name pattern --- libbuild2/parser.cxx | 25 ++++++++++++++++++++----- tests/name/pattern.testscript | 12 ++++++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/libbuild2/parser.cxx b/libbuild2/parser.cxx index 53f808c..61a9ed1 100644 --- a/libbuild2/parser.cxx +++ b/libbuild2/parser.cxx @@ -7569,7 +7569,9 @@ namespace build2 // and look for some wildcards since the pattern can be the result of an // expansion (or, worse, concatenation). Thus pattern_mode::detect: we // are going to ask parse_names() to detect for us if the first name is - // a pattern. And if it is, to refrain from adding pair/dir/type. + // a pattern. And if it is, to refrain from adding pair/dir/type (note: + // for the pattern inclusions and exclusions the name's type member will + // be set to "+" and "-", respectively). // optional pat_tt ( parse_names ( @@ -8313,11 +8315,24 @@ namespace build2 fail (loc) << "invalid path '" << e.path << "'"; } - count = parse_names_trailer ( - t, tt, ns, pmode, what, separators, pairn, *pp1, dp1, tp1, cross); + // Note that for a pattern inclusion group (see above) we make sure + // that the resulting patterns are simple names, passing NULL as the + // directory path (see the parse_names_trailer::parse() lambda + // implementation for details). + // + assert (!pinc || (tp1 != nullptr && *tp1 == "+")); - // If empty group or empty name, then this is not a pattern inclusion - // group (see above). + count = parse_names_trailer ( + t, tt, + ns, + pmode, + what, + separators, pairn, + *pp1, (!pinc ? dp1 : nullptr), tp1, + cross); + + // If empty group or empty name, then this is not a pattern + // inclusion group. // if (pinc) { diff --git a/tests/name/pattern.testscript b/tests/name/pattern.testscript index c1a4ce4..efd15b2 100644 --- a/tests/name/pattern.testscript +++ b/tests/name/pattern.testscript @@ -153,6 +153,9 @@ EOI mkdir bar; $* <'print {f*/ +{b*/}}' >/'bar/' : include-group + mkdir -p foo/bar; + $* <'print $path.canonicalize(foo/{+{b*/}})' >/'foo/bar/' : include-group-first + touch foo.txt fox.txt; $* <'print {*.txt -f*.txt +*x.txt}' >'fox.txt' : include-exclude-order @@ -309,6 +312,15 @@ EOI print {+{$pats}} EOI + : pattern-via-expansion-list-subdir + : + mkdir baz; + touch baz/foo.txt baz/bar.hxx; + $* <'baz/bar.hxx baz/foo.txt' + pats = '*.hxx' '*.txt' + print baz/{+{$pats}} + EOI + : pattern-via-expansion-type : touch foo.txt; -- cgit v1.1