From 355534c22ab547bceae189e11ce36fa0dea4e743 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 13 Mar 2019 13:43:54 +0200 Subject: 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'. --- build2/context.cxx | 2 +- build2/scope.cxx | 21 ++++++++++++++++++--- tests/variable/override/testscript | 29 +++++++++++++++++++++++++++++ 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 <>EOO + print $x + EOI + 0 1 2 + EOO + + : before + : + $* x+=2 x=+0 x=1 <>EOO + print $x + EOI + 1 + EOO + + : both + : + $* x=+0 x=1 x+=2 <>EOO + print $x + EOI + 1 2 + EOO +} -- cgit v1.1