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\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\n", err);
386 }
387
TEST_F(ParserTest, PhonySelfReferenceIgnored)388 TEST_F(ParserTest, PhonySelfReferenceIgnored) {
389 ASSERT_NO_FATAL_FAILURE(AssertParse(
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
TEST_F(ParserTest, PhonySelfReferenceKept)398 TEST_F(ParserTest, PhonySelfReferenceKept) {
399 const char kInput[] =
400 "build a: phony a\n";
401 ManifestParserOptions parser_opts;
402 parser_opts.phony_cycle_action_ = kPhonyCycleActionError;
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
TEST_F(ParserTest, ReservedWords)414 TEST_F(ParserTest, ReservedWords) {
415 ASSERT_NO_FATAL_FAILURE(AssertParse(
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
TEST_F(ParserTest, Errors)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
TEST_F(ParserTest, MissingInput)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
TEST_F(ParserTest, MultipleOutputs)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
TEST_F(ParserTest, MultipleOutputsWithDeps)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
TEST_F(ParserTest, SubNinja)868 TEST_F(ParserTest, SubNinja) {
869 fs_.Create("test.ninja",
870 "var = inner\n"
871 "build $builddir/inner: varref\n");
872 ASSERT_NO_FATAL_FAILURE(AssertParse(
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
TEST_F(ParserTest, MissingSubNinja)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
TEST_F(ParserTest, DuplicateRuleInDifferentSubninjas)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
TEST_F(ParserTest, DuplicateRuleInDifferentSubninjasWithInclude)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
TEST_F(ParserTest, Include)927 TEST_F(ParserTest, Include) {
928 fs_.Create("include.ninja", "var = inner\n");
929 ASSERT_NO_FATAL_FAILURE(AssertParse(
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
TEST_F(ParserTest, BrokenInclude)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
TEST_F(ParserTest, Implicit)949 TEST_F(ParserTest, Implicit) {
950 ASSERT_NO_FATAL_FAILURE(AssertParse(
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
TEST_F(ParserTest, OrderOnly)959 TEST_F(ParserTest, OrderOnly) {
960 ASSERT_NO_FATAL_FAILURE(AssertParse(
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
TEST_F(ParserTest, Validations)968 TEST_F(ParserTest, Validations) {
969 ASSERT_NO_FATAL_FAILURE(AssertParse(
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
TEST_F(ParserTest, ImplicitOutput)978 TEST_F(ParserTest, ImplicitOutput) {
979 ASSERT_NO_FATAL_FAILURE(AssertParse(
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
TEST_F(ParserTest, ImplicitOutputEmpty)989 TEST_F(ParserTest, ImplicitOutputEmpty) {
990 ASSERT_NO_FATAL_FAILURE(AssertParse(
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
TEST_F(ParserTest, ImplicitOutputDupe)1000 TEST_F(ParserTest, ImplicitOutputDupe) {
1001 ASSERT_NO_FATAL_FAILURE(AssertParse(
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
TEST_F(ParserTest, ImplicitOutputDupes)1013 TEST_F(ParserTest, ImplicitOutputDupes) {
1014 ASSERT_NO_FATAL_FAILURE(AssertParse(
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
TEST_F(ParserTest, NoExplicitOutput)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
TEST_F(ParserTest, DefaultDefault)1033 TEST_F(ParserTest, DefaultDefault) {
1034 ASSERT_NO_FATAL_FAILURE(AssertParse(
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
TEST_F(ParserTest, DefaultDefaultCycle)1046 TEST_F(ParserTest, DefaultDefaultCycle) {
1047 ASSERT_NO_FATAL_FAILURE(AssertParse(
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
TEST_F(ParserTest, DefaultStatements)1056 TEST_F(ParserTest, DefaultStatements) {
1057 ASSERT_NO_FATAL_FAILURE(AssertParse(
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
TEST_F(ParserTest, UTF8)1076 TEST_F(ParserTest, UTF8) {
1077 ASSERT_NO_FATAL_FAILURE(AssertParse(
1078 "rule utf8\n"
1079 " command = true\n"
1080 " description = compilaci\xC3\xB3\n"));
1081 }
1082
TEST_F(ParserTest, CRLF)1083 TEST_F(ParserTest, CRLF) {
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
TEST_F(ParserTest, DyndepNotSpecified)1099 TEST_F(ParserTest, DyndepNotSpecified) {
1100 ASSERT_NO_FATAL_FAILURE(AssertParse(
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
TEST_F(ParserTest, DyndepNotInput)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
TEST_F(ParserTest, DyndepExplicitInput)1121 TEST_F(ParserTest, DyndepExplicitInput) {
1122 ASSERT_NO_FATAL_FAILURE(AssertParse(
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_);
1129 EXPECT_TRUE(edge->dyndep_->dyndep_pending());
1130 EXPECT_EQ(edge->dyndep_->path(), "in");
1131 }
1132
TEST_F(ParserTest, DyndepImplicitInput)1133 TEST_F(ParserTest, DyndepImplicitInput) {
1134 ASSERT_NO_FATAL_FAILURE(AssertParse(
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_);
1141 EXPECT_TRUE(edge->dyndep_->dyndep_pending());
1142 EXPECT_EQ(edge->dyndep_->path(), "dd");
1143 }
1144
TEST_F(ParserTest, DyndepOrderOnlyInput)1145 TEST_F(ParserTest, DyndepOrderOnlyInput) {
1146 ASSERT_NO_FATAL_FAILURE(AssertParse(
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_);
1153 EXPECT_TRUE(edge->dyndep_->dyndep_pending());
1154 EXPECT_EQ(edge->dyndep_->path(), "dd");
1155 }
1156
TEST_F(ParserTest, DyndepRuleInput)1157 TEST_F(ParserTest, DyndepRuleInput) {
1158 ASSERT_NO_FATAL_FAILURE(AssertParse(
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_);
1165 EXPECT_TRUE(edge->dyndep_->dyndep_pending());
1166 EXPECT_EQ(edge->dyndep_->path(), "in");
1167 }
1168