diff options
author | Nicolas Despres <nicolas.despres@gmail.com> | 2015-09-21 10:01:33 (GMT) |
---|---|---|
committer | Nicolas Despres <nicolas.despres@gmail.com> | 2019-05-09 14:36:47 (GMT) |
commit | bb9512f53daa5913220282f0ad86a20d174e367c (patch) | |
tree | f4fdf019cad3ee6dc5fce2338f144431797607a2 | |
parent | 2e64645749ff91eff2f999f03f55da360ae5913d (diff) | |
download | Ninja-bb9512f53daa5913220282f0ad86a20d174e367c.zip Ninja-bb9512f53daa5913220282f0ad86a20d174e367c.tar.gz Ninja-bb9512f53daa5913220282f0ad86a20d174e367c.tar.bz2 |
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.
-rw-r--r-- | doc/manual.asciidoc | 3 | ||||
-rw-r--r-- | src/eval_env.cc | 14 | ||||
-rw-r--r-- | src/eval_env.h | 5 | ||||
-rw-r--r-- | src/ninja.cc | 52 |
4 files changed, 74 insertions, 0 deletions
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<char*>("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<string, const Rule*> 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<Edge*>* 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 } |