basic plan
authorEvan Martin <martine@danga.com>
Fri, 15 Oct 2010 06:40:26 +0000 (23:40 -0700)
committerEvan Martin <martine@danga.com>
Fri, 15 Oct 2010 06:40:26 +0000 (23:40 -0700)
ninja.h
ninja_test.cc

diff --git a/ninja.h b/ninja.h
index f17d336..70c82d0 100644 (file)
--- a/ninja.h
+++ b/ninja.h
@@ -1,5 +1,7 @@
 #include <algorithm>
 #include <map>
+#include <queue>
+#include <set>
 #include <string>
 #include <vector>
 
@@ -132,3 +134,50 @@ void State::AddInOut(Edge* edge, Edge::InOut inout, const string& path) {
     node->in_edge_ = edge;
   }
 }
+
+struct Plan {
+  Plan(State* state) : state_(state) {}
+
+  void AddTarget(const string& path);
+  bool AddTarget(Node* node);
+
+  Edge* FindWork();
+
+  State* state_;
+  set<Node*> want_;
+  queue<Edge*> ready_;
+};
+
+void Plan::AddTarget(const string& path) {
+  AddTarget(state_->GetNode(path));
+}
+bool Plan::AddTarget(Node* node) {
+  if (!node->dirty())
+    return false;
+  Edge* edge = node->in_edge_;
+  if (!edge) {
+    // TODO: if file doesn't exist we should die here.
+    return false;
+  }
+
+  want_.insert(node);
+
+  bool awaiting_inputs = false;
+  for (vector<Node*>::iterator i = edge->inputs_.begin(); i != edge->inputs_.end(); ++i) {
+    if (AddTarget(*i))
+      awaiting_inputs = true;
+  }
+
+  if (!awaiting_inputs)
+    ready_.push(edge);
+
+  return true;
+}
+
+Edge* Plan::FindWork() {
+  if (ready_.empty())
+    return NULL;
+  Edge* edge = ready_.front();
+  ready_.pop();
+  return edge;
+}
index ef3e676..c6e1626 100644 (file)
@@ -24,5 +24,9 @@ TEST_F(NinjaTest, Basic) {
   EXPECT_TRUE(state_.GetNode("in1")->dirty());
   EXPECT_FALSE(state_.GetNode("in2")->dirty());
   EXPECT_TRUE(state_.GetNode("out")->dirty());
-}
 
+  Plan plan(&state_);
+  plan.AddTarget("out");
+  ASSERT_TRUE(plan.FindWork());
+  ASSERT_FALSE(plan.FindWork());
+}