aboutsummaryrefslogtreecommitdiff
path: root/libbuild2
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2023-05-02 13:05:27 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2023-05-03 05:03:20 +0200
commit7a458f210f296cb3cc1551a4606f0cf025003f3a (patch)
tree71b20a6c67fb9b6801916406391c34e6710c3c2e /libbuild2
parentf66848dbd677b1027bade5728e04954c313231af (diff)
Add --dump-scope and --dump-target options to limit --dump output
Diffstat (limited to 'libbuild2')
-rw-r--r--libbuild2/b-options.cxx51
-rw-r--r--libbuild2/b-options.hxx30
-rw-r--r--libbuild2/b-options.ixx30
-rw-r--r--libbuild2/b.cli28
-rw-r--r--libbuild2/dump.cxx40
-rw-r--r--libbuild2/dump.hxx9
-rw-r--r--libbuild2/parser.cxx4
-rw-r--r--libbuild2/types-parsers.cxx67
-rw-r--r--libbuild2/types-parsers.hxx11
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