Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 719 lines (635 sloc) 20.049 kB
d52238f @martine add copyrights
authored
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
3baedf1 @tfarina Rename parsers.* to manifest_parser.*
tfarina authored
15 #include "manifest_parser.h"
3867ae0 @martine factor tests into files
authored
16
17 #include <gtest/gtest.h>
18
0a186ab @martine split out graph into its own header
authored
19 #include "graph.h"
3bf1d4b @tfarina Factor out State struct from ninja_jumble.cc into its header/source f…
tfarina authored
20 #include "state.h"
3867ae0 @martine factor tests into files
authored
21
549d996 @martine use a fixture for parser tests
authored
22 struct ParserTest : public testing::Test,
49ddf9b @martine use new interface for loading subfiles
authored
23 public ManifestParser::FileReader {
549d996 @martine use a fixture for parser tests
authored
24 void AssertParse(const char* input) {
bf6a8c4 @martine pass disk interface to parser
authored
25 ManifestParser parser(&state, this);
549d996 @martine use a fixture for parser tests
authored
26 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
27 ASSERT_TRUE(parser.ParseTest(input, &err)) << err;
549d996 @martine use a fixture for parser tests
authored
28 ASSERT_EQ("", err);
29 }
3867ae0 @martine factor tests into files
authored
30
49ddf9b @martine use new interface for loading subfiles
authored
31 virtual bool ReadFile(const string& path, string* content, string* err) {
f9c6232 @martine parse subfile; pass subninja test
authored
32 files_read_.push_back(path);
6dac2ee @martine failing test for loading subninja
authored
33 map<string, string>::iterator i = files_.find(path);
49ddf9b @martine use new interface for loading subfiles
authored
34 if (i == files_.end()) {
e69d8bf @martine include filename in subninja load err message
authored
35 *err = "No such file or directory"; // Match strerror() for ENOENT.
49ddf9b @martine use new interface for loading subfiles
authored
36 return false;
37 }
38 *content = i->second;
39 return true;
900bf30 @martine make DiskInterface pure virtual
authored
40 }
41
3867ae0 @martine factor tests into files
authored
42 State state;
6dac2ee @martine failing test for loading subninja
authored
43 map<string, string> files_;
f9c6232 @martine parse subfile; pass subninja test
authored
44 vector<string> files_read_;
549d996 @martine use a fixture for parser tests
authored
45 };
46
47 TEST_F(ParserTest, Empty) {
48 ASSERT_NO_FATAL_FAILURE(AssertParse(""));
3867ae0 @martine factor tests into files
authored
49 }
50
549d996 @martine use a fixture for parser tests
authored
51 TEST_F(ParserTest, Rules) {
52 ASSERT_NO_FATAL_FAILURE(AssertParse(
3867ae0 @martine factor tests into files
authored
53 "rule cat\n"
2f91ce0 @martine make all vars start with $
authored
54 " command = cat $in > $out\n"
3867ae0 @martine factor tests into files
authored
55 "\n"
56 "rule date\n"
57 " command = date > $out\n"
58 "\n"
59 "build result: cat in_1.cc in-2.O\n"));
60
4cc9326 @martine windows: fix more signedness warnings
authored
61 ASSERT_EQ(3u, state.rules_.size());
a95c75d @martine make Rule* const
authored
62 const Rule* rule = state.rules_.begin()->second;
2863acb @martine make Rule::name_ private
authored
63 EXPECT_EQ("cat", rule->name());
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
64 EXPECT_EQ("[cat ][$in][ > ][$out]", rule->command().Serialize());
3867ae0 @martine factor tests into files
authored
65 }
66
c90bdaa @martine add test that checks attributes on rules
authored
67 TEST_F(ParserTest, RuleAttributes) {
68 // Check that all of the allowed rule attributes are parsed ok.
69 ASSERT_NO_FATAL_FAILURE(AssertParse(
70 "rule cat\n"
71 " command = a\n"
72 " depfile = a\n"
73 " description = a\n"
74 " generator = a\n"
336efcd @martine update old test to cover newer rule attributes
authored
75 " restat = a\n"
76 " rspfile = a\n"
77 " rspfile_content = a\n"
78 ));
c90bdaa @martine add test that checks attributes on rules
authored
79 }
80
7311f3b @evanj Lexer: include leading whitespace in the comment token.
evanj authored
81 TEST_F(ParserTest, IgnoreIndentedComments) {
82 ASSERT_NO_FATAL_FAILURE(AssertParse(
83 " #indented comment\n"
84 "rule cat\n"
85 " command = cat $in > $out\n"
86 " #generator = 1\n"
87 " restat = 1 # comment\n"
88 " #comment\n"
89 "build result: cat in_1.cc in-2.O\n"
90 " #comment\n"));
91
92 ASSERT_EQ(2u, state.rules_.size());
93 const Rule* rule = state.rules_.begin()->second;
94 EXPECT_EQ("cat", rule->name());
95 EXPECT_TRUE(rule->restat());
96 EXPECT_FALSE(rule->generator());
97 }
98
831775c @evanj Lexer: include leading spaces in the newline token.
evanj authored
99 TEST_F(ParserTest, IgnoreIndentedBlankLines) {
100 // the indented blanks used to cause parse errors
101 ASSERT_NO_FATAL_FAILURE(AssertParse(
102 " \n"
103 "rule cat\n"
104 " command = cat $in > $out\n"
105 " \n"
106 "build result: cat in_1.cc in-2.O\n"
107 " \n"
108 "variable=1\n"));
109
110 // the variable must be in the top level environment
111 EXPECT_EQ("1", state.bindings_.LookupVariable("variable"));
112 }
113
af070e5 Response files
unknown authored
114 TEST_F(ParserTest, ResponseFiles) {
115 ASSERT_NO_FATAL_FAILURE(AssertParse(
116 "rule cat_rsp\n"
117 " command = cat $rspfile > $out\n"
118 " rspfile = $rspfile\n"
119 " rspfile_content = $in\n"
120 "\n"
121 "build out: cat_rsp in\n"
122 " rspfile=out.rsp\n"));
123
124 ASSERT_EQ(2u, state.rules_.size());
125 const Rule* rule = state.rules_.begin()->second;
126 EXPECT_EQ("cat_rsp", rule->name());
127 EXPECT_EQ("[cat ][$rspfile][ > ][$out]", rule->command().Serialize());
eab83e9 @martine fix some public/private errors in rspfile patch
authored
128 EXPECT_EQ("[$rspfile]", rule->rspfile().Serialize());
129 EXPECT_EQ("[$in]", rule->rspfile_content().Serialize());
e0dd93a @sgraham add $in_newline
sgraham authored
130 }
131
36aa519 @sgraham improve test
sgraham authored
132 TEST_F(ParserTest, InNewline) {
e0dd93a @sgraham add $in_newline
sgraham authored
133 ASSERT_NO_FATAL_FAILURE(AssertParse(
134 "rule cat_rsp\n"
36aa519 @sgraham improve test
sgraham authored
135 " command = cat $in_newline > $out\n"
e0dd93a @sgraham add $in_newline
sgraham authored
136 "\n"
36aa519 @sgraham improve test
sgraham authored
137 "build out: cat_rsp in in2\n"
e0dd93a @sgraham add $in_newline
sgraham authored
138 " rspfile=out.rsp\n"));
139
140 ASSERT_EQ(2u, state.rules_.size());
141 const Rule* rule = state.rules_.begin()->second;
142 EXPECT_EQ("cat_rsp", rule->name());
36aa519 @sgraham improve test
sgraham authored
143 EXPECT_EQ("[cat ][$in_newline][ > ][$out]", rule->command().Serialize());
144
145 Edge* edge = state.edges_[0];
146 EXPECT_EQ("cat in\nin2 > out", edge->EvaluateCommand());
af070e5 Response files
unknown authored
147 }
148
549d996 @martine use a fixture for parser tests
authored
149 TEST_F(ParserTest, Variables) {
150 ASSERT_NO_FATAL_FAILURE(AssertParse(
6f2a2ce @martine allow one-letter variable names
authored
151 "l = one-letter-test\n"
3867ae0 @martine factor tests into files
authored
152 "rule link\n"
6f2a2ce @martine allow one-letter variable names
authored
153 " command = ld $l $extra $with_under -o $out $in\n"
3867ae0 @martine factor tests into files
authored
154 "\n"
155 "extra = -pthread\n"
156 "with_under = -under\n"
f2a4bac @martine immediately evaluate variables in top-level bindings
authored
157 "build a: link b c\n"
158 "nested1 = 1\n"
db022ad @martine aggressively eval variables in build blocks
authored
159 "nested2 = $nested1/2\n"
160 "build supernested: link x\n"
161 " extra = $nested2/3\n"));
3867ae0 @martine factor tests into files
authored
162
4cc9326 @martine windows: fix more signedness warnings
authored
163 ASSERT_EQ(2u, state.edges_.size());
3867ae0 @martine factor tests into files
authored
164 Edge* edge = state.edges_[0];
6f2a2ce @martine allow one-letter variable names
authored
165 EXPECT_EQ("ld one-letter-test -pthread -under -o a b c",
166 edge->EvaluateCommand());
f2a4bac @martine immediately evaluate variables in top-level bindings
authored
167 EXPECT_EQ("1/2", state.bindings_.LookupVariable("nested2"));
db022ad @martine aggressively eval variables in build blocks
authored
168
169 edge = state.edges_[1];
170 EXPECT_EQ("ld one-letter-test 1/2/3 -under -o supernested x",
171 edge->EvaluateCommand());
3867ae0 @martine factor tests into files
authored
172 }
173
45f861e @martine nested scope for build lines
authored
174 TEST_F(ParserTest, VariableScope) {
175 ASSERT_NO_FATAL_FAILURE(AssertParse(
176 "foo = bar\n"
177 "rule cmd\n"
178 " command = cmd $foo $in $out\n"
179 "\n"
180 "build inner: cmd a\n"
181 " foo = baz\n"
1fdae9d @martine fix whitespace-eating regression
authored
182 "build outer: cmd b\n"
183 "\n" // Extra newline after build line tickles a regression.
184 ));
45f861e @martine nested scope for build lines
authored
185
4cc9326 @martine windows: fix more signedness warnings
authored
186 ASSERT_EQ(2u, state.edges_.size());
45f861e @martine nested scope for build lines
authored
187 EXPECT_EQ("cmd baz a inner", state.edges_[0]->EvaluateCommand());
188 EXPECT_EQ("cmd bar b outer", state.edges_[1]->EvaluateCommand());
189 }
190
549d996 @martine use a fixture for parser tests
authored
191 TEST_F(ParserTest, Continuation) {
192 ASSERT_NO_FATAL_FAILURE(AssertParse(
3867ae0 @martine factor tests into files
authored
193 "rule link\n"
55fd423 @martine switch to $ as the line continuation char
authored
194 " command = foo bar $\n"
3867ae0 @martine factor tests into files
authored
195 " baz\n"
196 "\n"
55fd423 @martine switch to $ as the line continuation char
authored
197 "build a: link c $\n"
3867ae0 @martine factor tests into files
authored
198 " d e f\n"));
199
4cc9326 @martine windows: fix more signedness warnings
authored
200 ASSERT_EQ(2u, state.rules_.size());
a95c75d @martine make Rule* const
authored
201 const Rule* rule = state.rules_.begin()->second;
2863acb @martine make Rule::name_ private
authored
202 EXPECT_EQ("link", rule->name());
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
203 EXPECT_EQ("[foo bar baz]", rule->command().Serialize());
3867ae0 @martine factor tests into files
authored
204 }
205
0b4ac26 @martine allow backslashes through
authored
206 TEST_F(ParserTest, Backslash) {
207 ASSERT_NO_FATAL_FAILURE(AssertParse(
208 "foo = bar\\baz\n"
209 "foo2 = bar\\ baz\n"
210 ));
211 EXPECT_EQ("bar\\baz", state.bindings_.LookupVariable("foo"));
212 EXPECT_EQ("bar\\ baz", state.bindings_.LookupVariable("foo2"));
213 }
214
549d996 @martine use a fixture for parser tests
authored
215 TEST_F(ParserTest, Comment) {
216 ASSERT_NO_FATAL_FAILURE(AssertParse(
3867ae0 @martine factor tests into files
authored
217 "# this is a comment\n"
218 "foo = not # a comment\n"));
b687060 @martine nested file-scoped binding environments
authored
219 EXPECT_EQ("not # a comment", state.bindings_.LookupVariable("foo"));
3867ae0 @martine factor tests into files
authored
220 }
221
511613c @martine expand $$ as $
authored
222 TEST_F(ParserTest, Dollars) {
223 ASSERT_NO_FATAL_FAILURE(AssertParse(
224 "rule foo\n"
225 " command = ${out}bar$$baz$$$\n"
226 "blah\n"
227 "x = $$dollar\n"
228 "build $x: foo y\n"
229 ));
230 EXPECT_EQ("$dollar", state.bindings_.LookupVariable("x"));
231 EXPECT_EQ("$dollarbar$baz$blah", state.edges_[0]->EvaluateCommand());
232 }
233
4d142a4 @nornagon Add tests for escaping spaces with '$ '.
nornagon authored
234 TEST_F(ParserTest, EscapeSpaces) {
235 ASSERT_NO_FATAL_FAILURE(AssertParse(
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
236 "rule spaces\n"
4d142a4 @nornagon Add tests for escaping spaces with '$ '.
nornagon authored
237 " command = something\n"
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
238 "build foo$ bar: spaces $$one two$$$ three\n"
4d142a4 @nornagon Add tests for escaping spaces with '$ '.
nornagon authored
239 ));
240 EXPECT_TRUE(state.LookupNode("foo bar"));
a3ace78 @martine fix bad merge
authored
241 EXPECT_EQ(state.edges_[0]->outputs_[0]->path(), "foo bar");
242 EXPECT_EQ(state.edges_[0]->inputs_[0]->path(), "$one");
243 EXPECT_EQ(state.edges_[0]->inputs_[1]->path(), "two$ three");
4d142a4 @nornagon Add tests for escaping spaces with '$ '.
nornagon authored
244 EXPECT_EQ(state.edges_[0]->EvaluateCommand(), "something");
245 }
246
3bb1b08 @martine canonicalize paths with // in them
authored
247 TEST_F(ParserTest, CanonicalizeFile) {
248 ASSERT_NO_FATAL_FAILURE(AssertParse(
249 "rule cat\n"
250 " command = cat $in > $out\n"
251 "build out: cat in/1 in//2\n"
252 "build in/1: cat\n"
253 "build in/2: cat\n"));
254
255 EXPECT_TRUE(state.LookupNode("in/1"));
256 EXPECT_TRUE(state.LookupNode("in/2"));
257 EXPECT_FALSE(state.LookupNode("in//1"));
258 EXPECT_FALSE(state.LookupNode("in//2"));
259 }
260
ac4cc82 @martine expand variables in build paths
authored
261 TEST_F(ParserTest, PathVariables) {
262 ASSERT_NO_FATAL_FAILURE(AssertParse(
263 "rule cat\n"
264 " command = cat $in > $out\n"
265 "dir = out\n"
266 "build $dir/exe: cat src\n"));
267
268 EXPECT_FALSE(state.LookupNode("$dir/exe"));
269 EXPECT_TRUE(state.LookupNode("out/exe"));
270 }
271
20b0b38 @martine use util's CanonicalizePath in parsers as well
authored
272 TEST_F(ParserTest, CanonicalizePaths) {
273 ASSERT_NO_FATAL_FAILURE(AssertParse(
274 "rule cat\n"
275 " command = cat $in > $out\n"
276 "build ./out.o: cat ./bar/baz/../foo.cc\n"));
277
278 EXPECT_FALSE(state.LookupNode("./out.o"));
279 EXPECT_TRUE(state.LookupNode("out.o"));
280 EXPECT_FALSE(state.LookupNode("./bar/baz/../foo.cc"));
281 EXPECT_TRUE(state.LookupNode("bar/foo.cc"));
282 }
283
f3910e0 @martine drop reserved words 'build'/'rule'/'subninja'/etc.
authored
284 TEST_F(ParserTest, ReservedWords) {
285 ASSERT_NO_FATAL_FAILURE(AssertParse(
286 "rule build\n"
287 " command = rule run $out\n"
7a6c9d4 @pcc Implement default target statements
pcc authored
288 "build subninja: build include default foo.cc\n"
289 "default subninja\n"));
f3910e0 @martine drop reserved words 'build'/'rule'/'subninja'/etc.
authored
290 }
291
549d996 @martine use a fixture for parser tests
authored
292 TEST_F(ParserTest, Errors) {
3867ae0 @martine factor tests into files
authored
293 {
bf6a8c4 @martine pass disk interface to parser
authored
294 ManifestParser parser(NULL, NULL);
3867ae0 @martine factor tests into files
authored
295 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
296 EXPECT_FALSE(parser.ParseTest("foobar", &err));
297 EXPECT_EQ("input:1: expected '=', got eof\n"
298 "foobar\n"
eeed724 @martine make Lexer::Error not emit trailing newline
authored
299 " ^ near here"
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
300 , err);
3867ae0 @martine factor tests into files
authored
301 }
302
303 {
bf6a8c4 @martine pass disk interface to parser
authored
304 ManifestParser parser(NULL, NULL);
3867ae0 @martine factor tests into files
authored
305 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
306 EXPECT_FALSE(parser.ParseTest("x 3", &err));
307 EXPECT_EQ("input:1: expected '=', got identifier\n"
308 "x 3\n"
eeed724 @martine make Lexer::Error not emit trailing newline
authored
309 " ^ near here"
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
310 , err);
3867ae0 @martine factor tests into files
authored
311 }
312
313 {
bf6a8c4 @martine pass disk interface to parser
authored
314 ManifestParser parser(NULL, NULL);
3867ae0 @martine factor tests into files
authored
315 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
316 EXPECT_FALSE(parser.ParseTest("x = 3", &err));
317 EXPECT_EQ("input:1: unexpected EOF\n"
318 "x = 3\n"
eeed724 @martine make Lexer::Error not emit trailing newline
authored
319 " ^ near here"
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
320 , err);
3867ae0 @martine factor tests into files
authored
321 }
322
323 {
324 State state;
bf6a8c4 @martine pass disk interface to parser
authored
325 ManifestParser parser(&state, NULL);
3867ae0 @martine factor tests into files
authored
326 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
327 EXPECT_FALSE(parser.ParseTest("x = 3\ny 2", &err));
328 EXPECT_EQ("input:2: expected '=', got identifier\n"
329 "y 2\n"
eeed724 @martine make Lexer::Error not emit trailing newline
authored
330 " ^ near here"
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
331 , err);
3867ae0 @martine factor tests into files
authored
332 }
333
334 {
335 State state;
bf6a8c4 @martine pass disk interface to parser
authored
336 ManifestParser parser(&state, NULL);
3867ae0 @martine factor tests into files
authored
337 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
338 EXPECT_FALSE(parser.ParseTest("x = $", &err));
339 EXPECT_EQ("input:1: bad $-escape (literal $ must be written as $$)\n"
340 "x = $\n"
eeed724 @martine make Lexer::Error not emit trailing newline
authored
341 " ^ near here"
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
342 , err);
2f6ac73 include location of error in parse error messages in EvalEnv strings
Alexei Svitkine authored
343 }
344
345 {
346 State state;
347 ManifestParser parser(&state, NULL);
348 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
349 EXPECT_FALSE(parser.ParseTest("x = $\n $[\n", &err));
350 EXPECT_EQ("input:2: bad $-escape (literal $ must be written as $$)\n"
351 " $[\n"
eeed724 @martine make Lexer::Error not emit trailing newline
authored
352 " ^ near here"
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
353 , err);
2f6ac73 include location of error in parse error messages in EvalEnv strings
Alexei Svitkine authored
354 }
355
356 {
357 State state;
358 ManifestParser parser(&state, NULL);
359 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
360 EXPECT_FALSE(parser.ParseTest("x = a$\n b$\n $\n", &err));
361 EXPECT_EQ("input:4: unexpected EOF\n"
362 , err);
2f6ac73 include location of error in parse error messages in EvalEnv strings
Alexei Svitkine authored
363 }
364
365 {
366 State state;
367 ManifestParser parser(&state, NULL);
368 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
369 EXPECT_FALSE(parser.ParseTest("build x: y z\n", &err));
370 EXPECT_EQ("input:1: unknown build rule 'y'\n"
371 "build x: y z\n"
eeed724 @martine make Lexer::Error not emit trailing newline
authored
372 " ^ near here"
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
373 , err);
3867ae0 @martine factor tests into files
authored
374 }
375
376 {
377 State state;
bf6a8c4 @martine pass disk interface to parser
authored
378 ManifestParser parser(&state, NULL);
3867ae0 @martine factor tests into files
authored
379 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
380 EXPECT_FALSE(parser.ParseTest("build x:: y z\n", &err));
381 EXPECT_EQ("input:1: expected build command name\n"
382 "build x:: y z\n"
eeed724 @martine make Lexer::Error not emit trailing newline
authored
383 " ^ near here"
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
384 , err);
3867ae0 @martine factor tests into files
authored
385 }
386
387 {
388 State state;
bf6a8c4 @martine pass disk interface to parser
authored
389 ManifestParser parser(&state, NULL);
3867ae0 @martine factor tests into files
authored
390 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
391 EXPECT_FALSE(parser.ParseTest("rule cat\n command = cat ok\n"
392 "build x: cat $\n :\n",
393 &err));
394 EXPECT_EQ("input:4: expected newline, got ':'\n"
395 " :\n"
eeed724 @martine make Lexer::Error not emit trailing newline
authored
396 " ^ near here"
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
397 , err);
3867ae0 @martine factor tests into files
authored
398 }
399
400 {
401 State state;
bf6a8c4 @martine pass disk interface to parser
authored
402 ManifestParser parser(&state, NULL);
3867ae0 @martine factor tests into files
authored
403 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
404 EXPECT_FALSE(parser.ParseTest("rule cat\n",
405 &err));
406 EXPECT_EQ("input:2: expected 'command =' line\n", err);
3867ae0 @martine factor tests into files
authored
407 }
408
409 {
410 State state;
bf6a8c4 @martine pass disk interface to parser
authored
411 ManifestParser parser(&state, NULL);
3867ae0 @martine factor tests into files
authored
412 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
413 EXPECT_FALSE(parser.ParseTest("rule cat\n"
414 " command = ${fafsd\n"
415 "foo = bar\n",
416 &err));
417 EXPECT_EQ("input:2: bad $-escape (literal $ must be written as $$)\n"
418 " command = ${fafsd\n"
eeed724 @martine make Lexer::Error not emit trailing newline
authored
419 " ^ near here"
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
420 , err);
2bdd317 @martine refactor parser, check in some failing tests
authored
421 }
422
423
424 {
425 State state;
426 ManifestParser parser(&state, NULL);
427 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
428 EXPECT_FALSE(parser.ParseTest("rule cat\n"
2e48108 @syntheticpp parse $:
syntheticpp authored
429 " command = cat\n"
430 "build $.: cat foo\n",
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
431 &err));
432 EXPECT_EQ("input:3: bad $-escape (literal $ must be written as $$)\n"
2e48108 @syntheticpp parse $:
syntheticpp authored
433 "build $.: cat foo\n"
eeed724 @martine make Lexer::Error not emit trailing newline
authored
434 " ^ near here"
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
435 , err);
2bdd317 @martine refactor parser, check in some failing tests
authored
436 }
437
2e48108 @syntheticpp parse $:
syntheticpp authored
438
439 {
440 State state;
441 ManifestParser parser(&state, NULL);
442 string err;
443 EXPECT_FALSE(parser.ParseTest("rule cat\n"
444 " command = cat\n"
445 "build $: cat foo\n",
446 &err));
447 EXPECT_EQ("input:3: expected ':', got newline ($ also escapes ':')\n"
448 "build $: cat foo\n"
449 " ^ near here"
450 , err);
451 }
452
2bdd317 @martine refactor parser, check in some failing tests
authored
453 {
454 State state;
455 ManifestParser parser(&state, NULL);
456 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
457 EXPECT_FALSE(parser.ParseTest("rule %foo\n",
458 &err));
459 EXPECT_EQ("input:1: expected rule name\n", err);
3867ae0 @martine factor tests into files
authored
460 }
461
462 {
463 State state;
bf6a8c4 @martine pass disk interface to parser
authored
464 ManifestParser parser(&state, NULL);
3867ae0 @martine factor tests into files
authored
465 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
466 EXPECT_FALSE(parser.ParseTest("rule cc\n"
467 " command = foo\n"
468 " othervar = bar\n",
469 &err));
470 EXPECT_EQ("input:3: unexpected variable 'othervar'\n"
471 " othervar = bar\n"
eeed724 @martine make Lexer::Error not emit trailing newline
authored
472 " ^ near here"
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
473 , err);
4e547a8 @martine die on unexpected vars in rule blocks
authored
474 }
ac4cc82 @martine expand variables in build paths
authored
475
476 {
477 State state;
478 ManifestParser parser(&state, NULL);
479 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
480 EXPECT_FALSE(parser.ParseTest("rule cc\n command = foo\n"
2e48108 @syntheticpp parse $:
syntheticpp authored
481 "build $.: cc bar.cc\n",
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
482 &err));
483 EXPECT_EQ("input:3: bad $-escape (literal $ must be written as $$)\n"
2e48108 @syntheticpp parse $:
syntheticpp authored
484 "build $.: cc bar.cc\n"
eeed724 @martine make Lexer::Error not emit trailing newline
authored
485 " ^ near here"
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
486 , err);
ac4cc82 @martine expand variables in build paths
authored
487 }
7a6c9d4 @pcc Implement default target statements
pcc authored
488
489 {
490 State state;
491 ManifestParser parser(&state, NULL);
492 string err;
2e48108 @syntheticpp parse $:
syntheticpp authored
493 EXPECT_FALSE(parser.ParseTest("rule cc\n command = foo\n"
494 "build $: cc bar.cc\n",
495 &err));
496 EXPECT_EQ("input:3: expected ':', got newline ($ also escapes ':')\n"
497 "build $: cc bar.cc\n"
498 " ^ near here"
499 , err);
500 }
501
502 {
503 State state;
504 ManifestParser parser(&state, NULL);
505 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
506 EXPECT_FALSE(parser.ParseTest("default\n",
507 &err));
508 EXPECT_EQ("input:1: expected target name\n"
509 "default\n"
eeed724 @martine make Lexer::Error not emit trailing newline
authored
510 " ^ near here"
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
511 , err);
7a6c9d4 @pcc Implement default target statements
pcc authored
512 }
513
514 {
515 State state;
516 ManifestParser parser(&state, NULL);
517 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
518 EXPECT_FALSE(parser.ParseTest("default nonexistent\n",
519 &err));
520 EXPECT_EQ("input:1: unknown target 'nonexistent'\n"
521 "default nonexistent\n"
eeed724 @martine make Lexer::Error not emit trailing newline
authored
522 " ^ near here"
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
523 , err);
7a6c9d4 @pcc Implement default target statements
pcc authored
524 }
525
526 {
527 State state;
528 ManifestParser parser(&state, NULL);
529 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
530 EXPECT_FALSE(parser.ParseTest("rule r\n command = r\n"
531 "build b: r\n"
532 "default b:\n",
533 &err));
534 EXPECT_EQ("input:4: expected newline, got ':'\n"
535 "default b:\n"
eeed724 @martine make Lexer::Error not emit trailing newline
authored
536 " ^ near here"
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
537 , err);
7a6c9d4 @pcc Implement default target statements
pcc authored
538 }
e54d2b6 @martine make CanonicalizePath report an error on empty path
authored
539
540 {
541 State state;
542 ManifestParser parser(&state, NULL);
543 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
544 EXPECT_FALSE(parser.ParseTest("default $a\n", &err));
545 EXPECT_EQ("input:1: empty path\n"
546 "default $a\n"
eeed724 @martine make Lexer::Error not emit trailing newline
authored
547 " ^ near here"
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
548 , err);
e54d2b6 @martine make CanonicalizePath report an error on empty path
authored
549 }
550
551 {
552 State state;
553 ManifestParser parser(&state, NULL);
554 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
555 EXPECT_FALSE(parser.ParseTest("rule r\n"
556 " command = r\n"
557 "build $a: r $c\n", &err));
e54d2b6 @martine make CanonicalizePath report an error on empty path
authored
558 // XXX the line number is wrong; we should evaluate paths in ParseEdge
559 // as we see them, not after we've read them all!
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
560 EXPECT_EQ("input:4: empty path\n", err);
e54d2b6 @martine make CanonicalizePath report an error on empty path
authored
561 }
831775c @evanj Lexer: include leading spaces in the newline token.
evanj authored
562
563 {
564 State state;
565 ManifestParser parser(&state, NULL);
566 string err;
567 // the indented blank line must terminate the rule
568 // this also verifies that "unexpected (token)" errors are correct
569 EXPECT_FALSE(parser.ParseTest("rule r\n"
570 " command = r\n"
571 " \n"
572 " generator = 1\n", &err));
573 EXPECT_EQ("input:4: unexpected indent\n", err);
574 }
3867ae0 @martine factor tests into files
authored
575 }
576
4b019b3 @martine test error message of ManifestParser::Load
authored
577 TEST_F(ParserTest, MissingInput) {
578 State state;
579 ManifestParser parser(&state, this);
580 string err;
581 EXPECT_FALSE(parser.Load("build.ninja", &err));
582 EXPECT_EQ("loading 'build.ninja': No such file or directory", err);
583 }
584
585 TEST_F(ParserTest, MultipleOutputs) {
d0b2492 @qhuo Move a passing test from Errors to MultipleOutputs
qhuo authored
586 State state;
587 ManifestParser parser(&state, NULL);
588 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
589 EXPECT_TRUE(parser.ParseTest("rule cc\n command = foo\n depfile = bar\n"
590 "build a.o b.o: cc c.cc\n",
591 &err));
d0b2492 @qhuo Move a passing test from Errors to MultipleOutputs
qhuo authored
592 EXPECT_EQ("", err);
593 }
594
6dac2ee @martine failing test for loading subninja
authored
595 TEST_F(ParserTest, SubNinja) {
b687060 @martine nested file-scoped binding environments
authored
596 files_["test.ninja"] =
597 "var = inner\n"
2449472 @martine remove special builddir
authored
598 "build $builddir/inner: varref\n";
6dac2ee @martine failing test for loading subninja
authored
599 ASSERT_NO_FATAL_FAILURE(AssertParse(
46aacaf @martine subninjas should inherit builddir
authored
600 "builddir = some_dir/\n"
b687060 @martine nested file-scoped binding environments
authored
601 "rule varref\n"
602 " command = varref $var\n"
603 "var = outer\n"
2449472 @martine remove special builddir
authored
604 "build $builddir/outer: varref\n"
b687060 @martine nested file-scoped binding environments
authored
605 "subninja test.ninja\n"
2449472 @martine remove special builddir
authored
606 "build $builddir/outer2: varref\n"));
4cc9326 @martine windows: fix more signedness warnings
authored
607 ASSERT_EQ(1u, files_read_.size());
b687060 @martine nested file-scoped binding environments
authored
608
f9c6232 @martine parse subfile; pass subninja test
authored
609 EXPECT_EQ("test.ninja", files_read_[0]);
b687060 @martine nested file-scoped binding environments
authored
610 EXPECT_TRUE(state.LookupNode("some_dir/outer"));
611 // Verify our builddir setting is inherited.
612 EXPECT_TRUE(state.LookupNode("some_dir/inner"));
613
4cc9326 @martine windows: fix more signedness warnings
authored
614 ASSERT_EQ(3u, state.edges_.size());
b687060 @martine nested file-scoped binding environments
authored
615 EXPECT_EQ("varref outer", state.edges_[0]->EvaluateCommand());
616 EXPECT_EQ("varref inner", state.edges_[1]->EvaluateCommand());
617 EXPECT_EQ("varref outer", state.edges_[2]->EvaluateCommand());
6dac2ee @martine failing test for loading subninja
authored
618 }
619
e69d8bf @martine include filename in subninja load err message
authored
620 TEST_F(ParserTest, MissingSubNinja) {
621 ManifestParser parser(&state, this);
622 string err;
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
623 EXPECT_FALSE(parser.ParseTest("subninja foo.ninja\n", &err));
624 EXPECT_EQ("input:1: loading 'foo.ninja': No such file or directory\n"
625 "subninja foo.ninja\n"
eeed724 @martine make Lexer::Error not emit trailing newline
authored
626 " ^ near here"
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
627 , err);
e69d8bf @martine include filename in subninja load err message
authored
628 }
629
facdb4c @martine add an include statement
authored
630 TEST_F(ParserTest, Include) {
631 files_["include.ninja"] = "var = inner\n";
632 ASSERT_NO_FATAL_FAILURE(AssertParse(
633 "var = outer\n"
634 "include include.ninja\n"));
635
4cc9326 @martine windows: fix more signedness warnings
authored
636 ASSERT_EQ(1u, files_read_.size());
facdb4c @martine add an include statement
authored
637 EXPECT_EQ("include.ninja", files_read_[0]);
638 EXPECT_EQ("inner", state.bindings_.LookupVariable("var"));
639 }
640
a206206 @martine allow implicit deps
authored
641 TEST_F(ParserTest, Implicit) {
dd6db97 @martine parse order-only dep syntax
authored
642 ASSERT_NO_FATAL_FAILURE(AssertParse(
8a0c960 @martine switch the core ninja parser to use re2c for the lexer
authored
643 "rule cat\n"
644 " command = cat $in > $out\n"
dd6db97 @martine parse order-only dep syntax
authored
645 "build foo: cat bar | baz\n"));
a206206 @martine allow implicit deps
authored
646
48526b9 @martine make Node::in_edge_ private
authored
647 Edge* edge = state.LookupNode("foo")->in_edge();
a206206 @martine allow implicit deps
authored
648 ASSERT_TRUE(edge->is_implicit(1));
649 }
650
651 TEST_F(ParserTest, OrderOnly) {
652 ASSERT_NO_FATAL_FAILURE(AssertParse(
653 "rule cat\n command = cat $in > $out\n"
654 "build foo: cat bar || baz\n"));
655
48526b9 @martine make Node::in_edge_ private
authored
656 Edge* edge = state.LookupNode("foo")->in_edge();
a206206 @martine allow implicit deps
authored
657 ASSERT_TRUE(edge->is_order_only(1));
dd6db97 @martine parse order-only dep syntax
authored
658 }
659
7a6c9d4 @pcc Implement default target statements
pcc authored
660 TEST_F(ParserTest, DefaultDefault) {
661 ASSERT_NO_FATAL_FAILURE(AssertParse(
662 "rule cat\n command = cat $in > $out\n"
663 "build a: cat foo\n"
664 "build b: cat foo\n"
665 "build c: cat foo\n"
666 "build d: cat foo\n"));
667
668 string err;
669 EXPECT_EQ(4u, state.DefaultNodes(&err).size());
670 EXPECT_EQ("", err);
671 }
672
673 TEST_F(ParserTest, DefaultStatements) {
674 ASSERT_NO_FATAL_FAILURE(AssertParse(
675 "rule cat\n command = cat $in > $out\n"
676 "build a: cat foo\n"
677 "build b: cat foo\n"
678 "build c: cat foo\n"
679 "build d: cat foo\n"
680 "third = c\n"
681 "default a b\n"
682 "default $third\n"));
683
684 string err;
685 std::vector<Node*> nodes = state.DefaultNodes(&err);
686 EXPECT_EQ("", err);
687 ASSERT_EQ(3u, nodes.size());
c6144cc @martine merge FileStat into Node
authored
688 EXPECT_EQ("a", nodes[0]->path());
689 EXPECT_EQ("b", nodes[1]->path());
690 EXPECT_EQ("c", nodes[2]->path());
7a6c9d4 @pcc Implement default target statements
pcc authored
691 }
01c7b2d @martine allow UTF-8 in rule descriptions
authored
692
693 TEST_F(ParserTest, UTF8) {
694 ASSERT_NO_FATAL_FAILURE(AssertParse(
695 "rule utf8\n"
696 " command = true\n"
697 " description = compilaci\xC3\xB3\n"));
698 }
8a37bff @martine disallow crlf in manifest files
authored
699
700 // We might want to eventually allow CRLF to be nice to Windows developers,
701 // but for now just verify we error out with a nice message.
702 TEST_F(ParserTest, CRLF) {
703 State state;
704 ManifestParser parser(&state, NULL);
705 string err;
706
707 EXPECT_FALSE(parser.ParseTest("# comment with crlf\r\n",
708 &err));
709 EXPECT_EQ("input:1: lexing error\n",
710 err);
711
712 EXPECT_FALSE(parser.ParseTest("foo = foo\nbar = bar\r\n",
713 &err));
ed07eb9 @martine reject tabs (and CRs) in input files more aggressively
authored
714 EXPECT_EQ("input:2: carriage returns are not allowed, use newlines\n"
8a37bff @martine disallow crlf in manifest files
authored
715 "bar = bar\r\n"
716 " ^ near here",
717 err);
718 }
Something went wrong with that request. Please try again.