Ninja
|
00001 // Copyright 2011 Google Inc. All Rights Reserved. 00002 // 00003 // Licensed under the Apache License, Version 2.0 (the "License"); 00004 // you may not use this file except in compliance with the License. 00005 // You may obtain a copy of the License at 00006 // 00007 // http://www.apache.org/licenses/LICENSE-2.0 00008 // 00009 // Unless required by applicable law or agreed to in writing, software 00010 // distributed under the License is distributed on an "AS IS" BASIS, 00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00012 // See the License for the specific language governing permissions and 00013 // limitations under the License. 00014 00015 #include "manifest_parser.h" 00016 00017 #include <map> 00018 #include <vector> 00019 00020 #include <gtest/gtest.h> 00021 00022 #include "graph.h" 00023 #include "state.h" 00024 00025 struct ParserTest : public testing::Test, 00026 public ManifestParser::FileReader { 00027 void AssertParse(const char* input) { 00028 ManifestParser parser(&state, this); 00029 string err; 00030 ASSERT_TRUE(parser.ParseTest(input, &err)) << err; 00031 ASSERT_EQ("", err); 00032 } 00033 00034 virtual bool ReadFile(const string& path, string* content, string* err) { 00035 files_read_.push_back(path); 00036 map<string, string>::iterator i = files_.find(path); 00037 if (i == files_.end()) { 00038 *err = "No such file or directory"; // Match strerror() for ENOENT. 00039 return false; 00040 } 00041 *content = i->second; 00042 return true; 00043 } 00044 00045 State state; 00046 map<string, string> files_; 00047 vector<string> files_read_; 00048 }; 00049 00050 TEST_F(ParserTest, Empty) { 00051 ASSERT_NO_FATAL_FAILURE(AssertParse("")); 00052 } 00053 00054 TEST_F(ParserTest, Rules) { 00055 ASSERT_NO_FATAL_FAILURE(AssertParse( 00056 "rule cat\n" 00057 " command = cat $in > $out\n" 00058 "\n" 00059 "rule date\n" 00060 " command = date > $out\n" 00061 "\n" 00062 "build result: cat in_1.cc in-2.O\n")); 00063 00064 ASSERT_EQ(3u, state.rules_.size()); 00065 const Rule* rule = state.rules_.begin()->second; 00066 EXPECT_EQ("cat", rule->name()); 00067 EXPECT_EQ("[cat ][$in][ > ][$out]", 00068 rule->GetBinding("command")->Serialize()); 00069 } 00070 00071 TEST_F(ParserTest, RuleAttributes) { 00072 // Check that all of the allowed rule attributes are parsed ok. 00073 ASSERT_NO_FATAL_FAILURE(AssertParse( 00074 "rule cat\n" 00075 " command = a\n" 00076 " depfile = a\n" 00077 " deps = a\n" 00078 " description = a\n" 00079 " generator = a\n" 00080 " restat = a\n" 00081 " rspfile = a\n" 00082 " rspfile_content = a\n" 00083 )); 00084 } 00085 00086 TEST_F(ParserTest, IgnoreIndentedComments) { 00087 ASSERT_NO_FATAL_FAILURE(AssertParse( 00088 " #indented comment\n" 00089 "rule cat\n" 00090 " command = cat $in > $out\n" 00091 " #generator = 1\n" 00092 " restat = 1 # comment\n" 00093 " #comment\n" 00094 "build result: cat in_1.cc in-2.O\n" 00095 " #comment\n")); 00096 00097 ASSERT_EQ(2u, state.rules_.size()); 00098 const Rule* rule = state.rules_.begin()->second; 00099 EXPECT_EQ("cat", rule->name()); 00100 Edge* edge = state.GetNode("result")->in_edge(); 00101 EXPECT_TRUE(edge->GetBindingBool("restat")); 00102 EXPECT_FALSE(edge->GetBindingBool("generator")); 00103 } 00104 00105 TEST_F(ParserTest, IgnoreIndentedBlankLines) { 00106 // the indented blanks used to cause parse errors 00107 ASSERT_NO_FATAL_FAILURE(AssertParse( 00108 " \n" 00109 "rule cat\n" 00110 " command = cat $in > $out\n" 00111 " \n" 00112 "build result: cat in_1.cc in-2.O\n" 00113 " \n" 00114 "variable=1\n")); 00115 00116 // the variable must be in the top level environment 00117 EXPECT_EQ("1", state.bindings_.LookupVariable("variable")); 00118 } 00119 00120 TEST_F(ParserTest, ResponseFiles) { 00121 ASSERT_NO_FATAL_FAILURE(AssertParse( 00122 "rule cat_rsp\n" 00123 " command = cat $rspfile > $out\n" 00124 " rspfile = $rspfile\n" 00125 " rspfile_content = $in\n" 00126 "\n" 00127 "build out: cat_rsp in\n" 00128 " rspfile=out.rsp\n")); 00129 00130 ASSERT_EQ(2u, state.rules_.size()); 00131 const Rule* rule = state.rules_.begin()->second; 00132 EXPECT_EQ("cat_rsp", rule->name()); 00133 EXPECT_EQ("[cat ][$rspfile][ > ][$out]", 00134 rule->GetBinding("command")->Serialize()); 00135 EXPECT_EQ("[$rspfile]", rule->GetBinding("rspfile")->Serialize()); 00136 EXPECT_EQ("[$in]", rule->GetBinding("rspfile_content")->Serialize()); 00137 } 00138 00139 TEST_F(ParserTest, InNewline) { 00140 ASSERT_NO_FATAL_FAILURE(AssertParse( 00141 "rule cat_rsp\n" 00142 " command = cat $in_newline > $out\n" 00143 "\n" 00144 "build out: cat_rsp in in2\n" 00145 " rspfile=out.rsp\n")); 00146 00147 ASSERT_EQ(2u, state.rules_.size()); 00148 const Rule* rule = state.rules_.begin()->second; 00149 EXPECT_EQ("cat_rsp", rule->name()); 00150 EXPECT_EQ("[cat ][$in_newline][ > ][$out]", 00151 rule->GetBinding("command")->Serialize()); 00152 00153 Edge* edge = state.edges_[0]; 00154 EXPECT_EQ("cat in\nin2 > out", edge->EvaluateCommand()); 00155 } 00156 00157 TEST_F(ParserTest, Variables) { 00158 ASSERT_NO_FATAL_FAILURE(AssertParse( 00159 "l = one-letter-test\n" 00160 "rule link\n" 00161 " command = ld $l $extra $with_under -o $out $in\n" 00162 "\n" 00163 "extra = -pthread\n" 00164 "with_under = -under\n" 00165 "build a: link b c\n" 00166 "nested1 = 1\n" 00167 "nested2 = $nested1/2\n" 00168 "build supernested: link x\n" 00169 " extra = $nested2/3\n")); 00170 00171 ASSERT_EQ(2u, state.edges_.size()); 00172 Edge* edge = state.edges_[0]; 00173 EXPECT_EQ("ld one-letter-test -pthread -under -o a b c", 00174 edge->EvaluateCommand()); 00175 EXPECT_EQ("1/2", state.bindings_.LookupVariable("nested2")); 00176 00177 edge = state.edges_[1]; 00178 EXPECT_EQ("ld one-letter-test 1/2/3 -under -o supernested x", 00179 edge->EvaluateCommand()); 00180 } 00181 00182 TEST_F(ParserTest, VariableScope) { 00183 ASSERT_NO_FATAL_FAILURE(AssertParse( 00184 "foo = bar\n" 00185 "rule cmd\n" 00186 " command = cmd $foo $in $out\n" 00187 "\n" 00188 "build inner: cmd a\n" 00189 " foo = baz\n" 00190 "build outer: cmd b\n" 00191 "\n" // Extra newline after build line tickles a regression. 00192 )); 00193 00194 ASSERT_EQ(2u, state.edges_.size()); 00195 EXPECT_EQ("cmd baz a inner", state.edges_[0]->EvaluateCommand()); 00196 EXPECT_EQ("cmd bar b outer", state.edges_[1]->EvaluateCommand()); 00197 } 00198 00199 TEST_F(ParserTest, Continuation) { 00200 ASSERT_NO_FATAL_FAILURE(AssertParse( 00201 "rule link\n" 00202 " command = foo bar $\n" 00203 " baz\n" 00204 "\n" 00205 "build a: link c $\n" 00206 " d e f\n")); 00207 00208 ASSERT_EQ(2u, state.rules_.size()); 00209 const Rule* rule = state.rules_.begin()->second; 00210 EXPECT_EQ("link", rule->name()); 00211 EXPECT_EQ("[foo bar baz]", rule->GetBinding("command")->Serialize()); 00212 } 00213 00214 TEST_F(ParserTest, Backslash) { 00215 ASSERT_NO_FATAL_FAILURE(AssertParse( 00216 "foo = bar\\baz\n" 00217 "foo2 = bar\\ baz\n" 00218 )); 00219 EXPECT_EQ("bar\\baz", state.bindings_.LookupVariable("foo")); 00220 EXPECT_EQ("bar\\ baz", state.bindings_.LookupVariable("foo2")); 00221 } 00222 00223 TEST_F(ParserTest, Comment) { 00224 ASSERT_NO_FATAL_FAILURE(AssertParse( 00225 "# this is a comment\n" 00226 "foo = not # a comment\n")); 00227 EXPECT_EQ("not # a comment", state.bindings_.LookupVariable("foo")); 00228 } 00229 00230 TEST_F(ParserTest, Dollars) { 00231 ASSERT_NO_FATAL_FAILURE(AssertParse( 00232 "rule foo\n" 00233 " command = ${out}bar$$baz$$$\n" 00234 "blah\n" 00235 "x = $$dollar\n" 00236 "build $x: foo y\n" 00237 )); 00238 EXPECT_EQ("$dollar", state.bindings_.LookupVariable("x")); 00239 EXPECT_EQ("$dollarbar$baz$blah", state.edges_[0]->EvaluateCommand()); 00240 } 00241 00242 TEST_F(ParserTest, EscapeSpaces) { 00243 ASSERT_NO_FATAL_FAILURE(AssertParse( 00244 "rule spaces\n" 00245 " command = something\n" 00246 "build foo$ bar: spaces $$one two$$$ three\n" 00247 )); 00248 EXPECT_TRUE(state.LookupNode("foo bar")); 00249 EXPECT_EQ(state.edges_[0]->outputs_[0]->path(), "foo bar"); 00250 EXPECT_EQ(state.edges_[0]->inputs_[0]->path(), "$one"); 00251 EXPECT_EQ(state.edges_[0]->inputs_[1]->path(), "two$ three"); 00252 EXPECT_EQ(state.edges_[0]->EvaluateCommand(), "something"); 00253 } 00254 00255 TEST_F(ParserTest, CanonicalizeFile) { 00256 ASSERT_NO_FATAL_FAILURE(AssertParse( 00257 "rule cat\n" 00258 " command = cat $in > $out\n" 00259 "build out: cat in/1 in//2\n" 00260 "build in/1: cat\n" 00261 "build in/2: cat\n")); 00262 00263 EXPECT_TRUE(state.LookupNode("in/1")); 00264 EXPECT_TRUE(state.LookupNode("in/2")); 00265 EXPECT_FALSE(state.LookupNode("in//1")); 00266 EXPECT_FALSE(state.LookupNode("in//2")); 00267 } 00268 00269 TEST_F(ParserTest, PathVariables) { 00270 ASSERT_NO_FATAL_FAILURE(AssertParse( 00271 "rule cat\n" 00272 " command = cat $in > $out\n" 00273 "dir = out\n" 00274 "build $dir/exe: cat src\n")); 00275 00276 EXPECT_FALSE(state.LookupNode("$dir/exe")); 00277 EXPECT_TRUE(state.LookupNode("out/exe")); 00278 } 00279 00280 TEST_F(ParserTest, CanonicalizePaths) { 00281 ASSERT_NO_FATAL_FAILURE(AssertParse( 00282 "rule cat\n" 00283 " command = cat $in > $out\n" 00284 "build ./out.o: cat ./bar/baz/../foo.cc\n")); 00285 00286 EXPECT_FALSE(state.LookupNode("./out.o")); 00287 EXPECT_TRUE(state.LookupNode("out.o")); 00288 EXPECT_FALSE(state.LookupNode("./bar/baz/../foo.cc")); 00289 EXPECT_TRUE(state.LookupNode("bar/foo.cc")); 00290 } 00291 00292 TEST_F(ParserTest, ReservedWords) { 00293 ASSERT_NO_FATAL_FAILURE(AssertParse( 00294 "rule build\n" 00295 " command = rule run $out\n" 00296 "build subninja: build include default foo.cc\n" 00297 "default subninja\n")); 00298 } 00299 00300 TEST_F(ParserTest, Errors) { 00301 { 00302 State state; 00303 ManifestParser parser(&state, NULL); 00304 string err; 00305 EXPECT_FALSE(parser.ParseTest("foobar", &err)); 00306 EXPECT_EQ("input:1: expected '=', got eof\n" 00307 "foobar\n" 00308 " ^ near here" 00309 , err); 00310 } 00311 00312 { 00313 State state; 00314 ManifestParser parser(&state, NULL); 00315 string err; 00316 EXPECT_FALSE(parser.ParseTest("x 3", &err)); 00317 EXPECT_EQ("input:1: expected '=', got identifier\n" 00318 "x 3\n" 00319 " ^ near here" 00320 , err); 00321 } 00322 00323 { 00324 State state; 00325 ManifestParser parser(&state, NULL); 00326 string err; 00327 EXPECT_FALSE(parser.ParseTest("x = 3", &err)); 00328 EXPECT_EQ("input:1: unexpected EOF\n" 00329 "x = 3\n" 00330 " ^ near here" 00331 , err); 00332 } 00333 00334 { 00335 State state; 00336 ManifestParser parser(&state, NULL); 00337 string err; 00338 EXPECT_FALSE(parser.ParseTest("x = 3\ny 2", &err)); 00339 EXPECT_EQ("input:2: expected '=', got identifier\n" 00340 "y 2\n" 00341 " ^ near here" 00342 , err); 00343 } 00344 00345 { 00346 State state; 00347 ManifestParser parser(&state, NULL); 00348 string err; 00349 EXPECT_FALSE(parser.ParseTest("x = $", &err)); 00350 EXPECT_EQ("input:1: bad $-escape (literal $ must be written as $$)\n" 00351 "x = $\n" 00352 " ^ near here" 00353 , err); 00354 } 00355 00356 { 00357 State state; 00358 ManifestParser parser(&state, NULL); 00359 string err; 00360 EXPECT_FALSE(parser.ParseTest("x = $\n $[\n", &err)); 00361 EXPECT_EQ("input:2: bad $-escape (literal $ must be written as $$)\n" 00362 " $[\n" 00363 " ^ near here" 00364 , err); 00365 } 00366 00367 { 00368 State state; 00369 ManifestParser parser(&state, NULL); 00370 string err; 00371 EXPECT_FALSE(parser.ParseTest("x = a$\n b$\n $\n", &err)); 00372 EXPECT_EQ("input:4: unexpected EOF\n" 00373 , err); 00374 } 00375 00376 { 00377 State state; 00378 ManifestParser parser(&state, NULL); 00379 string err; 00380 EXPECT_FALSE(parser.ParseTest("build x: y z\n", &err)); 00381 EXPECT_EQ("input:1: unknown build rule 'y'\n" 00382 "build x: y z\n" 00383 " ^ near here" 00384 , err); 00385 } 00386 00387 { 00388 State state; 00389 ManifestParser parser(&state, NULL); 00390 string err; 00391 EXPECT_FALSE(parser.ParseTest("build x:: y z\n", &err)); 00392 EXPECT_EQ("input:1: expected build command name\n" 00393 "build x:: y z\n" 00394 " ^ near here" 00395 , err); 00396 } 00397 00398 { 00399 State state; 00400 ManifestParser parser(&state, NULL); 00401 string err; 00402 EXPECT_FALSE(parser.ParseTest("rule cat\n command = cat ok\n" 00403 "build x: cat $\n :\n", 00404 &err)); 00405 EXPECT_EQ("input:4: expected newline, got ':'\n" 00406 " :\n" 00407 " ^ near here" 00408 , err); 00409 } 00410 00411 { 00412 State state; 00413 ManifestParser parser(&state, NULL); 00414 string err; 00415 EXPECT_FALSE(parser.ParseTest("rule cat\n", 00416 &err)); 00417 EXPECT_EQ("input:2: expected 'command =' line\n", err); 00418 } 00419 00420 { 00421 State state; 00422 ManifestParser parser(&state, NULL); 00423 string err; 00424 EXPECT_FALSE(parser.ParseTest("rule cat\n" 00425 " command = ${fafsd\n" 00426 "foo = bar\n", 00427 &err)); 00428 EXPECT_EQ("input:2: bad $-escape (literal $ must be written as $$)\n" 00429 " command = ${fafsd\n" 00430 " ^ near here" 00431 , err); 00432 } 00433 00434 00435 { 00436 State state; 00437 ManifestParser parser(&state, NULL); 00438 string err; 00439 EXPECT_FALSE(parser.ParseTest("rule cat\n" 00440 " command = cat\n" 00441 "build $.: cat foo\n", 00442 &err)); 00443 EXPECT_EQ("input:3: bad $-escape (literal $ must be written as $$)\n" 00444 "build $.: cat foo\n" 00445 " ^ near here" 00446 , err); 00447 } 00448 00449 00450 { 00451 State state; 00452 ManifestParser parser(&state, NULL); 00453 string err; 00454 EXPECT_FALSE(parser.ParseTest("rule cat\n" 00455 " command = cat\n" 00456 "build $: cat foo\n", 00457 &err)); 00458 EXPECT_EQ("input:3: expected ':', got newline ($ also escapes ':')\n" 00459 "build $: cat foo\n" 00460 " ^ near here" 00461 , err); 00462 } 00463 00464 { 00465 State state; 00466 ManifestParser parser(&state, NULL); 00467 string err; 00468 EXPECT_FALSE(parser.ParseTest("rule %foo\n", 00469 &err)); 00470 EXPECT_EQ("input:1: expected rule name\n", err); 00471 } 00472 00473 { 00474 State state; 00475 ManifestParser parser(&state, NULL); 00476 string err; 00477 EXPECT_FALSE(parser.ParseTest("rule cc\n" 00478 " command = foo\n" 00479 " othervar = bar\n", 00480 &err)); 00481 EXPECT_EQ("input:3: unexpected variable 'othervar'\n" 00482 " othervar = bar\n" 00483 " ^ near here" 00484 , err); 00485 } 00486 00487 { 00488 State state; 00489 ManifestParser parser(&state, NULL); 00490 string err; 00491 EXPECT_FALSE(parser.ParseTest("rule cc\n command = foo\n" 00492 "build $.: cc bar.cc\n", 00493 &err)); 00494 EXPECT_EQ("input:3: bad $-escape (literal $ must be written as $$)\n" 00495 "build $.: cc bar.cc\n" 00496 " ^ near here" 00497 , err); 00498 } 00499 00500 { 00501 State state; 00502 ManifestParser parser(&state, NULL); 00503 string err; 00504 EXPECT_FALSE(parser.ParseTest("rule cc\n command = foo\n" 00505 "build $: cc bar.cc\n", 00506 &err)); 00507 EXPECT_EQ("input:3: expected ':', got newline ($ also escapes ':')\n" 00508 "build $: cc bar.cc\n" 00509 " ^ near here" 00510 , err); 00511 } 00512 00513 { 00514 State state; 00515 ManifestParser parser(&state, NULL); 00516 string err; 00517 EXPECT_FALSE(parser.ParseTest("default\n", 00518 &err)); 00519 EXPECT_EQ("input:1: expected target name\n" 00520 "default\n" 00521 " ^ near here" 00522 , err); 00523 } 00524 00525 { 00526 State state; 00527 ManifestParser parser(&state, NULL); 00528 string err; 00529 EXPECT_FALSE(parser.ParseTest("default nonexistent\n", 00530 &err)); 00531 EXPECT_EQ("input:1: unknown target 'nonexistent'\n" 00532 "default nonexistent\n" 00533 " ^ near here" 00534 , err); 00535 } 00536 00537 { 00538 State state; 00539 ManifestParser parser(&state, NULL); 00540 string err; 00541 EXPECT_FALSE(parser.ParseTest("rule r\n command = r\n" 00542 "build b: r\n" 00543 "default b:\n", 00544 &err)); 00545 EXPECT_EQ("input:4: expected newline, got ':'\n" 00546 "default b:\n" 00547 " ^ near here" 00548 , err); 00549 } 00550 00551 { 00552 State state; 00553 ManifestParser parser(&state, NULL); 00554 string err; 00555 EXPECT_FALSE(parser.ParseTest("default $a\n", &err)); 00556 EXPECT_EQ("input:1: empty path\n" 00557 "default $a\n" 00558 " ^ near here" 00559 , err); 00560 } 00561 00562 { 00563 State state; 00564 ManifestParser parser(&state, NULL); 00565 string err; 00566 EXPECT_FALSE(parser.ParseTest("rule r\n" 00567 " command = r\n" 00568 "build $a: r $c\n", &err)); 00569 // XXX the line number is wrong; we should evaluate paths in ParseEdge 00570 // as we see them, not after we've read them all! 00571 EXPECT_EQ("input:4: empty path\n", err); 00572 } 00573 00574 { 00575 State state; 00576 ManifestParser parser(&state, NULL); 00577 string err; 00578 // the indented blank line must terminate the rule 00579 // this also verifies that "unexpected (token)" errors are correct 00580 EXPECT_FALSE(parser.ParseTest("rule r\n" 00581 " command = r\n" 00582 " \n" 00583 " generator = 1\n", &err)); 00584 EXPECT_EQ("input:4: unexpected indent\n", err); 00585 } 00586 } 00587 00588 TEST_F(ParserTest, MissingInput) { 00589 State state; 00590 ManifestParser parser(&state, this); 00591 string err; 00592 EXPECT_FALSE(parser.Load("build.ninja", &err)); 00593 EXPECT_EQ("loading 'build.ninja': No such file or directory", err); 00594 } 00595 00596 TEST_F(ParserTest, MultipleOutputs) { 00597 State state; 00598 ManifestParser parser(&state, NULL); 00599 string err; 00600 EXPECT_TRUE(parser.ParseTest("rule cc\n command = foo\n depfile = bar\n" 00601 "build a.o b.o: cc c.cc\n", 00602 &err)); 00603 EXPECT_EQ("", err); 00604 } 00605 00606 TEST_F(ParserTest, MultipleOutputsWithDeps) { 00607 State state; 00608 ManifestParser parser(&state, NULL); 00609 string err; 00610 EXPECT_FALSE(parser.ParseTest("rule cc\n command = foo\n deps = gcc\n" 00611 "build a.o b.o: cc c.cc\n", 00612 &err)); 00613 EXPECT_EQ("input:5: multiple outputs aren't (yet?) supported by depslog; " 00614 "bring this up on the mailing list if it affects you\n", err); 00615 } 00616 00617 TEST_F(ParserTest, SubNinja) { 00618 files_["test.ninja"] = 00619 "var = inner\n" 00620 "build $builddir/inner: varref\n"; 00621 ASSERT_NO_FATAL_FAILURE(AssertParse( 00622 "builddir = some_dir/\n" 00623 "rule varref\n" 00624 " command = varref $var\n" 00625 "var = outer\n" 00626 "build $builddir/outer: varref\n" 00627 "subninja test.ninja\n" 00628 "build $builddir/outer2: varref\n")); 00629 ASSERT_EQ(1u, files_read_.size()); 00630 00631 EXPECT_EQ("test.ninja", files_read_[0]); 00632 EXPECT_TRUE(state.LookupNode("some_dir/outer")); 00633 // Verify our builddir setting is inherited. 00634 EXPECT_TRUE(state.LookupNode("some_dir/inner")); 00635 00636 ASSERT_EQ(3u, state.edges_.size()); 00637 EXPECT_EQ("varref outer", state.edges_[0]->EvaluateCommand()); 00638 EXPECT_EQ("varref inner", state.edges_[1]->EvaluateCommand()); 00639 EXPECT_EQ("varref outer", state.edges_[2]->EvaluateCommand()); 00640 } 00641 00642 TEST_F(ParserTest, MissingSubNinja) { 00643 ManifestParser parser(&state, this); 00644 string err; 00645 EXPECT_FALSE(parser.ParseTest("subninja foo.ninja\n", &err)); 00646 EXPECT_EQ("input:1: loading 'foo.ninja': No such file or directory\n" 00647 "subninja foo.ninja\n" 00648 " ^ near here" 00649 , err); 00650 } 00651 00652 TEST_F(ParserTest, Include) { 00653 files_["include.ninja"] = "var = inner\n"; 00654 ASSERT_NO_FATAL_FAILURE(AssertParse( 00655 "var = outer\n" 00656 "include include.ninja\n")); 00657 00658 ASSERT_EQ(1u, files_read_.size()); 00659 EXPECT_EQ("include.ninja", files_read_[0]); 00660 EXPECT_EQ("inner", state.bindings_.LookupVariable("var")); 00661 } 00662 00663 TEST_F(ParserTest, Implicit) { 00664 ASSERT_NO_FATAL_FAILURE(AssertParse( 00665 "rule cat\n" 00666 " command = cat $in > $out\n" 00667 "build foo: cat bar | baz\n")); 00668 00669 Edge* edge = state.LookupNode("foo")->in_edge(); 00670 ASSERT_TRUE(edge->is_implicit(1)); 00671 } 00672 00673 TEST_F(ParserTest, OrderOnly) { 00674 ASSERT_NO_FATAL_FAILURE(AssertParse( 00675 "rule cat\n command = cat $in > $out\n" 00676 "build foo: cat bar || baz\n")); 00677 00678 Edge* edge = state.LookupNode("foo")->in_edge(); 00679 ASSERT_TRUE(edge->is_order_only(1)); 00680 } 00681 00682 TEST_F(ParserTest, DefaultDefault) { 00683 ASSERT_NO_FATAL_FAILURE(AssertParse( 00684 "rule cat\n command = cat $in > $out\n" 00685 "build a: cat foo\n" 00686 "build b: cat foo\n" 00687 "build c: cat foo\n" 00688 "build d: cat foo\n")); 00689 00690 string err; 00691 EXPECT_EQ(4u, state.DefaultNodes(&err).size()); 00692 EXPECT_EQ("", err); 00693 } 00694 00695 TEST_F(ParserTest, DefaultStatements) { 00696 ASSERT_NO_FATAL_FAILURE(AssertParse( 00697 "rule cat\n command = cat $in > $out\n" 00698 "build a: cat foo\n" 00699 "build b: cat foo\n" 00700 "build c: cat foo\n" 00701 "build d: cat foo\n" 00702 "third = c\n" 00703 "default a b\n" 00704 "default $third\n")); 00705 00706 string err; 00707 vector<Node*> nodes = state.DefaultNodes(&err); 00708 EXPECT_EQ("", err); 00709 ASSERT_EQ(3u, nodes.size()); 00710 EXPECT_EQ("a", nodes[0]->path()); 00711 EXPECT_EQ("b", nodes[1]->path()); 00712 EXPECT_EQ("c", nodes[2]->path()); 00713 } 00714 00715 TEST_F(ParserTest, UTF8) { 00716 ASSERT_NO_FATAL_FAILURE(AssertParse( 00717 "rule utf8\n" 00718 " command = true\n" 00719 " description = compilaci\xC3\xB3\n")); 00720 } 00721 00722 // We might want to eventually allow CRLF to be nice to Windows developers, 00723 // but for now just verify we error out with a nice message. 00724 TEST_F(ParserTest, CRLF) { 00725 State state; 00726 ManifestParser parser(&state, NULL); 00727 string err; 00728 00729 EXPECT_FALSE(parser.ParseTest("# comment with crlf\r\n", 00730 &err)); 00731 EXPECT_EQ("input:1: lexing error\n", 00732 err); 00733 00734 EXPECT_FALSE(parser.ParseTest("foo = foo\nbar = bar\r\n", 00735 &err)); 00736 EXPECT_EQ("input:2: carriage returns are not allowed, use newlines\n" 00737 "bar = bar\r\n" 00738 " ^ near here", 00739 err); 00740 }