aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2023-06-01 12:22:26 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2023-06-01 12:22:26 +0200
commit2dd1f9fa5a7427096b74aa85258ec2feeb93c104 (patch)
tree99e05e4fa8abb757f4420dbd7137e99acae48083
parent061879137a62cb905f75e35c104cff379fb95134 (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
-rw-r--r--libbuild2/target.cxx74
-rw-r--r--libbuild2/target.hxx4
2 files changed, 47 insertions, 31 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;
}
}
diff --git a/libbuild2/target.hxx b/libbuild2/target.hxx
index d01e8b7..d4ad780 100644
--- a/libbuild2/target.hxx
+++ b/libbuild2/target.hxx
@@ -1472,9 +1472,7 @@ namespace build2
}
include_type
- include (action, const target&,
- const prerequisite_member&,
- lookup* = nullptr);
+ include (action, const target&, const prerequisite_member&, lookup* = nullptr);
// A "range" that presents a sequence of prerequisites (e.g., from
// group_prerequisites()) as a sequence of prerequisite_member's. For each