Mercurial > ~dholland > hg > tradcpp > index.cgi
annotate directive.c @ 64:f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
Also, don't pass the string length to the directive processing
functions, as half of them weren't honoring it. Instead, ensure that
the directive line is terminated at the place the directive processing
functions should stop looking at it.
author | David A. Holland |
---|---|
date | Sun, 31 Mar 2013 02:04:56 -0400 |
parents | 90c6052410ce |
children | f8507e5ed84c |
rev | line source |
---|---|
30 | 1 /*- |
2 * Copyright (c) 2010 The NetBSD Foundation, Inc. | |
3 * All rights reserved. | |
4 * | |
5 * This code is derived from software contributed to The NetBSD Foundation | |
6 * by David A. Holland. | |
7 * | |
8 * Redistribution and use in source and binary forms, with or without | |
9 * modification, are permitted provided that the following conditions | |
10 * are met: | |
11 * 1. Redistributions of source code must retain the above copyright | |
12 * notice, this list of conditions and the following disclaimer. | |
13 * 2. Redistributions in binary form must reproduce the above copyright | |
14 * notice, this list of conditions and the following disclaimer in the | |
15 * documentation and/or other materials provided with the distribution. | |
16 * | |
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
27 * POSSIBILITY OF SUCH DAMAGE. | |
28 */ | |
29 | |
15 | 30 #include <assert.h> |
31 #include <stdbool.h> | |
32 #include <stdlib.h> | |
33 #include <string.h> | |
34 | |
35 #include "utils.h" | |
36 #include "mode.h" | |
37 #include "place.h" | |
38 #include "files.h" | |
39 #include "directive.h" | |
40 #include "macro.h" | |
41 #include "eval.h" | |
49
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
42 #include "output.h" |
15 | 43 |
44 struct ifstate { | |
45 struct ifstate *prev; | |
46 struct place startplace; | |
47 bool curtrue; | |
48 bool evertrue; | |
49 bool seenelse; | |
50 }; | |
51 | |
52 static struct ifstate *ifstate; | |
49
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
53 static bool in_multiline_comment; |
15 | 54 |
55 //////////////////////////////////////////////////////////// | |
56 // common parsing bits | |
57 | |
58 static | |
59 void | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
60 uncomment(char *buf) |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
61 { |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
62 char *s, *t, *u = NULL; |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
63 bool incomment = false; |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
64 |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
65 for (s = t = buf; *s; s++) { |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
66 if (incomment) { |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
67 if (s[0] == '*' && s[1] == '/') { |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
68 s++; |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
69 incomment = false; |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
70 } |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
71 } else { |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
72 if (s[0] == '/' && s[1] == '*') { |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
73 incomment = true; |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
74 } else { |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
75 if (t != s) { |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
76 *t = *s; |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
77 } |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
78 if (!strchr(ws, *t)) { |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
79 u = t; |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
80 } |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
81 t++; |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
82 } |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
83 } |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
84 } |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
85 if (u) { |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
86 /* end string after last non-whitespace char */ |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
87 u[1] = '\0'; |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
88 } else { |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
89 *t = '\0'; |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
90 } |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
91 } |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
92 |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
93 static |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
94 void |
15 | 95 oneword(const char *what, struct place *p2, char *line) |
96 { | |
97 size_t pos; | |
98 | |
99 pos = strcspn(line, ws); | |
100 if (line[pos] != '\0') { | |
101 p2->column += pos; | |
102 complain(p2, "Garbage after %s argument", what); | |
103 complain_fail(); | |
104 line[pos] = '\0'; | |
105 } | |
106 } | |
107 | |
108 //////////////////////////////////////////////////////////// | |
109 // if handling | |
110 | |
111 static | |
112 struct ifstate * | |
113 ifstate_create(struct ifstate *prev, struct place *p, bool startstate) | |
114 { | |
115 struct ifstate *is; | |
116 | |
117 is = domalloc(sizeof(*is)); | |
118 is->prev = prev; | |
119 if (p != NULL) { | |
120 is->startplace = *p; | |
121 } else { | |
122 place_setbuiltin(&is->startplace, 1); | |
123 } | |
124 is->curtrue = startstate; | |
125 is->evertrue = is->curtrue; | |
126 is->seenelse = false; | |
127 return is; | |
128 } | |
129 | |
130 static | |
131 void | |
132 ifstate_destroy(struct ifstate *is) | |
133 { | |
39
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
134 dofree(is, sizeof(*is)); |
15 | 135 } |
136 | |
137 static | |
138 void | |
139 ifstate_push(struct place *p, bool startstate) | |
140 { | |
141 ifstate = ifstate_create(ifstate, p, startstate); | |
142 } | |
143 | |
144 static | |
145 void | |
146 ifstate_pop(void) | |
147 { | |
148 struct ifstate *is; | |
149 | |
150 is = ifstate; | |
151 ifstate = ifstate->prev; | |
152 ifstate_destroy(is); | |
153 } | |
154 | |
155 static | |
156 void | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
157 d_if(struct place *p, struct place *p2, char *line) |
15 | 158 { |
159 char *expr; | |
160 bool val; | |
16 | 161 struct place p3 = *p2; |
15 | 162 |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
163 uncomment(line); |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
164 expr = macroexpand(p2, line, strlen(line), true); |
16 | 165 val = eval(&p3, expr); |
15 | 166 ifstate_push(p, val); |
39
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
167 dostrfree(expr); |
15 | 168 } |
169 | |
170 static | |
171 void | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
172 d_ifdef(struct place *p, struct place *p2, char *line) |
15 | 173 { |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
174 uncomment(line); |
15 | 175 oneword("#ifdef", p2, line); |
176 ifstate_push(p, macro_isdefined(line)); | |
177 } | |
178 | |
179 static | |
180 void | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
181 d_ifndef(struct place *p, struct place *p2, char *line) |
15 | 182 { |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
183 uncomment(line); |
15 | 184 oneword("#ifndef", p2, line); |
185 ifstate_push(p, !macro_isdefined(line)); | |
186 } | |
187 | |
188 static | |
189 void | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
190 d_elif(struct place *p, struct place *p2, char *line) |
15 | 191 { |
192 char *expr; | |
16 | 193 struct place p3 = *p2; |
15 | 194 |
195 if (ifstate->seenelse) { | |
196 complain(p, "#elif after #else"); | |
197 complain_fail(); | |
198 } | |
199 | |
200 if (ifstate->evertrue) { | |
201 ifstate->curtrue = false; | |
202 } else { | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
203 uncomment(line); |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
204 expr = macroexpand(p2, line, strlen(line), true); |
16 | 205 ifstate->curtrue = eval(&p3, expr); |
15 | 206 ifstate->evertrue = ifstate->curtrue; |
39
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
207 dostrfree(expr); |
15 | 208 } |
209 } | |
210 | |
211 static | |
212 void | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
213 d_else(struct place *p, struct place *p2, char *line) |
15 | 214 { |
215 if (ifstate->seenelse) { | |
216 complain(p, "Multiple #else directives in one conditional"); | |
217 complain_fail(); | |
218 } | |
219 | |
220 ifstate->curtrue = !ifstate->evertrue; | |
221 ifstate->evertrue = true; | |
222 ifstate->seenelse = true; | |
223 } | |
224 | |
225 static | |
226 void | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
227 d_endif(struct place *p, struct place *p2, char *line) |
15 | 228 { |
229 if (ifstate->prev == NULL) { | |
230 complain(p, "Unmatched #endif"); | |
231 complain_fail(); | |
232 } else { | |
233 ifstate_pop(); | |
234 } | |
235 } | |
236 | |
237 //////////////////////////////////////////////////////////// | |
238 // macros | |
239 | |
240 static | |
241 void | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
242 d_define(struct place *p, struct place *p2, char *line) |
15 | 243 { |
18 | 244 size_t pos, argpos; |
245 struct place p3, p4; | |
15 | 246 |
247 /* | |
248 * line may be: | |
249 * macro expansion | |
250 * macro(arg, arg, ...) expansion | |
251 */ | |
252 | |
253 pos = strcspn(line, " \t\f\v("); | |
254 if (line[pos] == '(') { | |
18 | 255 line[pos++] = '\0'; |
256 argpos = pos; | |
15 | 257 pos = pos + strcspn(line+pos, "()"); |
258 if (line[pos] == '(') { | |
259 p2->column += pos; | |
260 complain(p2, "Left parenthesis in macro parameters"); | |
261 complain_fail(); | |
262 return; | |
263 } | |
264 if (line[pos] != ')') { | |
265 p2->column += pos; | |
266 complain(p2, "Unclosed macro parameter list"); | |
267 complain_fail(); | |
268 return; | |
269 } | |
18 | 270 line[pos++] = '\0'; |
36
a489cc223483
Don't demand space after the macro argument parenthesis.
David A. Holland
parents:
30
diff
changeset
|
271 #if 0 |
15 | 272 if (!strchr(ws, line[pos])) { |
273 p2->column += pos; | |
274 complain(p2, "Trash after macro parameter list"); | |
275 complain_fail(); | |
276 return; | |
277 } | |
36
a489cc223483
Don't demand space after the macro argument parenthesis.
David A. Holland
parents:
30
diff
changeset
|
278 #endif |
15 | 279 } else if (line[pos] == '\0') { |
18 | 280 argpos = 0; |
15 | 281 } else { |
282 line[pos++] = '\0'; | |
18 | 283 argpos = 0; |
15 | 284 } |
285 | |
286 pos += strspn(line+pos, ws); | |
287 | |
288 p3 = *p2; | |
18 | 289 p3.column += argpos; |
290 | |
291 p4 = *p2; | |
292 p4.column += pos; | |
293 | |
294 if (argpos) { | |
295 macro_define_params(p2, line, &p3, | |
296 line + argpos, &p4, | |
297 line + pos); | |
298 } else { | |
299 macro_define_plain(p2, line, &p4, line + pos); | |
300 } | |
15 | 301 } |
302 | |
303 static | |
304 void | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
305 d_undef(struct place *p, struct place *p2, char *line) |
15 | 306 { |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
307 uncomment(line); |
15 | 308 oneword("#undef", p2, line); |
309 macro_undef(line); | |
310 } | |
311 | |
312 //////////////////////////////////////////////////////////// | |
313 // includes | |
314 | |
315 static | |
316 bool | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
317 tryinclude(struct place *p, char *line) |
15 | 318 { |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
319 size_t len; |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
320 |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
321 len = strlen(line); |
15 | 322 if (len > 2 && line[0] == '"' && line[len-1] == '"') { |
323 line[len-1] = '\0'; | |
324 file_readquote(p, line+1); | |
62
90c6052410ce
Don't truncate the candidate include path strings.
David A. Holland
parents:
49
diff
changeset
|
325 line[len-1] = '"'; |
15 | 326 return true; |
327 } | |
328 if (len > 2 && line[0] == '<' && line[len-1] == '>') { | |
329 line[len-1] = '\0'; | |
330 file_readbracket(p, line+1); | |
62
90c6052410ce
Don't truncate the candidate include path strings.
David A. Holland
parents:
49
diff
changeset
|
331 line[len-1] = '>'; |
15 | 332 return true; |
333 } | |
334 return false; | |
335 } | |
336 | |
337 static | |
338 void | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
339 d_include(struct place *p, struct place *p2, char *line) |
15 | 340 { |
341 char *text; | |
342 | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
343 uncomment(line); |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
344 if (tryinclude(p, line)) { |
15 | 345 return; |
346 } | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
347 text = macroexpand(p2, line, strlen(line), false); |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
348 if (tryinclude(p, text)) { |
39
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
349 dostrfree(text); |
15 | 350 return; |
351 } | |
39
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
352 dostrfree(text); |
15 | 353 complain(p, "Illegal #include directive"); |
354 complain_fail(); | |
355 } | |
356 | |
357 static | |
358 void | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
359 d_line(struct place *p, struct place *p2, char *line) |
15 | 360 { |
361 /* XXX */ | |
362 complain(p, "Sorry, no #line yet"); | |
363 } | |
364 | |
365 //////////////////////////////////////////////////////////// | |
366 // messages | |
367 | |
368 static | |
369 void | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
370 d_warning(struct place *p, struct place *p2, char *line) |
15 | 371 { |
372 char *msg; | |
373 | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
374 msg = macroexpand(p2, line, strlen(line), false); |
15 | 375 complain(p, "#warning: %s", msg); |
376 if (mode.werror) { | |
377 complain_fail(); | |
378 } | |
39
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
379 dostrfree(msg); |
15 | 380 } |
381 | |
382 static | |
383 void | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
384 d_error(struct place *p, struct place *p2, char *line) |
15 | 385 { |
386 char *msg; | |
387 | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
388 msg = macroexpand(p2, line, strlen(line), false); |
15 | 389 complain(p, "#error: %s", msg); |
390 complain_fail(); | |
39
337110e7240a
Pass the size to free; it makes debug checking easier.
David A. Holland
parents:
38
diff
changeset
|
391 dostrfree(msg); |
15 | 392 } |
393 | |
394 //////////////////////////////////////////////////////////// | |
395 // other | |
396 | |
397 static | |
398 void | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
399 d_pragma(struct place *p, struct place *p2, char *line) |
15 | 400 { |
401 complain(p, "#pragma %s", line); | |
402 complain_fail(); | |
403 } | |
404 | |
405 //////////////////////////////////////////////////////////// | |
406 // directive table | |
407 | |
408 static const struct { | |
409 const char *name; | |
410 bool ifskip; | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
411 void (*func)(struct place *, struct place *, char *line); |
15 | 412 } directives[] = { |
413 { "define", true, d_define }, | |
414 { "elif", false, d_elif }, | |
415 { "else", false, d_else }, | |
416 { "endif", false, d_endif }, | |
417 { "error", true, d_error }, | |
418 { "if", false, d_if }, | |
419 { "ifdef", false, d_ifdef }, | |
420 { "ifndef", false, d_ifndef }, | |
421 { "include", true, d_include }, | |
422 { "line", true, d_line }, | |
423 { "pragma", true, d_pragma }, | |
424 { "undef", true, d_undef }, | |
425 { "warning", true, d_warning }, | |
426 }; | |
427 static const unsigned numdirectives = HOWMANY(directives); | |
428 | |
429 static | |
430 void | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
431 directive_gotdirective(struct place *p, char *line) |
15 | 432 { |
433 struct place p2; | |
434 size_t len, skip; | |
435 unsigned i; | |
436 | |
437 p2 = *p; | |
438 for (i=0; i<numdirectives; i++) { | |
439 len = strlen(directives[i].name); | |
440 if (!strncmp(line, directives[i].name, len) && | |
441 strchr(ws, line[len])) { | |
442 if (directives[i].ifskip && !ifstate->curtrue) { | |
443 return; | |
444 } | |
445 skip = len + strspn(line+len, ws); | |
446 p2.column += skip; | |
447 line += skip; | |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
448 |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
449 len = strlen(line); |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
450 len = notrailingws(line, len); |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
451 if (len < strlen(line)) { |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
452 line[len] = '\0'; |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
453 } |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
454 directives[i].func(p, &p2, line); |
15 | 455 return; |
456 } | |
457 } | |
458 skip = strcspn(line, ws); | |
459 complain(p, "Unknown directive #%.*s", (int)skip, line); | |
460 complain_fail(); | |
461 } | |
462 | |
49
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
463 /* |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
464 * If desired, warn about a nested comment. The comment begins at |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
465 * offset POS from the place P. |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
466 */ |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
467 static |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
468 void |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
469 warn_nestcomment(const struct place *p, size_t pos) |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
470 { |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
471 struct place p2; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
472 |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
473 if (warns.nestcomment) { |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
474 p2 = *p; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
475 p2.column += pos; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
476 complain(p, "Warning: %c%c within comment", |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
477 '/', '*'); |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
478 if (mode.werror) { |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
479 complain_failed(); |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
480 } |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
481 } |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
482 } |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
483 |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
484 /* |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
485 * Check for comment delimiters in LINE. If a multi-line comment is |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
486 * continuing or ending, set ACOMM to its length. If a multi-line |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
487 * comment is starting, set BCOMM to its length. Set TEXT to the |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
488 * length of text that is not commented out, or that contains comments |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
489 * that both begin and end on this line. ACOMM + TEXT + BCOMM == LEN. |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
490 * |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
491 * Updates in_multiline_comment to the appropriate state for after |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
492 * this line is handled. |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
493 */ |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
494 static |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
495 size_t |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
496 directive_scancomments(const struct place *p, char *line, size_t len, |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
497 size_t *acomm, size_t *text, size_t *bcomm) |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
498 { |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
499 size_t pos; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
500 size_t first_commentend; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
501 size_t last_commentstart; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
502 bool incomment; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
503 |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
504 first_commentend = len; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
505 last_commentstart = len; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
506 incomment = in_multiline_comment; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
507 for (pos = 0; pos+1 < len; pos++) { |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
508 if (line[pos] == '/' && line[pos+1] == '*') { |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
509 if (incomment) { |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
510 warn_nestcomment(p, pos); |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
511 } else { |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
512 incomment = true; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
513 last_commentstart = pos; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
514 } |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
515 } else if (line[pos] == '*' && line[pos+1] == '/') { |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
516 if (incomment) { |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
517 incomment = false; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
518 if (first_commentend == len) { |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
519 first_commentend = pos; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
520 } |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
521 last_commentstart = len; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
522 } else { |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
523 /* stray end-comment; should we care? */ |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
524 } |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
525 } |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
526 } |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
527 |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
528 if (in_multiline_comment && first_commentend < last_commentstart) { |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
529 /* multiline comment ends */ |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
530 /* first_commentend points to the star, adjust */ |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
531 *acomm = first_commentend + 2; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
532 *text = len - *acomm; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
533 } else if (in_multiline_comment) { |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
534 /* comment did not end, so another one cannot have started */ |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
535 assert(last_commentstart == len); |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
536 *acomm = len; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
537 *text = 0; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
538 } else { |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
539 *acomm = 0; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
540 *text = len; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
541 } |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
542 |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
543 *bcomm = len - last_commentstart; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
544 *text -= *bcomm; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
545 |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
546 in_multiline_comment = incomment; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
547 return len; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
548 } |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
549 |
15 | 550 void |
551 directive_gotline(struct place *p, char *line, size_t len) | |
552 { | |
49
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
553 size_t acomm; /* length of comment ending on this line */ |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
554 size_t text; /* length of non-multi-line-comment text */ |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
555 size_t bcomm; /* length of comment beginning on this line */ |
15 | 556 size_t skip; |
557 | |
49
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
558 directive_scancomments(p, line, len, &acomm, &text, &bcomm); |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
559 |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
560 if (acomm > 0) { |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
561 if (mode.output_retain_comments && ifstate->curtrue) { |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
562 /* |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
563 * Do not expand the comment; send it straight |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
564 * to the output. This will cause it to appear |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
565 * first if we're partway through collecting a |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
566 * macro argument. Too bad. This isn't a |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
567 * standard mode anyway. |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
568 */ |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
569 output(p, line, acomm); |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
570 } |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
571 p->column += acomm; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
572 } |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
573 |
15 | 574 /* check if we have a directive line */ |
49
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
575 skip = strspn(line + acomm, ws); |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
576 if (acomm == 0 && line[skip] == '#') { |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
577 char ch; |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
578 |
15 | 579 skip = skip + 1 + strspn(line + skip + 1, ws); |
49
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
580 assert(skip <= text); |
15 | 581 p->column += skip; |
64
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
582 assert(line[len] == '\0'); |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
583 /* ensure null termination for directives */ |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
584 ch = line[text]; |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
585 if (ch != '\0') { |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
586 line[text] = '\0'; |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
587 } |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
588 directive_gotdirective(p, line+skip /*, length = text-skip */); |
f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
David A. Holland
parents:
62
diff
changeset
|
589 line[text] = ch; |
49
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
590 p->column += text-skip; |
15 | 591 } else if (ifstate->curtrue) { |
49
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
592 macro_sendline(p, line + acomm, text); |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
593 p->column += text; |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
594 } |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
595 |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
596 if (bcomm > 0) { |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
597 if (mode.output_retain_comments && ifstate->curtrue) { |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
598 output(p, line + acomm + text, bcomm); |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
599 } |
8a204d153398
Intercept multiline comments earlier. Leave same-line comments alone.
David A. Holland
parents:
39
diff
changeset
|
600 p->column += bcomm; |
15 | 601 } |
602 } | |
603 | |
604 void | |
605 directive_goteof(struct place *p) | |
606 { | |
607 while (ifstate->prev != NULL) { | |
608 complain(p, "Missing #endif"); | |
609 complain(&ifstate->startplace, "...opened at this point"); | |
610 complain_failed(); | |
611 ifstate_pop(); | |
612 } | |
613 macro_sendeof(p); | |
614 } | |
615 | |
616 //////////////////////////////////////////////////////////// | |
617 // module initialization | |
618 | |
619 void | |
620 directive_init(void) | |
621 { | |
622 ifstate = ifstate_create(NULL, NULL, true); | |
623 } | |
624 | |
625 void | |
626 directive_cleanup(void) | |
627 { | |
628 assert(ifstate->prev == NULL); | |
629 ifstate_destroy(ifstate); | |
630 ifstate = NULL; | |
631 } |