From 4f5c9357b7e17b4fb9ecaad36c8740a05cfc1bc6 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 27 Jun 2022 13:11:06 +0200 Subject: Add support for rule-specific import phase 2 For example: import! [metadata, rule_hint=cxx.link] lib = libhello%lib{hello} --- libbuild2/parser.cxx | 59 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 15 deletions(-) (limited to 'libbuild2/parser.cxx') 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[?!] [] = [] (|%])+ // bool opt (t.value.back () == '?'); - bool ph2 (opt || t.value.back () == '!'); + optional ph2 (opt || t.value.back () == '!' + ? optional (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 (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) -- cgit v1.1