aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2020-05-18 14:50:56 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2020-05-27 08:35:29 +0200
commit5910fbb854d7aa957091aa48a248b2de239eb558 (patch)
tree0989873ff8375ffadc07923468e86c3465dae922
parent80a9e7a52db8d686ba81beb5399c80b300ce4a96 (diff)
Integrate buildscript pre-parsing into recipe parsing
-rw-r--r--libbuild2/build/script/parser.cxx11
-rw-r--r--libbuild2/build/script/parser.hxx4
-rw-r--r--libbuild2/parser.cxx15
-rw-r--r--libbuild2/rule.cxx24
-rw-r--r--libbuild2/rule.hxx18
-rw-r--r--libbuild2/script/script.hxx2
6 files changed, 41 insertions, 33 deletions
diff --git a/libbuild2/build/script/parser.cxx b/libbuild2/build/script/parser.cxx
index d26b155..c64bcd9 100644
--- a/libbuild2/build/script/parser.cxx
+++ b/libbuild2/build/script/parser.cxx
@@ -20,8 +20,8 @@ namespace build2
// Pre-parse.
//
- void parser::
- pre_parse (istream& is, const path_name& pn, uint64_t line, script& s)
+ script parser::
+ pre_parse (istream& is, const path_name& pn, uint64_t line)
{
path_ = &pn;
@@ -30,17 +30,20 @@ namespace build2
lexer l (is, *path_, line, lexer_mode::command_line);
set_lexer (&l);
+ script s;
script_ = &s;
runner_ = nullptr;
environment_ = nullptr;
- script_->start_loc = location (*path_, line, 1);
+ s.start_loc = location (*path_, line, 1);
token t (pre_parse_script ());
assert (t.type == type::eos);
- script_->end_loc = get_location (t);
+ s.end_loc = get_location (t);
+
+ return s;
}
token parser::
diff --git a/libbuild2/build/script/parser.hxx b/libbuild2/build/script/parser.hxx
index a8ffb25..c88898b 100644
--- a/libbuild2/build/script/parser.hxx
+++ b/libbuild2/build/script/parser.hxx
@@ -30,8 +30,8 @@ namespace build2
public:
parser (context& c): build2::script::parser (c) {}
- void
- pre_parse (istream&, const path_name&, uint64_t line, script&);
+ script
+ pre_parse (istream&, const path_name&, uint64_t line);
// Recursive descent parser.
//
diff --git a/libbuild2/parser.cxx b/libbuild2/parser.cxx
index 588968e..f2cdbfd 100644
--- a/libbuild2/parser.cxx
+++ b/libbuild2/parser.cxx
@@ -20,6 +20,9 @@
#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;
@@ -1113,9 +1116,6 @@ namespace build2
fail (t) << "unterminated recipe block" <<
info (st) << "recipe block starts here" << endf;
- // @@ TODO: we need to reuse the same rules for all the targets! Kill
- // me now.
- //
shared_ptr<adhoc_rule> ar;
if (first)
{
@@ -1128,7 +1128,14 @@ namespace build2
if (!lang)
{
- ar.reset (new adhoc_script_rule (move (t.value),
+ using build::script::parser;
+ using build::script::script;
+
+ parser p (ctx);
+ istringstream is (move (t.value));
+ script s (p.pre_parse (is, path_name (loc.file), loc.line + 1));
+
+ ar.reset (new adhoc_script_rule (move (s),
move (diag),
loc,
st.value.size ()));
diff --git a/libbuild2/rule.cxx b/libbuild2/rule.cxx
index c3d8f88..849ae82 100644
--- a/libbuild2/rule.cxx
+++ b/libbuild2/rule.cxx
@@ -358,12 +358,8 @@ namespace build2
// adhoc_script_rule
//
void adhoc_script_rule::
- dump (ostream& os, const string& ind) const
+ dump (ostream& os, string& ind) const
{
- // @@ TODO: indentation is multi-line recipes is off (would need to insert
- // indentation after every newline). Maybe if we pre-parse them?
- //
-
// Do we need the header?
//
if (diag)
@@ -380,9 +376,11 @@ namespace build2
os << endl;
}
- os << ind << string (braces, '{') << endl
- << ind << code
- << ind << string (braces, '}');
+ os << ind << string (braces, '{') << endl;
+ ind += " ";
+ script::dump (os, ind, script.lines);
+ ind.resize (ind.size () - 2);
+ os << ind << string (braces, '}');
}
bool adhoc_script_rule::
@@ -505,8 +503,8 @@ namespace build2
// It feels like we need a special execute mode that instead
// of executing hashes the commands.
//
- if (dd.expect (sha256 (code).string ()) != nullptr)
- l4 ([&]{trace << "recipe change forcing update of " << t;});
+ //if (dd.expect (sha256 (code).string ()) != nullptr)
+ // l4 ([&]{trace << "recipe change forcing update of " << t;});
}
// Update if depdb mismatch.
@@ -526,8 +524,6 @@ namespace build2
//@@ TODO
//print_process (args);
-
- text << trim (string (code));
}
else if (verb)
{
@@ -570,8 +566,6 @@ namespace build2
//@@ TODO
//print_process (args);
-
- text << trim (string (code));
}
else if (verb)
{
@@ -606,7 +600,7 @@ namespace build2
}
void adhoc_cxx_rule::
- dump (ostream& os, const string& ind) const
+ dump (ostream& os, string& ind) const
{
// @@ TODO: indentation is multi-line recipes is off (would need to insert
// indentation after every newline).
diff --git a/libbuild2/rule.hxx b/libbuild2/rule.hxx
index 975dd59..8799b83 100644
--- a/libbuild2/rule.hxx
+++ b/libbuild2/rule.hxx
@@ -12,6 +12,8 @@
#include <libbuild2/target.hxx>
#include <libbuild2/recipe.hxx>
+#include <libbuild2/build/script/script.hxx>
+
#include <libbuild2/export.hxx>
namespace build2
@@ -143,7 +145,7 @@ namespace build2
match (action, target&, const string&) const override;
virtual void
- dump (ostream&, const string& indentation) const = 0;
+ dump (ostream&, string& indentation) const = 0;
// Implementation details.
//
@@ -178,16 +180,18 @@ namespace build2
default_action (action, const target&) const;
virtual void
- dump (ostream&, const string&) const override;
+ dump (ostream&, string&) const override;
+
+ using script_type = build::script::script;
- adhoc_script_rule (string c,
+ adhoc_script_rule (script_type&& s,
optional<string> d,
const location& l, size_t b)
- : adhoc_rule (l, b), code (move (c)), diag (move (d)) {}
+ : adhoc_rule (l, b), script (move (s)), diag (move (d)) {}
public:
- string code;
- optional<string> diag; // Command name for low-verbosity diagnostics.
+ const script_type script;
+ const optional<string> diag; // Command name for low-verbosity diag.
};
// Ad hoc C++ rule.
@@ -218,7 +222,7 @@ namespace build2
apply (action, target&) const override;
virtual void
- dump (ostream&, const string&) const override;
+ dump (ostream&, string&) const override;
adhoc_cxx_rule (string c, const location& l, size_t b)
: adhoc_rule (l, b), code (move (c)), impl (nullptr) {}
diff --git a/libbuild2/script/script.hxx b/libbuild2/script/script.hxx
index f02583c..ac9383c 100644
--- a/libbuild2/script/script.hxx
+++ b/libbuild2/script/script.hxx
@@ -48,7 +48,7 @@ namespace build2
//
using lines = small_vector<line, 1>;
- void
+ LIBBUILD2_SYMEXPORT void
dump (ostream&, const string& ind, const lines&);
// Parse object model.