Imported Upstream version 1.10.1
[platform/upstream/ninja.git] / src / depfile_parser_test.cc
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 "depfile_parser.h"
16
17 #include "test.h"
18
19 struct DepfileParserTest : public testing::Test {
20   bool Parse(const char* input, string* err);
21
22   DepfileParser parser_;
23   string input_;
24 };
25
26 bool DepfileParserTest::Parse(const char* input, string* err) {
27   input_ = input;
28   return parser_.Parse(&input_, err);
29 }
30
31 TEST_F(DepfileParserTest, Basic) {
32   string err;
33   EXPECT_TRUE(Parse(
34 "build/ninja.o: ninja.cc ninja.h eval_env.h manifest_parser.h\n",
35       &err));
36   ASSERT_EQ("", err);
37   ASSERT_EQ(1u, parser_.outs_.size());
38   EXPECT_EQ("build/ninja.o", parser_.outs_[0].AsString());
39   EXPECT_EQ(4u, parser_.ins_.size());
40 }
41
42 TEST_F(DepfileParserTest, EarlyNewlineAndWhitespace) {
43   string err;
44   EXPECT_TRUE(Parse(
45 " \\\n"
46 "  out: in\n",
47       &err));
48   ASSERT_EQ("", err);
49 }
50
51 TEST_F(DepfileParserTest, Continuation) {
52   string err;
53   EXPECT_TRUE(Parse(
54 "foo.o: \\\n"
55 "  bar.h baz.h\n",
56       &err));
57   ASSERT_EQ("", err);
58   ASSERT_EQ(1u, parser_.outs_.size());
59   EXPECT_EQ("foo.o", parser_.outs_[0].AsString());
60   EXPECT_EQ(2u, parser_.ins_.size());
61 }
62
63 TEST_F(DepfileParserTest, CarriageReturnContinuation) {
64   string err;
65   EXPECT_TRUE(Parse(
66 "foo.o: \\\r\n"
67 "  bar.h baz.h\r\n",
68       &err));
69   ASSERT_EQ("", err);
70   ASSERT_EQ(1u, parser_.outs_.size());
71   EXPECT_EQ("foo.o", parser_.outs_[0].AsString());
72   EXPECT_EQ(2u, parser_.ins_.size());
73 }
74
75 TEST_F(DepfileParserTest, BackSlashes) {
76   string err;
77   EXPECT_TRUE(Parse(
78 "Project\\Dir\\Build\\Release8\\Foo\\Foo.res : \\\n"
79 "  Dir\\Library\\Foo.rc \\\n"
80 "  Dir\\Library\\Version\\Bar.h \\\n"
81 "  Dir\\Library\\Foo.ico \\\n"
82 "  Project\\Thing\\Bar.tlb \\\n",
83       &err));
84   ASSERT_EQ("", err);
85   ASSERT_EQ(1u, parser_.outs_.size());
86   EXPECT_EQ("Project\\Dir\\Build\\Release8\\Foo\\Foo.res",
87             parser_.outs_[0].AsString());
88   EXPECT_EQ(4u, parser_.ins_.size());
89 }
90
91 TEST_F(DepfileParserTest, Spaces) {
92   string err;
93   EXPECT_TRUE(Parse(
94 "a\\ bc\\ def:   a\\ b c d",
95       &err));
96   ASSERT_EQ("", err);
97   ASSERT_EQ(1u, parser_.outs_.size());
98   EXPECT_EQ("a bc def",
99             parser_.outs_[0].AsString());
100   ASSERT_EQ(3u, parser_.ins_.size());
101   EXPECT_EQ("a b",
102             parser_.ins_[0].AsString());
103   EXPECT_EQ("c",
104             parser_.ins_[1].AsString());
105   EXPECT_EQ("d",
106             parser_.ins_[2].AsString());
107 }
108
109 TEST_F(DepfileParserTest, MultipleBackslashes) {
110   // Successive 2N+1 backslashes followed by space (' ') are replaced by N >= 0
111   // backslashes and the space. A single backslash before hash sign is removed.
112   // Other backslashes remain untouched (including 2N backslashes followed by
113   // space).
114   string err;
115   EXPECT_TRUE(Parse(
116 "a\\ b\\#c.h: \\\\\\\\\\  \\\\\\\\ \\\\share\\info\\\\#1",
117       &err));
118   ASSERT_EQ("", err);
119   ASSERT_EQ(1u, parser_.outs_.size());
120   EXPECT_EQ("a b#c.h",
121             parser_.outs_[0].AsString());
122   ASSERT_EQ(3u, parser_.ins_.size());
123   EXPECT_EQ("\\\\ ",
124             parser_.ins_[0].AsString());
125   EXPECT_EQ("\\\\\\\\",
126             parser_.ins_[1].AsString());
127   EXPECT_EQ("\\\\share\\info\\#1",
128             parser_.ins_[2].AsString());
129 }
130
131 TEST_F(DepfileParserTest, Escapes) {
132   // Put backslashes before a variety of characters, see which ones make
133   // it through.
134   string err;
135   EXPECT_TRUE(Parse(
136 "\\!\\@\\#$$\\%\\^\\&\\[\\]\\\\:",
137       &err));
138   ASSERT_EQ("", err);
139   ASSERT_EQ(1u, parser_.outs_.size());
140   EXPECT_EQ("\\!\\@#$\\%\\^\\&\\[\\]\\\\",
141             parser_.outs_[0].AsString());
142   ASSERT_EQ(0u, parser_.ins_.size());
143 }
144
145 TEST_F(DepfileParserTest, EscapedColons)
146 {
147   std::string err;
148   // Tests for correct parsing of depfiles produced on Windows
149   // by both Clang, GCC pre 10 and GCC 10
150   EXPECT_TRUE(Parse(
151 "c\\:\\gcc\\x86_64-w64-mingw32\\include\\stddef.o: \\\n"
152 " c:\\gcc\\x86_64-w64-mingw32\\include\\stddef.h \n",
153       &err));
154   ASSERT_EQ("", err);
155   ASSERT_EQ(1u, parser_.outs_.size());
156   EXPECT_EQ("c:\\gcc\\x86_64-w64-mingw32\\include\\stddef.o",
157             parser_.outs_[0].AsString());
158   ASSERT_EQ(1u, parser_.ins_.size());
159   EXPECT_EQ("c:\\gcc\\x86_64-w64-mingw32\\include\\stddef.h",
160             parser_.ins_[0].AsString());
161 }
162
163 TEST_F(DepfileParserTest, EscapedTargetColon)
164 {
165   std::string err;
166   EXPECT_TRUE(Parse(
167 "foo1\\: x\n"
168 "foo1\\:\n"
169 "foo1\\:\r\n"
170 "foo1\\:\t\n"
171 "foo1\\:",
172       &err));
173   ASSERT_EQ("", err);
174   ASSERT_EQ(1u, parser_.outs_.size());
175   EXPECT_EQ("foo1\\", parser_.outs_[0].AsString());
176   ASSERT_EQ(1u, parser_.ins_.size());
177   EXPECT_EQ("x", parser_.ins_[0].AsString());
178 }
179
180 TEST_F(DepfileParserTest, SpecialChars) {
181   // See filenames like istreambuf.iterator_op!= in
182   // https://github.com/google/libcxx/tree/master/test/iterators/stream.iterators/istreambuf.iterator/
183   string err;
184   EXPECT_TRUE(Parse(
185 "C:/Program\\ Files\\ (x86)/Microsoft\\ crtdefs.h: \\\n"
186 " en@quot.header~ t+t-x!=1 \\\n"
187 " openldap/slapd.d/cn=config/cn=schema/cn={0}core.ldif\\\n"
188 " Fu\303\244ball\\\n"
189 " a[1]b@2%c",
190       &err));
191   ASSERT_EQ("", err);
192   ASSERT_EQ(1u, parser_.outs_.size());
193   EXPECT_EQ("C:/Program Files (x86)/Microsoft crtdefs.h",
194             parser_.outs_[0].AsString());
195   ASSERT_EQ(5u, parser_.ins_.size());
196   EXPECT_EQ("en@quot.header~",
197             parser_.ins_[0].AsString());
198   EXPECT_EQ("t+t-x!=1",
199             parser_.ins_[1].AsString());
200   EXPECT_EQ("openldap/slapd.d/cn=config/cn=schema/cn={0}core.ldif",
201             parser_.ins_[2].AsString());
202   EXPECT_EQ("Fu\303\244ball",
203             parser_.ins_[3].AsString());
204   EXPECT_EQ("a[1]b@2%c",
205             parser_.ins_[4].AsString());
206 }
207
208 TEST_F(DepfileParserTest, UnifyMultipleOutputs) {
209   // check that multiple duplicate targets are properly unified
210   string err;
211   EXPECT_TRUE(Parse("foo foo: x y z", &err));
212   ASSERT_EQ(1u, parser_.outs_.size());
213   ASSERT_EQ("foo", parser_.outs_[0].AsString());
214   ASSERT_EQ(3u, parser_.ins_.size());
215   EXPECT_EQ("x", parser_.ins_[0].AsString());
216   EXPECT_EQ("y", parser_.ins_[1].AsString());
217   EXPECT_EQ("z", parser_.ins_[2].AsString());
218 }
219
220 TEST_F(DepfileParserTest, MultipleDifferentOutputs) {
221   // check that multiple different outputs are accepted by the parser
222   string err;
223   EXPECT_TRUE(Parse("foo bar: x y z", &err));
224   ASSERT_EQ(2u, parser_.outs_.size());
225   ASSERT_EQ("foo", parser_.outs_[0].AsString());
226   ASSERT_EQ("bar", parser_.outs_[1].AsString());
227   ASSERT_EQ(3u, parser_.ins_.size());
228   EXPECT_EQ("x", parser_.ins_[0].AsString());
229   EXPECT_EQ("y", parser_.ins_[1].AsString());
230   EXPECT_EQ("z", parser_.ins_[2].AsString());
231 }
232
233 TEST_F(DepfileParserTest, MultipleEmptyRules) {
234   string err;
235   EXPECT_TRUE(Parse("foo: x\n"
236                     "foo: \n"
237                     "foo:\n", &err));
238   ASSERT_EQ(1u, parser_.outs_.size());
239   ASSERT_EQ("foo", parser_.outs_[0].AsString());
240   ASSERT_EQ(1u, parser_.ins_.size());
241   EXPECT_EQ("x", parser_.ins_[0].AsString());
242 }
243
244 TEST_F(DepfileParserTest, UnifyMultipleRulesLF) {
245   string err;
246   EXPECT_TRUE(Parse("foo: x\n"
247                     "foo: y\n"
248                     "foo \\\n"
249                     "foo: z\n", &err));
250   ASSERT_EQ(1u, parser_.outs_.size());
251   ASSERT_EQ("foo", parser_.outs_[0].AsString());
252   ASSERT_EQ(3u, parser_.ins_.size());
253   EXPECT_EQ("x", parser_.ins_[0].AsString());
254   EXPECT_EQ("y", parser_.ins_[1].AsString());
255   EXPECT_EQ("z", parser_.ins_[2].AsString());
256 }
257
258 TEST_F(DepfileParserTest, UnifyMultipleRulesCRLF) {
259   string err;
260   EXPECT_TRUE(Parse("foo: x\r\n"
261                     "foo: y\r\n"
262                     "foo \\\r\n"
263                     "foo: z\r\n", &err));
264   ASSERT_EQ(1u, parser_.outs_.size());
265   ASSERT_EQ("foo", parser_.outs_[0].AsString());
266   ASSERT_EQ(3u, parser_.ins_.size());
267   EXPECT_EQ("x", parser_.ins_[0].AsString());
268   EXPECT_EQ("y", parser_.ins_[1].AsString());
269   EXPECT_EQ("z", parser_.ins_[2].AsString());
270 }
271
272 TEST_F(DepfileParserTest, UnifyMixedRulesLF) {
273   string err;
274   EXPECT_TRUE(Parse("foo: x\\\n"
275                     "     y\n"
276                     "foo \\\n"
277                     "foo: z\n", &err));
278   ASSERT_EQ(1u, parser_.outs_.size());
279   ASSERT_EQ("foo", parser_.outs_[0].AsString());
280   ASSERT_EQ(3u, parser_.ins_.size());
281   EXPECT_EQ("x", parser_.ins_[0].AsString());
282   EXPECT_EQ("y", parser_.ins_[1].AsString());
283   EXPECT_EQ("z", parser_.ins_[2].AsString());
284 }
285
286 TEST_F(DepfileParserTest, UnifyMixedRulesCRLF) {
287   string err;
288   EXPECT_TRUE(Parse("foo: x\\\r\n"
289                     "     y\r\n"
290                     "foo \\\r\n"
291                     "foo: z\r\n", &err));
292   ASSERT_EQ(1u, parser_.outs_.size());
293   ASSERT_EQ("foo", parser_.outs_[0].AsString());
294   ASSERT_EQ(3u, parser_.ins_.size());
295   EXPECT_EQ("x", parser_.ins_[0].AsString());
296   EXPECT_EQ("y", parser_.ins_[1].AsString());
297   EXPECT_EQ("z", parser_.ins_[2].AsString());
298 }
299
300 TEST_F(DepfileParserTest, IndentedRulesLF) {
301   string err;
302   EXPECT_TRUE(Parse(" foo: x\n"
303                     " foo: y\n"
304                     " foo: z\n", &err));
305   ASSERT_EQ(1u, parser_.outs_.size());
306   ASSERT_EQ("foo", parser_.outs_[0].AsString());
307   ASSERT_EQ(3u, parser_.ins_.size());
308   EXPECT_EQ("x", parser_.ins_[0].AsString());
309   EXPECT_EQ("y", parser_.ins_[1].AsString());
310   EXPECT_EQ("z", parser_.ins_[2].AsString());
311 }
312
313 TEST_F(DepfileParserTest, IndentedRulesCRLF) {
314   string err;
315   EXPECT_TRUE(Parse(" foo: x\r\n"
316                     " foo: y\r\n"
317                     " foo: z\r\n", &err));
318   ASSERT_EQ(1u, parser_.outs_.size());
319   ASSERT_EQ("foo", parser_.outs_[0].AsString());
320   ASSERT_EQ(3u, parser_.ins_.size());
321   EXPECT_EQ("x", parser_.ins_[0].AsString());
322   EXPECT_EQ("y", parser_.ins_[1].AsString());
323   EXPECT_EQ("z", parser_.ins_[2].AsString());
324 }
325
326 TEST_F(DepfileParserTest, TolerateMP) {
327   string err;
328   EXPECT_TRUE(Parse("foo: x y z\n"
329                     "x:\n"
330                     "y:\n"
331                     "z:\n", &err));
332   ASSERT_EQ(1u, parser_.outs_.size());
333   ASSERT_EQ("foo", parser_.outs_[0].AsString());
334   ASSERT_EQ(3u, parser_.ins_.size());
335   EXPECT_EQ("x", parser_.ins_[0].AsString());
336   EXPECT_EQ("y", parser_.ins_[1].AsString());
337   EXPECT_EQ("z", parser_.ins_[2].AsString());
338 }
339
340 TEST_F(DepfileParserTest, MultipleRulesTolerateMP) {
341   string err;
342   EXPECT_TRUE(Parse("foo: x\n"
343                     "x:\n"
344                     "foo: y\n"
345                     "y:\n"
346                     "foo: z\n"
347                     "z:\n", &err));
348   ASSERT_EQ(1u, parser_.outs_.size());
349   ASSERT_EQ("foo", parser_.outs_[0].AsString());
350   ASSERT_EQ(3u, parser_.ins_.size());
351   EXPECT_EQ("x", parser_.ins_[0].AsString());
352   EXPECT_EQ("y", parser_.ins_[1].AsString());
353   EXPECT_EQ("z", parser_.ins_[2].AsString());
354 }
355
356 TEST_F(DepfileParserTest, MultipleRulesDifferentOutputs) {
357   // check that multiple different outputs are accepted by the parser
358   // when spread across multiple rules
359   string err;
360   EXPECT_TRUE(Parse("foo: x y\n"
361                     "bar: y z\n", &err));
362   ASSERT_EQ(2u, parser_.outs_.size());
363   ASSERT_EQ("foo", parser_.outs_[0].AsString());
364   ASSERT_EQ("bar", parser_.outs_[1].AsString());
365   ASSERT_EQ(3u, parser_.ins_.size());
366   EXPECT_EQ("x", parser_.ins_[0].AsString());
367   EXPECT_EQ("y", parser_.ins_[1].AsString());
368   EXPECT_EQ("z", parser_.ins_[2].AsString());
369 }
370
371 TEST_F(DepfileParserTest, BuggyMP) {
372   std::string err;
373   EXPECT_FALSE(Parse("foo: x y z\n"
374                      "x: alsoin\n"
375                      "y:\n"
376                      "z:\n", &err));
377   ASSERT_EQ("inputs may not also have inputs", err);
378 }