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