From 9f93d058c363ef61802222d8a63a75b0643c8bf0 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 17 Mar 2017 15:20:41 +0200 Subject: Add support for inclusion/exclusion groups in wildcard patterns For example cxx{* -{foo bar *x}}. --- build2/parser.cxx | 15 +++++++++++++-- doc/manual.cli | 17 +++++++++++++++++ tests/name/pattern.test | 34 ++++++++++++++++++++-------------- 3 files changed, 50 insertions(+), 16 deletions(-) diff --git a/build2/parser.cxx b/build2/parser.cxx index 4d628b0..eacece1 100644 --- a/build2/parser.cxx +++ b/build2/parser.cxx @@ -2503,6 +2503,18 @@ namespace build2 name& n (*i); bool first (i == b); + char s ('\0'); // Inclusion/exclusion sign (+/-). + + // Reduce inclusions/exclusions group (-/+{foo bar}) to simple name/dir. + // + if (!first && n.typed () && n.type.size () == 1) + { + s = n.type[0]; + + if (s == '-' || s == '+') + n.type.clear (); + } + if (n.empty () || !(n.simple () || n.directory ())) fail (l) << "invalid '" << n << "' in " << what << " pattern"; @@ -2510,10 +2522,9 @@ namespace build2 // Figure out if this is inclusion or exclusion. // - char s; // +/- if (first) s = '+'; // Treat as inclusion. - else + else if (s == '\0') { s = v[0]; diff --git a/doc/manual.cli b/doc/manual.cli index 232b0fa..0afb97f 100644 --- a/doc/manual.cli +++ b/doc/manual.cli @@ -95,6 +95,23 @@ exe{hello}: cxx{f* +*oo} # Ok, no duplicates. ./: {*/ -build} # Error: exclusion must match a directory. \ +If many inclusions or exclusions need to be specified, then an +inclusion/exclusion group can be used. For example: + +\ +exe{hello}: cxx{f* -{foo bar}} # Exclude foo and bar if present. +\ + +This is particularly useful if you would like to list the names to exclude +in a variable. For example, this is how we can exclude certain files from +compilation but still include them as ordinary file prerequisites (so that +they are still included into the distribution): + +\ +exc = foo.cxx bar.cxx +exe{hello}: cxx{f* -{$exc}} file{$exc} +\ + One common situation that calls for exclusions is auto-generated source code. Let's say we have auto-generated command line parser in \c{options.hxx} and \c{options.cxx}. Because of the in-tree builds, our name pattern may or diff --git a/tests/name/pattern.test b/tests/name/pattern.test index ae0cc3a..6606d86 100644 --- a/tests/name/pattern.test +++ b/tests/name/pattern.test @@ -66,46 +66,52 @@ EOI : { touch foo.txt; - $* <'print *.txt' >'foo.txt' : simple-file + $* <'print *.txt' >'foo.txt' : simple-file mkdir foo; - $* <'print */' >/'foo/' : simple-dir + $* <'print */' >/'foo/' : simple-dir touch foo.txt; - $* <'print {*.txt}' >'foo.txt' : group + $* <'print {*.txt}' >'foo.txt' : group mkdir dir && touch dir/foo.txt; - $* <'print dir/{*.txt}' >'dir/foo.txt' : dir + $* <'print dir/{*.txt}' >'dir/foo.txt' : dir touch foo.txt; - $* <'print file{*.txt}' >'file{foo.txt}' : type + $* <'print file{*.txt}' >'file{foo.txt}' : type touch foo.txt; - $* <'print x@{*.txt}' >'x@foo.txt' : pair + $* <'print x@{*.txt}' >'x@foo.txt' : pair touch bar.txt; - $* <'print x@dir/file{f*.txt}' >'' : empty + $* <'print x@dir/file{f*.txt}' >'' : empty mkdir dir && touch dir/foo.txt; - $* <'print **.txt' >/'dir/foo.txt' : recursive + $* <'print **.txt' >/'dir/foo.txt' : recursive mkdir dir && touch dir/foo.txt; - $* <'print d*/*.txt' >/'dir/foo.txt' : multi-pattern + $* <'print d*/*.txt' >/'dir/foo.txt' : multi-pattern touch foo.txt bar.txt; - $* <'print {*.txt -bar.txt}' >'foo.txt' : exclude-match + $* <'print {*.txt -bar.txt}' >'foo.txt' : exclude-match touch foo.txt bar.txt; - $* <'print {*.txt -b*.txt}' >'foo.txt' : exclude-pattern + $* <'print {*.txt -b*.txt}' >'foo.txt' : exclude-pattern + + touch foo.txt bar.txt baz.txt; + $* <'print {*.txt -{*z.txt bar.txt}}' >'foo.txt' : exclude-group touch bar.txt; - $* <'print {f*.txt +bar.txt}' >'bar.txt' : include-match + $* <'print {f*.txt +bar.txt}' >'bar.txt' : include-match touch bar.txt; - $* <'print {f*.txt +b*.txt}' >'bar.txt' : include-pattern + $* <'print {f*.txt +b*.txt}' >'bar.txt' : include-pattern + + mkdir bar; + $* <'print {f*/ +{b*/}}' >/'bar/' : include-group touch foo.txt fox.txt; - $* <'print {*.txt -f*.txt +*x.txt}' >'fox.txt' : include-exclude-order + $* <'print {*.txt -f*.txt +*x.txt}' >'fox.txt' : include-exclude-order } : target-type -- cgit v1.1