|
Ninja
|
00001 // Copyright 2011 Google Inc. All Rights Reserved. 00002 // 00003 // Licensed under the Apache License, Version 2.0 (the "License"); 00004 // you may not use this file except in compliance with the License. 00005 // You may obtain a copy of the License at 00006 // 00007 // http://www.apache.org/licenses/LICENSE-2.0 00008 // 00009 // Unless required by applicable law or agreed to in writing, software 00010 // distributed under the License is distributed on an "AS IS" BASIS, 00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00012 // See the License for the specific language governing permissions and 00013 // limitations under the License. 00014 00015 #include "state.h" 00016 00017 #include <assert.h> 00018 00019 #include "graph.h" 00020 #include "util.h" 00021 00022 const Rule State::kPhonyRule("phony"); 00023 00024 State::State() : build_log_(NULL) { 00025 AddRule(&kPhonyRule); 00026 } 00027 00028 void State::AddRule(const Rule* rule) { 00029 assert(LookupRule(rule->name_) == NULL); 00030 rules_[rule->name_] = rule; 00031 } 00032 00033 const Rule* State::LookupRule(const string& rule_name) { 00034 map<string, const Rule*>::iterator i = rules_.find(rule_name); 00035 if (i == rules_.end()) 00036 return NULL; 00037 return i->second; 00038 } 00039 00040 Edge* State::AddEdge(const Rule* rule) { 00041 Edge* edge = new Edge(); 00042 edge->rule_ = rule; 00043 edge->env_ = &bindings_; 00044 edges_.push_back(edge); 00045 return edge; 00046 } 00047 00048 Node* State::GetNode(const string& path) { 00049 FileStat* file = stat_cache_.GetFile(path); 00050 if (!file->node_) 00051 file->node_ = new Node(file); 00052 return file->node_; 00053 } 00054 00055 Node* State::LookupNode(const string& path) { 00056 FileStat* file = stat_cache_.GetFile(path); 00057 if (!file->node_) 00058 return NULL; 00059 return file->node_; 00060 } 00061 00062 void State::AddIn(Edge* edge, const string& path) { 00063 Node* node = GetNode(path); 00064 edge->inputs_.push_back(node); 00065 node->out_edges_.push_back(edge); 00066 } 00067 00068 void State::AddOut(Edge* edge, const string& path) { 00069 Node* node = GetNode(path); 00070 edge->outputs_.push_back(node); 00071 if (node->in_edge_) { 00072 Warning("multiple rules generate %s. " 00073 "build will not be correct; continuing anyway", path.c_str()); 00074 } 00075 node->in_edge_ = edge; 00076 } 00077 00078 bool State::AddDefault(const string& path, string* err) { 00079 Node* node = LookupNode(path); 00080 if (!node) { 00081 *err = "unknown target '" + path + "'"; 00082 return false; 00083 } 00084 defaults_.push_back(node); 00085 return true; 00086 } 00087 00088 vector<Node*> State::RootNodes(string* err) { 00089 vector<Node*> root_nodes; 00090 // Search for nodes with no output. 00091 for (vector<Edge*>::iterator e = edges_.begin(); e != edges_.end(); ++e) { 00092 for (vector<Node*>::iterator out = (*e)->outputs_.begin(); 00093 out != (*e)->outputs_.end(); ++out) { 00094 if ((*out)->out_edges_.empty()) 00095 root_nodes.push_back(*out); 00096 } 00097 } 00098 00099 if (!edges_.empty() && root_nodes.empty()) 00100 *err = "could not determine root nodes of build graph"; 00101 00102 assert(edges_.empty() || !root_nodes.empty()); 00103 return root_nodes; 00104 } 00105 00106 vector<Node*> State::DefaultNodes(string* err) { 00107 return defaults_.empty() ? RootNodes(err) : defaults_; 00108 } 00109 00110 void State::Reset() { 00111 stat_cache_.Invalidate(); 00112 for (vector<Edge*>::iterator e = edges_.begin(); e != edges_.end(); ++e) 00113 (*e)->outputs_ready_ = false; 00114 }
1.7.5.1