diff options
author | Evan Martin <martine@danga.com> | 2012-09-05 01:41:13 (GMT) |
---|---|---|
committer | Evan Martin <martine@danga.com> | 2012-09-05 01:41:13 (GMT) |
commit | d6ff278e22c3392704eec71250584e21966534fe (patch) | |
tree | 1a3621783960cf8071a17f6b2268e7e5e189d51f | |
parent | d442b1c850236bde6e7a206d22c3a295744393ad (diff) | |
download | Ninja-d6ff278e22c3392704eec71250584e21966534fe.zip Ninja-d6ff278e22c3392704eec71250584e21966534fe.tar.gz Ninja-d6ff278e22c3392704eec71250584e21966534fe.tar.bz2 |
rearrange tool-picking logic
Now "ninja -t list" works from any directory.
-rw-r--r-- | src/ninja.cc | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/src/ninja.cc b/src/ninja.cc index 8d1c710..d194699 100644 --- a/src/ninja.cc +++ b/src/ninja.cc @@ -69,6 +69,9 @@ struct Globals { State* state; }; +/// The type of functions that are the entry points to tools (subcommands). +typedef int (*ToolFunc)(Globals*, int, char**); + /// Print usage information. void Usage(const BuildConfig& config) { fprintf(stderr, @@ -491,13 +494,14 @@ void ToolUrtle() { } } -int RunTool(const string& tool, Globals* globals, int argc, char** argv) { - typedef int (*ToolFunc)(Globals*, int, char**); - struct Tool { +/// Find the function to execute for \a tool_name and return it via \a func. +/// If there is no tool to run (e.g.: unknown tool), returns an exit code. +int ChooseTool(const string& tool_name, ToolFunc* func) { + const struct Tool { const char* name; const char* desc; ToolFunc func; - } tools[] = { + } kTools[] = { #if !defined(_WIN32) && !defined(NINJA_BOOTSTRAP) { "browse", "browse dependency graph in a web browser", ToolBrowse }, @@ -517,30 +521,33 @@ int RunTool(const string& tool, Globals* globals, int argc, char** argv) { { NULL, NULL, NULL } }; - if (tool == "list") { + if (tool_name == "list") { printf("ninja subtools:\n"); - for (int i = 0; tools[i].name; ++i) { - printf("%10s %s\n", tools[i].name, tools[i].desc); + for (const Tool* tool = &kTools[0]; tool->name; ++tool) { + printf("%10s %s\n", tool->name, tool->desc); } return 0; - } else if (tool == "urtle") { + } else if (tool_name == "urtle") { ToolUrtle(); return 0; } - for (int i = 0; tools[i].name; ++i) { - if (tool == tools[i].name) - return tools[i].func(globals, argc, argv); + for (const Tool* tool = &kTools[0]; tool->name; ++tool) { + if (tool->name == tool_name) { + *func = tool->func; + return 0; + } } vector<const char*> words; - for (int i = 0; tools[i].name; ++i) - words.push_back(tools[i].name); - const char* suggestion = SpellcheckStringV(tool, words); + for (const Tool* tool = &kTools[0]; tool->name; ++tool) + words.push_back(tool->name); + const char* suggestion = SpellcheckStringV(tool_name, words); if (suggestion) { - Error("unknown tool '%s', did you mean '%s'?", tool.c_str(), suggestion); + Error("unknown tool '%s', did you mean '%s'?", + tool_name.c_str(), suggestion); } else { - Error("unknown tool '%s'", tool.c_str()); + Error("unknown tool '%s'", tool_name.c_str()); } return 1; } @@ -708,6 +715,15 @@ int NinjaMain(int argc, char** argv) { argv += optind; argc -= optind; + // If specified, select a tool as early as possible, so commands like + // -t list can succeed before we attempt to load build.ninja etc. + ToolFunc tool_func = NULL; + if (!tool.empty()) { + int exit_code = ChooseTool(tool, &tool_func); + if (!tool_func) + return exit_code; + } + if (working_dir) { // The formatting of this string, complete with funny quotes, is // so Emacs can properly identify that the cwd has changed for @@ -733,8 +749,11 @@ reload: return 1; } - if (!tool.empty()) - return RunTool(tool, &globals, argc, argv); + // TODO: some tools want to run before we load the above manifest. + // A tool probably needs to be able to specify where in the startup + // process it runs. + if (tool_func) + return tool_func(&globals, argc, argv); BuildLog build_log; |