c5bc291e0e4e4bf15e787b276c84293a0456dac3
[platform/upstream/ninja.git] / src / depfile_parser.cc
1 /* Generated by re2c 0.13.5 */\r
2 // Copyright 2011 Google Inc. All Rights Reserved.\r
3 //\r
4 // Licensed under the Apache License, Version 2.0 (the "License");\r
5 // you may not use this file except in compliance with the License.\r
6 // You may obtain a copy of the License at\r
7 //\r
8 //     http://www.apache.org/licenses/LICENSE-2.0\r
9 //\r
10 // Unless required by applicable law or agreed to in writing, software\r
11 // distributed under the License is distributed on an "AS IS" BASIS,\r
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13 // See the License for the specific language governing permissions and\r
14 // limitations under the License.\r
15 \r
16 #include "depfile_parser.h"\r
17 \r
18 // A note on backslashes in Makefiles, from reading the docs:\r
19 // Backslash-newline is the line continuation character.\r
20 // Backslash-# escapes a # (otherwise meaningful as a comment start).\r
21 // Backslash-% escapes a % (otherwise meaningful as a special).\r
22 // Finally, quoting the GNU manual, "Backslashes that are not in danger\r
23 // of quoting ‘%’ characters go unmolested."\r
24 // How do you end a line with a backslash?  The netbsd Make docs suggest\r
25 // reading the result of a shell command echoing a backslash!\r
26 //\r
27 // Rather than implement all of above, we do a simpler thing here:\r
28 // Backslashes escape a set of characters (see "escapes" defined below),\r
29 // otherwise they are passed through verbatim.\r
30 // If anyone actually has depfiles that rely on the more complicated\r
31 // behavior we can adjust this.\r
32 bool DepfileParser::Parse(string* content, string* err) {\r
33   // in: current parser input point.\r
34   // end: end of input.\r
35   // parsing_targets: whether we are parsing targets or dependencies.\r
36   char* in = &(*content)[0];\r
37   char* end = in + content->size();\r
38   bool parsing_targets = true;\r
39   while (in < end) {\r
40     // out: current output point (typically same as in, but can fall behind\r
41     // as we de-escape backslashes).\r
42     char* out = in;\r
43     // filename: start of the current parsed filename.\r
44     char* filename = out;\r
45     for (;;) {\r
46       // start: beginning of the current parsed span.\r
47       const char* start = in;\r
48       \r
49     {\r
50       char yych;\r
51       static const unsigned char yybm[] = {\r
52           0,   0,   0,   0,   0,   0,   0,   0, \r
53           0,   0,   0,   0,   0,   0,   0,   0, \r
54           0,   0,   0,   0,   0,   0,   0,   0, \r
55           0,   0,   0,   0,   0,   0,   0,   0, \r
56           0, 128,   0,   0,   0,   0,   0,   0, \r
57         128, 128,   0, 128, 128, 128, 128, 128, \r
58         128, 128, 128, 128, 128, 128, 128, 128, \r
59         128, 128, 128,   0,   0, 128,   0,   0, \r
60         128, 128, 128, 128, 128, 128, 128, 128, \r
61         128, 128, 128, 128, 128, 128, 128, 128, \r
62         128, 128, 128, 128, 128, 128, 128, 128, \r
63         128, 128, 128,   0,   0,   0,   0, 128, \r
64           0, 128, 128, 128, 128, 128, 128, 128, \r
65         128, 128, 128, 128, 128, 128, 128, 128, \r
66         128, 128, 128, 128, 128, 128, 128, 128, \r
67         128, 128, 128, 128,   0, 128, 128,   0, \r
68           0,   0,   0,   0,   0,   0,   0,   0, \r
69           0,   0,   0,   0,   0,   0,   0,   0, \r
70           0,   0,   0,   0,   0,   0,   0,   0, \r
71           0,   0,   0,   0,   0,   0,   0,   0, \r
72           0,   0,   0,   0,   0,   0,   0,   0, \r
73           0,   0,   0,   0,   0,   0,   0,   0, \r
74           0,   0,   0,   0,   0,   0,   0,   0, \r
75           0,   0,   0,   0,   0,   0,   0,   0, \r
76           0,   0,   0,   0,   0,   0,   0,   0, \r
77           0,   0,   0,   0,   0,   0,   0,   0, \r
78           0,   0,   0,   0,   0,   0,   0,   0, \r
79           0,   0,   0,   0,   0,   0,   0,   0, \r
80           0,   0,   0,   0,   0,   0,   0,   0, \r
81           0,   0,   0,   0,   0,   0,   0,   0, \r
82           0,   0,   0,   0,   0,   0,   0,   0, \r
83           0,   0,   0,   0,   0,   0,   0,   0, \r
84       };\r
85 \r
86       yych = *in;\r
87       if (yych <= '=') {\r
88         if (yych <= '$') {\r
89           if (yych <= ' ') {\r
90             if (yych <= 0x00) goto yy7;\r
91             goto yy9;\r
92           } else {\r
93             if (yych <= '!') goto yy5;\r
94             if (yych <= '#') goto yy9;\r
95             goto yy4;\r
96           }\r
97         } else {\r
98           if (yych <= '*') {\r
99             if (yych <= '\'') goto yy9;\r
100             if (yych <= ')') goto yy5;\r
101             goto yy9;\r
102           } else {\r
103             if (yych <= ':') goto yy5;\r
104             if (yych <= '<') goto yy9;\r
105             goto yy5;\r
106           }\r
107         }\r
108       } else {\r
109         if (yych <= '^') {\r
110           if (yych <= 'Z') {\r
111             if (yych <= '?') goto yy9;\r
112             goto yy5;\r
113           } else {\r
114             if (yych != '\\') goto yy9;\r
115           }\r
116         } else {\r
117           if (yych <= '{') {\r
118             if (yych == '`') goto yy9;\r
119             goto yy5;\r
120           } else {\r
121             if (yych <= '|') goto yy9;\r
122             if (yych <= '~') goto yy5;\r
123             goto yy9;\r
124           }\r
125         }\r
126       }\r
127       ++in;\r
128       if ((yych = *in) <= '"') {\r
129         if (yych <= '\f') {\r
130           if (yych <= 0x00) goto yy3;\r
131           if (yych != '\n') goto yy14;\r
132         } else {\r
133           if (yych <= '\r') goto yy3;\r
134           if (yych == ' ') goto yy16;\r
135           goto yy14;\r
136         }\r
137       } else {\r
138         if (yych <= 'Z') {\r
139           if (yych <= '#') goto yy16;\r
140           if (yych == '*') goto yy16;\r
141           goto yy14;\r
142         } else {\r
143           if (yych <= '\\') goto yy16;\r
144           if (yych == '|') goto yy16;\r
145           goto yy14;\r
146         }\r
147       }\r
148 yy3:\r
149       {\r
150         // For any other character (e.g. whitespace), swallow it here,\r
151         // allowing the outer logic to loop around again.\r
152         break;\r
153       }\r
154 yy4:\r
155       yych = *++in;\r
156       if (yych == '$') goto yy12;\r
157       goto yy3;\r
158 yy5:\r
159       ++in;\r
160       yych = *in;\r
161       goto yy11;\r
162 yy6:\r
163       {\r
164         // Got a span of plain text.\r
165         int len = (int)(in - start);\r
166         // Need to shift it over if we're overwriting backslashes.\r
167         if (out < start)\r
168           memmove(out, start, len);\r
169         out += len;\r
170         continue;\r
171       }\r
172 yy7:\r
173       ++in;\r
174       {\r
175         break;\r
176       }\r
177 yy9:\r
178       yych = *++in;\r
179       goto yy3;\r
180 yy10:\r
181       ++in;\r
182       yych = *in;\r
183 yy11:\r
184       if (yybm[0+yych] & 128) {\r
185         goto yy10;\r
186       }\r
187       goto yy6;\r
188 yy12:\r
189       ++in;\r
190       {\r
191         // De-escape dollar character.\r
192         *out++ = '$';\r
193         continue;\r
194       }\r
195 yy14:\r
196       ++in;\r
197       {\r
198         // Let backslash before other characters through verbatim.\r
199         *out++ = '\\';\r
200         *out++ = yych;\r
201         continue;\r
202       }\r
203 yy16:\r
204       ++in;\r
205       {\r
206         // De-escape backslashed character.\r
207         *out++ = yych;\r
208         continue;\r
209       }\r
210     }\r
211 \r
212     }\r
213 \r
214     int len = (int)(out - filename);\r
215     const bool is_target = parsing_targets;\r
216     if (len > 0 && filename[len - 1] == ':') {\r
217       len--;  // Strip off trailing colon, if any.\r
218       parsing_targets = false;\r
219     }\r
220 \r
221     if (len == 0)\r
222       continue;\r
223 \r
224     if (!is_target) {\r
225       ins_.push_back(StringPiece(filename, len));\r
226     } else if (!out_.str_) {\r
227       out_ = StringPiece(filename, len);\r
228     } else if (out_ != StringPiece(filename, len)) {\r
229       *err = "depfile has multiple output paths";\r
230       return false;\r
231     }\r
232   }\r
233   if (parsing_targets) {\r
234     *err = "expected ':' in depfile";\r
235     return false;\r
236   }\r
237   return true;\r
238 }\r