diff options
Diffstat (limited to 'libbuild2/build/script/parser.cxx')
-rw-r--r-- | libbuild2/build/script/parser.cxx | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/libbuild2/build/script/parser.cxx b/libbuild2/build/script/parser.cxx index 04a257f..9b9f324 100644 --- a/libbuild2/build/script/parser.cxx +++ b/libbuild2/build/script/parser.cxx @@ -5,6 +5,7 @@ #include <libbutl/builtin.mxx> +#include <libbuild2/function.hxx> #include <libbuild2/algorithm.hxx> #include <libbuild2/build/script/lexer.hxx> @@ -26,7 +27,7 @@ namespace build2 // script parser:: - pre_parse (const target& tg, const adhoc_actions& acts, + pre_parse (const target& tg, const adhoc_actions& as, istream& is, const path_name& pn, uint64_t line, optional<string> diag, const location& diag_loc) { @@ -40,12 +41,15 @@ namespace build2 // The script shouldn't be able to modify the target/scopes. // target_ = const_cast<target*> (&tg); - actions_ = &acts; + actions_ = &as; scope_ = const_cast<scope*> (&tg.base_scope ()); root_ = scope_->root_scope (); pbase_ = scope_->src_path_; + perform_update_ = find (as.begin (), as.end (), perform_update_id) != + as.end (); + script s; script_ = &s; runner_ = nullptr; @@ -65,6 +69,15 @@ namespace build2 s.end_loc = get_location (t); + // Diagnose impure function calls. + // + if (impure_func_) + fail (impure_func_->second) + << "call to impure function " << impure_func_->first << " is " + << "only allowed in depdb preamble" << + info << "consider using 'depdb' builtin to track its result " + << "changes"; + // Diagnose absent/ambigous script name. // { @@ -538,6 +551,11 @@ namespace build2 script_->body_temp_dir = false; } + // Reset the impure function call info since it's valid for the + // depdb preamble. + // + impure_func_ = nullopt; + // Instruct the parser to save the depdb builtin line separately // from the script lines, when it is fully parsed. Note that the // builtin command arguments will be validated during execution, @@ -1164,6 +1182,18 @@ namespace build2 return r; } + + void parser:: + lookup_function (string&& name, const location& loc) + { + if (perform_update_ && !impure_func_) + { + const function_overloads* f (ctx.functions.find (name)); + + if (f != nullptr && !f->pure) + impure_func_ = make_pair (move (name), loc); + } + } } } } |