From 7a458f210f296cb3cc1551a4606f0cf025003f3a Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 2 May 2023 13:05:27 +0200 Subject: Add --dump-scope and --dump-target options to limit --dump output --- libbuild2/b-options.cxx | 51 +++++++++++++++++++++++++++++----- libbuild2/b-options.hxx | 30 ++++++++++++++------ libbuild2/b-options.ixx | 30 ++++++++++++++++++-- libbuild2/b.cli | 28 ++++++++++++++----- libbuild2/dump.cxx | 40 ++++++++++++++++++--------- libbuild2/dump.hxx | 9 ++++-- libbuild2/parser.cxx | 4 +-- libbuild2/types-parsers.cxx | 67 ++++++++++++++++++++++++++++++++++++--------- libbuild2/types-parsers.hxx | 11 ++++++++ 9 files changed, 214 insertions(+), 56 deletions(-) (limited to 'libbuild2') 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>::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>>>::merge ( + this->dump_target_, a.dump_target_); + this->dump_target_specified_ = true; + } + if (a.trace_match_specified_) { - ::build2::build::cli::parser< std::vector>::merge ( + ::build2::build::cli::parser< vector>::merge ( this->trace_match_, a.trace_match_); this->trace_match_specified_ = true; } if (a.trace_execute_specified_) { - ::build2::build::cli::parser< std::vector>::merge ( + ::build2::build::cli::parser< vector>::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, &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>>, &b_options::dump_target_, + &b_options::dump_target_specified_ >; _cli_b_options_map_["--trace-match"] = - &::build2::build::cli::thunk< b_options, std::vector, &b_options::trace_match_, + &::build2::build::cli::thunk< b_options, vector, &b_options::trace_match_, &b_options::trace_match_specified_ >; _cli_b_options_map_["--trace-execute"] = - &::build2::build::cli::thunk< b_options, std::vector, &b_options::trace_execute_, + &::build2::build::cli::thunk< b_options, vector, &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 - #include namespace build2 @@ -167,19 +165,31 @@ namespace build2 const bool& no_mtime_check () const; - const std::set& + const strings& dump () const; bool dump_specified () const; - const std::vector& + const dir_paths& + dump_scope () const; + + bool + dump_scope_specified () const; + + const vector>>& + dump_target () const; + + bool + dump_target_specified () const; + + const vector& trace_match () const; bool trace_match_specified () const; - const std::vector& + const vector& trace_execute () const; bool @@ -293,11 +303,15 @@ namespace build2 bool structured_result_specified_; bool mtime_check_; bool no_mtime_check_; - std::set dump_; + strings dump_; bool dump_specified_; - std::vector trace_match_; + dir_paths dump_scope_; + bool dump_scope_specified_; + vector>> dump_target_; + bool dump_target_specified_; + vector trace_match_; bool trace_match_specified_; - std::vector trace_execute_; + vector 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& 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& 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>>& 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& b_options:: trace_match () const { return this->trace_match_; @@ -230,7 +254,7 @@ namespace build2 return this->trace_match_specified_; } - inline const std::vector& b_options:: + inline const vector& 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 ; - include ; "\section=1" @@ -774,23 +772,39 @@ namespace build2 \cb{--mtime-check} for details." } - std::set --dump + strings --dump { "", "Dump the build system state after the specified phase. Valid 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 + { + "", + "Dump the build system state for the specified scope only. Repeat this + option to dump the state of multiple scopes." + } + + vector>> --dump-target + { + "", + "Dump the build system state for the specified target only. Repeat this + option to dump the state of multiple targets." } - std::vector --trace-match + vector --trace-match { "", "Trace rule matching for the specified target. This is primarily useful during troubleshooting. Repeat this option to trace multiple targets." } - std::vector --trace-execute + vector --trace-execute { "", "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 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 << ""; + os << endl; } void - dump (const target& t, const char* cind) + dump (const target* t, optional 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 << ""; + 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 = nullopt); + dump (const context&, optional); LIBBUILD2_SYMEXPORT void - dump (const scope&, const char* ind = ""); + dump (const scope*, optional, const char* ind = ""); LIBBUILD2_SYMEXPORT void - dump (const target&, const char* ind = ""); + dump (const target*, optional, 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 << " " << 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 << " :: 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>>:: + parse (pair>& 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:: 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>> + { + static void + parse (pair>&, bool&, scanner&); + + static void + merge (pair>& b, + const pair>& a) {b = a;} + }; + + template <> struct parser { static void -- cgit v1.1