20 #include <gtest/gtest.h> 30 ASSERT_TRUE(parser.
ParseTest(input, &err)) << err;
34 virtual bool ReadFile(
const string& path,
string* content,
string* err) {
36 map<string, string>::iterator i =
files_.find(path);
38 *err =
"No such file or directory";
57 " command = cat $in > $out\n" 60 " command = date > $out\n" 62 "build result: cat in_1.cc in-2.O\n"));
66 EXPECT_EQ(
"cat", rule->name());
67 EXPECT_EQ(
"[cat ][$in][ > ][$out]",
68 rule->GetBinding(
"command")->Serialize());
82 " rspfile_content = a\n" 88 " #indented comment\n" 90 " command = cat $in > $out\n" 92 " restat = 1 # comment\n" 94 "build result: cat in_1.cc in-2.O\n" 99 EXPECT_EQ(
"cat", rule->name());
101 EXPECT_TRUE(edge->GetBindingBool(
"restat"));
102 EXPECT_FALSE(edge->GetBindingBool(
"generator"));
110 " command = cat $in > $out\n" 112 "build result: cat in_1.cc in-2.O\n" 123 " command = cat $rspfile > $out\n" 124 " rspfile = $rspfile\n" 125 " rspfile_content = $in\n" 127 "build out: cat_rsp in\n" 128 " rspfile=out.rsp\n"));
132 EXPECT_EQ(
"cat_rsp", rule->name());
133 EXPECT_EQ(
"[cat ][$rspfile][ > ][$out]",
134 rule->GetBinding(
"command")->Serialize());
135 EXPECT_EQ(
"[$rspfile]", rule->GetBinding(
"rspfile")->Serialize());
136 EXPECT_EQ(
"[$in]", rule->GetBinding(
"rspfile_content")->Serialize());
142 " command = cat $in_newline > $out\n" 144 "build out: cat_rsp in in2\n" 145 " rspfile=out.rsp\n"));
149 EXPECT_EQ(
"cat_rsp", rule->name());
150 EXPECT_EQ(
"[cat ][$in_newline][ > ][$out]",
151 rule->GetBinding(
"command")->Serialize());
154 EXPECT_EQ(
"cat in\nin2 > out", edge->EvaluateCommand());
159 "l = one-letter-test\n" 161 " command = ld $l $extra $with_under -o $out $in\n" 164 "with_under = -under\n" 165 "build a: link b c\n" 167 "nested2 = $nested1/2\n" 168 "build supernested: link x\n" 169 " extra = $nested2/3\n"));
173 EXPECT_EQ(
"ld one-letter-test -pthread -under -o a b c",
174 edge->EvaluateCommand());
178 EXPECT_EQ(
"ld one-letter-test 1/2/3 -under -o supernested x",
179 edge->EvaluateCommand());
186 " command = cmd $foo $in $out\n" 188 "build inner: cmd a\n" 190 "build outer: cmd b\n" 195 EXPECT_EQ(
"cmd baz a inner",
state.
edges_[0]->EvaluateCommand());
196 EXPECT_EQ(
"cmd bar b outer",
state.
edges_[1]->EvaluateCommand());
202 " command = foo bar $\n" 205 "build a: link c $\n" 210 EXPECT_EQ(
"link", rule->name());
211 EXPECT_EQ(
"[foo bar baz]", rule->GetBinding(
"command")->Serialize());
225 "# this is a comment\n" 226 "foo = not # a comment\n"));
233 " command = ${out}bar$$baz$$$\n" 240 EXPECT_EQ(
"$dollarbar$baz$blah",
state.
edges_[0]->EvaluateCommand());
242 EXPECT_EQ(
"'$dollar'bar$baz$blah",
state.
edges_[0]->EvaluateCommand());
249 " command = something\n" 250 "build foo$ bar: spaces $$one two$$$ three\n" 253 EXPECT_EQ(
state.
edges_[0]->outputs_[0]->path(),
"foo bar");
254 EXPECT_EQ(
state.
edges_[0]->inputs_[0]->path(),
"$one");
255 EXPECT_EQ(
state.
edges_[0]->inputs_[1]->path(),
"two$ three");
256 EXPECT_EQ(
state.
edges_[0]->EvaluateCommand(),
"something");
262 " command = cat $in > $out\n" 263 "build out: cat in/1 in//2\n" 265 "build in/2: cat\n"));
276 " command = cat $in > $out\n" 278 "build $dir/exe: cat src\n"));
287 " command = cat $in > $out\n" 288 "build ./out.o: cat ./bar/baz/../foo.cc\n"));
299 " command = rule run $out\n" 300 "build subninja: build include default foo.cc\n" 301 "default subninja\n"));
309 EXPECT_FALSE(parser.
ParseTest(
string(
"subn", 4), &err));
310 EXPECT_EQ(
"input:1: expected '=', got eof\n" 320 EXPECT_FALSE(parser.
ParseTest(
"foobar", &err));
321 EXPECT_EQ(
"input:1: expected '=', got eof\n" 331 EXPECT_FALSE(parser.
ParseTest(
"x 3", &err));
332 EXPECT_EQ(
"input:1: expected '=', got identifier\n" 342 EXPECT_FALSE(parser.
ParseTest(
"x = 3", &err));
343 EXPECT_EQ(
"input:1: unexpected EOF\n" 353 EXPECT_FALSE(parser.
ParseTest(
"x = 3\ny 2", &err));
354 EXPECT_EQ(
"input:2: expected '=', got identifier\n" 364 EXPECT_FALSE(parser.
ParseTest(
"x = $", &err));
365 EXPECT_EQ(
"input:1: bad $-escape (literal $ must be written as $$)\n" 375 EXPECT_FALSE(parser.
ParseTest(
"x = $\n $[\n", &err));
376 EXPECT_EQ(
"input:2: bad $-escape (literal $ must be written as $$)\n" 386 EXPECT_FALSE(parser.
ParseTest(
"x = a$\n b$\n $\n", &err));
387 EXPECT_EQ(
"input:4: unexpected EOF\n" 395 EXPECT_FALSE(parser.
ParseTest(
"build\n", &err));
396 EXPECT_EQ(
"input:1: expected path\n" 406 EXPECT_FALSE(parser.
ParseTest(
"build x: y z\n", &err));
407 EXPECT_EQ(
"input:1: unknown build rule 'y'\n" 417 EXPECT_FALSE(parser.
ParseTest(
"build x:: y z\n", &err));
418 EXPECT_EQ(
"input:1: expected build command name\n" 428 EXPECT_FALSE(parser.
ParseTest(
"rule cat\n command = cat ok\n" 429 "build x: cat $\n :\n",
431 EXPECT_EQ(
"input:4: expected newline, got ':'\n" 441 EXPECT_FALSE(parser.
ParseTest(
"rule cat\n",
443 EXPECT_EQ(
"input:2: expected 'command =' line\n", err);
450 EXPECT_FALSE(parser.
ParseTest(
"rule cat\n" 453 " command = echo\n", &err));
454 EXPECT_EQ(
"input:3: duplicate rule 'cat'\n" 464 EXPECT_FALSE(parser.
ParseTest(
"rule cat\n" 466 " rspfile = cat.rsp\n", &err));
468 "input:4: rspfile and rspfile_content need to be both specified\n",
476 EXPECT_FALSE(parser.
ParseTest(
"rule cat\n" 477 " command = ${fafsd\n" 480 EXPECT_EQ(
"input:2: bad $-escape (literal $ must be written as $$)\n" 481 " command = ${fafsd\n" 491 EXPECT_FALSE(parser.
ParseTest(
"rule cat\n" 493 "build $.: cat foo\n",
495 EXPECT_EQ(
"input:3: bad $-escape (literal $ must be written as $$)\n" 496 "build $.: cat foo\n" 506 EXPECT_FALSE(parser.
ParseTest(
"rule cat\n" 508 "build $: cat foo\n",
510 EXPECT_EQ(
"input:3: expected ':', got newline ($ also escapes ':')\n" 520 EXPECT_FALSE(parser.
ParseTest(
"rule %foo\n",
522 EXPECT_EQ(
"input:1: expected rule name\n", err);
529 EXPECT_FALSE(parser.
ParseTest(
"rule cc\n" 533 EXPECT_EQ(
"input:3: unexpected variable 'othervar'\n" 543 EXPECT_FALSE(parser.
ParseTest(
"rule cc\n command = foo\n" 544 "build $.: cc bar.cc\n",
546 EXPECT_EQ(
"input:3: bad $-escape (literal $ must be written as $$)\n" 547 "build $.: cc bar.cc\n" 556 EXPECT_FALSE(parser.
ParseTest(
"rule cc\n command = foo\n" 557 "build $: cc bar.cc\n",
559 EXPECT_EQ(
"input:3: expected ':', got newline ($ also escapes ':')\n" 560 "build $: cc bar.cc\n" 569 EXPECT_FALSE(parser.
ParseTest(
"default\n",
571 EXPECT_EQ(
"input:1: expected target name\n" 581 EXPECT_FALSE(parser.
ParseTest(
"default nonexistent\n",
583 EXPECT_EQ(
"input:1: unknown target 'nonexistent'\n" 584 "default nonexistent\n" 593 EXPECT_FALSE(parser.
ParseTest(
"rule r\n command = r\n" 597 EXPECT_EQ(
"input:4: expected newline, got ':'\n" 607 EXPECT_FALSE(parser.
ParseTest(
"default $a\n", &err));
608 EXPECT_EQ(
"input:1: empty path\n" 620 "build $a: r $c\n", &err));
623 EXPECT_EQ(
"input:4: empty path\n", err);
635 " generator = 1\n", &err));
636 EXPECT_EQ(
"input:4: unexpected indent\n", err);
643 EXPECT_FALSE(parser.
ParseTest(
"pool\n", &err));
644 EXPECT_EQ(
"input:1: expected pool name\n", err);
651 EXPECT_FALSE(parser.
ParseTest(
"pool foo\n", &err));
652 EXPECT_EQ(
"input:2: expected 'depth =' line\n", err);
659 EXPECT_FALSE(parser.
ParseTest(
"pool foo\n" 661 "pool foo\n", &err));
662 EXPECT_EQ(
"input:3: duplicate pool 'foo'\n" 672 EXPECT_FALSE(parser.
ParseTest(
"pool foo\n" 673 " depth = -1\n", &err));
674 EXPECT_EQ(
"input:2: invalid pool depth\n" 684 EXPECT_FALSE(parser.
ParseTest(
"pool foo\n" 685 " bar = 1\n", &err));
686 EXPECT_EQ(
"input:2: unexpected variable 'bar'\n" 697 EXPECT_FALSE(parser.
ParseTest(
"rule run\n" 699 " pool = unnamed_pool\n" 700 "build out: run in\n", &err));
701 EXPECT_EQ(
"input:5: unknown pool name 'unnamed_pool'\n", err);
709 EXPECT_FALSE(parser.
Load(
"build.ninja", &err));
710 EXPECT_EQ(
"loading 'build.ninja': No such file or directory", err);
717 EXPECT_TRUE(parser.
ParseTest(
"rule cc\n command = foo\n depfile = bar\n" 718 "build a.o b.o: cc c.cc\n",
727 EXPECT_FALSE(parser.
ParseTest(
"rule cc\n command = foo\n deps = gcc\n" 728 "build a.o b.o: cc c.cc\n",
730 EXPECT_EQ(
"input:5: multiple outputs aren't (yet?) supported by depslog; " 731 "bring this up on the mailing list if it affects you\n", err);
737 "build $builddir/inner: varref\n";
739 "builddir = some_dir/\n" 741 " command = varref $var\n" 743 "build $builddir/outer: varref\n" 744 "subninja test.ninja\n" 745 "build $builddir/outer2: varref\n"));
754 EXPECT_EQ(
"varref outer",
state.
edges_[0]->EvaluateCommand());
755 EXPECT_EQ(
"varref inner",
state.
edges_[1]->EvaluateCommand());
756 EXPECT_EQ(
"varref outer",
state.
edges_[2]->EvaluateCommand());
762 EXPECT_FALSE(parser.
ParseTest(
"subninja foo.ninja\n", &err));
763 EXPECT_EQ(
"input:1: loading 'foo.ninja': No such file or directory\n" 764 "subninja foo.ninja\n" 771 files_[
"test.ninja"] =
"rule cat\n" 775 EXPECT_FALSE(parser.
ParseTest(
"rule cat\n" 777 "subninja test.ninja\n", &err));
778 EXPECT_EQ(
"test.ninja:1: duplicate rule 'cat'\n" 785 files_[
"include.ninja"] =
"var = inner\n";
788 "include include.ninja\n"));
796 files_[
"include.ninja"] =
"build\n";
799 EXPECT_FALSE(parser.
ParseTest(
"include include.ninja\n", &err));
800 EXPECT_EQ(
"include.ninja:1: expected path\n" 809 " command = cat $in > $out\n" 810 "build foo: cat bar | baz\n"));
818 "rule cat\n command = cat $in > $out\n" 819 "build foo: cat bar || baz\n"));
827 "rule cat\n command = cat $in > $out\n" 831 "build d: cat foo\n"));
840 "rule cat\n command = cat $in > $out\n" 847 "default $third\n"));
852 ASSERT_EQ(3u, nodes.size());
853 EXPECT_EQ(
"a", nodes[0]->path());
854 EXPECT_EQ(
"b", nodes[1]->path());
855 EXPECT_EQ(
"c", nodes[2]->path());
862 " description = compilaci\xC3\xB3\n"));
872 EXPECT_FALSE(parser.
ParseTest(
"# comment with crlf\r\n",
874 EXPECT_EQ(
"input:1: lexing error\n",
877 EXPECT_FALSE(parser.
ParseTest(
"foo = foo\nbar = bar\r\n",
879 EXPECT_EQ(
"input:2: carriage returns are not allowed, use newlines\n" bool Load(const string &filename, string *err, Lexer *parent=NULL)
Load and parse a file.
vector< Edge * > edges_
All the edges of the graph.
vector< string > files_read_
Node * GetNode(StringPiece path)
map< string, string > files_
An edge in the dependency graph; links between Nodes using Rules.
bool is_order_only(size_t index)
bool is_implicit(size_t index)
vector< Node * > DefaultNodes(string *error)
An invokable build command and associated metadata (description, etc.).
TEST_F(ParserTest, Empty)
virtual string LookupVariable(const string &var)
void AssertParse(const char *input)
Global state (file status, loaded rules) for a single run.
map< string, const Rule * > rules_
All the rules used in the graph.
bool ParseTest(const string &input, string *err)
Parse a text string of input. Used by tests.
Node * LookupNode(StringPiece path) const
virtual bool ReadFile(const string &path, string *content, string *err)