refactor EdgeEnv
authorEvan Martin <martine@danga.com>
Wed, 7 Dec 2011 18:01:00 +0000 (10:01 -0800)
committerEvan Martin <martine@danga.com>
Wed, 7 Dec 2011 18:01:00 +0000 (10:01 -0800)
src/graph.cc

index 90e730c..9733e3d 100644 (file)
@@ -155,32 +155,44 @@ bool Edge::AllInputsReady() const {
 /// An Env for an Edge, providing $in and $out.
 struct EdgeEnv : public Env {
   EdgeEnv(Edge* edge) : edge_(edge) {}
-  virtual string LookupVariable(const string& var) {
-    string result;
-    if (var == "in") {
-      int explicit_deps = edge_->inputs_.size() - edge_->implicit_deps_ -
-          edge_->order_only_deps_;
-      for (vector<Node*>::iterator i = edge_->inputs_.begin();
-           i != edge_->inputs_.end() && explicit_deps; ++i, --explicit_deps) {
-        if (!result.empty())
-          result.push_back(' ');
-        result.append((*i)->path());
-      }
-    } else if (var == "out") {
-      for (vector<Node*>::iterator i = edge_->outputs_.begin();
-           i != edge_->outputs_.end(); ++i) {
-        if (!result.empty())
-          result.push_back(' ');
-        result.append((*i)->path());
-      }
-    } else if (edge_->env_) {
-      return edge_->env_->LookupVariable(var);
-    }
-    return result;
-  }
+  virtual string LookupVariable(const string& var);
+
+  /// Given a span of Nodes, construct a list of paths suitable for a command
+  /// line.  XXX here is where shell-escaping of e.g spaces should happen.
+  string MakePathList(vector<Node*>::iterator begin,
+                      vector<Node*>::iterator end);
+
   Edge* edge_;
 };
 
+string EdgeEnv::LookupVariable(const string& var) {
+  if (var == "in") {
+    int explicit_deps_count = edge_->inputs_.size() - edge_->implicit_deps_ -
+      edge_->order_only_deps_;
+    return MakePathList(edge_->inputs_.begin(),
+                        edge_->inputs_.begin() + explicit_deps_count);
+  } else if (var == "out") {
+    return MakePathList(edge_->outputs_.begin(),
+                        edge_->outputs_.end());
+  } else if (edge_->env_) {
+    return edge_->env_->LookupVariable(var);
+  } else {
+    // XXX shoudl we warn here?
+    return string();
+  }
+}
+
+string EdgeEnv::MakePathList(vector<Node*>::iterator begin,
+                             vector<Node*>::iterator end) {
+  string result;
+  for (vector<Node*>::iterator i = begin; i != end; ++i) {
+    if (!result.empty())
+      result.push_back(' ');
+    result.append((*i)->path());
+  }
+  return result;
+}
+
 string Edge::EvaluateCommand() {
   EdgeEnv env(this);
   return rule_->command_.Evaluate(&env);