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