Ninja
manifest_parser_test.cc
Go to the documentation of this file.
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 {
27  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 
37 };
38 
39 TEST_F(ParserTest, Empty) {
41 }
42 
43 TEST_F(ParserTest, Rules) {
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 
60 TEST_F(ParserTest, RuleAttributes) {
61  // Check that all of the allowed rule attributes are parsed ok.
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 
75 TEST_F(ParserTest, IgnoreIndentedComments) {
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 
94 TEST_F(ParserTest, IgnoreIndentedBlankLines) {
95  // the indented blanks used to cause parse errors
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 
109 TEST_F(ParserTest, ResponseFiles) {
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 
128 TEST_F(ParserTest, InNewline) {
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 
146 TEST_F(ParserTest, Variables) {
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 
171 TEST_F(ParserTest, VariableScope) {
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 
188 TEST_F(ParserTest, Continuation) {
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 
203 TEST_F(ParserTest, Backslash) {
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 
212 TEST_F(ParserTest, Comment) {
214 "# this is a comment\n"
215 "foo = not # a comment\n"));
216  EXPECT_EQ("not # a comment", state.bindings_.LookupVariable("foo"));
217 }
218 
219 TEST_F(ParserTest, Dollars) {
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 
235 TEST_F(ParserTest, EscapeSpaces) {
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 
248 TEST_F(ParserTest, CanonicalizeFile) {
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
263 TEST_F(ParserTest, CanonicalizeFileBackslashes) {
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 
282 TEST_F(ParserTest, PathVariables) {
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 
293 TEST_F(ParserTest, CanonicalizePaths) {
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
306 TEST_F(ParserTest, CanonicalizePathsBackslashes) {
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 
333 TEST_F(ParserTest, DuplicateEdgeWithMultipleOutputs) {
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 
345 TEST_F(ParserTest, NoDeadPointerFromDuplicateEdge) {
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 
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;
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\n", err);
369 }
370 
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;
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\n", err);
386 }
387 
388 TEST_F(ParserTest, PhonySelfReferenceIgnored) {
390 "build a: phony a\n"
391 ));
392 
393  Node* node = state.LookupNode("a");
394  Edge* edge = node->in_edge();
395  ASSERT_TRUE(edge->inputs_.empty());
396 }
397 
398 TEST_F(ParserTest, PhonySelfReferenceKept) {
399  const char kInput[] =
400 "build a: phony a\n";
401  ManifestParserOptions parser_opts;
403  ManifestParser parser(&state, &fs_, parser_opts);
404  string err;
405  EXPECT_TRUE(parser.ParseTest(kInput, &err));
406  EXPECT_EQ("", err);
407 
408  Node* node = state.LookupNode("a");
409  Edge* edge = node->in_edge();
410  ASSERT_EQ(edge->inputs_.size(), 1);
411  ASSERT_EQ(edge->inputs_[0], node);
412 }
413 
414 TEST_F(ParserTest, ReservedWords) {
416 "rule build\n"
417 " command = rule run $out\n"
418 "build subninja: build include default foo.cc\n"
419 "default subninja\n"));
420 }
421 
422 TEST_F(ParserTest, Errors) {
423  {
424  State local_state;
425  ManifestParser parser(&local_state, NULL);
426  string err;
427  EXPECT_FALSE(parser.ParseTest(string("subn", 4), &err));
428  EXPECT_EQ("input:1: expected '=', got eof\n"
429  "subn\n"
430  " ^ near here"
431  , err);
432  }
433 
434  {
435  State local_state;
436  ManifestParser parser(&local_state, NULL);
437  string err;
438  EXPECT_FALSE(parser.ParseTest("foobar", &err));
439  EXPECT_EQ("input:1: expected '=', got eof\n"
440  "foobar\n"
441  " ^ near here"
442  , err);
443  }
444 
445  {
446  State local_state;
447  ManifestParser parser(&local_state, NULL);
448  string err;
449  EXPECT_FALSE(parser.ParseTest("x 3", &err));
450  EXPECT_EQ("input:1: expected '=', got identifier\n"
451  "x 3\n"
452  " ^ near here"
453  , err);
454  }
455 
456  {
457  State local_state;
458  ManifestParser parser(&local_state, NULL);
459  string err;
460  EXPECT_FALSE(parser.ParseTest("x = 3", &err));
461  EXPECT_EQ("input:1: unexpected EOF\n"
462  "x = 3\n"
463  " ^ near here"
464  , err);
465  }
466 
467  {
468  State local_state;
469  ManifestParser parser(&local_state, NULL);
470  string err;
471  EXPECT_FALSE(parser.ParseTest("x = 3\ny 2", &err));
472  EXPECT_EQ("input:2: expected '=', got identifier\n"
473  "y 2\n"
474  " ^ near here"
475  , err);
476  }
477 
478  {
479  State local_state;
480  ManifestParser parser(&local_state, NULL);
481  string err;
482  EXPECT_FALSE(parser.ParseTest("x = $", &err));
483  EXPECT_EQ("input:1: bad $-escape (literal $ must be written as $$)\n"
484  "x = $\n"
485  " ^ near here"
486  , err);
487  }
488 
489  {
490  State local_state;
491  ManifestParser parser(&local_state, NULL);
492  string err;
493  EXPECT_FALSE(parser.ParseTest("x = $\n $[\n", &err));
494  EXPECT_EQ("input:2: bad $-escape (literal $ must be written as $$)\n"
495  " $[\n"
496  " ^ near here"
497  , err);
498  }
499 
500  {
501  State local_state;
502  ManifestParser parser(&local_state, NULL);
503  string err;
504  EXPECT_FALSE(parser.ParseTest("x = a$\n b$\n $\n", &err));
505  EXPECT_EQ("input:4: unexpected EOF\n"
506  , err);
507  }
508 
509  {
510  State local_state;
511  ManifestParser parser(&local_state, NULL);
512  string err;
513  EXPECT_FALSE(parser.ParseTest("build\n", &err));
514  EXPECT_EQ("input:1: expected path\n"
515  "build\n"
516  " ^ near here"
517  , err);
518  }
519 
520  {
521  State local_state;
522  ManifestParser parser(&local_state, NULL);
523  string err;
524  EXPECT_FALSE(parser.ParseTest("build x: y z\n", &err));
525  EXPECT_EQ("input:1: unknown build rule 'y'\n"
526  "build x: y z\n"
527  " ^ near here"
528  , err);
529  }
530 
531  {
532  State local_state;
533  ManifestParser parser(&local_state, NULL);
534  string err;
535  EXPECT_FALSE(parser.ParseTest("build x:: y z\n", &err));
536  EXPECT_EQ("input:1: expected build command name\n"
537  "build x:: y z\n"
538  " ^ near here"
539  , err);
540  }
541 
542  {
543  State local_state;
544  ManifestParser parser(&local_state, NULL);
545  string err;
546  EXPECT_FALSE(parser.ParseTest("rule cat\n command = cat ok\n"
547  "build x: cat $\n :\n",
548  &err));
549  EXPECT_EQ("input:4: expected newline, got ':'\n"
550  " :\n"
551  " ^ near here"
552  , err);
553  }
554 
555  {
556  State local_state;
557  ManifestParser parser(&local_state, NULL);
558  string err;
559  EXPECT_FALSE(parser.ParseTest("rule cat\n",
560  &err));
561  EXPECT_EQ("input:2: expected 'command =' line\n", err);
562  }
563 
564  {
565  State local_state;
566  ManifestParser parser(&local_state, NULL);
567  string err;
568  EXPECT_FALSE(parser.ParseTest("rule cat\n"
569  " command = echo\n"
570  "rule cat\n"
571  " command = echo\n", &err));
572  EXPECT_EQ("input:3: duplicate rule 'cat'\n"
573  "rule cat\n"
574  " ^ near here"
575  , err);
576  }
577 
578  {
579  State local_state;
580  ManifestParser parser(&local_state, NULL);
581  string err;
582  EXPECT_FALSE(parser.ParseTest("rule cat\n"
583  " command = echo\n"
584  " rspfile = cat.rsp\n", &err));
585  EXPECT_EQ(
586  "input:4: rspfile and rspfile_content need to be both specified\n",
587  err);
588  }
589 
590  {
591  State local_state;
592  ManifestParser parser(&local_state, NULL);
593  string err;
594  EXPECT_FALSE(parser.ParseTest("rule cat\n"
595  " command = ${fafsd\n"
596  "foo = bar\n",
597  &err));
598  EXPECT_EQ("input:2: bad $-escape (literal $ must be written as $$)\n"
599  " command = ${fafsd\n"
600  " ^ near here"
601  , err);
602  }
603 
604 
605  {
606  State local_state;
607  ManifestParser parser(&local_state, NULL);
608  string err;
609  EXPECT_FALSE(parser.ParseTest("rule cat\n"
610  " command = cat\n"
611  "build $.: cat foo\n",
612  &err));
613  EXPECT_EQ("input:3: bad $-escape (literal $ must be written as $$)\n"
614  "build $.: cat foo\n"
615  " ^ near here"
616  , err);
617  }
618 
619 
620  {
621  State local_state;
622  ManifestParser parser(&local_state, NULL);
623  string err;
624  EXPECT_FALSE(parser.ParseTest("rule cat\n"
625  " command = cat\n"
626  "build $: cat foo\n",
627  &err));
628  EXPECT_EQ("input:3: expected ':', got newline ($ also escapes ':')\n"
629  "build $: cat foo\n"
630  " ^ near here"
631  , err);
632  }
633 
634  {
635  State local_state;
636  ManifestParser parser(&local_state, NULL);
637  string err;
638  EXPECT_FALSE(parser.ParseTest("rule %foo\n",
639  &err));
640  EXPECT_EQ("input:1: expected rule name\n"
641  "rule %foo\n"
642  " ^ near here",
643  err);
644  }
645 
646  {
647  State local_state;
648  ManifestParser parser(&local_state, NULL);
649  string err;
650  EXPECT_FALSE(parser.ParseTest("rule cc\n"
651  " command = foo\n"
652  " othervar = bar\n",
653  &err));
654  EXPECT_EQ("input:3: unexpected variable 'othervar'\n"
655  " othervar = bar\n"
656  " ^ near here"
657  , err);
658  }
659 
660  {
661  State local_state;
662  ManifestParser parser(&local_state, NULL);
663  string err;
664  EXPECT_FALSE(parser.ParseTest("rule cc\n command = foo\n"
665  "build $.: cc bar.cc\n",
666  &err));
667  EXPECT_EQ("input:3: bad $-escape (literal $ must be written as $$)\n"
668  "build $.: cc bar.cc\n"
669  " ^ near here"
670  , err);
671  }
672 
673  {
674  State local_state;
675  ManifestParser parser(&local_state, NULL);
676  string err;
677  EXPECT_FALSE(parser.ParseTest("rule cc\n command = foo\n && bar",
678  &err));
679  EXPECT_EQ("input:3: expected variable name\n"
680  " && bar\n"
681  " ^ near here",
682  err);
683  }
684 
685  {
686  State local_state;
687  ManifestParser parser(&local_state, NULL);
688  string err;
689  EXPECT_FALSE(parser.ParseTest("rule cc\n command = foo\n"
690  "build $: cc bar.cc\n",
691  &err));
692  EXPECT_EQ("input:3: expected ':', got newline ($ also escapes ':')\n"
693  "build $: cc bar.cc\n"
694  " ^ near here"
695  , err);
696  }
697 
698  {
699  State local_state;
700  ManifestParser parser(&local_state, NULL);
701  string err;
702  EXPECT_FALSE(parser.ParseTest("default\n",
703  &err));
704  EXPECT_EQ("input:1: expected target name\n"
705  "default\n"
706  " ^ near here"
707  , err);
708  }
709 
710  {
711  State local_state;
712  ManifestParser parser(&local_state, NULL);
713  string err;
714  EXPECT_FALSE(parser.ParseTest("default nonexistent\n",
715  &err));
716  EXPECT_EQ("input:1: unknown target 'nonexistent'\n"
717  "default nonexistent\n"
718  " ^ near here"
719  , err);
720  }
721 
722  {
723  State local_state;
724  ManifestParser parser(&local_state, NULL);
725  string err;
726  EXPECT_FALSE(parser.ParseTest("rule r\n command = r\n"
727  "build b: r\n"
728  "default b:\n",
729  &err));
730  EXPECT_EQ("input:4: expected newline, got ':'\n"
731  "default b:\n"
732  " ^ near here"
733  , err);
734  }
735 
736  {
737  State local_state;
738  ManifestParser parser(&local_state, NULL);
739  string err;
740  EXPECT_FALSE(parser.ParseTest("default $a\n", &err));
741  EXPECT_EQ("input:1: empty path\n"
742  "default $a\n"
743  " ^ near here"
744  , err);
745  }
746 
747  {
748  State local_state;
749  ManifestParser parser(&local_state, NULL);
750  string err;
751  EXPECT_FALSE(parser.ParseTest("rule r\n"
752  " command = r\n"
753  "build $a: r $c\n", &err));
754  // XXX the line number is wrong; we should evaluate paths in ParseEdge
755  // as we see them, not after we've read them all!
756  EXPECT_EQ("input:4: empty path\n", err);
757  }
758 
759  {
760  State local_state;
761  ManifestParser parser(&local_state, NULL);
762  string err;
763  // the indented blank line must terminate the rule
764  // this also verifies that "unexpected (token)" errors are correct
765  EXPECT_FALSE(parser.ParseTest("rule r\n"
766  " command = r\n"
767  " \n"
768  " generator = 1\n", &err));
769  EXPECT_EQ("input:4: unexpected indent\n", err);
770  }
771 
772  {
773  State local_state;
774  ManifestParser parser(&local_state, NULL);
775  string err;
776  EXPECT_FALSE(parser.ParseTest("pool\n", &err));
777  EXPECT_EQ("input:1: expected pool name\n"
778  "pool\n"
779  " ^ near here", err);
780  }
781 
782  {
783  State local_state;
784  ManifestParser parser(&local_state, NULL);
785  string err;
786  EXPECT_FALSE(parser.ParseTest("pool foo\n", &err));
787  EXPECT_EQ("input:2: expected 'depth =' line\n", err);
788  }
789 
790  {
791  State local_state;
792  ManifestParser parser(&local_state, NULL);
793  string err;
794  EXPECT_FALSE(parser.ParseTest("pool foo\n"
795  " depth = 4\n"
796  "pool foo\n", &err));
797  EXPECT_EQ("input:3: duplicate pool 'foo'\n"
798  "pool foo\n"
799  " ^ near here"
800  , err);
801  }
802 
803  {
804  State local_state;
805  ManifestParser parser(&local_state, NULL);
806  string err;
807  EXPECT_FALSE(parser.ParseTest("pool foo\n"
808  " depth = -1\n", &err));
809  EXPECT_EQ("input:2: invalid pool depth\n"
810  " depth = -1\n"
811  " ^ near here"
812  , err);
813  }
814 
815  {
816  State local_state;
817  ManifestParser parser(&local_state, NULL);
818  string err;
819  EXPECT_FALSE(parser.ParseTest("pool foo\n"
820  " bar = 1\n", &err));
821  EXPECT_EQ("input:2: unexpected variable 'bar'\n"
822  " bar = 1\n"
823  " ^ near here"
824  , err);
825  }
826 
827  {
828  State local_state;
829  ManifestParser parser(&local_state, NULL);
830  string err;
831  // Pool names are dereferenced at edge parsing time.
832  EXPECT_FALSE(parser.ParseTest("rule run\n"
833  " command = echo\n"
834  " pool = unnamed_pool\n"
835  "build out: run in\n", &err));
836  EXPECT_EQ("input:5: unknown pool name 'unnamed_pool'\n", err);
837  }
838 }
839 
840 TEST_F(ParserTest, MissingInput) {
841  State local_state;
842  ManifestParser parser(&local_state, &fs_);
843  string err;
844  EXPECT_FALSE(parser.Load("build.ninja", &err));
845  EXPECT_EQ("loading 'build.ninja': No such file or directory", err);
846 }
847 
848 TEST_F(ParserTest, MultipleOutputs) {
849  State local_state;
850  ManifestParser parser(&local_state, NULL);
851  string err;
852  EXPECT_TRUE(parser.ParseTest("rule cc\n command = foo\n depfile = bar\n"
853  "build a.o b.o: cc c.cc\n",
854  &err));
855  EXPECT_EQ("", err);
856 }
857 
858 TEST_F(ParserTest, MultipleOutputsWithDeps) {
859  State local_state;
860  ManifestParser parser(&local_state, NULL);
861  string err;
862  EXPECT_TRUE(parser.ParseTest("rule cc\n command = foo\n deps = gcc\n"
863  "build a.o b.o: cc c.cc\n",
864  &err));
865  EXPECT_EQ("", err);
866 }
867 
868 TEST_F(ParserTest, SubNinja) {
869  fs_.Create("test.ninja",
870  "var = inner\n"
871  "build $builddir/inner: varref\n");
873 "builddir = some_dir/\n"
874 "rule varref\n"
875 " command = varref $var\n"
876 "var = outer\n"
877 "build $builddir/outer: varref\n"
878 "subninja test.ninja\n"
879 "build $builddir/outer2: varref\n"));
880  ASSERT_EQ(1u, fs_.files_read_.size());
881 
882  EXPECT_EQ("test.ninja", fs_.files_read_[0]);
883  EXPECT_TRUE(state.LookupNode("some_dir/outer"));
884  // Verify our builddir setting is inherited.
885  EXPECT_TRUE(state.LookupNode("some_dir/inner"));
886 
887  ASSERT_EQ(3u, state.edges_.size());
888  EXPECT_EQ("varref outer", state.edges_[0]->EvaluateCommand());
889  EXPECT_EQ("varref inner", state.edges_[1]->EvaluateCommand());
890  EXPECT_EQ("varref outer", state.edges_[2]->EvaluateCommand());
891 }
892 
893 TEST_F(ParserTest, MissingSubNinja) {
894  ManifestParser parser(&state, &fs_);
895  string err;
896  EXPECT_FALSE(parser.ParseTest("subninja foo.ninja\n", &err));
897  EXPECT_EQ("input:1: loading 'foo.ninja': No such file or directory\n"
898  "subninja foo.ninja\n"
899  " ^ near here"
900  , err);
901 }
902 
903 TEST_F(ParserTest, DuplicateRuleInDifferentSubninjas) {
904  // Test that rules are scoped to subninjas.
905  fs_.Create("test.ninja", "rule cat\n"
906  " command = cat\n");
907  ManifestParser parser(&state, &fs_);
908  string err;
909  EXPECT_TRUE(parser.ParseTest("rule cat\n"
910  " command = cat\n"
911  "subninja test.ninja\n", &err));
912 }
913 
914 TEST_F(ParserTest, DuplicateRuleInDifferentSubninjasWithInclude) {
915  // Test that rules are scoped to subninjas even with includes.
916  fs_.Create("rules.ninja", "rule cat\n"
917  " command = cat\n");
918  fs_.Create("test.ninja", "include rules.ninja\n"
919  "build x : cat\n");
920  ManifestParser parser(&state, &fs_);
921  string err;
922  EXPECT_TRUE(parser.ParseTest("include rules.ninja\n"
923  "subninja test.ninja\n"
924  "build y : cat\n", &err));
925 }
926 
927 TEST_F(ParserTest, Include) {
928  fs_.Create("include.ninja", "var = inner\n");
930 "var = outer\n"
931 "include include.ninja\n"));
932 
933  ASSERT_EQ(1u, fs_.files_read_.size());
934  EXPECT_EQ("include.ninja", fs_.files_read_[0]);
935  EXPECT_EQ("inner", state.bindings_.LookupVariable("var"));
936 }
937 
938 TEST_F(ParserTest, BrokenInclude) {
939  fs_.Create("include.ninja", "build\n");
940  ManifestParser parser(&state, &fs_);
941  string err;
942  EXPECT_FALSE(parser.ParseTest("include include.ninja\n", &err));
943  EXPECT_EQ("include.ninja:1: expected path\n"
944  "build\n"
945  " ^ near here"
946  , err);
947 }
948 
949 TEST_F(ParserTest, Implicit) {
951 "rule cat\n"
952 " command = cat $in > $out\n"
953 "build foo: cat bar | baz\n"));
954 
955  Edge* edge = state.LookupNode("foo")->in_edge();
956  ASSERT_TRUE(edge->is_implicit(1));
957 }
958 
959 TEST_F(ParserTest, OrderOnly) {
961 "rule cat\n command = cat $in > $out\n"
962 "build foo: cat bar || baz\n"));
963 
964  Edge* edge = state.LookupNode("foo")->in_edge();
965  ASSERT_TRUE(edge->is_order_only(1));
966 }
967 
968 TEST_F(ParserTest, Validations) {
970 "rule cat\n command = cat $in > $out\n"
971 "build foo: cat bar |@ baz\n"));
972 
973  Edge* edge = state.LookupNode("foo")->in_edge();
974  ASSERT_EQ(edge->validations_.size(), 1);
975  EXPECT_EQ(edge->validations_[0]->path(), "baz");
976 }
977 
978 TEST_F(ParserTest, ImplicitOutput) {
980 "rule cat\n"
981 " command = cat $in > $out\n"
982 "build foo | imp: cat bar\n"));
983 
984  Edge* edge = state.LookupNode("imp")->in_edge();
985  ASSERT_EQ(edge->outputs_.size(), 2);
986  EXPECT_TRUE(edge->is_implicit_out(1));
987 }
988 
989 TEST_F(ParserTest, ImplicitOutputEmpty) {
991 "rule cat\n"
992 " command = cat $in > $out\n"
993 "build foo | : cat bar\n"));
994 
995  Edge* edge = state.LookupNode("foo")->in_edge();
996  ASSERT_EQ(edge->outputs_.size(), 1);
997  EXPECT_FALSE(edge->is_implicit_out(0));
998 }
999 
1000 TEST_F(ParserTest, ImplicitOutputDupe) {
1002 "rule cat\n"
1003 " command = cat $in > $out\n"
1004 "build foo baz | foo baq foo: cat bar\n"));
1005 
1006  Edge* edge = state.LookupNode("foo")->in_edge();
1007  ASSERT_EQ(edge->outputs_.size(), 3);
1008  EXPECT_FALSE(edge->is_implicit_out(0));
1009  EXPECT_FALSE(edge->is_implicit_out(1));
1010  EXPECT_TRUE(edge->is_implicit_out(2));
1011 }
1012 
1013 TEST_F(ParserTest, ImplicitOutputDupes) {
1015 "rule cat\n"
1016 " command = cat $in > $out\n"
1017 "build foo foo foo | foo foo foo foo: cat bar\n"));
1018 
1019  Edge* edge = state.LookupNode("foo")->in_edge();
1020  ASSERT_EQ(edge->outputs_.size(), 1);
1021  EXPECT_FALSE(edge->is_implicit_out(0));
1022 }
1023 
1024 TEST_F(ParserTest, NoExplicitOutput) {
1025  ManifestParser parser(&state, NULL);
1026  string err;
1027  EXPECT_TRUE(parser.ParseTest(
1028 "rule cat\n"
1029 " command = cat $in > $out\n"
1030 "build | imp : cat bar\n", &err));
1031 }
1032 
1033 TEST_F(ParserTest, DefaultDefault) {
1035 "rule cat\n command = cat $in > $out\n"
1036 "build a: cat foo\n"
1037 "build b: cat foo\n"
1038 "build c: cat foo\n"
1039 "build d: cat foo\n"));
1040 
1041  string err;
1042  EXPECT_EQ(4u, state.DefaultNodes(&err).size());
1043  EXPECT_EQ("", err);
1044 }
1045 
1046 TEST_F(ParserTest, DefaultDefaultCycle) {
1048 "rule cat\n command = cat $in > $out\n"
1049 "build a: cat a\n"));
1050 
1051  string err;
1052  EXPECT_EQ(0u, state.DefaultNodes(&err).size());
1053  EXPECT_EQ("could not determine root nodes of build graph", err);
1054 }
1055 
1056 TEST_F(ParserTest, DefaultStatements) {
1058 "rule cat\n command = cat $in > $out\n"
1059 "build a: cat foo\n"
1060 "build b: cat foo\n"
1061 "build c: cat foo\n"
1062 "build d: cat foo\n"
1063 "third = c\n"
1064 "default a b\n"
1065 "default $third\n"));
1066 
1067  string err;
1068  vector<Node*> nodes = state.DefaultNodes(&err);
1069  EXPECT_EQ("", err);
1070  ASSERT_EQ(3u, nodes.size());
1071  EXPECT_EQ("a", nodes[0]->path());
1072  EXPECT_EQ("b", nodes[1]->path());
1073  EXPECT_EQ("c", nodes[2]->path());
1074 }
1075 
1078 "rule utf8\n"
1079 " command = true\n"
1080 " description = compilaci\xC3\xB3\n"));
1081 }
1082 
1084  State local_state;
1085  ManifestParser parser(&local_state, NULL);
1086  string err;
1087 
1088  EXPECT_TRUE(parser.ParseTest("# comment with crlf\r\n", &err));
1089  EXPECT_TRUE(parser.ParseTest("foo = foo\nbar = bar\r\n", &err));
1090  EXPECT_TRUE(parser.ParseTest(
1091  "pool link_pool\r\n"
1092  " depth = 15\r\n\r\n"
1093  "rule xyz\r\n"
1094  " command = something$expand \r\n"
1095  " description = YAY!\r\n",
1096  &err));
1097 }
1098 
1099 TEST_F(ParserTest, DyndepNotSpecified) {
1101 "rule cat\n"
1102 " command = cat $in > $out\n"
1103 "build result: cat in\n"));
1104  Edge* edge = state.GetNode("result", 0)->in_edge();
1105  ASSERT_FALSE(edge->dyndep_);
1106 }
1107 
1108 TEST_F(ParserTest, DyndepNotInput) {
1109  State lstate;
1110  ManifestParser parser(&lstate, NULL);
1111  string err;
1112  EXPECT_FALSE(parser.ParseTest(
1113 "rule touch\n"
1114 " command = touch $out\n"
1115 "build result: touch\n"
1116 " dyndep = notin\n",
1117  &err));
1118  EXPECT_EQ("input:5: dyndep 'notin' is not an input\n", err);
1119 }
1120 
1121 TEST_F(ParserTest, DyndepExplicitInput) {
1123 "rule cat\n"
1124 " command = cat $in > $out\n"
1125 "build result: cat in\n"
1126 " dyndep = in\n"));
1127  Edge* edge = state.GetNode("result", 0)->in_edge();
1128  ASSERT_TRUE(edge->dyndep_);
1130  EXPECT_EQ(edge->dyndep_->path(), "in");
1131 }
1132 
1133 TEST_F(ParserTest, DyndepImplicitInput) {
1135 "rule cat\n"
1136 " command = cat $in > $out\n"
1137 "build result: cat in | dd\n"
1138 " dyndep = dd\n"));
1139  Edge* edge = state.GetNode("result", 0)->in_edge();
1140  ASSERT_TRUE(edge->dyndep_);
1142  EXPECT_EQ(edge->dyndep_->path(), "dd");
1143 }
1144 
1145 TEST_F(ParserTest, DyndepOrderOnlyInput) {
1147 "rule cat\n"
1148 " command = cat $in > $out\n"
1149 "build result: cat in || dd\n"
1150 " dyndep = dd\n"));
1151  Edge* edge = state.GetNode("result", 0)->in_edge();
1152  ASSERT_TRUE(edge->dyndep_);
1154  EXPECT_EQ(edge->dyndep_->path(), "dd");
1155 }
1156 
1157 TEST_F(ParserTest, DyndepRuleInput) {
1159 "rule cat\n"
1160 " command = cat $in > $out\n"
1161 " dyndep = $in\n"
1162 "build result: cat in\n"));
1163  Edge* edge = state.GetNode("result", 0)->in_edge();
1164  ASSERT_TRUE(edge->dyndep_);
1166  EXPECT_EQ(edge->dyndep_->path(), "in");
1167 }
bool dyndep_pending() const
Definition: graph.h:101
An implementation of DiskInterface that uses an in-memory representation of disk state.
Definition: test.h:134
void AssertParse(State *state, const char *input, ManifestParserOptions opts)
Definition: test.cc:100
Edge * in_edge() const
Definition: graph.h:104
std::vector< Node * > validations_
Definition: graph.h:205
PhonyCycleAction phony_cycle_action_
VirtualFileSystem fs_
#define EXPECT_TRUE(a)
Definition: test.h:76
Information about a node in the dependency graph: the file, whether it&#39;s dirty, mtime, etc.
Definition: graph.h:39
#define EXPECT_FALSE(a)
Definition: test.h:78
uint64_t slash_bits() const
Definition: graph.h:93
bool is_implicit_out(size_t index) const
Definition: graph.h:244
std::vector< Node * > outputs_
Definition: graph.h:204
bool Load(const std::string &filename, std::string *err, Lexer *parent=NULL)
Load and parse a file.
Definition: parser.cc:22
An edge in the dependency graph; links between Nodes using Rules.
Definition: graph.h:164
bool is_order_only(size_t index)
Definition: graph.h:234
const std::string & path() const
Definition: graph.h:86
Parses .ninja files.
bool is_implicit(size_t index)
Definition: graph.h:230
#define EXPECT_EQ(a, b)
Definition: test.h:64
An invocable build command and associated metadata (description, etc.).
Definition: eval_env.h:59
#define ASSERT_FALSE(a)
Definition: test.h:95
TEST_F(ParserTest, Empty)
void VerifyGraph(const State &state)
Definition: test.cc:113
void AssertParse(const char *input)
std::vector< Node * > inputs_
Definition: graph.h:203
#define ASSERT_EQ(a, b)
Definition: test.h:81
bool ParseTest(const std::string &input, std::string *err)
Parse a text string of input. Used by tests.
#define ASSERT_NO_FATAL_FAILURE(a)
Definition: test.h:97
Global state (file status) for a single run.
Definition: state.h:92
#define ASSERT_TRUE(a)
Definition: test.h:93
Bindings bindings_
Definition: eval_env.h:76
DupeEdgeAction dupe_edge_action_
Node * dyndep_
Definition: graph.h:206