diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2023-05-02 13:05:27 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2023-05-03 05:03:20 +0200 |
commit | 7a458f210f296cb3cc1551a4606f0cf025003f3a (patch) | |
tree | 71b20a6c67fb9b6801916406391c34e6710c3c2e /libbuild2 | |
parent | f66848dbd677b1027bade5728e04954c313231af (diff) |
Add --dump-scope and --dump-target options to limit --dump output
Diffstat (limited to 'libbuild2')
-rw-r--r-- | libbuild2/b-options.cxx | 51 | ||||
-rw-r--r-- | libbuild2/b-options.hxx | 30 | ||||
-rw-r--r-- | libbuild2/b-options.ixx | 30 | ||||
-rw-r--r-- | libbuild2/b.cli | 28 | ||||
-rw-r--r-- | libbuild2/dump.cxx | 40 | ||||
-rw-r--r-- | libbuild2/dump.hxx | 9 | ||||
-rw-r--r-- | libbuild2/parser.cxx | 4 | ||||
-rw-r--r-- | libbuild2/types-parsers.cxx | 67 | ||||
-rw-r--r-- | libbuild2/types-parsers.hxx | 11 |
9 files changed, 214 insertions, 56 deletions
diff --git a/libbuild2/b-options.cxx b/libbuild2/b-options.cxx index 9cdfd1b..1fbc5d9 100644 --- a/libbuild2/b-options.cxx +++ b/libbuild2/b-options.cxx @@ -361,6 +361,10 @@ namespace build2 no_mtime_check_ (), dump_ (), dump_specified_ (false), + dump_scope_ (), + dump_scope_specified_ (false), + dump_target_ (), + dump_target_specified_ (false), trace_match_ (), trace_match_specified_ (false), trace_execute_ (), @@ -609,21 +613,35 @@ namespace build2 if (a.dump_specified_) { - ::build2::build::cli::parser< std::set<string>>::merge ( + ::build2::build::cli::parser< strings>::merge ( this->dump_, a.dump_); this->dump_specified_ = true; } + if (a.dump_scope_specified_) + { + ::build2::build::cli::parser< dir_paths>::merge ( + this->dump_scope_, a.dump_scope_); + this->dump_scope_specified_ = true; + } + + if (a.dump_target_specified_) + { + ::build2::build::cli::parser< vector<pair<name, optional<name>>>>::merge ( + this->dump_target_, a.dump_target_); + this->dump_target_specified_ = true; + } + if (a.trace_match_specified_) { - ::build2::build::cli::parser< std::vector<name>>::merge ( + ::build2::build::cli::parser< vector<name>>::merge ( this->trace_match_, a.trace_match_); this->trace_match_specified_ = true; } if (a.trace_execute_specified_) { - ::build2::build::cli::parser< std::vector<name>>::merge ( + ::build2::build::cli::parser< vector<name>>::merge ( this->trace_execute_, a.trace_execute_); this->trace_execute_specified_ = true; } @@ -958,7 +976,20 @@ namespace build2 << "\033[1m--dump\033[0m \033[4mphase\033[0m Dump the build system state after the specified phase." << ::std::endl << " Valid \033[4mphase\033[0m values are \033[1mload\033[0m (after loading \033[1mbuildfiles\033[0m)" << ::std::endl << " and \033[1mmatch\033[0m (after matching rules to targets). Repeat" << ::std::endl - << " this option to dump the state after multiple phases." << ::std::endl; + << " this option to dump the state after multiple phases. By" << ::std::endl + << " default the entire build state is dumped but this" << ::std::endl + << " behavior can be altered with the --dump-scope\033[0m and" << ::std::endl + << " \033[1m--dump-target\033[0m options." << ::std::endl; + + os << std::endl + << "\033[1m--dump-scope\033[0m \033[4mdir\033[0m Dump the build system state for the specified scope" << ::std::endl + << " only. Repeat this option to dump the state of multiple" << ::std::endl + << " scopes." << ::std::endl; + + os << std::endl + << "\033[1m--dump-target\033[0m \033[4mtarget\033[0m Dump the build system state for the specified target" << ::std::endl + << " only. Repeat this option to dump the state of multiple" << ::std::endl + << " targets." << ::std::endl; os << std::endl << "\033[1m--trace-match\033[0m \033[4mtarget\033[0m Trace rule matching for the specified target. This is" << ::std::endl @@ -1135,13 +1166,19 @@ namespace build2 _cli_b_options_map_["--no-mtime-check"] = &::build2::build::cli::thunk< b_options, &b_options::no_mtime_check_ >; _cli_b_options_map_["--dump"] = - &::build2::build::cli::thunk< b_options, std::set<string>, &b_options::dump_, + &::build2::build::cli::thunk< b_options, strings, &b_options::dump_, &b_options::dump_specified_ >; + _cli_b_options_map_["--dump-scope"] = + &::build2::build::cli::thunk< b_options, dir_paths, &b_options::dump_scope_, + &b_options::dump_scope_specified_ >; + _cli_b_options_map_["--dump-target"] = + &::build2::build::cli::thunk< b_options, vector<pair<name, optional<name>>>, &b_options::dump_target_, + &b_options::dump_target_specified_ >; _cli_b_options_map_["--trace-match"] = - &::build2::build::cli::thunk< b_options, std::vector<name>, &b_options::trace_match_, + &::build2::build::cli::thunk< b_options, vector<name>, &b_options::trace_match_, &b_options::trace_match_specified_ >; _cli_b_options_map_["--trace-execute"] = - &::build2::build::cli::thunk< b_options, std::vector<name>, &b_options::trace_execute_, + &::build2::build::cli::thunk< b_options, vector<name>, &b_options::trace_execute_, &b_options::trace_execute_specified_ >; _cli_b_options_map_["--no-column"] = &::build2::build::cli::thunk< b_options, &b_options::no_column_ >; diff --git a/libbuild2/b-options.hxx b/libbuild2/b-options.hxx index d965ff6..9afef25 100644 --- a/libbuild2/b-options.hxx +++ b/libbuild2/b-options.hxx @@ -13,8 +13,6 @@ // // End prologue. -#include <set> - #include <libbuild2/common-options.hxx> namespace build2 @@ -167,19 +165,31 @@ namespace build2 const bool& no_mtime_check () const; - const std::set<string>& + const strings& dump () const; bool dump_specified () const; - const std::vector<name>& + const dir_paths& + dump_scope () const; + + bool + dump_scope_specified () const; + + const vector<pair<name, optional<name>>>& + dump_target () const; + + bool + dump_target_specified () const; + + const vector<name>& trace_match () const; bool trace_match_specified () const; - const std::vector<name>& + const vector<name>& trace_execute () const; bool @@ -293,11 +303,15 @@ namespace build2 bool structured_result_specified_; bool mtime_check_; bool no_mtime_check_; - std::set<string> dump_; + strings dump_; bool dump_specified_; - std::vector<name> trace_match_; + dir_paths dump_scope_; + bool dump_scope_specified_; + vector<pair<name, optional<name>>> dump_target_; + bool dump_target_specified_; + vector<name> trace_match_; bool trace_match_specified_; - std::vector<name> trace_execute_; + vector<name> trace_execute_; bool trace_execute_specified_; bool no_column_; bool no_line_; diff --git a/libbuild2/b-options.ixx b/libbuild2/b-options.ixx index cdbbc3a..d19edb8 100644 --- a/libbuild2/b-options.ixx +++ b/libbuild2/b-options.ixx @@ -206,7 +206,7 @@ namespace build2 return this->no_mtime_check_; } - inline const std::set<string>& b_options:: + inline const strings& b_options:: dump () const { return this->dump_; @@ -218,7 +218,31 @@ namespace build2 return this->dump_specified_; } - inline const std::vector<name>& b_options:: + inline const dir_paths& b_options:: + dump_scope () const + { + return this->dump_scope_; + } + + inline bool b_options:: + dump_scope_specified () const + { + return this->dump_scope_specified_; + } + + inline const vector<pair<name, optional<name>>>& b_options:: + dump_target () const + { + return this->dump_target_; + } + + inline bool b_options:: + dump_target_specified () const + { + return this->dump_target_specified_; + } + + inline const vector<name>& b_options:: trace_match () const { return this->trace_match_; @@ -230,7 +254,7 @@ namespace build2 return this->trace_match_specified_; } - inline const std::vector<name>& b_options:: + inline const vector<name>& b_options:: trace_execute () const { return this->trace_execute_; diff --git a/libbuild2/b.cli b/libbuild2/b.cli index 5d6ead2..768bcd0 100644 --- a/libbuild2/b.cli +++ b/libbuild2/b.cli @@ -1,8 +1,6 @@ // file : libbuild2/b.cli // license : MIT; see accompanying LICENSE file -include <set>; - include <libbuild2/common.cli>; "\section=1" @@ -774,23 +772,39 @@ namespace build2 \cb{--mtime-check} for details." } - std::set<string> --dump + strings --dump { "<phase>", "Dump the build system state after the specified phase. Valid <phase> values are \cb{load} (after loading \cb{buildfiles}) and \cb{match} - (after matching rules to targets). Repeat this option to dump the - state after multiple phases." + (after matching rules to targets). Repeat this option to dump the state + after multiple phases. By default the entire build state is dumped but + this behavior can be altered with the \c{--dump-scope} and + \cb{--dump-target} options." + } + + dir_paths --dump-scope + { + "<dir>", + "Dump the build system state for the specified scope only. Repeat this + option to dump the state of multiple scopes." + } + + vector<pair<name, optional<name>>> --dump-target + { + "<target>", + "Dump the build system state for the specified target only. Repeat this + option to dump the state of multiple targets." } - std::vector<name> --trace-match + vector<name> --trace-match { "<target>", "Trace rule matching for the specified target. This is primarily useful during troubleshooting. Repeat this option to trace multiple targets." } - std::vector<name> --trace-execute + vector<name> --trace-execute { "<target>", "Trace rule execution for the specified target. This is primarily useful diff --git a/libbuild2/dump.cxx b/libbuild2/dump.cxx index 4ee75ee..e00d1b9 100644 --- a/libbuild2/dump.cxx +++ b/libbuild2/dump.cxx @@ -651,29 +651,43 @@ namespace build2 } void - dump (const scope& s, const char* cind) + dump (const scope* s, optional<action> a, const char* cind) { - const scope_map& m (s.ctx.scopes); - auto i (m.find_exact (s.out_path ())); - assert (i != m.end () && i->second.front () == &s); - string ind (cind); ostream& os (*diag_stream); - dump_scope (nullopt /* action */, os, ind, i, false /* relative */); + + if (s != nullptr) + { + const scope_map& m (s->ctx.scopes); + auto i (m.find_exact (s->out_path ())); + assert (i != m.end () && i->second.front () == s); + + dump_scope (a, os, ind, i, false /* relative */); + } + else + os << ind << "<no known scope to dump>"; + os << endl; } void - dump (const target& t, const char* cind) + dump (const target* t, optional<action> a, const char* cind) { string ind (cind); ostream& os (*diag_stream); - dump_target (nullopt /* action */, - os, - ind, - t, - t.base_scope (), - false /* relative */); + + if (t != nullptr) + { + dump_target (a, + os, + ind, + *t, + t->base_scope (), + false /* relative */); + } + else + os << ind << "<no known target to dump>"; + os << endl; } } diff --git a/libbuild2/dump.hxx b/libbuild2/dump.hxx index 6ec6944..4e08634 100644 --- a/libbuild2/dump.hxx +++ b/libbuild2/dump.hxx @@ -18,14 +18,17 @@ namespace build2 // rules have been matched for this action and dump action-specific // information (like rule-specific variables). // + // If scope or target is NULL, then assume not found and write a format- + // appropriate indication. + // LIBBUILD2_SYMEXPORT void - dump (const context&, optional<action> = nullopt); + dump (const context&, optional<action>); LIBBUILD2_SYMEXPORT void - dump (const scope&, const char* ind = ""); + dump (const scope*, optional<action>, const char* ind = ""); LIBBUILD2_SYMEXPORT void - dump (const target&, const char* ind = ""); + dump (const target*, optional<action>, const char* ind = ""); } #endif // LIBBUILD2_DUMP_HXX diff --git a/libbuild2/parser.cxx b/libbuild2/parser.cxx index 0b8fb42..6f212da 100644 --- a/libbuild2/parser.cxx +++ b/libbuild2/parser.cxx @@ -4703,7 +4703,7 @@ namespace build2 if (ns.empty ()) { if (scope_ != nullptr) - dump (*scope_, " "); // Indent two spaces. + dump (scope_, nullopt /* action */, " "); // Indent two spaces. else os << " <no current scope>" << endl; } @@ -4722,7 +4722,7 @@ namespace build2 const target* t (enter_target::find_target (*this, n, o, l, trace)); if (t != nullptr) - dump (*t, " "); // Indent two spaces. + dump (t, nullopt /* action */, " "); // Indent two spaces. else { os << " <no target " << n; diff --git a/libbuild2/types-parsers.cxx b/libbuild2/types-parsers.cxx index d220541..9c3dc52 100644 --- a/libbuild2/types-parsers.cxx +++ b/libbuild2/types-parsers.cxx @@ -52,6 +52,24 @@ namespace build2 parse_path (x, s); } + static names + parse_names (const char* o, const char* v) + { + using build2::parser; + using std::istringstream; + + istringstream is (v); + is.exceptions (istringstream::failbit | istringstream::badbit); + + // @@ TODO: currently this issues diagnostics to diag_stream. + // Perhaps we should redirect it? Also below. + // + path_name in (o); + lexer l (is, in, 1 /* line */, "\'\"\\$("); // Effective. + parser p (nullptr); + return p.parse_names (l, nullptr, parser::pattern_mode::preserve); + } + void parser<name>:: parse (name& x, bool& xs, scanner& s) { @@ -64,19 +82,7 @@ namespace build2 try { - using build2::parser; - using std::istringstream; - - istringstream is (v); - is.exceptions (istringstream::failbit | istringstream::badbit); - - // @@ TODO: currently this issues diagnostics to diag_stream. - // Perhaps we should redirect it? - // - path_name in (o); - lexer l (is, in, 1 /* line */, "\'\"\\$("); // Effective. - parser p (nullptr); - names r (p.parse_names (l, nullptr, parser::pattern_mode::preserve)); + names r (parse_names (o, v)); if (r.size () != 1) throw invalid_value (o, v); @@ -90,6 +96,41 @@ namespace build2 } } + void parser<pair<name, optional<name>>>:: + parse (pair<name, optional<name>>& x, bool& xs, scanner& s) + { + const char* o (s.next ()); + + if (!s.more ()) + throw missing_value (o); + + const char* v (s.next ()); + + try + { + names r (parse_names (o, v)); + + if (r.size () == 1) + { + x.first = move (r.front ()); + x.second = nullopt; + } + else if (r.size () == 2 && r.front ().pair == '@') + { + x.first = move (r.front ()); + x.second = move (r.back ()); + } + else + throw invalid_value (o, v); + + xs = true; + } + catch (const failed&) + { + throw invalid_value (o, v); + } + } + void parser<structured_result_format>:: parse (structured_result_format& x, bool& xs, scanner& s) { diff --git a/libbuild2/types-parsers.hxx b/libbuild2/types-parsers.hxx index ebd2a02..42fc60d 100644 --- a/libbuild2/types-parsers.hxx +++ b/libbuild2/types-parsers.hxx @@ -54,6 +54,17 @@ namespace build2 }; template <> + struct parser<pair<name, optional<name>>> + { + static void + parse (pair<name, optional<name>>&, bool&, scanner&); + + static void + merge (pair<name, optional<name>>& b, + const pair<name, optional<name>>& a) {b = a;} + }; + + template <> struct parser<structured_result_format> { static void |