From 5910fbb854d7aa957091aa48a248b2de239eb558 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 18 May 2020 14:50:56 +0200 Subject: Integrate buildscript pre-parsing into recipe parsing --- libbuild2/build/script/parser.cxx | 11 +++++++---- libbuild2/build/script/parser.hxx | 4 ++-- libbuild2/parser.cxx | 15 +++++++++++---- libbuild2/rule.cxx | 24 +++++++++--------------- libbuild2/rule.hxx | 18 +++++++++++------- libbuild2/script/script.hxx | 2 +- 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 #include +#include +#include + #include // 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 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 #include +#include + #include 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 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 diag; // Command name for low-verbosity diagnostics. + const script_type script; + const optional 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; - void + LIBBUILD2_SYMEXPORT void dump (ostream&, const string& ind, const lines&); // Parse object model. -- cgit v1.1