refactoring: decompose CollectTargetsFromArgs
authorMaxim Kalaev <maximk@il.ibm.com>
Fri, 9 Nov 2012 07:20:05 +0000 (09:20 +0200)
committerMaxim Kalaev <maximk@il.ibm.com>
Fri, 9 Nov 2012 13:08:32 +0000 (15:08 +0200)
src/ninja.cc

index e408ce1..7869774 100644 (file)
@@ -168,6 +168,50 @@ bool RebuildManifest(Builder* builder, const char* input_file, string* err) {
   return node->dirty();
 }
 
+Node* CollectTarget(State* state, const char* cpath, string* err) {
+  string path = cpath;
+  if (!CanonicalizePath(&path, err))
+    return NULL;
+
+  // Special syntax: "foo.cc^" means "the first output of foo.cc".
+  bool first_dependent = false;
+  if (!path.empty() && path[path.size() - 1] == '^') {
+    path.resize(path.size() - 1);
+    first_dependent = true;
+  }
+
+  Node* node = state->LookupNode(path);
+  if (node) {
+    if (first_dependent) {
+      if (node->out_edges().empty()) {
+        *err = "'" + path + "' has no out edge";
+        return false;
+      }
+      Edge* edge = node->out_edges()[0];
+      if (edge->outputs_.empty()) {
+        edge->Dump();
+        Fatal("edge has no outputs");
+      }
+      node = edge->outputs_[0];
+    }
+    return node;
+  } else {
+    *err = "unknown target '" + path + "'";
+
+    if (path == "clean") {
+      *err += ", did you mean 'ninja -t clean'?";
+    } else if (path == "help") {
+      *err += ", did you mean 'ninja -h'?";
+    } else {
+      Node* suggestion = state->SpellcheckNode(path);
+      if (suggestion) {
+        *err += ", did you mean '" + suggestion->path() + "'?";
+      }
+    }
+    return NULL;
+  }
+}
+
 bool CollectTargetsFromArgs(State* state, int argc, char* argv[],
                             vector<Node*>* targets, string* err) {
   if (argc == 0) {
@@ -176,47 +220,10 @@ bool CollectTargetsFromArgs(State* state, int argc, char* argv[],
   }
 
   for (int i = 0; i < argc; ++i) {
-    string path = argv[i];
-    if (!CanonicalizePath(&path, err))
-      return false;
-
-    // Special syntax: "foo.cc^" means "the first output of foo.cc".
-    bool first_dependent = false;
-    if (!path.empty() && path[path.size() - 1] == '^') {
-      path.resize(path.size() - 1);
-      first_dependent = true;
-    }
-
-    Node* node = state->LookupNode(path);
-    if (node) {
-      if (first_dependent) {
-        if (node->out_edges().empty()) {
-          *err = "'" + path + "' has no out edge";
-          return false;
-        }
-        Edge* edge = node->out_edges()[0];
-        if (edge->outputs_.empty()) {
-          edge->Dump();
-          Fatal("edge has no outputs");
-        }
-        node = edge->outputs_[0];
-      }
-      targets->push_back(node);
-    } else {
-      *err = "unknown target '" + path + "'";
-
-      if (path == "clean") {
-        *err += ", did you mean 'ninja -t clean'?";
-      } else if (path == "help") {
-        *err += ", did you mean 'ninja -h'?";
-      } else {
-        Node* suggestion = state->SpellcheckNode(path);
-        if (suggestion) {
-          *err += ", did you mean '" + suggestion->path() + "'?";
-        }
-      }
+    Node* node = CollectTarget(state, argv[i], err);
+    if (node == NULL)
       return false;
-    }
+    targets->push_back(node);
   }
   return true;
 }
@@ -244,19 +251,14 @@ int ToolQuery(Globals* globals, int argc, char* argv[]) {
     return 1;
   }
   for (int i = 0; i < argc; ++i) {
-    Node* node = globals->state->LookupNode(argv[i]);
+    string err;
+    Node* node = CollectTarget(globals->state, argv[i], &err);
     if (!node) {
-      Node* suggestion = globals->state->SpellcheckNode(argv[i]);
-      if (suggestion) {
-        printf("%s unknown, did you mean %s?\n",
-               argv[i], suggestion->path().c_str());
-      } else {
-        printf("%s unknown\n", argv[i]);
-      }
+      Error("%s", err.c_str());
       return 1;
     }
 
-    printf("%s:\n", argv[i]);
+    printf("%s:\n", node->path().c_str());
     if (Edge* edge = node->in_edge()) {
       printf("  input: %s\n", edge->rule_->name().c_str());
       for (int in = 0; in < (int)edge->inputs_.size(); in++) {