aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/parser.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2020-06-03 08:39:36 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2020-06-03 08:39:36 +0200
commitbc3c8492f129d9295c9ef6c325bf2c99e88ca73e (patch)
tree79fa0ccfbf030568caa2d521f3bc3dbc613d4796 /libbuild2/parser.cxx
parent7368566619bc990b69f90a4828be2966854fa785 (diff)
Factor implementation-specific ad hoc recipe parsing to adhoc_*_rule
Diffstat (limited to 'libbuild2/parser.cxx')
-rw-r--r--libbuild2/parser.cxx108
1 files changed, 40 insertions, 68 deletions
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 <libbuild2/diagnostics.hxx>
#include <libbuild2/prerequisite.hxx>
-#include <libbuild2/build/script/parser.hxx>
-#include <libbuild2/build/script/script.hxx>
-
#include <libbuild2/config/utility.hxx> // 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<adhoc_rule> ar;
if (!skip)
{
- shared_ptr<adhoc_rule> 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<string> 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<string> (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)});