1 // Copyright 2011 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "manifest_parser.h"
16 
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <vector>
20 
21 #include "disk_interface.h"
22 #include "graph.h"
23 #include "metrics.h"
24 #include "state.h"
25 #include "util.h"
26 #include "version.h"
27 
ManifestParser(State * state,FileReader * file_reader,ManifestParserOptions options)28 ManifestParser::ManifestParser(State* state, FileReader* file_reader,
29                                ManifestParserOptions options)
30     : state_(state), file_reader_(file_reader),
31       options_(options), quiet_(false) {
32   env_ = &state->bindings_;
33 }
34 
Load(const string & filename,string * err,Lexer * parent)35 bool ManifestParser::Load(const string& filename, string* err, Lexer* parent) {
36   METRIC_RECORD(".ninja parse");
37   string contents;
38   string read_err;
39   if (file_reader_->ReadFile(filename, &contents, &read_err) != FileReader::Okay) {
40     *err = "loading '" + filename + "': " + read_err;
41     if (parent)
42       parent->Error(string(*err), err);
43     return false;
44   }
45 
46   // The lexer needs a nul byte at the end of its input, to know when it's done.
47   // It takes a StringPiece, and StringPiece's string constructor uses
48   // string::data().  data()'s return value isn't guaranteed to be
49   // null-terminated (although in practice - libc++, libstdc++, msvc's stl --
50   // it is, and C++11 demands that too), so add an explicit nul byte.
51   contents.resize(contents.size() + 1);
52 
53   return Parse(filename, contents, err);
54 }
55 
Parse(const string & filename,const string & input,string * err)56 bool ManifestParser::Parse(const string& filename, const string& input,
57                            string* err) {
58   lexer_.Start(filename, input);
59 
60   for (;;) {
61     Lexer::Token token = lexer_.ReadToken();
62     switch (token) {
63     case Lexer::POOL:
64       if (!ParsePool(err))
65         return false;
66       break;
67     case Lexer::BUILD:
68       if (!ParseEdge(err))
69         return false;
70       break;
71     case Lexer::RULE:
72       if (!ParseRule(err))
73         return false;
74       break;
75     case Lexer::DEFAULT:
76       if (!ParseDefault(err))
77         return false;
78       break;
79     case Lexer::IDENT: {
80       lexer_.UnreadToken();
81       string name;
82       EvalString let_value;
83       if (!ParseLet(&name, &let_value, err))
84         return false;
85       string value = let_value.Evaluate(env_);
86       // Check ninja_required_version immediately so we can exit
87       // before encountering any syntactic surprises.
88       if (name == "ninja_required_version")
89         CheckNinjaVersion(value);
90       env_->AddBinding(name, value);
91       break;
92     }
93     case Lexer::INCLUDE:
94       if (!ParseFileInclude(false, err))
95         return false;
96       break;
97     case Lexer::SUBNINJA:
98       if (!ParseFileInclude(true, err))
99         return false;
100       break;
101     case Lexer::ERROR: {
102       return lexer_.Error(lexer_.DescribeLastError(), err);
103     }
104     case Lexer::TEOF:
105       return true;
106     case Lexer::NEWLINE:
107       break;
108     default:
109       return lexer_.Error(string("unexpected ") + Lexer::TokenName(token),
110                           err);
111     }
112   }
113   return false;  // not reached
114 }
115 
116 
ParsePool(string * err)117 bool ManifestParser::ParsePool(string* err) {
118   string name;
119   if (!lexer_.ReadIdent(&name))
120     return lexer_.Error("expected pool name", err);
121 
122   if (!ExpectToken(Lexer::NEWLINE, err))
123     return false;
124 
125   if (state_->LookupPool(name) != NULL)
126     return lexer_.Error("duplicate pool '" + name + "'", err);
127 
128   int depth = -1;
129 
130   while (lexer_.PeekToken(Lexer::INDENT)) {
131     string key;
132     EvalString value;
133     if (!ParseLet(&key, &value, err))
134       return false;
135 
136     if (key == "depth") {
137       string depth_string = value.Evaluate(env_);
138       depth = atol(depth_string.c_str());
139       if (depth < 0)
140         return lexer_.Error("invalid pool depth", err);
141     } else {
142       return lexer_.Error("unexpected variable '" + key + "'", err);
143     }
144   }
145 
146   if (depth < 0)
147     return lexer_.Error("expected 'depth =' line", err);
148 
149   state_->AddPool(new Pool(name, depth));
150   return true;
151 }
152 
153 
ParseRule(string * err)154 bool ManifestParser::ParseRule(string* err) {
155   string name;
156   if (!lexer_.ReadIdent(&name))
157     return lexer_.Error("expected rule name", err);
158 
159   if (!ExpectToken(Lexer::NEWLINE, err))
160     return false;
161 
162   if (env_->LookupRuleCurrentScope(name) != NULL)
163     return lexer_.Error("duplicate rule '" + name + "'", err);
164 
165   Rule* rule = new Rule(name);  // XXX scoped_ptr
166 
167   while (lexer_.PeekToken(Lexer::INDENT)) {
168     string key;
169     EvalString value;
170     if (!ParseLet(&key, &value, err))
171       return false;
172 
173     if (Rule::IsReservedBinding(key)) {
174       rule->AddBinding(key, value);
175     } else {
176       // Die on other keyvals for now; revisit if we want to add a
177       // scope here.
178       return lexer_.Error("unexpected variable '" + key + "'", err);
179     }
180   }
181 
182   if (rule->bindings_["rspfile"].empty() !=
183       rule->bindings_["rspfile_content"].empty()) {
184     return lexer_.Error("rspfile and rspfile_content need to be "
185                         "both specified", err);
186   }
187 
188   if (rule->bindings_["command"].empty())
189     return lexer_.Error("expected 'command =' line", err);
190 
191   env_->AddRule(rule);
192   return true;
193 }
194 
ParseLet(string * key,EvalString * value,string * err)195 bool ManifestParser::ParseLet(string* key, EvalString* value, string* err) {
196   if (!lexer_.ReadIdent(key))
197     return lexer_.Error("expected variable name", err);
198   if (!ExpectToken(Lexer::EQUALS, err))
199     return false;
200   if (!lexer_.ReadVarValue(value, err))
201     return false;
202   return true;
203 }
204 
ParseDefault(string * err)205 bool ManifestParser::ParseDefault(string* err) {
206   EvalString eval;
207   if (!lexer_.ReadPath(&eval, err))
208     return false;
209   if (eval.empty())
210     return lexer_.Error("expected target name", err);
211 
212   do {
213     string path = eval.Evaluate(env_);
214     string path_err;
215     uint64_t slash_bits;  // Unused because this only does lookup.
216     if (!CanonicalizePath(&path, &slash_bits, &path_err))
217       return lexer_.Error(path_err, err);
218     if (!state_->AddDefault(path, &path_err))
219       return lexer_.Error(path_err, err);
220 
221     eval.Clear();
222     if (!lexer_.ReadPath(&eval, err))
223       return false;
224   } while (!eval.empty());
225 
226   if (!ExpectToken(Lexer::NEWLINE, err))
227     return false;
228 
229   return true;
230 }
231 
ParseEdge(string * err)232 bool ManifestParser::ParseEdge(string* err) {
233   vector<EvalString> ins, outs;
234 
235   {
236     EvalString out;
237     if (!lexer_.ReadPath(&out, err))
238       return false;
239     while (!out.empty()) {
240       outs.push_back(out);
241 
242       out.Clear();
243       if (!lexer_.ReadPath(&out, err))
244         return false;
245     }
246   }
247 
248   // Add all implicit outs, counting how many as we go.
249   int implicit_outs = 0;
250   if (lexer_.PeekToken(Lexer::PIPE)) {
251     for (;;) {
252       EvalString out;
253       if (!lexer_.ReadPath(&out, err))
254         return err;
255       if (out.empty())
256         break;
257       outs.push_back(out);
258       ++implicit_outs;
259     }
260   }
261 
262   if (outs.empty())
263     return lexer_.Error("expected path", err);
264 
265   if (!ExpectToken(Lexer::COLON, err))
266     return false;
267 
268   string rule_name;
269   if (!lexer_.ReadIdent(&rule_name))
270     return lexer_.Error("expected build command name", err);
271 
272   const Rule* rule = env_->LookupRule(rule_name);
273   if (!rule)
274     return lexer_.Error("unknown build rule '" + rule_name + "'", err);
275 
276   for (;;) {
277     // XXX should we require one path here?
278     EvalString in;
279     if (!lexer_.ReadPath(&in, err))
280       return false;
281     if (in.empty())
282       break;
283     ins.push_back(in);
284   }
285 
286   // Add all implicit deps, counting how many as we go.
287   int implicit = 0;
288   if (lexer_.PeekToken(Lexer::PIPE)) {
289     for (;;) {
290       EvalString in;
291       if (!lexer_.ReadPath(&in, err))
292         return err;
293       if (in.empty())
294         break;
295       ins.push_back(in);
296       ++implicit;
297     }
298   }
299 
300   // Add all order-only deps, counting how many as we go.
301   int order_only = 0;
302   if (lexer_.PeekToken(Lexer::PIPE2)) {
303     for (;;) {
304       EvalString in;
305       if (!lexer_.ReadPath(&in, err))
306         return false;
307       if (in.empty())
308         break;
309       ins.push_back(in);
310       ++order_only;
311     }
312   }
313 
314   if (!ExpectToken(Lexer::NEWLINE, err))
315     return false;
316 
317   // Bindings on edges are rare, so allocate per-edge envs only when needed.
318   bool has_indent_token = lexer_.PeekToken(Lexer::INDENT);
319   BindingEnv* env = has_indent_token ? new BindingEnv(env_) : env_;
320   while (has_indent_token) {
321     string key;
322     EvalString val;
323     if (!ParseLet(&key, &val, err))
324       return false;
325 
326     env->AddBinding(key, val.Evaluate(env_));
327     has_indent_token = lexer_.PeekToken(Lexer::INDENT);
328   }
329 
330   Edge* edge = state_->AddEdge(rule);
331   edge->env_ = env;
332 
333   string pool_name = edge->GetBinding("pool");
334   if (!pool_name.empty()) {
335     Pool* pool = state_->LookupPool(pool_name);
336     if (pool == NULL)
337       return lexer_.Error("unknown pool name '" + pool_name + "'", err);
338     edge->pool_ = pool;
339   }
340 
341   edge->outputs_.reserve(outs.size());
342   for (size_t i = 0, e = outs.size(); i != e; ++i) {
343     string path = outs[i].Evaluate(env);
344     string path_err;
345     uint64_t slash_bits;
346     if (!CanonicalizePath(&path, &slash_bits, &path_err))
347       return lexer_.Error(path_err, err);
348     if (!state_->AddOut(edge, path, slash_bits)) {
349       if (options_.dupe_edge_action_ == kDupeEdgeActionError) {
350         lexer_.Error("multiple rules generate " + path + " [-w dupbuild=err]",
351                      err);
352         return false;
353       } else {
354         if (!quiet_) {
355           Warning("multiple rules generate %s. "
356                   "builds involving this target will not be correct; "
357                   "continuing anyway [-w dupbuild=warn]",
358                   path.c_str());
359         }
360         if (e - i <= static_cast<size_t>(implicit_outs))
361           --implicit_outs;
362       }
363     }
364   }
365   if (edge->outputs_.empty()) {
366     // All outputs of the edge are already created by other edges. Don't add
367     // this edge.  Do this check before input nodes are connected to the edge.
368     state_->edges_.pop_back();
369     delete edge;
370     return true;
371   }
372   edge->implicit_outs_ = implicit_outs;
373 
374   edge->inputs_.reserve(ins.size());
375   for (vector<EvalString>::iterator i = ins.begin(); i != ins.end(); ++i) {
376     string path = i->Evaluate(env);
377     string path_err;
378     uint64_t slash_bits;
379     if (!CanonicalizePath(&path, &slash_bits, &path_err))
380       return lexer_.Error(path_err, err);
381     state_->AddIn(edge, path, slash_bits);
382   }
383   edge->implicit_deps_ = implicit;
384   edge->order_only_deps_ = order_only;
385 
386   if (options_.phony_cycle_action_ == kPhonyCycleActionWarn &&
387       edge->maybe_phonycycle_diagnostic()) {
388     // CMake 2.8.12.x and 3.0.x incorrectly write phony build statements
389     // that reference themselves.  Ninja used to tolerate these in the
390     // build graph but that has since been fixed.  Filter them out to
391     // support users of those old CMake versions.
392     Node* out = edge->outputs_[0];
393     vector<Node*>::iterator new_end =
394         remove(edge->inputs_.begin(), edge->inputs_.end(), out);
395     if (new_end != edge->inputs_.end()) {
396       edge->inputs_.erase(new_end, edge->inputs_.end());
397       if (!quiet_) {
398         Warning("phony target '%s' names itself as an input; "
399                 "ignoring [-w phonycycle=warn]",
400                 out->path().c_str());
401       }
402     }
403   }
404 
405   // Multiple outputs aren't (yet?) supported with depslog.
406   string deps_type = edge->GetBinding("deps");
407   if (!deps_type.empty() && edge->outputs_.size() > 1) {
408     return lexer_.Error("multiple outputs aren't (yet?) supported by depslog; "
409                         "bring this up on the mailing list if it affects you",
410                         err);
411   }
412 
413   return true;
414 }
415 
ParseFileInclude(bool new_scope,string * err)416 bool ManifestParser::ParseFileInclude(bool new_scope, string* err) {
417   EvalString eval;
418   if (!lexer_.ReadPath(&eval, err))
419     return false;
420   string path = eval.Evaluate(env_);
421 
422   ManifestParser subparser(state_, file_reader_, options_);
423   if (new_scope) {
424     subparser.env_ = new BindingEnv(env_);
425   } else {
426     subparser.env_ = env_;
427   }
428 
429   if (!subparser.Load(path, err, &lexer_))
430     return false;
431 
432   if (!ExpectToken(Lexer::NEWLINE, err))
433     return false;
434 
435   return true;
436 }
437 
ExpectToken(Lexer::Token expected,string * err)438 bool ManifestParser::ExpectToken(Lexer::Token expected, string* err) {
439   Lexer::Token token = lexer_.ReadToken();
440   if (token != expected) {
441     string message = string("expected ") + Lexer::TokenName(expected);
442     message += string(", got ") + Lexer::TokenName(token);
443     message += Lexer::TokenErrorHint(expected);
444     return lexer_.Error(message, err);
445   }
446   return true;
447 }
448