From bb9512f53daa5913220282f0ad86a20d174e367c Mon Sep 17 00:00:00 2001 From: Nicolas Despres Date: Mon, 21 Sep 2015 12:01:33 +0200 Subject: Resurrect the 'rules' tool. This tool is useful for writing shell completion script for tools expecting a rule name as argument. The tool was dropped by 34b46f28c. Fix #1024. --- doc/manual.asciidoc | 3 +++ src/eval_env.cc | 14 ++++++++++++++ src/eval_env.h | 5 +++++ src/ninja.cc | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+) diff --git a/doc/manual.asciidoc b/doc/manual.asciidoc index c9309ad..7f3ab8a 100644 --- a/doc/manual.asciidoc +++ b/doc/manual.asciidoc @@ -283,6 +283,9 @@ target, show just the target's dependencies. _Available since Ninja 1.4._ `recompact`:: recompact the `.ninja_deps` file. _Available since Ninja 1.4._ +`rules`:: output the list of all rules (eventually with their description +if they have one). It can be used to know which rule name to pass to ++ninja -t targets rule _name_+ or +ninja -t compdb+. Writing your own Ninja files ---------------------------- diff --git a/src/eval_env.cc b/src/eval_env.cc index aa3d2b6..e9b6c43 100644 --- a/src/eval_env.cc +++ b/src/eval_env.cc @@ -131,3 +131,17 @@ string EvalString::Serialize() const { } return result; } + +string EvalString::Unparse() const { + string result; + for (TokenList::const_iterator i = parsed_.begin(); + i != parsed_.end(); ++i) { + bool special = (i->second == SPECIAL); + if (special) + result.append("${"); + result.append(i->first); + if (special) + result.append("}"); + } + return result; +} diff --git a/src/eval_env.h b/src/eval_env.h index 999ce42..8fb9bf4 100644 --- a/src/eval_env.h +++ b/src/eval_env.h @@ -33,8 +33,13 @@ struct Env { /// A tokenized string that contains variable references. /// Can be evaluated relative to an Env. struct EvalString { + /// @return The evaluated string with variable expanded using value found in + /// environment @a env. string Evaluate(Env* env) const; + /// @return The string with variables not expanded. + string Unparse() const; + void Clear() { parsed_.clear(); } bool empty() const { return parsed_.empty(); } diff --git a/src/ninja.cc b/src/ninja.cc index 5f19a65..a093cd1 100644 --- a/src/ninja.cc +++ b/src/ninja.cc @@ -126,6 +126,7 @@ struct NinjaMain : public BuildLogUser { int ToolCompilationDatabase(const Options* options, int argc, char* argv[]); int ToolRecompact(const Options* options, int argc, char* argv[]); int ToolUrtle(const Options* options, int argc, char** argv); + int ToolRules(const Options* options, int argc, char* argv[]); /// Open the build log. /// @return false on error. @@ -561,6 +562,55 @@ int NinjaMain::ToolTargets(const Options* options, int argc, char* argv[]) { } } +int NinjaMain::ToolRules(const Options* options, int argc, char* argv[]) { + // Parse options. + + // The rules tool uses getopt, and expects argv[0] to contain the name of + // the tool, i.e. "rules". + argc++; + argv--; + + bool print_description = false; + + optind = 1; + int opt; + while ((opt = getopt(argc, argv, const_cast("hd"))) != -1) { + switch (opt) { + case 'd': + print_description = true; + break; + case 'h': + default: + printf("usage: ninja -t rules [options]\n" + "\n" + "options:\n" + " -d also print the description of the rule\n" + " -h print this message\n" + ); + return 1; + } + } + argv += optind; + argc -= optind; + + // Print rules + + typedef map Rules; + const Rules& rules = state_.bindings_.GetRules(); + for (Rules::const_iterator i = rules.begin(); i != rules.end(); ++i) { + printf("%s", i->first.c_str()); + if (print_description) { + const Rule* rule = i->second; + const EvalString* description = rule->GetBinding("description"); + if (description != NULL) { + printf(": %s", description->Unparse().c_str()); + } + } + printf("\n"); + } + return 0; +} + enum PrintCommandMode { PCM_Single, PCM_All }; void PrintCommands(Edge* edge, set* seen, PrintCommandMode mode) { if (!edge) @@ -841,6 +891,8 @@ const Tool* ChooseTool(const string& tool_name) { Tool::RUN_AFTER_LOAD, &NinjaMain::ToolCompilationDatabase }, { "recompact", "recompacts ninja-internal data structures", Tool::RUN_AFTER_LOAD, &NinjaMain::ToolRecompact }, + { "rules", "list all rules", + Tool::RUN_AFTER_LOAD, &NinjaMain::ToolRules }, { "urtle", NULL, Tool::RUN_AFTER_FLAGS, &NinjaMain::ToolUrtle }, { NULL, NULL, Tool::RUN_AFTER_FLAGS, NULL } -- cgit v0.12