}
bool Plan::AddSubTarget(Node* node, vector<Node*>* stack, string* err) {
- Edge* edge = node->in_edge_;
+ Edge* edge = node->in_edge();
if (!edge) { // Leaf node.
if (node->dirty()) {
string referenced;
}
return false;
}
- assert(edge);
if (CheckDependencyCycle(node, stack, err))
return false;
bool Builder::AddTarget(Node* node, string* err) {
node->StatIfNecessary(disk_interface_);
- if (Edge* in_edge = node->in_edge_) {
+ if (Edge* in_edge = node->in_edge()) {
if (!in_edge->RecomputeDirty(state_, disk_interface_, err))
return false;
if (in_edge->outputs_ready())
// If it's an input file, mark that we've already stat()ed it and
// it's missing.
- if (!node->in_edge_)
+ if (!node->in_edge())
node->MarkMissing();
}
}
void Cleaner::DoCleanTarget(Node* target) {
- if (target->in_edge_) {
+ if (target->in_edge()) {
Remove(target->path());
- for (vector<Node*>::iterator n = target->in_edge_->inputs_.begin();
- n != target->in_edge_->inputs_.end();
+ for (vector<Node*>::iterator n = target->in_edge()->inputs_.begin();
+ n != target->in_edge()->inputs_.end();
++n) {
DoCleanTarget(*n);
}
Node* out = GetNode("out");
out->Stat(this);
ASSERT_EQ(1u, stats_.size());
- Edge* edge = out->in_edge_;
- edge->RecomputeDirty(NULL, this, NULL);
+ out->in_edge()->RecomputeDirty(NULL, this, NULL);
ASSERT_EQ(2u, stats_.size());
ASSERT_EQ("out", stats_[0]);
ASSERT_EQ("in", stats_[1]);
Node* out = GetNode("out");
out->Stat(this);
ASSERT_EQ(1u, stats_.size());
- Edge* edge = out->in_edge_;
- edge->RecomputeDirty(NULL, this, NULL);
+ out->in_edge()->RecomputeDirty(NULL, this, NULL);
ASSERT_EQ(3u, stats_.size());
ASSERT_EQ("out", stats_[0]);
ASSERT_TRUE(GetNode("out")->dirty());
Node* out = GetNode("out");
out->Stat(this);
ASSERT_EQ(1u, stats_.size());
- Edge* edge = out->in_edge_;
- edge->RecomputeDirty(NULL, this, NULL);
+ out->in_edge()->RecomputeDirty(NULL, this, NULL);
ASSERT_EQ(1u + 6u, stats_.size());
ASSERT_EQ("mid1", stats_[1]);
ASSERT_TRUE(GetNode("mid1")->dirty());
Node* out = GetNode("out");
out->Stat(this);
ASSERT_EQ(1u, stats_.size());
- Edge* edge = out->in_edge_;
- edge->RecomputeDirty(NULL, this, NULL);
+ out->in_edge()->RecomputeDirty(NULL, this, NULL);
ASSERT_FALSE(GetNode("in")->dirty());
ASSERT_TRUE(GetNode("mid")->dirty());
ASSERT_TRUE(GetNode("out")->dirty());
time_t most_recent_input = 1;
for (vector<Node*>::iterator i = inputs_.begin(); i != inputs_.end(); ++i) {
if ((*i)->StatIfNecessary(disk_interface)) {
- if (Edge* edge = (*i)->in_edge_) {
+ if (Edge* edge = (*i)->in_edge()) {
if (!edge->RecomputeDirty(state, disk_interface, err))
return false;
} else {
}
// If an input is not ready, neither are our outputs.
- if (Edge* edge = (*i)->in_edge_) {
+ if (Edge* edge = (*i)->in_edge()) {
if (!edge->outputs_ready_)
outputs_ready_ = false;
}
bool Edge::AllInputsReady() const {
for (vector<Node*>::const_iterator i = inputs_.begin();
i != inputs_.end(); ++i) {
- if ((*i)->in_edge_ && !(*i)->in_edge_->outputs_ready())
+ if ((*i)->in_edge() && !(*i)->in_edge()->outputs_ready())
return false;
}
return true;
// If we don't have a edge that generates this input already,
// create one; this makes us not abort if the input is missing,
// but instead will rebuild in that circumstance.
- if (!node->in_edge_) {
+ if (!node->in_edge()) {
Edge* phony_edge = state->AddEdge(&State::kPhonyRule);
- node->in_edge_ = phony_edge;
+ node->set_in_edge(phony_edge);
phony_edge->outputs_.push_back(node);
// RecomputeDirty might not be called for phony_edge if a previous call
void set_dirty(bool dirty) { dirty_ = dirty; }
void MarkDirty() { dirty_ = true; }
+ Edge* in_edge() const { return in_edge_; }
+ void set_in_edge(Edge* edge) { in_edge_ = edge; }
+
private:
string path_;
/// Possible values of mtime_:
/// edges to build.
bool dirty_;
+ /// The Edge that produces this Node, or NULL when there is no
+ /// known edge to produce it.
+ Edge* in_edge_;
+
// TODO: make these private as well. But don't just blindly add
// setters/getters, instead pay attention to the proper API.
public:
- Edge* in_edge_;
vector<Edge*> out_edges_;
};
fs_.Create("in", 1, "");
fs_.Create("out", 1, "");
- Edge* edge = GetNode("out")->in_edge_;
+ Edge* edge = GetNode("out")->in_edge();
string err;
EXPECT_TRUE(edge->RecomputeDirty(&state_, &fs_, &err));
ASSERT_EQ("", err);
fs_.Create("out", 1, "");
fs_.Create("implicit", 2, "");
- Edge* edge = GetNode("out")->in_edge_;
+ Edge* edge = GetNode("out")->in_edge();
string err;
EXPECT_TRUE(edge->RecomputeDirty(&state_, &fs_, &err));
ASSERT_EQ("", err);
fs_.Create("out.o.d", 1, "out.o: ./foo/../implicit.h\n");
fs_.Create("out.o", 1, "");
- Edge* edge = GetNode("out.o")->in_edge_;
+ Edge* edge = GetNode("out.o")->in_edge();
string err;
EXPECT_TRUE(edge->RecomputeDirty(&state_, &fs_, &err));
ASSERT_EQ("", err);
fs_.Create("out.o.d", 1, "out.o: implicit.h\n");
fs_.Create("out.o", 1, "");
- Edge* edge = GetNode("out.o")->in_edge_;
+ Edge* edge = GetNode("out.o")->in_edge();
string err;
EXPECT_TRUE(edge->RecomputeDirty(&state_, &fs_, &err));
ASSERT_EQ("", err);
fs_.Create("out.o.d", 1, "out.o: foo.cc\n");
fs_.Create("out.o", 1, "");
- Edge* edge = GetNode("out.o")->in_edge_;
+ Edge* edge = GetNode("out.o")->in_edge();
string err;
EXPECT_TRUE(edge->RecomputeDirty(&state_, &fs_, &err));
ASSERT_EQ("", err);
printf("\"%p\" [label=\"%s\"]\n", node, node->path().c_str());
visited_.insert(node);
- if (!node->in_edge_) {
+ Edge* edge = node->in_edge();
+
+ if (!edge) {
// Leaf node.
// Draw as a rect?
return;
}
- Edge* edge = node->in_edge_;
-
if (edge->inputs_.size() == 1 && edge->outputs_.size() == 1) {
// Can draw simply.
// Note extra space before label text -- this is cosmetic and feels
Node* node = state->LookupNode(argv[i]);
if (node) {
printf("%s:\n", argv[i]);
- if (node->in_edge_) {
- printf(" input: %s\n", node->in_edge_->rule_->name_.c_str());
- for (vector<Node*>::iterator in = node->in_edge_->inputs_.begin();
- in != node->in_edge_->inputs_.end(); ++in) {
+ if (node->in_edge()) {
+ printf(" input: %s\n", node->in_edge()->rule_->name_.c_str());
+ for (vector<Node*>::iterator in = node->in_edge()->inputs_.begin();
+ in != node->in_edge()->inputs_.end(); ++in) {
printf(" %s\n", (*in)->path().c_str());
}
}
for (int i = 0; i < indent; ++i)
printf(" ");
const char* target = (*n)->path().c_str();
- if ((*n)->in_edge_) {
- printf("%s: %s\n", target, (*n)->in_edge_->rule_->name_.c_str());
+ if ((*n)->in_edge()) {
+ printf("%s: %s\n", target, (*n)->in_edge()->rule_->name_.c_str());
if (depth > 1 || depth <= 0)
- CmdTargetsList((*n)->in_edge_->inputs_, depth - 1, indent + 1);
+ CmdTargetsList((*n)->in_edge()->inputs_, depth - 1, indent + 1);
} else {
printf("%s\n", target);
}
for (vector<Node*>::iterator inps = (*e)->inputs_.begin();
inps != (*e)->inputs_.end();
++inps)
- if (!(*inps)->in_edge_)
+ if (!(*inps)->in_edge())
printf("%s\n", (*inps)->path().c_str());
return 0;
}
for (vector<Node*>::iterator in = edge->inputs_.begin();
in != edge->inputs_.end(); ++in)
- PrintCommands((*in)->in_edge_, seen);
+ PrintCommands((*in)->in_edge(), seen);
if (!edge->is_phony())
puts(edge->EvaluateCommand().c_str());
set<Edge*> seen;
for (vector<Node*>::iterator in = nodes.begin(); in != nodes.end(); ++in)
- PrintCommands((*in)->in_edge_, &seen);
+ PrintCommands((*in)->in_edge(), &seen);
return 0;
}
"rule cat\n command = cat $in > $out\n"
"build foo: cat bar | baz\n"));
- Edge* edge = state.LookupNode("foo")->in_edge_;
+ Edge* edge = state.LookupNode("foo")->in_edge();
ASSERT_TRUE(edge->is_implicit(1));
}
"rule cat\n command = cat $in > $out\n"
"build foo: cat bar || baz\n"));
- Edge* edge = state.LookupNode("foo")->in_edge_;
+ Edge* edge = state.LookupNode("foo")->in_edge();
ASSERT_TRUE(edge->is_order_only(1));
}
void State::AddOut(Edge* edge, const string& path) {
Node* node = GetNode(path);
edge->outputs_.push_back(node);
- if (node->in_edge_) {
+ if (node->in_edge()) {
Warning("multiple rules generate %s. "
"build will not be correct; continuing anyway", path.c_str());
}
- node->in_edge_ = edge;
+ node->set_in_edge(edge);
}
bool State::AddDefault(const string& path, string* err) {