aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build2/parser.cxx15
-rw-r--r--doc/manual.cli17
-rw-r--r--tests/name/pattern.test34
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