diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2022-04-06 14:39:34 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2022-04-06 14:39:34 +0200 |
commit | d1f436049f0fba43ed1d5e5d8e490b7873009403 (patch) | |
tree | ac683030a61c777673be720b33482a731817295f /libbuild2/parser.cxx | |
parent | 76be0a35f6c37cda7ba65530330f1ac246fb52a8 (diff) |
Add support for specifying custom ad hoc pattern rule names
Besides diagnostics, this allows us to use name in the rule hint, for
example:
[rule_name=hello.link] exe{~'/(.*)/'}: obje{~'/\1/'}
{{
$cxx.path -o $path($>) $path($<[0])
}}
[rule_hint=hello] exe{hello}: obje{hello}
obje{hello}: c{hello-c}
Diffstat (limited to 'libbuild2/parser.cxx')
-rw-r--r-- | libbuild2/parser.cxx | 60 |
1 files changed, 53 insertions, 7 deletions
diff --git a/libbuild2/parser.cxx b/libbuild2/parser.cxx index f91e85e..c97e19e 100644 --- a/libbuild2/parser.cxx +++ b/libbuild2/parser.cxx @@ -868,9 +868,6 @@ namespace build2 // if (ns[0].pattern && ns.size () == (ns[0].pair ? 2 : 1)) { - if (!as.empty ()) - fail (as.loc) << "attributes before target type/pattern"; - name& n (ns[0]); if (n.qualified ()) @@ -936,6 +933,10 @@ namespace build2 nloc); next_after_newline (t, tt); + + if (!as.empty ()) + fail (as.loc) << "attributes before target type/pattern"; + continue; // Just a target type/pattern-specific var assignment. } @@ -987,12 +988,47 @@ namespace build2 if (!ans.empty ()) fail (ans[0].loc) << "ad hoc member in target type/pattern"; + if (!as.empty ()) + fail (as.loc) << "attributes before target type/pattern"; + continue; } } // Ok, this is an ad hoc pattern rule. // + // First process the attributes. + // + string rn; + { + const location& l (as.loc); + + for (auto& a: as) + { + const string& n (a.name); + value& v (a.value); + + // rule_name= + // + if (n == "rule_name") + { + try + { + rn = convert<string> (move (v)); + + if (rn.empty ()) + throw invalid_argument ("empty name"); + } + catch (const invalid_argument& e) + { + fail (l) << "invalid " << n << " attribute value: " << e; + } + } + else + fail (l) << "unknown ad hoc pattern rule attribute " << a; + } + } + // What should we do if we have neither prerequisites nor recipes? // While such a declaration doesn't make much sense, it can happen, // for example, with an empty variable expansion: @@ -1089,14 +1125,18 @@ namespace build2 } } - // Derive the rule name. It must be unique in this scope. + // Derive the rule name unless specified explicitly. It must be + // unique in this scope. // // It would have been nice to include the location but unless we // include the absolute path to the buildfile (which would be // unwieldy), it could be ambigous. // - string rn ("<ad hoc pattern rule #" + - to_string (scope_->adhoc_rules.size () + 1) + '>'); + // NOTE: we rely on the <...> format in dump. + // + if (rn.empty ()) + rn = "<ad hoc pattern rule #" + + to_string (scope_->adhoc_rules.size () + 1) + '>'; auto& ars (scope_->adhoc_rules); @@ -1109,7 +1149,9 @@ namespace build2 const target_type* ttype (nullptr); if (i != ars.end ()) { - // @@ TODO: append ad hoc members, prereqs. + // @@ TODO: append ad hoc members, prereqs (we now have + // [rule_name=] which we can use to reference the same + // rule). // ttype = &(*i)->type; assert (false); @@ -1711,6 +1753,10 @@ namespace build2 // location loc (get_location (st)); + // @@ We could add an attribute (name= or recipe_name=) to allow + // the user specify a friendly name for diagnostics, similar + // to rule_name. + shared_ptr<adhoc_rule> ar; if (!lang) { |