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