aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2019-03-13 13:43:54 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2019-03-13 13:52:32 +0200
commit355534c22ab547bceae189e11ce36fa0dea4e743 (patch)
treec93af55fb30dd13da13bbcadd3729ed386f6e824
parente5d55e3245e148d675d4be607f1bfa944c4559e7 (diff)
Cutoff append/prepend overrides that come before assignment override
For example: $ b x+=1 x=2 x+=3 Should result in '2 3', not '1 2 3'.
-rw-r--r--build2/context.cxx2
-rw-r--r--build2/scope.cxx21
-rw-r--r--tests/variable/override/testscript29
3 files changed, 48 insertions, 4 deletions
diff --git a/build2/context.cxx b/build2/context.cxx
index f7234a7..7b473e2 100644
--- a/build2/context.cxx
+++ b/build2/context.cxx
@@ -590,7 +590,7 @@ namespace build2
//
// But that's probably ok (the need for a scope-qualified override with
// scope visibility should be pretty rare). Note also that to set the
- // value on the root (global) scope we use !.
+ // value on the global scope we use !.
//
// And so the first token should be a word which can be either a
// variable name (potentially with the directory qualification) or just
diff --git a/build2/scope.cxx b/build2/scope.cxx
index bae9818..69ab4b6 100644
--- a/build2/scope.cxx
+++ b/build2/scope.cxx
@@ -269,8 +269,8 @@ namespace build2
return true;
};
- // Return the override value if it is present and (optionally) ends with
- // a suffix.
+ // Return the override value if present in scope s and (optionally) ends
+ // with the specified suffix.
//
auto find = [&s, &var] (const variable* o,
const char* sf = nullptr) -> lookup
@@ -363,6 +363,7 @@ namespace build2
lookup stem;
size_t stem_depth (0);
const scope* stem_proj (nullptr);
+ const variable* stem_ovr (nullptr); // __override if found and applies.
// Again the special case of a target/rule-specific variable.
//
@@ -413,6 +414,7 @@ namespace build2
stem = move (l);
stem_depth = ovr_depth;
stem_proj = s->root_scope ();
+ stem_ovr = o;
done = true;
break;
}
@@ -486,10 +488,23 @@ namespace build2
{
++ovr_depth;
+ // Skip any append/prepend overrides that appear before __override,
+ // provided it is from this scope.
+ //
+ bool skip (stem_ovr != nullptr && stem_depth == ovr_depth);
+
for (const variable* o (var.override.get ());
o != nullptr;
o = o->override.get ())
{
+ if (skip)
+ {
+ if (stem_ovr == o) // Keep skipping until after we see __override.
+ skip = false;
+
+ continue;
+ }
+
// First see if this override applies. This is tricky: what if the
// stem is a "visible" override from an outer project? Shouldn't its
// overrides apply? Sure sounds logical. So we use the project of the
@@ -507,7 +522,7 @@ namespace build2
if (cl)
{
- // Note: if we have both, then the prefix is already in the stem.
+ // Note: if we have both, then one is already in the stem.
//
if (lp) // No sense to prepend/append if NULL.
{
diff --git a/tests/variable/override/testscript b/tests/variable/override/testscript
index 82b8e98..28225c1 100644
--- a/tests/variable/override/testscript
+++ b/tests/variable/override/testscript
@@ -56,6 +56,7 @@
}
: override-cached
+:
: Test overriding cached target type/pattern-specific prepend/append
:
{
@@ -76,3 +77,31 @@
1 a b X
EOO
}
+
+: order
+:
+{
+ : after
+ :
+ $* x=1 x+=2 x=+0 <<EOI >>EOO
+ print $x
+ EOI
+ 0 1 2
+ EOO
+
+ : before
+ :
+ $* x+=2 x=+0 x=1 <<EOI >>EOO
+ print $x
+ EOI
+ 1
+ EOO
+
+ : both
+ :
+ $* x=+0 x=1 x+=2 <<EOI >>EOO
+ print $x
+ EOI
+ 1 2
+ EOO
+}