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 <map>
18 #include <vector>
19 
20 #include "graph.h"
21 #include "state.h"
22 #include "test.h"
23 
24 using namespace std;
25 
26 struct ParserTest : public testing::Test {
AssertParseParserTest27   void AssertParse(const char* input) {
28     ManifestParser parser(&state, &fs_);
29     string err;
30     EXPECT_TRUE(parser.ParseTest(input, &err));
31     ASSERT_EQ("", err);
32     VerifyGraph(state);
33   }
34 
35   State state;
36   VirtualFileSystem fs_;
37 };
38 
TEST_F(ParserTest,Empty)39 TEST_F(ParserTest, Empty) {
40   ASSERT_NO_FATAL_FAILURE(AssertParse(""));
41 }
42 
TEST_F(ParserTest,Rules)43 TEST_F(ParserTest, Rules) {
44   ASSERT_NO_FATAL_FAILURE(AssertParse(
45 "rule cat\n"
46 "  command = cat $in > $out\n"
47 "\n"
48 "rule date\n"
49 "  command = date > $out\n"
50 "\n"
51 "build result: cat in_1.cc in-2.O\n"));
52 
53   ASSERT_EQ(3u, state.bindings_.GetRules().size());
54   const Rule* rule = state.bindings_.GetRules().begin()->second;
55   EXPECT_EQ("cat", rule->name());
56   EXPECT_EQ("[cat ][$in][ > ][$out]",
57             rule->GetBinding("command")->Serialize());
58 }
59 
TEST_F(ParserTest,RuleAttributes)60 TEST_F(ParserTest, RuleAttributes) {
61   // Check that all of the allowed rule attributes are parsed ok.
62   ASSERT_NO_FATAL_FAILURE(AssertParse(
63 "rule cat\n"
64 "  command = a\n"
65 "  depfile = a\n"
66 "  deps = a\n"
67 "  description = a\n"
68 "  generator = a\n"
69 "  restat = a\n"
70 "  rspfile = a\n"
71 "  rspfile_content = a\n"
72 ));
73 }
74 
TEST_F(ParserTest,IgnoreIndentedComments)75 TEST_F(ParserTest, IgnoreIndentedComments) {
76   ASSERT_NO_FATAL_FAILURE(AssertParse(
77 "  #indented comment\n"
78 "rule cat\n"
79 "  command = cat $in > $out\n"
80 "  #generator = 1\n"
81 "  restat = 1 # comment\n"
82 "  #comment\n"
83 "build result: cat in_1.cc in-2.O\n"
84 "  #comment\n"));
85 
86   ASSERT_EQ(2u, state.bindings_.GetRules().size());
87   const Rule* rule = state.bindings_.GetRules().begin()->second;
88   EXPECT_EQ("cat", rule->name());
89   Edge* edge = state.GetNode("result", 0)->in_edge();
90   EXPECT_TRUE(edge->GetBindingBool("restat"));
91   EXPECT_FALSE(edge->GetBindingBool("generator"));
92 }
93 
TEST_F(ParserTest,IgnoreIndentedBlankLines)94 TEST_F(ParserTest, IgnoreIndentedBlankLines) {
95   // the indented blanks used to cause parse errors
96   ASSERT_NO_FATAL_FAILURE(AssertParse(
97 "  \n"
98 "rule cat\n"
99 "  command = cat $in > $out\n"
100 "  \n"
101 "build result: cat in_1.cc in-2.O\n"
102 "  \n"
103 "variable=1\n"));
104 
105   // the variable must be in the top level environment
106   EXPECT_EQ("1", state.bindings_.LookupVariable("variable"));
107 }
108 
TEST_F(ParserTest,ResponseFiles)109 TEST_F(ParserTest, ResponseFiles) {
110   ASSERT_NO_FATAL_FAILURE(AssertParse(
111 "rule cat_rsp\n"
112 "  command = cat $rspfile > $out\n"
113 "  rspfile = $rspfile\n"
114 "  rspfile_content = $in\n"
115 "\n"
116 "build out: cat_rsp in\n"
117 "  rspfile=out.rsp\n"));
118 
119   ASSERT_EQ(2u, state.bindings_.GetRules().size());
120   const Rule* rule = state.bindings_.GetRules().begin()->second;
121   EXPECT_EQ("cat_rsp", rule->name());
122   EXPECT_EQ("[cat ][$rspfile][ > ][$out]",
123             rule->GetBinding("command")->Serialize());
124   EXPECT_EQ("[$rspfile]", rule->GetBinding("rspfile")->Serialize());
125   EXPECT_EQ("[$in]", rule->GetBinding("rspfile_content")->Serialize());
126 }
127 
TEST_F(ParserTest,InNewline)128 TEST_F(ParserTest, InNewline) {
129   ASSERT_NO_FATAL_FAILURE(AssertParse(
130 "rule cat_rsp\n"
131 "  command = cat $in_newline > $out\n"
132 "\n"
133 "build out: cat_rsp in in2\n"
134 "  rspfile=out.rsp\n"));
135 
136   ASSERT_EQ(2u, state.bindings_.GetRules().size());
137   const Rule* rule = state.bindings_.GetRules().begin()->second;
138   EXPECT_EQ("cat_rsp", rule->name());
139   EXPECT_EQ("[cat ][$in_newline][ > ][$out]",
140             rule->GetBinding("command")->Serialize());
141 
142   Edge* edge = state.edges_[0];
143   EXPECT_EQ("cat in\nin2 > out", edge->EvaluateCommand());
144 }
145 
TEST_F(ParserTest,Variables)146 TEST_F(ParserTest, Variables) {
147   ASSERT_NO_FATAL_FAILURE(AssertParse(
148 "l = one-letter-test\n"
149 "rule link\n"
150 "  command = ld $l $extra $with_under -o $out $in\n"
151 "\n"
152 "extra = -pthread\n"
153 "with_under = -under\n"
154 "build a: link b c\n"
155 "nested1 = 1\n"
156 "nested2 = $nested1/2\n"
157 "build supernested: link x\n"
158 "  extra = $nested2/3\n"));
159 
160   ASSERT_EQ(2u, state.edges_.size());
161   Edge* edge = state.edges_[0];
162   EXPECT_EQ("ld one-letter-test -pthread -under -o a b c",
163             edge->EvaluateCommand());
164   EXPECT_EQ("1/2", state.bindings_.LookupVariable("nested2"));
165 
166   edge = state.edges_[1];
167   EXPECT_EQ("ld one-letter-test 1/2/3 -under -o supernested x",
168             edge->EvaluateCommand());
169 }
170 
TEST_F(ParserTest,VariableScope)171 TEST_F(ParserTest, VariableScope) {
172   ASSERT_NO_FATAL_FAILURE(AssertParse(
173 "foo = bar\n"
174 "rule cmd\n"
175 "  command = cmd $foo $in $out\n"
176 "\n"
177 "build inner: cmd a\n"
178 "  foo = baz\n"
179 "build outer: cmd b\n"
180 "\n"  // Extra newline after build line tickles a regression.
181 ));
182 
183   ASSERT_EQ(2u, state.edges_.size());
184   EXPECT_EQ("cmd baz a inner", state.edges_[0]->EvaluateCommand());
185   EXPECT_EQ("cmd bar b outer", state.edges_[1]->EvaluateCommand());
186 }
187 
TEST_F(ParserTest,Continuation)188 TEST_F(ParserTest, Continuation) {
189   ASSERT_NO_FATAL_FAILURE(AssertParse(
190 "rule link\n"
191 "  command = foo bar $\n"
192 "    baz\n"
193 "\n"
194 "build a: link c $\n"
195 " d e f\n"));
196 
197   ASSERT_EQ(2u, state.bindings_.GetRules().size());
198   const Rule* rule = state.bindings_.GetRules().begin()->second;
199   EXPECT_EQ("link", rule->name());
200   EXPECT_EQ("[foo bar baz]", rule->GetBinding("command")->Serialize());
201 }
202 
TEST_F(ParserTest,Backslash)203 TEST_F(ParserTest, Backslash) {
204   ASSERT_NO_FATAL_FAILURE(AssertParse(
205 "foo = bar\\baz\n"
206 "foo2 = bar\\ baz\n"
207 ));
208   EXPECT_EQ("bar\\baz", state.bindings_.LookupVariable("foo"));
209   EXPECT_EQ("bar\\ baz", state.bindings_.LookupVariable("foo2"));
210 }
211 
TEST_F(ParserTest,Comment)212 TEST_F(ParserTest, Comment) {
213   ASSERT_NO_FATAL_FAILURE(AssertParse(
214 "# this is a comment\n"
215 "foo = not # a comment\n"));
216   EXPECT_EQ("not # a comment", state.bindings_.LookupVariable("foo"));
217 }
218 
TEST_F(ParserTest,Dollars)219 TEST_F(ParserTest, Dollars) {
220   ASSERT_NO_FATAL_FAILURE(AssertParse(
221 "rule foo\n"
222 "  command = ${out}bar$$baz$$$\n"
223 "blah\n"
224 "x = $$dollar\n"
225 "build $x: foo y\n"
226 ));
227   EXPECT_EQ("$dollar", state.bindings_.LookupVariable("x"));
228 #ifdef _WIN32
229   EXPECT_EQ("$dollarbar$baz$blah", state.edges_[0]->EvaluateCommand());
230 #else
231   EXPECT_EQ("'$dollar'bar$baz$blah", state.edges_[0]->EvaluateCommand());
232 #endif
233 }
234 
TEST_F(ParserTest,EscapeSpaces)235 TEST_F(ParserTest, EscapeSpaces) {
236   ASSERT_NO_FATAL_FAILURE(AssertParse(
237 "rule spaces\n"
238 "  command = something\n"
239 "build foo$ bar: spaces $$one two$$$ three\n"
240 ));
241   EXPECT_TRUE(state.LookupNode("foo bar"));
242   EXPECT_EQ(state.edges_[0]->outputs_[0]->path(), "foo bar");
243   EXPECT_EQ(state.edges_[0]->inputs_[0]->path(), "$one");
244   EXPECT_EQ(state.edges_[0]->inputs_[1]->path(), "two$ three");
245   EXPECT_EQ(state.edges_[0]->EvaluateCommand(), "something");
246 }
247 
TEST_F(ParserTest,CanonicalizeFile)248 TEST_F(ParserTest, CanonicalizeFile) {
249   ASSERT_NO_FATAL_FAILURE(AssertParse(
250 "rule cat\n"
251 "  command = cat $in > $out\n"
252 "build out: cat in/1 in//2\n"
253 "build in/1: cat\n"
254 "build in/2: cat\n"));
255 
256   EXPECT_TRUE(state.LookupNode("in/1"));
257   EXPECT_TRUE(state.LookupNode("in/2"));
258   EXPECT_FALSE(state.LookupNode("in//1"));
259   EXPECT_FALSE(state.LookupNode("in//2"));
260 }
261 
262 #ifdef _WIN32
TEST_F(ParserTest,CanonicalizeFileBackslashes)263 TEST_F(ParserTest, CanonicalizeFileBackslashes) {
264   ASSERT_NO_FATAL_FAILURE(AssertParse(
265 "rule cat\n"
266 "  command = cat $in > $out\n"
267 "build out: cat in\\1 in\\\\2\n"
268 "build in\\1: cat\n"
269 "build in\\2: cat\n"));
270 
271   Node* node = state.LookupNode("in/1");;
272   EXPECT_TRUE(node);
273   EXPECT_EQ(1, node->slash_bits());
274   node = state.LookupNode("in/2");
275   EXPECT_TRUE(node);
276   EXPECT_EQ(1, node->slash_bits());
277   EXPECT_FALSE(state.LookupNode("in//1"));
278   EXPECT_FALSE(state.LookupNode("in//2"));
279 }
280 #endif
281 
TEST_F(ParserTest,PathVariables)282 TEST_F(ParserTest, PathVariables) {
283   ASSERT_NO_FATAL_FAILURE(AssertParse(
284 "rule cat\n"
285 "  command = cat $in > $out\n"
286 "dir = out\n"
287 "build $dir/exe: cat src\n"));
288 
289   EXPECT_FALSE(state.LookupNode("$dir/exe"));
290   EXPECT_TRUE(state.LookupNode("out/exe"));
291 }
292 
TEST_F(ParserTest,CanonicalizePaths)293 TEST_F(ParserTest, CanonicalizePaths) {
294   ASSERT_NO_FATAL_FAILURE(AssertParse(
295 "rule cat\n"
296 "  command = cat $in > $out\n"
297 "build ./out.o: cat ./bar/baz/../foo.cc\n"));
298 
299   EXPECT_FALSE(state.LookupNode("./out.o"));
300   EXPECT_TRUE(state.LookupNode("out.o"));
301   EXPECT_FALSE(state.LookupNode("./bar/baz/../foo.cc"));
302   EXPECT_TRUE(state.LookupNode("bar/foo.cc"));
303 }
304 
305 #ifdef _WIN32
TEST_F(ParserTest,CanonicalizePathsBackslashes)306 TEST_F(ParserTest, CanonicalizePathsBackslashes) {
307   ASSERT_NO_FATAL_FAILURE(AssertParse(
308 "rule cat\n"
309 "  command = cat $in > $out\n"
310 "build ./out.o: cat ./bar/baz/../foo.cc\n"
311 "build .\\out2.o: cat .\\bar/baz\\..\\foo.cc\n"
312 "build .\\out3.o: cat .\\bar\\baz\\..\\foo3.cc\n"
313 ));
314 
315   EXPECT_FALSE(state.LookupNode("./out.o"));
316   EXPECT_FALSE(state.LookupNode(".\\out2.o"));
317   EXPECT_FALSE(state.LookupNode(".\\out3.o"));
318   EXPECT_TRUE(state.LookupNode("out.o"));
319   EXPECT_TRUE(state.LookupNode("out2.o"));
320   EXPECT_TRUE(state.LookupNode("out3.o"));
321   EXPECT_FALSE(state.LookupNode("./bar/baz/../foo.cc"));
322   EXPECT_FALSE(state.LookupNode(".\\bar/baz\\..\\foo.cc"));
323   EXPECT_FALSE(state.LookupNode(".\\bar/baz\\..\\foo3.cc"));
324   Node* node = state.LookupNode("bar/foo.cc");
325   EXPECT_TRUE(node);
326   EXPECT_EQ(0, node->slash_bits());
327   node = state.LookupNode("bar/foo3.cc");
328   EXPECT_TRUE(node);
329   EXPECT_EQ(1, node->slash_bits());
330 }
331 #endif
332 
TEST_F(ParserTest,DuplicateEdgeWithMultipleOutputs)333 TEST_F(ParserTest, DuplicateEdgeWithMultipleOutputs) {
334   ASSERT_NO_FATAL_FAILURE(AssertParse(
335 "rule cat\n"
336 "  command = cat $in > $out\n"
337 "build out1 out2: cat in1\n"
338 "build out1: cat in2\n"
339 "build final: cat out1\n"
340 ));
341   // AssertParse() checks that the generated build graph is self-consistent.
342   // That's all the checking that this test needs.
343 }
344 
TEST_F(ParserTest,NoDeadPointerFromDuplicateEdge)345 TEST_F(ParserTest, NoDeadPointerFromDuplicateEdge) {
346   ASSERT_NO_FATAL_FAILURE(AssertParse(
347 "rule cat\n"
348 "  command = cat $in > $out\n"
349 "build out: cat in\n"
350 "build out: cat in\n"
351 ));
352   // AssertParse() checks that the generated build graph is self-consistent.
353   // That's all the checking that this test needs.
354 }
355 
TEST_F(ParserTest,DuplicateEdgeWithMultipleOutputsError)356 TEST_F(ParserTest, DuplicateEdgeWithMultipleOutputsError) {
357   const char kInput[] =
358 "rule cat\n"
359 "  command = cat $in > $out\n"
360 "build out1 out2: cat in1\n"
361 "build out1: cat in2\n"
362 "build final: cat out1\n";
363   ManifestParserOptions parser_opts;
364   parser_opts.dupe_edge_action_ = kDupeEdgeActionError;
365   ManifestParser parser(&state, &fs_, parser_opts);
366   string err;
367   EXPECT_FALSE(parser.ParseTest(kInput, &err));
368   EXPECT_EQ("input:5: multiple rules generate out1 [-w dupbuild=err]\n", err);
369 }
370 
TEST_F(ParserTest,DuplicateEdgeInIncludedFile)371 TEST_F(ParserTest, DuplicateEdgeInIncludedFile) {
372   fs_.Create("sub.ninja",
373     "rule cat\n"
374     "  command = cat $in > $out\n"
375     "build out1 out2: cat in1\n"
376     "build out1: cat in2\n"
377     "build final: cat out1\n");
378   const char kInput[] =
379     "subninja sub.ninja\n";
380   ManifestParserOptions parser_opts;
381   parser_opts.dupe_edge_action_ = kDupeEdgeActionError;
382   ManifestParser parser(&state, &fs_, parser_opts);
383   string err;
384   EXPECT_FALSE(parser.ParseTest(kInput, &err));
385   EXPECT_EQ("sub.ninja:5: multiple rules generate out1 [-w dupbuild=err]\n",
386             err);
387 }
388 
TEST_F(ParserTest,PhonySelfReferenceIgnored)389 TEST_F(ParserTest, PhonySelfReferenceIgnored) {
390   ASSERT_NO_FATAL_FAILURE(AssertParse(
391 "build a: phony a\n"
392 ));
393 
394   Node* node = state.LookupNode("a");
395   Edge* edge = node->in_edge();
396   ASSERT_TRUE(edge->inputs_.empty());
397 }
398 
TEST_F(ParserTest,PhonySelfReferenceKept)399 TEST_F(ParserTest, PhonySelfReferenceKept) {
400   const char kInput[] =
401 "build a: phony a\n";
402   ManifestParserOptions parser_opts;
403   parser_opts.phony_cycle_action_ = kPhonyCycleActionError;
404   ManifestParser parser(&state, &fs_, parser_opts);
405   string err;
406   EXPECT_TRUE(parser.ParseTest(kInput, &err));
407   EXPECT_EQ("", err);
408 
409   Node* node = state.LookupNode("a");
410   Edge* edge = node->in_edge();
411   ASSERT_EQ(edge->inputs_.size(), 1);
412   ASSERT_EQ(edge->inputs_[0], node);
413 }
414 
TEST_F(ParserTest,ReservedWords)415 TEST_F(ParserTest, ReservedWords) {
416   ASSERT_NO_FATAL_FAILURE(AssertParse(
417 "rule build\n"
418 "  command = rule run $out\n"
419 "build subninja: build include default foo.cc\n"
420 "default subninja\n"));
421 }
422 
TEST_F(ParserTest,Errors)423 TEST_F(ParserTest, Errors) {
424   {
425     State local_state;
426     ManifestParser parser(&local_state, NULL);
427     string err;
428     EXPECT_FALSE(parser.ParseTest(string("subn", 4), &err));
429     EXPECT_EQ("input:1: expected '=', got eof\n"
430               "subn\n"
431               "    ^ near here"
432               , err);
433   }
434 
435   {
436     State local_state;
437     ManifestParser parser(&local_state, NULL);
438     string err;
439     EXPECT_FALSE(parser.ParseTest("foobar", &err));
440     EXPECT_EQ("input:1: expected '=', got eof\n"
441               "foobar\n"
442               "      ^ near here"
443               , err);
444   }
445 
446   {
447     State local_state;
448     ManifestParser parser(&local_state, NULL);
449     string err;
450     EXPECT_FALSE(parser.ParseTest("x 3", &err));
451     EXPECT_EQ("input:1: expected '=', got identifier\n"
452               "x 3\n"
453               "  ^ near here"
454               , err);
455   }
456 
457   {
458     State local_state;
459     ManifestParser parser(&local_state, NULL);
460     string err;
461     EXPECT_FALSE(parser.ParseTest("x = 3", &err));
462     EXPECT_EQ("input:1: unexpected EOF\n"
463               "x = 3\n"
464               "     ^ near here"
465               , err);
466   }
467 
468   {
469     State local_state;
470     ManifestParser parser(&local_state, NULL);
471     string err;
472     EXPECT_FALSE(parser.ParseTest("x = 3\ny 2", &err));
473     EXPECT_EQ("input:2: expected '=', got identifier\n"
474               "y 2\n"
475               "  ^ near here"
476               , err);
477   }
478 
479   {
480     State local_state;
481     ManifestParser parser(&local_state, NULL);
482     string err;
483     EXPECT_FALSE(parser.ParseTest("x = $", &err));
484     EXPECT_EQ("input:1: bad $-escape (literal $ must be written as $$)\n"
485               "x = $\n"
486               "    ^ near here"
487               , err);
488   }
489 
490   {
491     State local_state;
492     ManifestParser parser(&local_state, NULL);
493     string err;
494     EXPECT_FALSE(parser.ParseTest("x = $\n $[\n", &err));
495     EXPECT_EQ("input:2: bad $-escape (literal $ must be written as $$)\n"
496               " $[\n"
497               " ^ near here"
498               , err);
499   }
500 
501   {
502     State local_state;
503     ManifestParser parser(&local_state, NULL);
504     string err;
505     EXPECT_FALSE(parser.ParseTest("x = a$\n b$\n $\n", &err));
506     EXPECT_EQ("input:4: unexpected EOF\n"
507               , err);
508   }
509 
510   {
511     State local_state;
512     ManifestParser parser(&local_state, NULL);
513     string err;
514     EXPECT_FALSE(parser.ParseTest("build\n", &err));
515     EXPECT_EQ("input:1: expected path\n"
516               "build\n"
517               "     ^ near here"
518               , err);
519   }
520 
521   {
522     State local_state;
523     ManifestParser parser(&local_state, NULL);
524     string err;
525     EXPECT_FALSE(parser.ParseTest("build x: y z\n", &err));
526     EXPECT_EQ("input:1: unknown build rule 'y'\n"
527               "build x: y z\n"
528               "         ^ near here"
529               , err);
530   }
531 
532   {
533     State local_state;
534     ManifestParser parser(&local_state, NULL);
535     string err;
536     EXPECT_FALSE(parser.ParseTest("build x:: y z\n", &err));
537     EXPECT_EQ("input:1: expected build command name\n"
538               "build x:: y z\n"
539               "        ^ near here"
540               , err);
541   }
542 
543   {
544     State local_state;
545     ManifestParser parser(&local_state, NULL);
546     string err;
547     EXPECT_FALSE(parser.ParseTest("rule cat\n  command = cat ok\n"
548                                   "build x: cat $\n :\n",
549                                   &err));
550     EXPECT_EQ("input:4: expected newline, got ':'\n"
551               " :\n"
552               " ^ near here"
553               , err);
554   }
555 
556   {
557     State local_state;
558     ManifestParser parser(&local_state, NULL);
559     string err;
560     EXPECT_FALSE(parser.ParseTest("rule cat\n",
561                                   &err));
562     EXPECT_EQ("input:2: expected 'command =' line\n", err);
563   }
564 
565   {
566     State local_state;
567     ManifestParser parser(&local_state, NULL);
568     string err;
569     EXPECT_FALSE(parser.ParseTest("rule cat\n"
570                                   "  command = echo\n"
571                                   "rule cat\n"
572                                   "  command = echo\n", &err));
573     EXPECT_EQ("input:3: duplicate rule 'cat'\n"
574               "rule cat\n"
575               "        ^ near here"
576               , err);
577   }
578 
579   {
580     State local_state;
581     ManifestParser parser(&local_state, NULL);
582     string err;
583     EXPECT_FALSE(parser.ParseTest("rule cat\n"
584                                   "  command = echo\n"
585                                   "  rspfile = cat.rsp\n", &err));
586     EXPECT_EQ(
587         "input:4: rspfile and rspfile_content need to be both specified\n",
588         err);
589   }
590 
591   {
592     State local_state;
593     ManifestParser parser(&local_state, NULL);
594     string err;
595     EXPECT_FALSE(parser.ParseTest("rule cat\n"
596                                   "  command = ${fafsd\n"
597                                   "foo = bar\n",
598                                   &err));
599     EXPECT_EQ("input:2: bad $-escape (literal $ must be written as $$)\n"
600               "  command = ${fafsd\n"
601               "            ^ near here"
602               , err);
603   }
604 
605 
606   {
607     State local_state;
608     ManifestParser parser(&local_state, NULL);
609     string err;
610     EXPECT_FALSE(parser.ParseTest("rule cat\n"
611                                   "  command = cat\n"
612                                   "build $.: cat foo\n",
613                                   &err));
614     EXPECT_EQ("input:3: bad $-escape (literal $ must be written as $$)\n"
615               "build $.: cat foo\n"
616               "      ^ near here"
617               , err);
618   }
619 
620 
621   {
622     State local_state;
623     ManifestParser parser(&local_state, NULL);
624     string err;
625     EXPECT_FALSE(parser.ParseTest("rule cat\n"
626                                   "  command = cat\n"
627                                   "build $: cat foo\n",
628                                   &err));
629     EXPECT_EQ("input:3: expected ':', got newline ($ also escapes ':')\n"
630               "build $: cat foo\n"
631               "                ^ near here"
632               , err);
633   }
634 
635   {
636     State local_state;
637     ManifestParser parser(&local_state, NULL);
638     string err;
639     EXPECT_FALSE(parser.ParseTest("rule %foo\n",
640                                   &err));
641     EXPECT_EQ("input:1: expected rule name\n"
642               "rule %foo\n"
643               "     ^ near here",
644               err);
645   }
646 
647   {
648     State local_state;
649     ManifestParser parser(&local_state, NULL);
650     string err;
651     EXPECT_FALSE(parser.ParseTest("rule cc\n"
652                                   "  command = foo\n"
653                                   "  othervar = bar\n",
654                                   &err));
655     EXPECT_EQ("input:3: unexpected variable 'othervar'\n"
656               "  othervar = bar\n"
657               "                ^ near here"
658               , err);
659   }
660 
661   {
662     State local_state;
663     ManifestParser parser(&local_state, NULL);
664     string err;
665     EXPECT_FALSE(parser.ParseTest("rule cc\n  command = foo\n"
666                                   "build $.: cc bar.cc\n",
667                                   &err));
668     EXPECT_EQ("input:3: bad $-escape (literal $ must be written as $$)\n"
669               "build $.: cc bar.cc\n"
670               "      ^ near here"
671               , err);
672   }
673 
674   {
675     State local_state;
676     ManifestParser parser(&local_state, NULL);
677     string err;
678     EXPECT_FALSE(parser.ParseTest("rule cc\n  command = foo\n  && bar",
679                                   &err));
680     EXPECT_EQ("input:3: expected variable name\n"
681               "  && bar\n"
682               "  ^ near here",
683               err);
684   }
685 
686   {
687     State local_state;
688     ManifestParser parser(&local_state, NULL);
689     string err;
690     EXPECT_FALSE(parser.ParseTest("rule cc\n  command = foo\n"
691                                   "build $: cc bar.cc\n",
692                                   &err));
693     EXPECT_EQ("input:3: expected ':', got newline ($ also escapes ':')\n"
694               "build $: cc bar.cc\n"
695               "                  ^ near here"
696               , err);
697   }
698 
699   {
700     State local_state;
701     ManifestParser parser(&local_state, NULL);
702     string err;
703     EXPECT_FALSE(parser.ParseTest("default\n",
704                                   &err));
705     EXPECT_EQ("input:1: expected target name\n"
706               "default\n"
707               "       ^ near here"
708               , err);
709   }
710 
711   {
712     State local_state;
713     ManifestParser parser(&local_state, NULL);
714     string err;
715     EXPECT_FALSE(parser.ParseTest("default nonexistent\n",
716                                   &err));
717     EXPECT_EQ("input:1: unknown target 'nonexistent'\n"
718               "default nonexistent\n"
719               "                   ^ near here"
720               , err);
721   }
722 
723   {
724     State local_state;
725     ManifestParser parser(&local_state, NULL);
726     string err;
727     EXPECT_FALSE(parser.ParseTest("rule r\n  command = r\n"
728                                   "build b: r\n"
729                                   "default b:\n",
730                                   &err));
731     EXPECT_EQ("input:4: expected newline, got ':'\n"
732               "default b:\n"
733               "         ^ near here"
734               , err);
735   }
736 
737   {
738     State local_state;
739     ManifestParser parser(&local_state, NULL);
740     string err;
741     EXPECT_FALSE(parser.ParseTest("default $a\n", &err));
742     EXPECT_EQ("input:1: empty path\n"
743               "default $a\n"
744               "          ^ near here"
745               , err);
746   }
747 
748   {
749     State local_state;
750     ManifestParser parser(&local_state, NULL);
751     string err;
752     EXPECT_FALSE(parser.ParseTest("rule r\n"
753                                   "  command = r\n"
754                                   "build $a: r $c\n", &err));
755     // XXX the line number is wrong; we should evaluate paths in ParseEdge
756     // as we see them, not after we've read them all!
757     EXPECT_EQ("input:4: empty path\n", err);
758   }
759 
760   {
761     State local_state;
762     ManifestParser parser(&local_state, NULL);
763     string err;
764     // the indented blank line must terminate the rule
765     // this also verifies that "unexpected (token)" errors are correct
766     EXPECT_FALSE(parser.ParseTest("rule r\n"
767                                   "  command = r\n"
768                                   "  \n"
769                                   "  generator = 1\n", &err));
770     EXPECT_EQ("input:4: unexpected indent\n", err);
771   }
772 
773   {
774     State local_state;
775     ManifestParser parser(&local_state, NULL);
776     string err;
777     EXPECT_FALSE(parser.ParseTest("pool\n", &err));
778     EXPECT_EQ("input:1: expected pool name\n"
779               "pool\n"
780               "    ^ near here", err);
781   }
782 
783   {
784     State local_state;
785     ManifestParser parser(&local_state, NULL);
786     string err;
787     EXPECT_FALSE(parser.ParseTest("pool foo\n", &err));
788     EXPECT_EQ("input:2: expected 'depth =' line\n", err);
789   }
790 
791   {
792     State local_state;
793     ManifestParser parser(&local_state, NULL);
794     string err;
795     EXPECT_FALSE(parser.ParseTest("pool foo\n"
796                                   "  depth = 4\n"
797                                   "pool foo\n", &err));
798     EXPECT_EQ("input:3: duplicate pool 'foo'\n"
799               "pool foo\n"
800               "        ^ near here"
801               , err);
802   }
803 
804   {
805     State local_state;
806     ManifestParser parser(&local_state, NULL);
807     string err;
808     EXPECT_FALSE(parser.ParseTest("pool foo\n"
809                                   "  depth = -1\n", &err));
810     EXPECT_EQ("input:2: invalid pool depth\n"
811               "  depth = -1\n"
812               "            ^ near here"
813               , err);
814   }
815 
816   {
817     State local_state;
818     ManifestParser parser(&local_state, NULL);
819     string err;
820     EXPECT_FALSE(parser.ParseTest("pool foo\n"
821                                   "  bar = 1\n", &err));
822     EXPECT_EQ("input:2: unexpected variable 'bar'\n"
823               "  bar = 1\n"
824               "         ^ near here"
825               , err);
826   }
827 
828   {
829     State local_state;
830     ManifestParser parser(&local_state, NULL);
831     string err;
832     // Pool names are dereferenced at edge parsing time.
833     EXPECT_FALSE(parser.ParseTest("rule run\n"
834                                   "  command = echo\n"
835                                   "  pool = unnamed_pool\n"
836                                   "build out: run in\n", &err));
837     EXPECT_EQ("input:5: unknown pool name 'unnamed_pool'\n", err);
838   }
839 }
840 
TEST_F(ParserTest,MissingInput)841 TEST_F(ParserTest, MissingInput) {
842   State local_state;
843   ManifestParser parser(&local_state, &fs_);
844   string err;
845   EXPECT_FALSE(parser.Load("build.ninja", &err));
846   EXPECT_EQ("loading 'build.ninja': No such file or directory", err);
847 }
848 
TEST_F(ParserTest,MultipleOutputs)849 TEST_F(ParserTest, MultipleOutputs) {
850   State local_state;
851   ManifestParser parser(&local_state, NULL);
852   string err;
853   EXPECT_TRUE(parser.ParseTest("rule cc\n  command = foo\n  depfile = bar\n"
854                                "build a.o b.o: cc c.cc\n",
855                                &err));
856   EXPECT_EQ("", err);
857 }
858 
TEST_F(ParserTest,MultipleOutputsWithDeps)859 TEST_F(ParserTest, MultipleOutputsWithDeps) {
860   State local_state;
861   ManifestParser parser(&local_state, NULL);
862   string err;
863   EXPECT_TRUE(parser.ParseTest("rule cc\n  command = foo\n  deps = gcc\n"
864                                "build a.o b.o: cc c.cc\n",
865                                &err));
866   EXPECT_EQ("", err);
867 }
868 
TEST_F(ParserTest,SubNinja)869 TEST_F(ParserTest, SubNinja) {
870   fs_.Create("test.ninja",
871     "var = inner\n"
872     "build $builddir/inner: varref\n");
873   ASSERT_NO_FATAL_FAILURE(AssertParse(
874 "builddir = some_dir/\n"
875 "rule varref\n"
876 "  command = varref $var\n"
877 "var = outer\n"
878 "build $builddir/outer: varref\n"
879 "subninja test.ninja\n"
880 "build $builddir/outer2: varref\n"));
881   ASSERT_EQ(1u, fs_.files_read_.size());
882 
883   EXPECT_EQ("test.ninja", fs_.files_read_[0]);
884   EXPECT_TRUE(state.LookupNode("some_dir/outer"));
885   // Verify our builddir setting is inherited.
886   EXPECT_TRUE(state.LookupNode("some_dir/inner"));
887 
888   ASSERT_EQ(3u, state.edges_.size());
889   EXPECT_EQ("varref outer", state.edges_[0]->EvaluateCommand());
890   EXPECT_EQ("varref inner", state.edges_[1]->EvaluateCommand());
891   EXPECT_EQ("varref outer", state.edges_[2]->EvaluateCommand());
892 }
893 
TEST_F(ParserTest,MissingSubNinja)894 TEST_F(ParserTest, MissingSubNinja) {
895   ManifestParser parser(&state, &fs_);
896   string err;
897   EXPECT_FALSE(parser.ParseTest("subninja foo.ninja\n", &err));
898   EXPECT_EQ("input:1: loading 'foo.ninja': No such file or directory\n"
899             "subninja foo.ninja\n"
900             "                  ^ near here"
901             , err);
902 }
903 
TEST_F(ParserTest,DuplicateRuleInDifferentSubninjas)904 TEST_F(ParserTest, DuplicateRuleInDifferentSubninjas) {
905   // Test that rules are scoped to subninjas.
906   fs_.Create("test.ninja", "rule cat\n"
907                          "  command = cat\n");
908   ManifestParser parser(&state, &fs_);
909   string err;
910   EXPECT_TRUE(parser.ParseTest("rule cat\n"
911                                 "  command = cat\n"
912                                 "subninja test.ninja\n", &err));
913 }
914 
TEST_F(ParserTest,DuplicateRuleInDifferentSubninjasWithInclude)915 TEST_F(ParserTest, DuplicateRuleInDifferentSubninjasWithInclude) {
916   // Test that rules are scoped to subninjas even with includes.
917   fs_.Create("rules.ninja", "rule cat\n"
918                          "  command = cat\n");
919   fs_.Create("test.ninja", "include rules.ninja\n"
920                          "build x : cat\n");
921   ManifestParser parser(&state, &fs_);
922   string err;
923   EXPECT_TRUE(parser.ParseTest("include rules.ninja\n"
924                                 "subninja test.ninja\n"
925                                 "build y : cat\n", &err));
926 }
927 
TEST_F(ParserTest,Include)928 TEST_F(ParserTest, Include) {
929   fs_.Create("include.ninja", "var = inner\n");
930   ASSERT_NO_FATAL_FAILURE(AssertParse(
931 "var = outer\n"
932 "include include.ninja\n"));
933 
934   ASSERT_EQ(1u, fs_.files_read_.size());
935   EXPECT_EQ("include.ninja", fs_.files_read_[0]);
936   EXPECT_EQ("inner", state.bindings_.LookupVariable("var"));
937 }
938 
TEST_F(ParserTest,BrokenInclude)939 TEST_F(ParserTest, BrokenInclude) {
940   fs_.Create("include.ninja", "build\n");
941   ManifestParser parser(&state, &fs_);
942   string err;
943   EXPECT_FALSE(parser.ParseTest("include include.ninja\n", &err));
944   EXPECT_EQ("include.ninja:1: expected path\n"
945             "build\n"
946             "     ^ near here"
947             , err);
948 }
949 
TEST_F(ParserTest,Implicit)950 TEST_F(ParserTest, Implicit) {
951   ASSERT_NO_FATAL_FAILURE(AssertParse(
952 "rule cat\n"
953 "  command = cat $in > $out\n"
954 "build foo: cat bar | baz\n"));
955 
956   Edge* edge = state.LookupNode("foo")->in_edge();
957   ASSERT_TRUE(edge->is_implicit(1));
958 }
959 
TEST_F(ParserTest,OrderOnly)960 TEST_F(ParserTest, OrderOnly) {
961   ASSERT_NO_FATAL_FAILURE(AssertParse(
962 "rule cat\n  command = cat $in > $out\n"
963 "build foo: cat bar || baz\n"));
964 
965   Edge* edge = state.LookupNode("foo")->in_edge();
966   ASSERT_TRUE(edge->is_order_only(1));
967 }
968 
TEST_F(ParserTest,ImplicitOutput)969 TEST_F(ParserTest, ImplicitOutput) {
970   ASSERT_NO_FATAL_FAILURE(AssertParse(
971 "rule cat\n"
972 "  command = cat $in > $out\n"
973 "build foo | imp: cat bar\n"));
974 
975   Edge* edge = state.LookupNode("imp")->in_edge();
976   ASSERT_EQ(edge->outputs_.size(), 2);
977   EXPECT_TRUE(edge->is_implicit_out(1));
978 }
979 
TEST_F(ParserTest,ImplicitOutputEmpty)980 TEST_F(ParserTest, ImplicitOutputEmpty) {
981   ASSERT_NO_FATAL_FAILURE(AssertParse(
982 "rule cat\n"
983 "  command = cat $in > $out\n"
984 "build foo | : cat bar\n"));
985 
986   Edge* edge = state.LookupNode("foo")->in_edge();
987   ASSERT_EQ(edge->outputs_.size(), 1);
988   EXPECT_FALSE(edge->is_implicit_out(0));
989 }
990 
TEST_F(ParserTest,ImplicitOutputDupe)991 TEST_F(ParserTest, ImplicitOutputDupe) {
992   ASSERT_NO_FATAL_FAILURE(AssertParse(
993 "rule cat\n"
994 "  command = cat $in > $out\n"
995 "build foo baz | foo baq foo: cat bar\n"));
996 
997   Edge* edge = state.LookupNode("foo")->in_edge();
998   ASSERT_EQ(edge->outputs_.size(), 3);
999   EXPECT_FALSE(edge->is_implicit_out(0));
1000   EXPECT_FALSE(edge->is_implicit_out(1));
1001   EXPECT_TRUE(edge->is_implicit_out(2));
1002 }
1003 
TEST_F(ParserTest,ImplicitOutputDupes)1004 TEST_F(ParserTest, ImplicitOutputDupes) {
1005   ASSERT_NO_FATAL_FAILURE(AssertParse(
1006 "rule cat\n"
1007 "  command = cat $in > $out\n"
1008 "build foo foo foo | foo foo foo foo: cat bar\n"));
1009 
1010   Edge* edge = state.LookupNode("foo")->in_edge();
1011   ASSERT_EQ(edge->outputs_.size(), 1);
1012   EXPECT_FALSE(edge->is_implicit_out(0));
1013 }
1014 
TEST_F(ParserTest,NoExplicitOutput)1015 TEST_F(ParserTest, NoExplicitOutput) {
1016   ManifestParser parser(&state, NULL);
1017   string err;
1018   EXPECT_TRUE(parser.ParseTest(
1019 "rule cat\n"
1020 "  command = cat $in > $out\n"
1021 "build | imp : cat bar\n", &err));
1022 }
1023 
TEST_F(ParserTest,DefaultDefault)1024 TEST_F(ParserTest, DefaultDefault) {
1025   ASSERT_NO_FATAL_FAILURE(AssertParse(
1026 "rule cat\n  command = cat $in > $out\n"
1027 "build a: cat foo\n"
1028 "build b: cat foo\n"
1029 "build c: cat foo\n"
1030 "build d: cat foo\n"));
1031 
1032   string err;
1033   EXPECT_EQ(4u, state.DefaultNodes(&err).size());
1034   EXPECT_EQ("", err);
1035 }
1036 
TEST_F(ParserTest,DefaultDefaultCycle)1037 TEST_F(ParserTest, DefaultDefaultCycle) {
1038   ASSERT_NO_FATAL_FAILURE(AssertParse(
1039 "rule cat\n  command = cat $in > $out\n"
1040 "build a: cat a\n"));
1041 
1042   string err;
1043   EXPECT_EQ(0u, state.DefaultNodes(&err).size());
1044   EXPECT_EQ("could not determine root nodes of build graph", err);
1045 }
1046 
TEST_F(ParserTest,DefaultStatements)1047 TEST_F(ParserTest, DefaultStatements) {
1048   ASSERT_NO_FATAL_FAILURE(AssertParse(
1049 "rule cat\n  command = cat $in > $out\n"
1050 "build a: cat foo\n"
1051 "build b: cat foo\n"
1052 "build c: cat foo\n"
1053 "build d: cat foo\n"
1054 "third = c\n"
1055 "default a b\n"
1056 "default $third\n"));
1057 
1058   string err;
1059   vector<Node*> nodes = state.DefaultNodes(&err);
1060   EXPECT_EQ("", err);
1061   ASSERT_EQ(3u, nodes.size());
1062   EXPECT_EQ("a", nodes[0]->path());
1063   EXPECT_EQ("b", nodes[1]->path());
1064   EXPECT_EQ("c", nodes[2]->path());
1065 }
1066 
TEST_F(ParserTest,UTF8)1067 TEST_F(ParserTest, UTF8) {
1068   ASSERT_NO_FATAL_FAILURE(AssertParse(
1069 "rule utf8\n"
1070 "  command = true\n"
1071 "  description = compilaci\xC3\xB3\n"));
1072 }
1073 
TEST_F(ParserTest,CRLF)1074 TEST_F(ParserTest, CRLF) {
1075   State local_state;
1076   ManifestParser parser(&local_state, NULL);
1077   string err;
1078 
1079   EXPECT_TRUE(parser.ParseTest("# comment with crlf\r\n", &err));
1080   EXPECT_TRUE(parser.ParseTest("foo = foo\nbar = bar\r\n", &err));
1081   EXPECT_TRUE(parser.ParseTest(
1082       "pool link_pool\r\n"
1083       "  depth = 15\r\n\r\n"
1084       "rule xyz\r\n"
1085       "  command = something$expand \r\n"
1086       "  description = YAY!\r\n",
1087       &err));
1088 }
1089 
TEST_F(ParserTest,DyndepNotSpecified)1090 TEST_F(ParserTest, DyndepNotSpecified) {
1091   ASSERT_NO_FATAL_FAILURE(AssertParse(
1092 "rule cat\n"
1093 "  command = cat $in > $out\n"
1094 "build result: cat in\n"));
1095   Edge* edge = state.GetNode("result", 0)->in_edge();
1096   ASSERT_FALSE(edge->dyndep_);
1097 }
1098 
TEST_F(ParserTest,DyndepNotInput)1099 TEST_F(ParserTest, DyndepNotInput) {
1100   State lstate;
1101   ManifestParser parser(&lstate, NULL);
1102   string err;
1103   EXPECT_FALSE(parser.ParseTest(
1104 "rule touch\n"
1105 "  command = touch $out\n"
1106 "build result: touch\n"
1107 "  dyndep = notin\n",
1108                                &err));
1109   EXPECT_EQ("input:5: dyndep 'notin' is not an input\n", err);
1110 }
1111 
TEST_F(ParserTest,DyndepExplicitInput)1112 TEST_F(ParserTest, DyndepExplicitInput) {
1113   ASSERT_NO_FATAL_FAILURE(AssertParse(
1114 "rule cat\n"
1115 "  command = cat $in > $out\n"
1116 "build result: cat in\n"
1117 "  dyndep = in\n"));
1118   Edge* edge = state.GetNode("result", 0)->in_edge();
1119   ASSERT_TRUE(edge->dyndep_);
1120   EXPECT_TRUE(edge->dyndep_->dyndep_pending());
1121   EXPECT_EQ(edge->dyndep_->path(), "in");
1122 }
1123 
TEST_F(ParserTest,DyndepImplicitInput)1124 TEST_F(ParserTest, DyndepImplicitInput) {
1125   ASSERT_NO_FATAL_FAILURE(AssertParse(
1126 "rule cat\n"
1127 "  command = cat $in > $out\n"
1128 "build result: cat in | dd\n"
1129 "  dyndep = dd\n"));
1130   Edge* edge = state.GetNode("result", 0)->in_edge();
1131   ASSERT_TRUE(edge->dyndep_);
1132   EXPECT_TRUE(edge->dyndep_->dyndep_pending());
1133   EXPECT_EQ(edge->dyndep_->path(), "dd");
1134 }
1135 
TEST_F(ParserTest,DyndepOrderOnlyInput)1136 TEST_F(ParserTest, DyndepOrderOnlyInput) {
1137   ASSERT_NO_FATAL_FAILURE(AssertParse(
1138 "rule cat\n"
1139 "  command = cat $in > $out\n"
1140 "build result: cat in || dd\n"
1141 "  dyndep = dd\n"));
1142   Edge* edge = state.GetNode("result", 0)->in_edge();
1143   ASSERT_TRUE(edge->dyndep_);
1144   EXPECT_TRUE(edge->dyndep_->dyndep_pending());
1145   EXPECT_EQ(edge->dyndep_->path(), "dd");
1146 }
1147 
TEST_F(ParserTest,DyndepRuleInput)1148 TEST_F(ParserTest, DyndepRuleInput) {
1149   ASSERT_NO_FATAL_FAILURE(AssertParse(
1150 "rule cat\n"
1151 "  command = cat $in > $out\n"
1152 "  dyndep = $in\n"
1153 "build result: cat in\n"));
1154   Edge* edge = state.GetNode("result", 0)->in_edge();
1155   ASSERT_TRUE(edge->dyndep_);
1156   EXPECT_TRUE(edge->dyndep_->dyndep_pending());
1157   EXPECT_EQ(edge->dyndep_->path(), "in");
1158 }
1159