1695b41eeSopenharmony_ci// Copyright 2011 Google Inc. All Rights Reserved.
2695b41eeSopenharmony_ci//
3695b41eeSopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
4695b41eeSopenharmony_ci// you may not use this file except in compliance with the License.
5695b41eeSopenharmony_ci// You may obtain a copy of the License at
6695b41eeSopenharmony_ci//
7695b41eeSopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
8695b41eeSopenharmony_ci//
9695b41eeSopenharmony_ci// Unless required by applicable law or agreed to in writing, software
10695b41eeSopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
11695b41eeSopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12695b41eeSopenharmony_ci// See the License for the specific language governing permissions and
13695b41eeSopenharmony_ci// limitations under the License.
14695b41eeSopenharmony_ci
15695b41eeSopenharmony_ci#include "depfile_parser.h"
16695b41eeSopenharmony_ci
17695b41eeSopenharmony_ci#include "test.h"
18695b41eeSopenharmony_ci
19695b41eeSopenharmony_ciusing namespace std;
20695b41eeSopenharmony_ci
21695b41eeSopenharmony_cistruct DepfileParserTest : public testing::Test {
22695b41eeSopenharmony_ci  bool Parse(const char* input, string* err);
23695b41eeSopenharmony_ci
24695b41eeSopenharmony_ci  DepfileParser parser_;
25695b41eeSopenharmony_ci  string input_;
26695b41eeSopenharmony_ci};
27695b41eeSopenharmony_ci
28695b41eeSopenharmony_cibool DepfileParserTest::Parse(const char* input, string* err) {
29695b41eeSopenharmony_ci  input_ = input;
30695b41eeSopenharmony_ci  return parser_.Parse(&input_, err);
31695b41eeSopenharmony_ci}
32695b41eeSopenharmony_ci
33695b41eeSopenharmony_ciTEST_F(DepfileParserTest, Basic) {
34695b41eeSopenharmony_ci  string err;
35695b41eeSopenharmony_ci  EXPECT_TRUE(Parse(
36695b41eeSopenharmony_ci"build/ninja.o: ninja.cc ninja.h eval_env.h manifest_parser.h\n",
37695b41eeSopenharmony_ci      &err));
38695b41eeSopenharmony_ci  ASSERT_EQ("", err);
39695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.outs_.size());
40695b41eeSopenharmony_ci  EXPECT_EQ("build/ninja.o", parser_.outs_[0].AsString());
41695b41eeSopenharmony_ci  EXPECT_EQ(4u, parser_.ins_.size());
42695b41eeSopenharmony_ci}
43695b41eeSopenharmony_ci
44695b41eeSopenharmony_ciTEST_F(DepfileParserTest, EarlyNewlineAndWhitespace) {
45695b41eeSopenharmony_ci  string err;
46695b41eeSopenharmony_ci  EXPECT_TRUE(Parse(
47695b41eeSopenharmony_ci" \\\n"
48695b41eeSopenharmony_ci"  out: in\n",
49695b41eeSopenharmony_ci      &err));
50695b41eeSopenharmony_ci  ASSERT_EQ("", err);
51695b41eeSopenharmony_ci}
52695b41eeSopenharmony_ci
53695b41eeSopenharmony_ciTEST_F(DepfileParserTest, Continuation) {
54695b41eeSopenharmony_ci  string err;
55695b41eeSopenharmony_ci  EXPECT_TRUE(Parse(
56695b41eeSopenharmony_ci"foo.o: \\\n"
57695b41eeSopenharmony_ci"  bar.h baz.h\n",
58695b41eeSopenharmony_ci      &err));
59695b41eeSopenharmony_ci  ASSERT_EQ("", err);
60695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.outs_.size());
61695b41eeSopenharmony_ci  EXPECT_EQ("foo.o", parser_.outs_[0].AsString());
62695b41eeSopenharmony_ci  EXPECT_EQ(2u, parser_.ins_.size());
63695b41eeSopenharmony_ci}
64695b41eeSopenharmony_ci
65695b41eeSopenharmony_ciTEST_F(DepfileParserTest, CarriageReturnContinuation) {
66695b41eeSopenharmony_ci  string err;
67695b41eeSopenharmony_ci  EXPECT_TRUE(Parse(
68695b41eeSopenharmony_ci"foo.o: \\\r\n"
69695b41eeSopenharmony_ci"  bar.h baz.h\r\n",
70695b41eeSopenharmony_ci      &err));
71695b41eeSopenharmony_ci  ASSERT_EQ("", err);
72695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.outs_.size());
73695b41eeSopenharmony_ci  EXPECT_EQ("foo.o", parser_.outs_[0].AsString());
74695b41eeSopenharmony_ci  EXPECT_EQ(2u, parser_.ins_.size());
75695b41eeSopenharmony_ci}
76695b41eeSopenharmony_ci
77695b41eeSopenharmony_ciTEST_F(DepfileParserTest, BackSlashes) {
78695b41eeSopenharmony_ci  string err;
79695b41eeSopenharmony_ci  EXPECT_TRUE(Parse(
80695b41eeSopenharmony_ci"Project\\Dir\\Build\\Release8\\Foo\\Foo.res : \\\n"
81695b41eeSopenharmony_ci"  Dir\\Library\\Foo.rc \\\n"
82695b41eeSopenharmony_ci"  Dir\\Library\\Version\\Bar.h \\\n"
83695b41eeSopenharmony_ci"  Dir\\Library\\Foo.ico \\\n"
84695b41eeSopenharmony_ci"  Project\\Thing\\Bar.tlb \\\n",
85695b41eeSopenharmony_ci      &err));
86695b41eeSopenharmony_ci  ASSERT_EQ("", err);
87695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.outs_.size());
88695b41eeSopenharmony_ci  EXPECT_EQ("Project\\Dir\\Build\\Release8\\Foo\\Foo.res",
89695b41eeSopenharmony_ci            parser_.outs_[0].AsString());
90695b41eeSopenharmony_ci  EXPECT_EQ(4u, parser_.ins_.size());
91695b41eeSopenharmony_ci}
92695b41eeSopenharmony_ci
93695b41eeSopenharmony_ciTEST_F(DepfileParserTest, Spaces) {
94695b41eeSopenharmony_ci  string err;
95695b41eeSopenharmony_ci  EXPECT_TRUE(Parse(
96695b41eeSopenharmony_ci"a\\ bc\\ def:   a\\ b c d",
97695b41eeSopenharmony_ci      &err));
98695b41eeSopenharmony_ci  ASSERT_EQ("", err);
99695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.outs_.size());
100695b41eeSopenharmony_ci  EXPECT_EQ("a bc def",
101695b41eeSopenharmony_ci            parser_.outs_[0].AsString());
102695b41eeSopenharmony_ci  ASSERT_EQ(3u, parser_.ins_.size());
103695b41eeSopenharmony_ci  EXPECT_EQ("a b",
104695b41eeSopenharmony_ci            parser_.ins_[0].AsString());
105695b41eeSopenharmony_ci  EXPECT_EQ("c",
106695b41eeSopenharmony_ci            parser_.ins_[1].AsString());
107695b41eeSopenharmony_ci  EXPECT_EQ("d",
108695b41eeSopenharmony_ci            parser_.ins_[2].AsString());
109695b41eeSopenharmony_ci}
110695b41eeSopenharmony_ci
111695b41eeSopenharmony_ciTEST_F(DepfileParserTest, MultipleBackslashes) {
112695b41eeSopenharmony_ci  // Successive 2N+1 backslashes followed by space (' ') are replaced by N >= 0
113695b41eeSopenharmony_ci  // backslashes and the space. A single backslash before hash sign is removed.
114695b41eeSopenharmony_ci  // Other backslashes remain untouched (including 2N backslashes followed by
115695b41eeSopenharmony_ci  // space).
116695b41eeSopenharmony_ci  string err;
117695b41eeSopenharmony_ci  EXPECT_TRUE(Parse(
118695b41eeSopenharmony_ci"a\\ b\\#c.h: \\\\\\\\\\  \\\\\\\\ \\\\share\\info\\\\#1",
119695b41eeSopenharmony_ci      &err));
120695b41eeSopenharmony_ci  ASSERT_EQ("", err);
121695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.outs_.size());
122695b41eeSopenharmony_ci  EXPECT_EQ("a b#c.h",
123695b41eeSopenharmony_ci            parser_.outs_[0].AsString());
124695b41eeSopenharmony_ci  ASSERT_EQ(3u, parser_.ins_.size());
125695b41eeSopenharmony_ci  EXPECT_EQ("\\\\ ",
126695b41eeSopenharmony_ci            parser_.ins_[0].AsString());
127695b41eeSopenharmony_ci  EXPECT_EQ("\\\\\\\\",
128695b41eeSopenharmony_ci            parser_.ins_[1].AsString());
129695b41eeSopenharmony_ci  EXPECT_EQ("\\\\share\\info\\#1",
130695b41eeSopenharmony_ci            parser_.ins_[2].AsString());
131695b41eeSopenharmony_ci}
132695b41eeSopenharmony_ci
133695b41eeSopenharmony_ciTEST_F(DepfileParserTest, Escapes) {
134695b41eeSopenharmony_ci  // Put backslashes before a variety of characters, see which ones make
135695b41eeSopenharmony_ci  // it through.
136695b41eeSopenharmony_ci  string err;
137695b41eeSopenharmony_ci  EXPECT_TRUE(Parse(
138695b41eeSopenharmony_ci"\\!\\@\\#$$\\%\\^\\&\\[\\]\\\\:",
139695b41eeSopenharmony_ci      &err));
140695b41eeSopenharmony_ci  ASSERT_EQ("", err);
141695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.outs_.size());
142695b41eeSopenharmony_ci  EXPECT_EQ("\\!\\@#$\\%\\^\\&\\[\\]\\\\",
143695b41eeSopenharmony_ci            parser_.outs_[0].AsString());
144695b41eeSopenharmony_ci  ASSERT_EQ(0u, parser_.ins_.size());
145695b41eeSopenharmony_ci}
146695b41eeSopenharmony_ci
147695b41eeSopenharmony_ciTEST_F(DepfileParserTest, EscapedColons)
148695b41eeSopenharmony_ci{
149695b41eeSopenharmony_ci  std::string err;
150695b41eeSopenharmony_ci  // Tests for correct parsing of depfiles produced on Windows
151695b41eeSopenharmony_ci  // by both Clang, GCC pre 10 and GCC 10
152695b41eeSopenharmony_ci  EXPECT_TRUE(Parse(
153695b41eeSopenharmony_ci"c\\:\\gcc\\x86_64-w64-mingw32\\include\\stddef.o: \\\n"
154695b41eeSopenharmony_ci" c:\\gcc\\x86_64-w64-mingw32\\include\\stddef.h \n",
155695b41eeSopenharmony_ci      &err));
156695b41eeSopenharmony_ci  ASSERT_EQ("", err);
157695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.outs_.size());
158695b41eeSopenharmony_ci  EXPECT_EQ("c:\\gcc\\x86_64-w64-mingw32\\include\\stddef.o",
159695b41eeSopenharmony_ci            parser_.outs_[0].AsString());
160695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.ins_.size());
161695b41eeSopenharmony_ci  EXPECT_EQ("c:\\gcc\\x86_64-w64-mingw32\\include\\stddef.h",
162695b41eeSopenharmony_ci            parser_.ins_[0].AsString());
163695b41eeSopenharmony_ci}
164695b41eeSopenharmony_ci
165695b41eeSopenharmony_ciTEST_F(DepfileParserTest, EscapedTargetColon)
166695b41eeSopenharmony_ci{
167695b41eeSopenharmony_ci  std::string err;
168695b41eeSopenharmony_ci  EXPECT_TRUE(Parse(
169695b41eeSopenharmony_ci"foo1\\: x\n"
170695b41eeSopenharmony_ci"foo1\\:\n"
171695b41eeSopenharmony_ci"foo1\\:\r\n"
172695b41eeSopenharmony_ci"foo1\\:\t\n"
173695b41eeSopenharmony_ci"foo1\\:",
174695b41eeSopenharmony_ci      &err));
175695b41eeSopenharmony_ci  ASSERT_EQ("", err);
176695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.outs_.size());
177695b41eeSopenharmony_ci  EXPECT_EQ("foo1\\", parser_.outs_[0].AsString());
178695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.ins_.size());
179695b41eeSopenharmony_ci  EXPECT_EQ("x", parser_.ins_[0].AsString());
180695b41eeSopenharmony_ci}
181695b41eeSopenharmony_ci
182695b41eeSopenharmony_ciTEST_F(DepfileParserTest, SpecialChars) {
183695b41eeSopenharmony_ci  // See filenames like istreambuf.iterator_op!= in
184695b41eeSopenharmony_ci  // https://github.com/google/libcxx/tree/master/test/iterators/stream.iterators/istreambuf.iterator/
185695b41eeSopenharmony_ci  string err;
186695b41eeSopenharmony_ci  EXPECT_TRUE(Parse(
187695b41eeSopenharmony_ci"C:/Program\\ Files\\ (x86)/Microsoft\\ crtdefs.h: \\\n"
188695b41eeSopenharmony_ci" en@quot.header~ t+t-x!=1 \\\n"
189695b41eeSopenharmony_ci" openldap/slapd.d/cn=config/cn=schema/cn={0}core.ldif\\\n"
190695b41eeSopenharmony_ci" Fu\303\244ball\\\n"
191695b41eeSopenharmony_ci" a[1]b@2%c",
192695b41eeSopenharmony_ci      &err));
193695b41eeSopenharmony_ci  ASSERT_EQ("", err);
194695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.outs_.size());
195695b41eeSopenharmony_ci  EXPECT_EQ("C:/Program Files (x86)/Microsoft crtdefs.h",
196695b41eeSopenharmony_ci            parser_.outs_[0].AsString());
197695b41eeSopenharmony_ci  ASSERT_EQ(5u, parser_.ins_.size());
198695b41eeSopenharmony_ci  EXPECT_EQ("en@quot.header~",
199695b41eeSopenharmony_ci            parser_.ins_[0].AsString());
200695b41eeSopenharmony_ci  EXPECT_EQ("t+t-x!=1",
201695b41eeSopenharmony_ci            parser_.ins_[1].AsString());
202695b41eeSopenharmony_ci  EXPECT_EQ("openldap/slapd.d/cn=config/cn=schema/cn={0}core.ldif",
203695b41eeSopenharmony_ci            parser_.ins_[2].AsString());
204695b41eeSopenharmony_ci  EXPECT_EQ("Fu\303\244ball",
205695b41eeSopenharmony_ci            parser_.ins_[3].AsString());
206695b41eeSopenharmony_ci  EXPECT_EQ("a[1]b@2%c",
207695b41eeSopenharmony_ci            parser_.ins_[4].AsString());
208695b41eeSopenharmony_ci}
209695b41eeSopenharmony_ci
210695b41eeSopenharmony_ciTEST_F(DepfileParserTest, UnifyMultipleOutputs) {
211695b41eeSopenharmony_ci  // check that multiple duplicate targets are properly unified
212695b41eeSopenharmony_ci  string err;
213695b41eeSopenharmony_ci  EXPECT_TRUE(Parse("foo foo: x y z", &err));
214695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.outs_.size());
215695b41eeSopenharmony_ci  ASSERT_EQ("foo", parser_.outs_[0].AsString());
216695b41eeSopenharmony_ci  ASSERT_EQ(3u, parser_.ins_.size());
217695b41eeSopenharmony_ci  EXPECT_EQ("x", parser_.ins_[0].AsString());
218695b41eeSopenharmony_ci  EXPECT_EQ("y", parser_.ins_[1].AsString());
219695b41eeSopenharmony_ci  EXPECT_EQ("z", parser_.ins_[2].AsString());
220695b41eeSopenharmony_ci}
221695b41eeSopenharmony_ci
222695b41eeSopenharmony_ciTEST_F(DepfileParserTest, MultipleDifferentOutputs) {
223695b41eeSopenharmony_ci  // check that multiple different outputs are accepted by the parser
224695b41eeSopenharmony_ci  string err;
225695b41eeSopenharmony_ci  EXPECT_TRUE(Parse("foo bar: x y z", &err));
226695b41eeSopenharmony_ci  ASSERT_EQ(2u, parser_.outs_.size());
227695b41eeSopenharmony_ci  ASSERT_EQ("foo", parser_.outs_[0].AsString());
228695b41eeSopenharmony_ci  ASSERT_EQ("bar", parser_.outs_[1].AsString());
229695b41eeSopenharmony_ci  ASSERT_EQ(3u, parser_.ins_.size());
230695b41eeSopenharmony_ci  EXPECT_EQ("x", parser_.ins_[0].AsString());
231695b41eeSopenharmony_ci  EXPECT_EQ("y", parser_.ins_[1].AsString());
232695b41eeSopenharmony_ci  EXPECT_EQ("z", parser_.ins_[2].AsString());
233695b41eeSopenharmony_ci}
234695b41eeSopenharmony_ci
235695b41eeSopenharmony_ciTEST_F(DepfileParserTest, MultipleEmptyRules) {
236695b41eeSopenharmony_ci  string err;
237695b41eeSopenharmony_ci  EXPECT_TRUE(Parse("foo: x\n"
238695b41eeSopenharmony_ci                    "foo: \n"
239695b41eeSopenharmony_ci                    "foo:\n", &err));
240695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.outs_.size());
241695b41eeSopenharmony_ci  ASSERT_EQ("foo", parser_.outs_[0].AsString());
242695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.ins_.size());
243695b41eeSopenharmony_ci  EXPECT_EQ("x", parser_.ins_[0].AsString());
244695b41eeSopenharmony_ci}
245695b41eeSopenharmony_ci
246695b41eeSopenharmony_ciTEST_F(DepfileParserTest, UnifyMultipleRulesLF) {
247695b41eeSopenharmony_ci  string err;
248695b41eeSopenharmony_ci  EXPECT_TRUE(Parse("foo: x\n"
249695b41eeSopenharmony_ci                    "foo: y\n"
250695b41eeSopenharmony_ci                    "foo \\\n"
251695b41eeSopenharmony_ci                    "foo: z\n", &err));
252695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.outs_.size());
253695b41eeSopenharmony_ci  ASSERT_EQ("foo", parser_.outs_[0].AsString());
254695b41eeSopenharmony_ci  ASSERT_EQ(3u, parser_.ins_.size());
255695b41eeSopenharmony_ci  EXPECT_EQ("x", parser_.ins_[0].AsString());
256695b41eeSopenharmony_ci  EXPECT_EQ("y", parser_.ins_[1].AsString());
257695b41eeSopenharmony_ci  EXPECT_EQ("z", parser_.ins_[2].AsString());
258695b41eeSopenharmony_ci}
259695b41eeSopenharmony_ci
260695b41eeSopenharmony_ciTEST_F(DepfileParserTest, UnifyMultipleRulesCRLF) {
261695b41eeSopenharmony_ci  string err;
262695b41eeSopenharmony_ci  EXPECT_TRUE(Parse("foo: x\r\n"
263695b41eeSopenharmony_ci                    "foo: y\r\n"
264695b41eeSopenharmony_ci                    "foo \\\r\n"
265695b41eeSopenharmony_ci                    "foo: z\r\n", &err));
266695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.outs_.size());
267695b41eeSopenharmony_ci  ASSERT_EQ("foo", parser_.outs_[0].AsString());
268695b41eeSopenharmony_ci  ASSERT_EQ(3u, parser_.ins_.size());
269695b41eeSopenharmony_ci  EXPECT_EQ("x", parser_.ins_[0].AsString());
270695b41eeSopenharmony_ci  EXPECT_EQ("y", parser_.ins_[1].AsString());
271695b41eeSopenharmony_ci  EXPECT_EQ("z", parser_.ins_[2].AsString());
272695b41eeSopenharmony_ci}
273695b41eeSopenharmony_ci
274695b41eeSopenharmony_ciTEST_F(DepfileParserTest, UnifyMixedRulesLF) {
275695b41eeSopenharmony_ci  string err;
276695b41eeSopenharmony_ci  EXPECT_TRUE(Parse("foo: x\\\n"
277695b41eeSopenharmony_ci                    "     y\n"
278695b41eeSopenharmony_ci                    "foo \\\n"
279695b41eeSopenharmony_ci                    "foo: z\n", &err));
280695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.outs_.size());
281695b41eeSopenharmony_ci  ASSERT_EQ("foo", parser_.outs_[0].AsString());
282695b41eeSopenharmony_ci  ASSERT_EQ(3u, parser_.ins_.size());
283695b41eeSopenharmony_ci  EXPECT_EQ("x", parser_.ins_[0].AsString());
284695b41eeSopenharmony_ci  EXPECT_EQ("y", parser_.ins_[1].AsString());
285695b41eeSopenharmony_ci  EXPECT_EQ("z", parser_.ins_[2].AsString());
286695b41eeSopenharmony_ci}
287695b41eeSopenharmony_ci
288695b41eeSopenharmony_ciTEST_F(DepfileParserTest, UnifyMixedRulesCRLF) {
289695b41eeSopenharmony_ci  string err;
290695b41eeSopenharmony_ci  EXPECT_TRUE(Parse("foo: x\\\r\n"
291695b41eeSopenharmony_ci                    "     y\r\n"
292695b41eeSopenharmony_ci                    "foo \\\r\n"
293695b41eeSopenharmony_ci                    "foo: z\r\n", &err));
294695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.outs_.size());
295695b41eeSopenharmony_ci  ASSERT_EQ("foo", parser_.outs_[0].AsString());
296695b41eeSopenharmony_ci  ASSERT_EQ(3u, parser_.ins_.size());
297695b41eeSopenharmony_ci  EXPECT_EQ("x", parser_.ins_[0].AsString());
298695b41eeSopenharmony_ci  EXPECT_EQ("y", parser_.ins_[1].AsString());
299695b41eeSopenharmony_ci  EXPECT_EQ("z", parser_.ins_[2].AsString());
300695b41eeSopenharmony_ci}
301695b41eeSopenharmony_ci
302695b41eeSopenharmony_ciTEST_F(DepfileParserTest, IndentedRulesLF) {
303695b41eeSopenharmony_ci  string err;
304695b41eeSopenharmony_ci  EXPECT_TRUE(Parse(" foo: x\n"
305695b41eeSopenharmony_ci                    " foo: y\n"
306695b41eeSopenharmony_ci                    " foo: z\n", &err));
307695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.outs_.size());
308695b41eeSopenharmony_ci  ASSERT_EQ("foo", parser_.outs_[0].AsString());
309695b41eeSopenharmony_ci  ASSERT_EQ(3u, parser_.ins_.size());
310695b41eeSopenharmony_ci  EXPECT_EQ("x", parser_.ins_[0].AsString());
311695b41eeSopenharmony_ci  EXPECT_EQ("y", parser_.ins_[1].AsString());
312695b41eeSopenharmony_ci  EXPECT_EQ("z", parser_.ins_[2].AsString());
313695b41eeSopenharmony_ci}
314695b41eeSopenharmony_ci
315695b41eeSopenharmony_ciTEST_F(DepfileParserTest, IndentedRulesCRLF) {
316695b41eeSopenharmony_ci  string err;
317695b41eeSopenharmony_ci  EXPECT_TRUE(Parse(" foo: x\r\n"
318695b41eeSopenharmony_ci                    " foo: y\r\n"
319695b41eeSopenharmony_ci                    " foo: z\r\n", &err));
320695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.outs_.size());
321695b41eeSopenharmony_ci  ASSERT_EQ("foo", parser_.outs_[0].AsString());
322695b41eeSopenharmony_ci  ASSERT_EQ(3u, parser_.ins_.size());
323695b41eeSopenharmony_ci  EXPECT_EQ("x", parser_.ins_[0].AsString());
324695b41eeSopenharmony_ci  EXPECT_EQ("y", parser_.ins_[1].AsString());
325695b41eeSopenharmony_ci  EXPECT_EQ("z", parser_.ins_[2].AsString());
326695b41eeSopenharmony_ci}
327695b41eeSopenharmony_ci
328695b41eeSopenharmony_ciTEST_F(DepfileParserTest, TolerateMP) {
329695b41eeSopenharmony_ci  string err;
330695b41eeSopenharmony_ci  EXPECT_TRUE(Parse("foo: x y z\n"
331695b41eeSopenharmony_ci                    "x:\n"
332695b41eeSopenharmony_ci                    "y:\n"
333695b41eeSopenharmony_ci                    "z:\n", &err));
334695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.outs_.size());
335695b41eeSopenharmony_ci  ASSERT_EQ("foo", parser_.outs_[0].AsString());
336695b41eeSopenharmony_ci  ASSERT_EQ(3u, parser_.ins_.size());
337695b41eeSopenharmony_ci  EXPECT_EQ("x", parser_.ins_[0].AsString());
338695b41eeSopenharmony_ci  EXPECT_EQ("y", parser_.ins_[1].AsString());
339695b41eeSopenharmony_ci  EXPECT_EQ("z", parser_.ins_[2].AsString());
340695b41eeSopenharmony_ci}
341695b41eeSopenharmony_ci
342695b41eeSopenharmony_ciTEST_F(DepfileParserTest, MultipleRulesTolerateMP) {
343695b41eeSopenharmony_ci  string err;
344695b41eeSopenharmony_ci  EXPECT_TRUE(Parse("foo: x\n"
345695b41eeSopenharmony_ci                    "x:\n"
346695b41eeSopenharmony_ci                    "foo: y\n"
347695b41eeSopenharmony_ci                    "y:\n"
348695b41eeSopenharmony_ci                    "foo: z\n"
349695b41eeSopenharmony_ci                    "z:\n", &err));
350695b41eeSopenharmony_ci  ASSERT_EQ(1u, parser_.outs_.size());
351695b41eeSopenharmony_ci  ASSERT_EQ("foo", parser_.outs_[0].AsString());
352695b41eeSopenharmony_ci  ASSERT_EQ(3u, parser_.ins_.size());
353695b41eeSopenharmony_ci  EXPECT_EQ("x", parser_.ins_[0].AsString());
354695b41eeSopenharmony_ci  EXPECT_EQ("y", parser_.ins_[1].AsString());
355695b41eeSopenharmony_ci  EXPECT_EQ("z", parser_.ins_[2].AsString());
356695b41eeSopenharmony_ci}
357695b41eeSopenharmony_ci
358695b41eeSopenharmony_ciTEST_F(DepfileParserTest, MultipleRulesDifferentOutputs) {
359695b41eeSopenharmony_ci  // check that multiple different outputs are accepted by the parser
360695b41eeSopenharmony_ci  // when spread across multiple rules
361695b41eeSopenharmony_ci  string err;
362695b41eeSopenharmony_ci  EXPECT_TRUE(Parse("foo: x y\n"
363695b41eeSopenharmony_ci                    "bar: y z\n", &err));
364695b41eeSopenharmony_ci  ASSERT_EQ(2u, parser_.outs_.size());
365695b41eeSopenharmony_ci  ASSERT_EQ("foo", parser_.outs_[0].AsString());
366695b41eeSopenharmony_ci  ASSERT_EQ("bar", parser_.outs_[1].AsString());
367695b41eeSopenharmony_ci  ASSERT_EQ(3u, parser_.ins_.size());
368695b41eeSopenharmony_ci  EXPECT_EQ("x", parser_.ins_[0].AsString());
369695b41eeSopenharmony_ci  EXPECT_EQ("y", parser_.ins_[1].AsString());
370695b41eeSopenharmony_ci  EXPECT_EQ("z", parser_.ins_[2].AsString());
371695b41eeSopenharmony_ci}
372695b41eeSopenharmony_ci
373695b41eeSopenharmony_ciTEST_F(DepfileParserTest, BuggyMP) {
374695b41eeSopenharmony_ci  std::string err;
375695b41eeSopenharmony_ci  EXPECT_FALSE(Parse("foo: x y z\n"
376695b41eeSopenharmony_ci                     "x: alsoin\n"
377695b41eeSopenharmony_ci                     "y:\n"
378695b41eeSopenharmony_ci                     "z:\n", &err));
379695b41eeSopenharmony_ci  ASSERT_EQ("inputs may not also have inputs", err);
380695b41eeSopenharmony_ci}
381695b41eeSopenharmony_ci
382695b41eeSopenharmony_ciTEST_F(DepfileParserTest, EmptyFile) {
383695b41eeSopenharmony_ci  std::string err;
384695b41eeSopenharmony_ci  EXPECT_TRUE(Parse("", &err));
385695b41eeSopenharmony_ci  ASSERT_EQ(0u, parser_.outs_.size());
386695b41eeSopenharmony_ci  ASSERT_EQ(0u, parser_.ins_.size());
387695b41eeSopenharmony_ci}
388695b41eeSopenharmony_ci
389695b41eeSopenharmony_ciTEST_F(DepfileParserTest, EmptyLines) {
390695b41eeSopenharmony_ci  std::string err;
391695b41eeSopenharmony_ci  EXPECT_TRUE(Parse("\n\n", &err));
392695b41eeSopenharmony_ci  ASSERT_EQ(0u, parser_.outs_.size());
393695b41eeSopenharmony_ci  ASSERT_EQ(0u, parser_.ins_.size());
394695b41eeSopenharmony_ci}
395695b41eeSopenharmony_ci
396695b41eeSopenharmony_ciTEST_F(DepfileParserTest, MissingColon) {
397695b41eeSopenharmony_ci  // The file is not empty but is missing a colon separator.
398695b41eeSopenharmony_ci  std::string err;
399695b41eeSopenharmony_ci  EXPECT_FALSE(Parse("foo.o foo.c\n", &err));
400695b41eeSopenharmony_ci  EXPECT_EQ("expected ':' in depfile", err);
401695b41eeSopenharmony_ci}
402