From bc3c8492f129d9295c9ef6c325bf2c99e88ca73e Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 3 Jun 2020 08:39:36 +0200 Subject: Factor implementation-specific ad hoc recipe parsing to adhoc_*_rule --- libbuild2/parser.cxx | 108 +++++++++++++++++++-------------------------------- 1 file changed, 40 insertions(+), 68 deletions(-) (limited to 'libbuild2/parser.cxx') diff --git a/libbuild2/parser.cxx b/libbuild2/parser.cxx index 72d189e..65a42fe 100644 --- a/libbuild2/parser.cxx +++ b/libbuild2/parser.cxx @@ -20,9 +20,6 @@ #include #include -#include -#include - #include // lookup_config using namespace std; @@ -33,7 +30,7 @@ namespace build2 using type = token_type; ostream& - operator<< (ostream& o, const parser::attribute& a) + operator<< (ostream& o, const attribute& a) { o << a.name; @@ -1111,24 +1108,9 @@ namespace build2 else fail (t) << "expected recipe language instead of " << t; - mode (lexer_mode::foreign, '\0', st.value.size ()); - next_after_newline (t, tt, st); // Should be on its own line. - - if (tt != type::word) - { - diag_record dr; - - dr << fail (t) << "unterminated recipe "; - if (kind.empty ()) dr << "block"; else dr << kind << "-block"; - - dr << info (st) << "recipe "; - if (kind.empty ()) dr << "block"; else dr << kind << "-block"; - dr << " starts here" << endf; - } - + shared_ptr ar; if (!skip) { - shared_ptr ar; if (d.first) { // Note that this is always the location of the opening multi- @@ -1138,72 +1120,62 @@ namespace build2 // location loc (get_location (st)); - // Buildscript - // if (!lang) { - // Handle and erase recipe-specific attributes. + // Buildscript // - optional diag; - for (auto i (d.as.begin ()); i != d.as.end (); ) - { - attribute& a (*i); - const string& n (a.name); - - if (n == "diag") - try - { - diag = convert (move (a.value)); - } - catch (const invalid_argument& e) - { - fail (d.as.loc) << "invalid " << n << " attribute value: " - << e; - } - else - { - ++i; - continue; - } - - i = d.as.erase (i); - } - - auto* asr (new adhoc_script_rule (loc, st.value.size ())); - ar.reset (asr); - - asr->checksum = sha256 (t.value).string (); - - istringstream is (move (t.value)); - build::script::parser p (ctx); - asr->script = p.pre_parse ( - is, asr->loc.file, loc.line + 1, move (diag)); + ar.reset (new adhoc_script_rule (loc, st.value.size ())); } - // - // C++ - // else if (*lang == "c++") { - ar.reset (new adhoc_cxx_rule ( - move (t.value), loc, st.value.size ())); - d.clean = true; + // C++ + // + ar.reset (new adhoc_cxx_rule (loc, st.value.size ())); } else fail (lloc) << "unknown recipe language '" << *lang << "'"; - // Verify we have no unhandled attributes. - // - for (attribute& a: d.as) - fail (d.as.loc) << "unknown recipe attribute " << a << endf; - assert (d.recipes[d.i] == nullptr); d.recipes[d.i] = ar; } else { + skip_line (t, tt); + assert (d.recipes[d.i] != nullptr); ar = d.recipes[d.i]; } + } + else + skip_line (t, tt); + + mode (lexer_mode::foreign, '\0', st.value.size ()); + next_after_newline (t, tt, st); // Should be on its own line. + + if (tt != type::word) + { + diag_record dr; + + dr << fail (t) << "unterminated recipe "; + if (kind.empty ()) dr << "block"; else dr << kind << "-block"; + + dr << info (st) << "recipe "; + if (kind.empty ()) dr << "block"; else dr << kind << "-block"; + dr << " starts here" << endf; + } + + if (!skip) + { + if (d.first) + { + if (ar->recipe_text (ctx, move (t.value), d.as)) + d.clean = true; + + // Verify we have no unhandled attributes. + // + for (attribute& a: d.as) + fail (d.as.loc) << "unknown recipe attribute " << a << endf; + } target_->adhoc_recipes.push_back ( adhoc_recipe {perform_update_id, move (ar)}); -- cgit v1.1