diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2022-06-27 13:11:06 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2022-06-28 11:11:55 +0200 |
commit | 4f5c9357b7e17b4fb9ecaad36c8740a05cfc1bc6 (patch) | |
tree | 1849fdadad55c5efd9ee7e19d21f3915b626c9f7 /libbuild2/parser.cxx | |
parent | f1c981a22365411794806ed0744b857ef0804e35 (diff) |
Add support for rule-specific import phase 2
For example:
import! [metadata, rule_hint=cxx.link] lib = libhello%lib{hello}
Diffstat (limited to 'libbuild2/parser.cxx')
-rw-r--r-- | libbuild2/parser.cxx | 59 |
1 files changed, 44 insertions, 15 deletions
diff --git a/libbuild2/parser.cxx b/libbuild2/parser.cxx index da20a48..1fa29f6 100644 --- a/libbuild2/parser.cxx +++ b/libbuild2/parser.cxx @@ -3378,7 +3378,9 @@ namespace build2 // import[?!] [<attrs>] <var> = [<attrs>] (<target>|<project>%<target>])+ // bool opt (t.value.back () == '?'); - bool ph2 (opt || t.value.back () == '!'); + optional<string> ph2 (opt || t.value.back () == '!' + ? optional<string> (string ()) + : nullopt); // We are now in the normal lexing mode and we let the lexer handle `=`. // @@ -3389,26 +3391,53 @@ namespace build2 // we handle it in an ad hoc manner. // attributes_push (t, tt); - attributes& as (attributes_top ()); bool meta (false); - for (auto i (as.begin ()); i != as.end (); ) { - if (i->name == "metadata") - { - if (!ph2) - fail (as.loc) << "loading metadata requires immediate import" << - info << "consider using the import! directive instead"; + attributes& as (attributes_top ()); + const location& l (as.loc); - meta = true; - } - else + for (auto i (as.begin ()); i != as.end (); ) { - ++i; - continue; - } + const string& n (i->name); + value& v (i->value); - i = as.erase (i); + if (n == "metadata") + { + if (!ph2) + fail (l) << "loading metadata requires immediate import" << + info << "consider using the import! directive instead"; + + meta = true; + } + else if (n == "rule_hint") + { + if (!ph2) + fail (l) << "rule hint can only be used with immediate import" << + info << "consider using the import! directive instead"; + + // Here we only allow a single name. + // + try + { + ph2 = convert<string> (move (v)); + + if (ph2->empty ()) + throw invalid_argument ("empty name"); + } + catch (const invalid_argument& e) + { + fail (l) << "invalid " << n << " attribute value: " << e; + } + } + else + { + ++i; + continue; + } + + i = as.erase (i); + } } if (tt != type::word) |