aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/build/script
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2022-09-19 10:13:48 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2022-09-19 11:35:50 +0200
commit47ae21f6558f81ae7c13d143d297f61acae2b530 (patch)
treec9458eb0b0ef62feffd485a975286b372582c78e /libbuild2/build/script
parent65ce598d17a662b4c8b9a8df02b619549c5824c3 (diff)
Allow computed variables in depdb preamble similar to impure functions
Diffstat (limited to 'libbuild2/build/script')
-rw-r--r--libbuild2/build/script/parser.cxx46
-rw-r--r--libbuild2/build/script/parser.hxx9
-rw-r--r--libbuild2/build/script/script.hxx3
3 files changed, 49 insertions, 9 deletions
diff --git a/libbuild2/build/script/parser.cxx b/libbuild2/build/script/parser.cxx
index 2112b5e..0614f20 100644
--- a/libbuild2/build/script/parser.cxx
+++ b/libbuild2/build/script/parser.cxx
@@ -93,6 +93,15 @@ namespace build2
info << "consider using 'depdb' builtin to track its result "
<< "changes";
+ // Diagnose computed variable exansions.
+ //
+ if (computed_var_)
+ fail (*computed_var_)
+ << "expansion of computed variable is only allowed in depdb "
+ << "preamble" <<
+ info << "consider using 'depdb' builtin to track its value "
+ << "changes";
+
// Diagnose absent/ambigous script name.
//
{
@@ -137,6 +146,7 @@ namespace build2
// Save the custom dependency change tracking lines, if present.
//
s.depdb_clear = depdb_clear_.has_value ();
+ s.depdb_value = depdb_value_;
if (depdb_dyndep_)
{
s.depdb_dyndep = depdb_dyndep_->second;
@@ -579,6 +589,8 @@ namespace build2
info (depdb_dyndep_->first) << "'depdb dyndep' call is here";
}
+ depdb_value_ = depdb_value_ || (v == "string" || v == "hash");
+
// Move the script body to the end of the depdb preamble.
//
// Note that at this (pre-parsing) stage we cannot evaluate if
@@ -603,10 +615,12 @@ namespace build2
script_->body_temp_dir = false;
}
- // Reset the impure function call info since it's valid for the
- // depdb preamble.
+ // Reset the impure function call and computed variable
+ // expansion tracking since both are valid for the depdb
+ // preamble.
//
impure_func_ = nullopt;
+ computed_var_ = nullopt;
// Instruct the parser to save the depdb builtin line separately
// from the script lines, when it is fully parsed. Note that the
@@ -2299,6 +2313,9 @@ namespace build2
// In the pre-parse mode collect the referenced variable names for the
// script semantics change tracking.
//
+ // Note that during pre-parse a computed (including qualified) name
+ // is signalled as an empty name.
+ //
if (pre_parse_ || pre_parse_suspended_)
{
lookup r;
@@ -2332,12 +2349,27 @@ namespace build2
vars.push_back (move (name));
}
}
+ else
+ {
+ // What about pre_parse_suspended_? Don't think it makes sense to
+ // diagnose this since it can be indirect (that is, via an
+ // intermediate variable).
+ //
+ if (perform_update_ && file_based_ && !computed_var_)
+ computed_var_ = loc;
+ }
return r;
}
if (!qual.empty ())
- fail (loc) << "qualified variable name";
+ {
+ // Qualified variable is computed and we expect the user to track
+ // its changes manually.
+ //
+ return build2::script::parser::lookup_variable (
+ move (qual), move (name), loc);
+ }
lookup r (environment_->lookup (name));
@@ -2348,13 +2380,13 @@ namespace build2
// diag builtin argument change (which can be affected by such a
// variable expansion) doesn't affect the script semantics and the
// depdb argument is specifically used for the script semantics change
- // tracking. We also omit this check it the depdb builtin is used in
- // the script, assuming that such variables are tracked manually, if
- // required.
+ // tracking. We also omit this check if the depdb "value" (string,
+ // hash) builtin is used in the script, assuming that such variables
+ // are tracked manually, if required.
//
if (script_ != nullptr &&
!script_->depdb_clear &&
- script_->depdb_preamble.empty ())
+ !script_->depdb_value)
{
if (r.defined () && !r.belongs (*environment_))
{
diff --git a/libbuild2/build/script/parser.hxx b/libbuild2/build/script/parser.hxx
index a02e34a..932cbad 100644
--- a/libbuild2/build/script/parser.hxx
+++ b/libbuild2/build/script/parser.hxx
@@ -327,7 +327,8 @@ namespace build2
// recipe should be provided.
//
//
- optional<location> depdb_clear_; // depdb-clear location.
+ optional<location> depdb_clear_; // depdb-clear location.
+ bool depdb_value_ = false; // depdb-{string,hash}
optional<pair<location, size_t>>
depdb_dyndep_; // depdb-dyndep location/position.
bool depdb_dyndep_byproduct_ = false; // --byproduct
@@ -344,6 +345,12 @@ namespace build2
//
optional<pair<string, location>> impure_func_;
+ // Similar to the impure function above but for a computed (e.g.,
+ // target-qualified) variable expansion. In this case we don't have a
+ // name (it's computed).
+ //
+ optional<location> computed_var_;
+
// True during pre-parsing when the pre-parse mode is temporarily
// suspended to perform expansion.
//
diff --git a/libbuild2/build/script/script.hxx b/libbuild2/build/script/script.hxx
index 0619253..d0ab139 100644
--- a/libbuild2/build/script/script.hxx
+++ b/libbuild2/build/script/script.hxx
@@ -75,9 +75,10 @@ namespace build2
// script parser for details).
//
bool depdb_clear;
+ bool depdb_value; // String or hash.
optional<size_t> depdb_dyndep; // Pos of first dyndep.
bool depdb_dyndep_byproduct = false; // dyndep --byproduct
- lines_type depdb_preamble;
+ lines_type depdb_preamble; // Note include vars.
bool depdb_preamble_temp_dir = false; // True if refs $~.
location start_loc;