diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2023-06-01 12:22:26 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2023-06-01 12:22:26 +0200 |
commit | 2dd1f9fa5a7427096b74aa85258ec2feeb93c104 (patch) | |
tree | 99e05e4fa8abb757f4420dbd7137e99acae48083 /libbuild2/target.cxx | |
parent | 061879137a62cb905f75e35c104cff379fb95134 (diff) |
Diagnose null include, operation-specific variable values
While assigning null directly is unlikely, it's fairly easy via a variable
expansion. Real-world example:
./: exe{tensor}: include = $config.Eigen.unsupported
Diffstat (limited to 'libbuild2/target.cxx')
-rw-r--r-- | libbuild2/target.cxx | 74 |
1 files changed, 46 insertions, 28 deletions
diff --git a/libbuild2/target.cxx b/libbuild2/target.cxx index 6b2c702..4634688 100644 --- a/libbuild2/target.cxx +++ b/libbuild2/target.cxx @@ -566,16 +566,25 @@ namespace build2 context& ctx (t.ctx); include_type r (include_type::normal); - - if (const string* v = cast_null<string> (p.vars[ctx.var_include])) { - if (*v == "false") r = include_type::excluded; - else if (*v == "true") r = include_type::normal; - else if (*v == "adhoc") r = include_type::adhoc; - else if (*v == "posthoc") r = include_type::posthoc; - else - fail << "invalid " << *ctx.var_include << " variable value " - << "'" << *v << "' specified for prerequisite " << p; + lookup l (p.vars[ctx.var_include]); + + if (l.defined ()) + { + if (l->null) + fail << "null " << *ctx.var_include << " variable value specified " + << "for prerequisite " << p; + + const string& v (cast<string> (*l)); + + if (v == "false") r = include_type::excluded; + else if (v == "true") r = include_type::normal; + else if (v == "adhoc") r = include_type::adhoc; + else if (v == "posthoc") r = include_type::posthoc; + else + fail << "invalid " << *ctx.var_include << " variable value '" + << v << "' specified for prerequisite " << p; + } } // Handle operation-specific override (see var_include documentation @@ -601,31 +610,40 @@ namespace build2 ? ctx.current_outer_oif : ctx.current_inner_oif)->id].ovar; - if (ovar != nullptr && (l = p.vars[*ovar])) + if (ovar != nullptr) { - // Maybe we should optimize this for the common cases (bool, path, - // name)? But then again we don't expect many such overrides. Plus - // will complicate the diagnostics below. - // - ns = reverse (*l, storage, true /* reduce */); + l = p.vars[*ovar]; - if (ns.size () == 1) + if (l.defined ()) { - const name& n (ns[0]); + if (l->null) + fail << "null " << *ovar << " variable value specified for " + << "prerequisite " << p; + + // Maybe we should optimize this for the common cases (bool, path, + // name)? But then again we don't expect many such overrides. Plus + // will complicate the diagnostics below. + // + ns = reverse (*l, storage, true /* reduce */); - if (n.simple ()) + if (ns.size () == 1) { - const string& v (n.value); + const name& n (ns[0]); - if (v == "false") - r1 = false; - else if (v == "true") - r1 = true; + if (n.simple ()) + { + const string& v (n.value); + + if (v == "false") + r1 = false; + else if (v == "true") + r1 = true; + } } - } - if (r1 && !*r1) - r = include_type::excluded; + if (r1 && !*r1) + r = include_type::excluded; + } } } @@ -646,8 +664,8 @@ namespace build2 // Note: we have to delay this until the meta-operation callback above // had a chance to override it. // - fail << "unrecognized " << *ovar << " variable value " - << "'" << ns << "' specified for prerequisite " << p; + fail << "unrecognized " << *ovar << " variable value '" << ns + << "' specified for prerequisite " << p; } } |