Line data Source code
1 : /*
2 : * (c) Thomas Pornin 1999 - 2002
3 : *
4 : * Redistribution and use in source and binary forms, with or without
5 : * modification, are permitted provided that the following conditions
6 : * are met:
7 : * 1. Redistributions of source code must retain the above copyright
8 : * notice, this list of conditions and the following disclaimer.
9 : * 2. Redistributions in binary form must reproduce the above copyright
10 : * notice, this list of conditions and the following disclaimer in the
11 : * documentation and/or other materials provided with the distribution.
12 : * 4. The name of the authors may not be used to endorse or promote
13 : * products derived from this software without specific prior written
14 : * permission.
15 : *
16 : * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17 : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 : * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
20 : * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 : * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
22 : * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 : * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 : * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 : * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 : * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 : *
28 : */
29 :
30 : #include "tune.h"
31 : #include <stdio.h>
32 : #include <string.h>
33 : #include <stddef.h>
34 : #include <limits.h>
35 : #include "ucppi.h"
36 : #include "mem.h"
37 : #include "nhash.h"
38 :
39 : /*
40 : * we store macros in a hash table, and retrieve them using their name
41 : * as identifier.
42 : */
43 : static HTT macros;
44 : static int macros_init_done = 0;
45 :
46 0 : static void del_macro(void *m)
47 : {
48 0 : struct macro *n = m;
49 : size_t i;
50 :
51 0 : for (i = 0; (int)i < n->narg; i ++) freemem(n->arg[i]);
52 0 : if (n->narg > 0) freemem(n->arg);
53 : #ifdef LOW_MEM
54 0 : if (n->cval.length) freemem(n->cval.t);
55 : #else
56 : if (n->val.nt) {
57 : for (i = 0; i < n->val.nt; i ++)
58 : if (S_TOKEN(n->val.t[i].type))
59 : freemem(n->val.t[i].name);
60 : freemem(n->val.t);
61 : }
62 : #endif
63 0 : freemem(n);
64 0 : }
65 :
66 0 : static inline struct macro *new_macro(void)
67 : {
68 0 : struct macro *m = getmem(sizeof(struct macro));
69 :
70 0 : m->narg = -1;
71 0 : m->nest = 0;
72 : #ifdef LOW_MEM
73 0 : m->cval.length = 0;
74 : #else
75 : m->val.nt = m->val.art = 0;
76 : #endif
77 0 : m->vaarg = 0;
78 0 : return m;
79 : }
80 :
81 : /*
82 : * for special macros, and the "defined" operator
83 : */
84 : enum {
85 : MAC_NONE, MAC_DEFINED,
86 : MAC_LINE, MAC_FILE, MAC_DATE, MAC_TIME, MAC_STDC, MAC_PRAGMA
87 : };
88 : #define MAC_SPECIAL MAC_LINE
89 :
90 : /*
91 : * returns 1 for "defined"
92 : * returns x > 1 for a special macro such as __FILE__
93 : * returns 0 otherwise
94 : */
95 0 : static inline int check_special_macro(char *name)
96 : {
97 0 : if (!strcmp(name, "defined")) return MAC_DEFINED;
98 0 : if (*name != '_') return MAC_NONE;
99 0 : if (*(name + 1) == 'P') {
100 0 : if (!strcmp(name, "_Pragma")) return MAC_PRAGMA;
101 0 : return MAC_NONE;
102 0 : } else if (*(name + 1) != '_') return MAC_NONE;
103 0 : if (no_special_macros) return MAC_NONE;
104 0 : if (!strcmp(name, "__LINE__")) return MAC_LINE;
105 0 : else if (!strcmp(name, "__FILE__")) return MAC_FILE;
106 0 : else if (!strcmp(name, "__DATE__")) return MAC_DATE;
107 0 : else if (!strcmp(name, "__TIME__")) return MAC_TIME;
108 0 : else if (!strcmp(name, "__STDC__")) return MAC_STDC;
109 0 : return MAC_NONE;
110 : }
111 :
112 : int c99_compliant = 1;
113 : int c99_hosted = 1;
114 :
115 : /*
116 : * add the special macros to the macro table
117 : */
118 0 : static void add_special_macros(void)
119 : {
120 : struct macro *m;
121 :
122 0 : HTT_put(¯os, new_macro(), "__LINE__");
123 0 : HTT_put(¯os, new_macro(), "__FILE__");
124 0 : HTT_put(¯os, new_macro(), "__DATE__");
125 0 : HTT_put(¯os, new_macro(), "__TIME__");
126 0 : HTT_put(¯os, new_macro(), "__STDC__");
127 0 : m = new_macro(); m->narg = 1;
128 0 : m->arg = getmem(sizeof(char *)); m->arg[0] = sdup("foo");
129 0 : HTT_put(¯os, m, "_Pragma");
130 0 : if (c99_compliant) {
131 : #ifndef LOW_MEM
132 : struct token t;
133 : #endif
134 :
135 0 : m = new_macro();
136 : #ifdef LOW_MEM
137 0 : m->cval.t = getmem(9);
138 0 : m->cval.t[0] = NUMBER;
139 0 : mmv(m->cval.t + 1, "199901L", 8);
140 0 : m->cval.length = 9;
141 : #else
142 : t.type = NUMBER;
143 : t.line = 0;
144 : t.name = sdup("199901L");
145 : aol(m->val.t, m->val.nt, t, TOKEN_LIST_MEMG);
146 : #endif
147 0 : HTT_put(¯os, m, "__STDC_VERSION__");
148 : }
149 0 : if (c99_hosted) {
150 : #ifndef LOW_MEM
151 : struct token t;
152 : #endif
153 :
154 0 : m = new_macro();
155 : #ifdef LOW_MEM
156 0 : m->cval.t = getmem(3);
157 0 : m->cval.t[0] = NUMBER;
158 0 : mmv(m->cval.t + 1, "1", 2);
159 0 : m->cval.length = 3;
160 : #else
161 : t.type = NUMBER;
162 : t.line = 0;
163 : t.name = sdup("1");
164 : aol(m->val.t, m->val.nt, t, TOKEN_LIST_MEMG);
165 : #endif
166 0 : HTT_put(¯os, m, "__STDC_HOSTED__");
167 : }
168 0 : }
169 :
170 : #ifdef LOW_MEM
171 : /*
172 : * We store macro arguments as a single-byte token MACROARG, followed
173 : * by the argument number as a one or two-byte value. If the argument
174 : * number is between 0 and 127 (inclusive), it is stored as such in
175 : * a single byte. Otherwise, it is supposed to be a 14-bit number, with
176 : * the 7 upper bits stored in the first byte (with the high bit set to 1)
177 : * and the 7 lower bits in the second byte.
178 : */
179 : #endif
180 :
181 : /*
182 : * print the content of a macro, in #define form
183 : */
184 0 : static void print_macro(void *vm)
185 : {
186 0 : struct macro *m = vm;
187 0 : char *mname = HASH_ITEM_NAME(m);
188 0 : int x = check_special_macro(mname);
189 : size_t i;
190 :
191 0 : if (x != MAC_NONE) {
192 0 : fprintf(emit_output, "/* #define %s */ /* special */\n",
193 : mname);
194 0 : return;
195 : }
196 0 : fprintf(emit_output, "#define %s", mname);
197 0 : if (m->narg >= 0) {
198 0 : fprintf(emit_output, "(");
199 0 : for (i = 0; i < (size_t)(m->narg); i ++) {
200 0 : fprintf(emit_output, i ? ", %s" : "%s", m->arg[i]);
201 : }
202 0 : if (m->vaarg) {
203 0 : fputs(m->narg ? ", ..." : "...", emit_output);
204 : }
205 0 : fprintf(emit_output, ")");
206 : }
207 : #ifdef LOW_MEM
208 0 : if (m->cval.length == 0) {
209 0 : fputc('\n', emit_output);
210 0 : return;
211 : }
212 0 : fputc(' ', emit_output);
213 0 : for (i = 0; i < m->cval.length;) {
214 0 : int tt = m->cval.t[i ++];
215 :
216 0 : if (tt == MACROARG) {
217 0 : unsigned anum = m->cval.t[i];
218 :
219 0 : if (anum >= 128) anum = ((anum & 127U) << 8)
220 0 : | m->cval.t[++ i];
221 0 : if (anum == (unsigned)m->narg)
222 0 : fputs("__VA_ARGS__", emit_output);
223 : else
224 0 : fputs(m->arg[anum], emit_output);
225 0 : i ++;
226 : }
227 0 : else if (S_TOKEN(tt)) {
228 0 : fputs((char *)(m->cval.t + i), emit_output);
229 0 : i += 1 + strlen((char *)(m->cval.t + i));
230 0 : } else fputs(operators_name[tt], emit_output);
231 : }
232 : #else
233 : if (m->val.nt == 0) {
234 : fputc('\n', emit_output);
235 : return;
236 : }
237 : fputc(' ', emit_output);
238 : for (i = 0; i < m->val.nt; i ++) {
239 : if (m->val.t[i].type == MACROARG) {
240 : if (m->val.t[i].line == m->narg)
241 : fputs("__VA_ARGS__", emit_output);
242 : else
243 : fputs(m->arg[(size_t)(m->val.t[i].line)],
244 : emit_output);
245 : } else fputs(token_name(m->val.t + i), emit_output);
246 : }
247 : #endif
248 0 : fputc('\n', emit_output);
249 : }
250 :
251 : /*
252 : * Send a token to the output (a token_fifo in lexer mode, the output
253 : * buffer in stand alone mode).
254 : */
255 0 : void print_token(struct lexer_state *ls, struct token *t, long uz_line)
256 : {
257 0 : char *x = t->name;
258 :
259 0 : if (uz_line && t->line < 0) t->line = uz_line;
260 0 : if (ls->flags & LEXER) {
261 : struct token at;
262 :
263 0 : at = *t;
264 0 : if (S_TOKEN(t->type)) {
265 0 : at.name = sdup(at.name);
266 0 : throw_away(ls->gf, at.name);
267 : }
268 0 : aol(ls->output_fifo->t, ls->output_fifo->nt, at,
269 : TOKEN_LIST_MEMG);
270 0 : return;
271 : }
272 0 : if (ls->flags & KEEP_OUTPUT) {
273 0 : for (; ls->oline < ls->line;) put_char(ls, '\n');
274 : }
275 0 : if (!S_TOKEN(t->type)) x = operators_name[t->type];
276 0 : for (; *x; x ++) put_char(ls, *x);
277 : }
278 :
279 : /*
280 : * Send a token to the output at a given line (this is for text output
281 : * and unreplaced macros due to lack of arguments).
282 : */
283 0 : static void print_token_nailed(struct lexer_state *ls, struct token *t,
284 : long nail_line)
285 : {
286 0 : char *x = t->name;
287 :
288 0 : if (ls->flags & LEXER) {
289 0 : print_token(ls, t, 0);
290 0 : return;
291 : }
292 0 : if (ls->flags & KEEP_OUTPUT) {
293 0 : for (; ls->oline < nail_line;) put_char(ls, '\n');
294 : }
295 0 : if (!S_TOKEN(t->type)) x = operators_name[t->type];
296 0 : for (; *x; x ++) put_char(ls, *x);
297 : }
298 :
299 : /*
300 : * send a reduced whitespace token to the output
301 : */
302 : #define print_space(ls) do { \
303 : struct token lt; \
304 : lt.type = OPT_NONE; \
305 : lt.line = (ls)->line; \
306 : print_token((ls), <, 0); \
307 : } while (0)
308 :
309 : /*
310 : * We found a #define directive; parse the end of the line, perform
311 : * sanity checks, store the new macro into the "macros" hash table.
312 : *
313 : * In case of a redefinition of a macro: we enforce the rule that a
314 : * macro should be redefined identically, including the spelling of
315 : * parameters. We emit an error on offending code; dura lex, sed lex.
316 : * After all, it is easy to avoid such problems, with a #undef directive.
317 : */
318 0 : int handle_define(struct lexer_state *ls)
319 : {
320 0 : struct macro *m = 0, *n;
321 : #ifdef LOW_MEM
322 : struct token_fifo mv;
323 : #endif
324 0 : int ltwws = 1, redef = 0;
325 0 : char *mname = 0;
326 : int narg;
327 : size_t nt;
328 0 : long l = ls->line;
329 :
330 : #ifdef LOW_MEM
331 0 : mv.art = mv.nt = 0;
332 : #endif
333 : /* find the next non-white token on the line, this should be
334 : the macro name */
335 0 : while (!next_token(ls) && ls->ctok->type != NEWLINE) {
336 0 : if (ttMWS(ls->ctok->type)) continue;
337 0 : if (ls->ctok->type == NAME) mname = sdup(ls->ctok->name);
338 0 : break;
339 : }
340 0 : if (mname == 0) {
341 0 : error(l, "missing macro name");
342 0 : return 1;
343 : }
344 0 : if (check_special_macro(mname)) {
345 0 : error(l, "trying to redefine the special macro %s", mname);
346 0 : goto warp_error;
347 : }
348 : /*
349 : * If a macro with this name was already defined: the K&R
350 : * states that the new macro should be identical to the old one
351 : * (with some arcane rule of equivalence of whitespace); otherwise,
352 : * redefining the macro is an error. Most preprocessors would
353 : * only emit a warning (or nothing at all) on an unidentical
354 : * redefinition.
355 : *
356 : * Since it is easy to avoid this error (with a #undef directive),
357 : * we choose to enforce the rule and emit an error.
358 : */
359 0 : if ((n = HTT_get(¯os, mname)) != 0) {
360 : /* redefinition of a macro: we must check that we define
361 : it identical */
362 0 : redef = 1;
363 : #ifdef LOW_MEM
364 0 : n->cval.rp = 0;
365 : #endif
366 0 : freemem(mname);
367 0 : mname = 0;
368 : }
369 0 : if (!redef) {
370 0 : m = new_macro();
371 0 : m->narg = -1;
372 : #ifdef LOW_MEM
373 : #define mval mv
374 : #else
375 : #define mval (m->val)
376 : #endif
377 : }
378 0 : if (next_token(ls)) goto define_end;
379 : /*
380 : * Check if the token immediately following the macro name is
381 : * a left parenthesis; if so, then this is a macro with arguments.
382 : * Collect their names and try to match the next parenthesis.
383 : */
384 0 : if (ls->ctok->type == LPAR) {
385 : int i, j;
386 0 : int need_comma = 0, saw_mdots = 0;
387 :
388 0 : narg = 0;
389 0 : while (!next_token(ls)) {
390 0 : if (ls->ctok->type == NEWLINE) {
391 0 : error(l, "truncated macro definition");
392 0 : goto define_error;
393 : }
394 0 : if (ls->ctok->type == COMMA) {
395 0 : if (saw_mdots) {
396 0 : error(l, "'...' must end the macro "
397 : "argument list");
398 0 : goto warp_error;
399 : }
400 0 : if (!need_comma) {
401 0 : error(l, "void macro argument");
402 0 : goto warp_error;
403 : }
404 0 : need_comma = 0;
405 0 : continue;
406 0 : } else if (ls->ctok->type == NAME) {
407 0 : if (saw_mdots) {
408 0 : error(l, "'...' must end the macro "
409 : "argument list");
410 0 : goto warp_error;
411 : }
412 0 : if (need_comma) {
413 0 : error(l, "missing comma in "
414 : "macro argument list");
415 0 : goto warp_error;
416 : }
417 0 : if (!redef) {
418 0 : aol(m->arg, narg,
419 : sdup(ls->ctok->name), 8);
420 : /* we must keep track of m->narg
421 : so that cleanup in case of
422 : error works. */
423 0 : m->narg = narg;
424 0 : if (narg == 128
425 0 : && (ls->flags & WARN_STANDARD))
426 0 : warning(l, "more arguments to "
427 : "macro than the ISO "
428 : "limit (127)");
429 : #ifdef LOW_MEM
430 0 : if (narg == 32767) {
431 0 : error(l, "too many arguments "
432 : "in macro definition "
433 : "(max 32766)");
434 0 : goto warp_error;
435 : }
436 : #endif
437 : } else {
438 : /* this is a redefinition of the
439 : macro; check equality between
440 : old and new definitions */
441 0 : if (narg >= n->narg) goto redef_error;
442 0 : if (strcmp(ls->ctok->name,
443 0 : n->arg[narg ++]))
444 0 : goto redef_error;
445 : }
446 0 : need_comma = 1;
447 0 : continue;
448 0 : } else if ((ls->flags & MACRO_VAARG)
449 0 : && ls->ctok->type == MDOTS) {
450 0 : if (need_comma) {
451 0 : error(l, "missing comma before '...'");
452 0 : goto warp_error;
453 : }
454 0 : if (redef && !n->vaarg) goto redef_error;
455 0 : if (!redef) m->vaarg = 1;
456 0 : saw_mdots = 1;
457 0 : need_comma = 1;
458 0 : continue;
459 0 : } else if (ls->ctok->type == RPAR) {
460 0 : if (narg > 0 && !need_comma) {
461 0 : error(l, "void macro argument");
462 0 : goto warp_error;
463 : }
464 0 : if (redef && n->vaarg && !saw_mdots)
465 0 : goto redef_error;
466 0 : break;
467 0 : } else if (ttMWS(ls->ctok->type)) {
468 0 : continue;
469 : }
470 0 : error(l, "invalid macro argument");
471 0 : goto warp_error;
472 : }
473 0 : if (!redef) {
474 0 : for (i = 1; i < narg; i ++) for (j = 0; j < i; j ++)
475 0 : if (!strcmp(m->arg[i], m->arg[j])) {
476 0 : error(l, "duplicate macro "
477 : "argument");
478 0 : goto warp_error;
479 : }
480 : }
481 0 : if (!redef) m->narg = narg;
482 : } else {
483 0 : if (!ttWHI(ls->ctok->type) && (ls->flags & WARN_STANDARD))
484 0 : warning(ls->line, "identifier not followed by "
485 : "whitespace in #define");
486 0 : ls->flags |= READ_AGAIN;
487 0 : narg = 0;
488 : }
489 0 : if (redef) nt = 0;
490 :
491 : /* now, we have the arguments. Let's get the macro contents. */
492 0 : while (!next_token(ls) && ls->ctok->type != NEWLINE) {
493 : struct token t;
494 :
495 0 : t.type = ls->ctok->type;
496 0 : if (ltwws && ttMWS(t.type)) continue;
497 0 : t.line = 0;
498 0 : if (t.type == NAME) {
499 : int i;
500 :
501 0 : if ((ls->flags & MACRO_VAARG)
502 0 : && !strcmp(ls->ctok->name, "__VA_ARGS__")) {
503 0 : if (redef) {
504 0 : if (!n->vaarg) goto redef_error;
505 0 : } else if (!m->vaarg) {
506 0 : error(l, "'__VA_ARGS__' is forbidden "
507 : "in macros with a fixed "
508 : "number of arguments");
509 : goto warp_error;
510 : }
511 0 : t.type = MACROARG;
512 0 : t.line = redef ? n->narg : m->narg;
513 : }
514 0 : for (i = 0; i < narg; i ++)
515 0 : if (!strcmp(redef ? n->arg[i] : m->arg[i],
516 0 : ls->ctok->name)) {
517 0 : t.type = MACROARG;
518 : /* this is a hack: we store the
519 : argument number in the line field */
520 0 : t.line = i;
521 0 : break;
522 : }
523 : }
524 0 : if (!redef && S_TOKEN(t.type)) t.name = sdup(ls->ctok->name);
525 0 : if (ttMWS(t.type)) {
526 0 : if (ltwws) continue;
527 : #ifdef SEMPER_FIDELIS
528 : t.type = OPT_NONE;
529 : #else
530 0 : t.type = NONE;
531 : #endif
532 0 : ltwws = 1;
533 0 : } else ltwws = 0;
534 0 : if (!redef) {
535 : /* we ensure that each macro token has a correct
536 : line number */
537 0 : if (t.type != MACROARG) t.line = 1;
538 0 : aol(mval.t, mval.nt, t, TOKEN_LIST_MEMG);
539 : } else {
540 : #ifdef LOW_MEM
541 : int tt;
542 :
543 0 : if (n->cval.rp >= n->cval.length) {
544 : #ifdef SEMPER_FIDELIS
545 : if (t.type != OPT_NONE) goto redef_error;
546 : #else
547 0 : if (t.type != NONE) goto redef_error;
548 : #endif
549 0 : } else if (t.type != n->cval.t[n->cval.rp]) {
550 : goto redef_error;
551 0 : } else if (t.type == MACROARG) {
552 0 : unsigned anum = n->cval.t[n->cval.rp + 1];
553 :
554 0 : if (anum >= 128U) anum = ((anum & 127U) << 8)
555 0 : | m->cval.t[n->cval.rp + 2];
556 0 : if (anum != (unsigned)t.line) goto redef_error;
557 0 : } else if (S_TOKEN(t.type) && strcmp(ls->ctok->name,
558 0 : (char *)(n->cval.t + n->cval.rp + 1))) {
559 : goto redef_error;
560 : }
561 0 : tt = n->cval.t[n->cval.rp ++];
562 0 : if (S_TOKEN(tt)) n->cval.rp += 1
563 0 : + strlen((char *)(n->cval.t + n->cval.rp));
564 0 : else if (tt == MACROARG) {
565 0 : if (n->cval.t[++ n->cval.rp] >= 128)
566 0 : n->cval.rp ++;
567 : }
568 : #else
569 : if (nt >= n->val.nt) {
570 : #ifdef SEMPER_FIDELIS
571 : if (t.type != OPT_NONE) goto redef_error;
572 : #else
573 : if (t.type != NONE) goto redef_error;
574 : #endif
575 : } else if (t.type != n->val.t[nt].type
576 : || (t.type == MACROARG
577 : && t.line != n->val.t[nt].line)
578 : || (S_TOKEN(t.type) && strcmp(ls->ctok->name,
579 : n->val.t[nt].name))) {
580 : goto redef_error;
581 : }
582 : #endif
583 0 : nt ++;
584 : }
585 : }
586 :
587 0 : if (redef) {
588 : #ifdef LOW_MEM
589 0 : if (n->cval.rp < n->cval.length) goto redef_error_2;
590 : #else
591 : if (nt < n->val.nt) goto redef_error_2;
592 : #endif
593 0 : return 0;
594 : }
595 :
596 : /* now we have the complete macro; perform some checks about
597 : the operators # and ##, and, if everything is ok,
598 : store the macro into the hash table */
599 : define_end:
600 : #ifdef SEMPER_FIDELIS
601 : if (mval.nt && mval.t[mval.nt - 1].type == OPT_NONE) {
602 : #else
603 0 : if (mval.nt && mval.t[mval.nt - 1].type == NONE) {
604 : #endif
605 0 : mval.nt --;
606 0 : if (mval.nt == 0) freemem(mval.t);
607 : }
608 0 : if (mval.nt != 0) {
609 : size_t i;
610 :
611 : /* some checks about the macro */
612 0 : if (mval.t[0].type == DSHARP
613 0 : || mval.t[0].type == DIG_DSHARP
614 0 : || mval.t[mval.nt - 1].type == DSHARP
615 0 : || mval.t[mval.nt - 1].type == DIG_DSHARP) {
616 0 : error(l, "operator '##' may neither begin "
617 : "nor end a macro");
618 0 : goto define_error;
619 : }
620 0 : if (m->narg >= 0) for (i = 0; i < mval.nt; i ++)
621 0 : if ((mval.t[i].type == SHARP
622 0 : || mval.t[i].type == DIG_SHARP) &&
623 0 : (i == (mval.nt - 1)
624 0 : || (ttMWS(mval.t[i + 1].type) &&
625 0 : (i == mval.nt - 2
626 0 : || mval.t[i + 2].type != MACROARG))
627 0 : || (!ttMWS(mval.t[i + 1].type)
628 0 : && mval.t[i + 1].type != MACROARG))) {
629 0 : error(l, "operator '#' not followed "
630 : "by a macro argument");
631 0 : goto define_error;
632 : }
633 : }
634 : #ifdef LOW_MEM
635 : {
636 : size_t i, l;
637 :
638 0 : for (i = 0, l = 0; i < mval.nt; i ++) {
639 0 : l ++;
640 0 : if (S_TOKEN(mval.t[i].type))
641 0 : l += 1 + strlen(mval.t[i].name);
642 0 : else if (mval.t[i].type == MACROARG) {
643 0 : l ++;
644 0 : if (mval.t[i].line >= 128) l ++;
645 : }
646 : }
647 0 : m->cval.length = l;
648 0 : if (l) m->cval.t = getmem(l);
649 0 : for (i = 0, l = 0; i < mval.nt; i ++) {
650 0 : m->cval.t[l ++] = mval.t[i].type;
651 0 : if (S_TOKEN(mval.t[i].type)) {
652 0 : size_t x = 1 + strlen(mval.t[i].name);
653 :
654 0 : mmv(m->cval.t + l, mval.t[i].name, x);
655 0 : l += x;
656 0 : freemem(mval.t[i].name);
657 : }
658 0 : else if (mval.t[i].type == MACROARG) {
659 0 : unsigned anum = mval.t[i].line;
660 :
661 0 : if (anum >= 128) {
662 0 : m->cval.t[l ++] = 128 | (anum >> 8);
663 0 : m->cval.t[l ++] = anum & 0xFF;
664 : } else {
665 0 : m->cval.t[l ++] = anum;
666 : }
667 : }
668 : }
669 0 : if (mval.nt) freemem(mval.t);
670 : }
671 : #endif
672 0 : HTT_put(¯os, m, mname);
673 0 : freemem(mname);
674 0 : if (emit_defines) print_macro(m);
675 0 : return 0;
676 :
677 : redef_error:
678 0 : while (ls->ctok->type != NEWLINE && !next_token(ls));
679 : redef_error_2:
680 0 : error(l, "macro '%s' redefined unidentically", HASH_ITEM_NAME(n));
681 0 : return 1;
682 : warp_error:
683 0 : while (ls->ctok->type != NEWLINE && !next_token(ls));
684 : define_error:
685 0 : if (m) del_macro(m);
686 0 : if (mname) freemem(mname);
687 : #ifdef LOW_MEM
688 0 : if (mv.nt) {
689 : size_t i;
690 :
691 0 : for (i = 0; i < mv.nt; i ++)
692 0 : if (S_TOKEN(mv.t[i].type)) freemem(mv.t[i].name);
693 0 : freemem(mv.t);
694 : }
695 : #endif
696 0 : return 1;
697 : #undef mval
698 : }
699 :
700 : /*
701 : * Get the arguments for a macro. This code is tricky because there can
702 : * be multiple sources for these arguments, if we are in the middle of
703 : * a macro replacement; arguments are macro-replaced before inclusion
704 : * into the macro replacement.
705 : *
706 : * return value:
707 : * 1 no argument (last token read from next_token())
708 : * 2 no argument (last token read from tfi)
709 : * 3 no argument (nothing read)
710 : * 4 error
711 : *
712 : * Void arguments are allowed in C99.
713 : */
714 0 : static int collect_arguments(struct lexer_state *ls, struct token_fifo *tfi,
715 : int penury, struct token_fifo *atl, int narg, int vaarg, int *wr)
716 : {
717 0 : int ltwws = 1, npar = 0, i;
718 0 : struct token *ct = 0;
719 0 : int read_from_fifo = 0;
720 0 : long begin_line = ls->line;
721 :
722 : #define unravel(ls) (read_from_fifo = 0, !((tfi && tfi->art < tfi->nt \
723 : && (read_from_fifo = 1) != 0 && (ct = tfi->t + (tfi->art ++))) \
724 : || ((!tfi || penury) && !next_token(ls) && (ct = (ls)->ctok))))
725 :
726 : /*
727 : * collect_arguments() is assumed to setup correctly atl
728 : * (this is not elegant, but it works)
729 : */
730 0 : for (i = 0; i < narg; i ++) atl[i].art = atl[i].nt = 0;
731 0 : if (vaarg) atl[narg].art = atl[narg].nt = 0;
732 0 : *wr = 0;
733 0 : while (!unravel(ls)) {
734 0 : if (!read_from_fifo && ct->type == NEWLINE) ls->ltwnl = 1;
735 0 : if (ttWHI(ct->type)) {
736 0 : *wr = 1;
737 0 : continue;
738 : }
739 0 : if (ct->type == LPAR) {
740 0 : npar = 1;
741 : }
742 0 : break;
743 : }
744 0 : if (!npar) {
745 0 : if (ct == ls->ctok) return 1;
746 0 : if (read_from_fifo) return 2;
747 0 : return 3;
748 : }
749 0 : if (!read_from_fifo && ct == ls->ctok) ls->ltwnl = 0;
750 0 : i = 0;
751 0 : if ((narg + vaarg) == 0) {
752 0 : while(!unravel(ls)) {
753 0 : if (ttWHI(ct->type)) continue;
754 0 : if (ct->type == RPAR) goto harvested;
755 0 : npar = 1;
756 0 : goto too_many_args;
757 : }
758 : }
759 0 : while (!unravel(ls)) {
760 : struct token t;
761 :
762 0 : if (ct->type == LPAR) npar ++;
763 0 : else if (ct->type == RPAR && (-- npar) == 0) {
764 0 : if (atl[i].nt != 0
765 0 : && ttMWS(atl[i].t[atl[i].nt - 1].type))
766 0 : atl[i].nt --;
767 0 : i ++;
768 : /*
769 : * C99 standard states that at least one argument
770 : * should be present for the ... part; to relax
771 : * this behaviour, change 'narg + vaarg' to 'narg'.
772 : */
773 0 : if (i < (narg + vaarg)) {
774 0 : error(begin_line, "not enough arguments "
775 : "to macro");
776 0 : return 4;
777 : }
778 0 : if (i > narg) {
779 0 : if (!(ls->flags & MACRO_VAARG) || !vaarg)
780 : goto too_many_args;
781 : }
782 : goto harvested;
783 0 : } else if (ct->type == COMMA && npar <= 1 && i < narg) {
784 0 : if (atl[i].nt != 0
785 0 : && ttMWS(atl[i].t[atl[i].nt - 1].type))
786 0 : atl[i].nt --;
787 0 : if (++ i == narg) {
788 0 : if (!(ls->flags & MACRO_VAARG) || !vaarg)
789 : goto too_many_args;
790 : }
791 0 : if (i > 30000) goto too_many_args;
792 0 : ltwws = 1;
793 0 : continue;
794 0 : } else if (ltwws && ttWHI(ct->type)) continue;
795 :
796 0 : t.type = ct->type;
797 0 : if (!read_from_fifo) t.line = ls->line; else t.line = ct->line;
798 : /*
799 : * Stringification applies only to macro arguments;
800 : * so we handle here OPT_NONE.
801 : * OPT_NONE is kept, but does not count as whitespace,
802 : * and merges with other whitespace to give a fully
803 : * qualified NONE token. Two OPT_NONE tokens merge.
804 : * Initial and final OPT_NONE are discarded (initial
805 : * is already done, as OPT_NONE is matched by ttWHI).
806 : */
807 0 : if (ttWHI(t.type)) {
808 0 : if (t.type != OPT_NONE) {
809 0 : t.type = NONE;
810 : #ifdef SEMPER_FIDELIS
811 : t.name = sdup(" ");
812 : throw_away(ls->gf, t.name);
813 : #endif
814 0 : ltwws = 1;
815 : }
816 0 : if (atl[i].nt > 0
817 0 : && atl[i].t[atl[i].nt - 1].type == OPT_NONE)
818 0 : atl[i].nt --;
819 : } else {
820 0 : ltwws = 0;
821 0 : if (S_TOKEN(t.type)) {
822 0 : t.name = ct->name;
823 0 : if (ct == (ls)->ctok) {
824 0 : t.name = sdup(t.name);
825 0 : throw_away(ls->gf, t.name);
826 : }
827 : }
828 : }
829 0 : aol(atl[i].t, atl[i].nt, t, TOKEN_LIST_MEMG);
830 : }
831 0 : error(begin_line, "unfinished macro call");
832 0 : return 4;
833 : too_many_args:
834 0 : error(begin_line, "too many arguments to macro");
835 0 : while (npar && !unravel(ls)) {
836 0 : if (ct->type == LPAR) npar ++;
837 0 : else if (ct->type == RPAR) npar --;
838 : }
839 0 : return 4;
840 : harvested:
841 0 : if (i > 127 && (ls->flags & WARN_STANDARD))
842 0 : warning(begin_line, "macro call with %d arguments (ISO "
843 : "specifies 127 max)", i);
844 0 : return 0;
845 : #undef unravel
846 : }
847 :
848 : /*
849 : * concat_token() is called when the ## operator is used. It uses
850 : * the struct lexer_state dsharp_lexer to parse the result of the
851 : * concatenation.
852 : *
853 : * Law enforcement: if the whole string does not produce a valid
854 : * single token, an error (non-zero result) is returned.
855 : */
856 : struct lexer_state dsharp_lexer;
857 :
858 0 : static inline int concat_token(struct token *t1, struct token *t2)
859 : {
860 0 : char *n1 = token_name(t1), *n2 = token_name(t2);
861 0 : size_t l1 = strlen(n1), l2 = strlen(n2);
862 0 : unsigned char *x = getmem(l1 + l2 + 1);
863 : int r;
864 :
865 0 : mmv(x, n1, l1);
866 0 : mmv(x + l1, n2, l2);
867 0 : x[l1 + l2] = 0;
868 0 : dsharp_lexer.input = 0;
869 0 : dsharp_lexer.input_string = x;
870 0 : dsharp_lexer.pbuf = 0;
871 0 : dsharp_lexer.ebuf = l1 + l2;
872 0 : dsharp_lexer.discard = 1;
873 0 : dsharp_lexer.flags = DEFAULT_LEXER_FLAGS;
874 0 : dsharp_lexer.pending_token = 0;
875 0 : r = next_token(&dsharp_lexer);
876 0 : freemem(x);
877 0 : return (r == 1 || dsharp_lexer.pbuf < (l1 + l2)
878 0 : || dsharp_lexer.pending_token
879 0 : || (dsharp_lexer.pbuf == (l1 + l2) && !dsharp_lexer.discard));
880 : }
881 :
882 : #ifdef PRAGMA_TOKENIZE
883 : /*
884 : * tokenize_string() takes a string as input, and split it into tokens,
885 : * reassembling the tokens into a single compressed string generated by
886 : * compress_token_list(); this function is used for _Pragma processing.
887 : */
888 : struct lexer_state tokenize_lexer;
889 :
890 0 : static char *tokenize_string(struct lexer_state *ls, char *buf)
891 : {
892 : struct token_fifo tf;
893 0 : size_t bl = strlen(buf);
894 : int r;
895 :
896 0 : tokenize_lexer.input = 0;
897 0 : tokenize_lexer.input_string = (unsigned char *)buf;
898 0 : tokenize_lexer.pbuf = 0;
899 0 : tokenize_lexer.ebuf = bl;
900 0 : tokenize_lexer.discard = 1;
901 0 : tokenize_lexer.flags = ls->flags | LEXER;
902 0 : tokenize_lexer.pending_token = 0;
903 0 : tf.art = tf.nt = 0;
904 0 : while (!(r = next_token(&tokenize_lexer))) {
905 0 : struct token t, *ct = tokenize_lexer.ctok;
906 :
907 0 : if (ttWHI(ct->type)) continue;
908 0 : t = *ct;
909 0 : if (S_TOKEN(t.type)) t.name = sdup(t.name);
910 0 : aol(tf.t, tf.nt, t, TOKEN_LIST_MEMG);
911 : }
912 0 : if (tokenize_lexer.pbuf < bl) goto tokenize_error;
913 0 : return (char *)((compress_token_list(&tf)).t);
914 :
915 : tokenize_error:
916 0 : if (tf.nt) {
917 0 : for (tf.art = 0; tf.art < tf.nt; tf.art ++)
918 0 : if (S_TOKEN(tf.t[tf.art].type))
919 0 : freemem(tf.t[tf.art].name);
920 0 : freemem(tf.t);
921 : }
922 0 : return 0;
923 : }
924 : #endif
925 :
926 : /*
927 : * stringify_string() has a self-explanatory name. It is called when
928 : * the # operator is used in a macro and a string constant must be
929 : * stringified.
930 : */
931 0 : static inline char *stringify_string(char *x)
932 : {
933 : size_t l;
934 0 : int i, inside_str = 0, inside_cc = 0, must_quote, has_quoted = 0;
935 : char *y, *d;
936 :
937 0 : for (i = 0; i < 2; i ++) {
938 0 : if (i) d[0] = '"';
939 0 : for (l = 1, y = x; *y; y ++, l ++) {
940 0 : must_quote = 0;
941 0 : if (inside_cc) {
942 0 : if (*y == '\\') {
943 0 : must_quote = 1;
944 0 : has_quoted = 1;
945 0 : } else if (!has_quoted && *y == '\'')
946 0 : inside_cc = 0;
947 0 : } else if (inside_str) {
948 0 : if (*y == '"' || *y == '\\') must_quote = 1;
949 0 : if (*y == '\\') has_quoted = 1;
950 0 : else if (!has_quoted && *y == '"')
951 0 : inside_str = 0;
952 0 : } else if (*y == '"') {
953 0 : inside_str = 1;
954 0 : must_quote = 1;
955 0 : } else if (*y == '\'') {
956 0 : inside_cc = 1;
957 : }
958 0 : if (must_quote) {
959 0 : if (i) d[l] = '\\';
960 0 : l ++;
961 : }
962 0 : if (i) d[l] = *y;
963 : }
964 0 : if (!i) d = getmem(l + 2);
965 0 : if (i) {
966 0 : d[l] = '"';
967 0 : d[l + 1] = 0;
968 : }
969 : }
970 0 : return d;
971 : }
972 :
973 : /*
974 : * stringify() produces a constant string, result of the # operator
975 : * on a list of tokens.
976 : */
977 0 : static char *stringify(struct token_fifo *tf)
978 : {
979 : size_t tlen;
980 : size_t i;
981 : char *x, *y;
982 :
983 0 : for (tlen = 0, i = 0; i < tf->nt; i ++)
984 0 : if (tf->t[i].type < CPPERR && tf->t[i].type != OPT_NONE)
985 0 : tlen += strlen(token_name(tf->t + i));
986 0 : if (tlen == 0) return sdup("\"\"");
987 0 : x = getmem(tlen + 1);
988 0 : for (tlen = 0, i = 0; i < tf->nt; i ++) {
989 0 : if (tf->t[i].type >= CPPERR || tf->t[i].type == OPT_NONE)
990 0 : continue;
991 0 : strcpy(x + tlen, token_name(tf->t + i));
992 0 : tlen += strlen(token_name(tf->t + i));
993 : }
994 : /* no need to add a trailing 0: strcpy() did that (and the string
995 : is not empty) */
996 0 : y = stringify_string(x);
997 0 : freemem(x);
998 0 : return y;
999 : }
1000 :
1001 : /*
1002 : * Two strings evaluated at initialization time, to handle the __TIME__
1003 : * and __DATE__ special macros.
1004 : *
1005 : * C99 specifies that these macros should remain constant throughout
1006 : * the whole preprocessing.
1007 : */
1008 : char compile_time[12], compile_date[24];
1009 :
1010 : /*
1011 : * substitute_macro() performs the macro substitution. It is called when
1012 : * an identifier recognized as a macro name has been found; this function
1013 : * tries to collect the arguments (if needed), applies # and ## operators
1014 : * and perform recursive and nested macro expansions.
1015 : *
1016 : * In the substitution of a macro, we remove all newlines that were in the
1017 : * arguments. This might confuse error reporting (which could report
1018 : * erroneous line numbers) or have worse effect is the preprocessor is
1019 : * used for another language pickier than C. Since the interface between
1020 : * the preprocessor and the compiler is not fully specified, I believe
1021 : * that this is no violation of the standard. Comments welcome.
1022 : *
1023 : * We take tokens from tfi. If tfi has no more tokens to give: we may
1024 : * take some tokens from ls to complete a call (fetch arguments) if
1025 : * and only if penury is non zero.
1026 : */
1027 0 : int substitute_macro(struct lexer_state *ls, struct macro *m,
1028 : struct token_fifo *tfi, int penury, int reject_nested, long l)
1029 : {
1030 0 : char *mname = HASH_ITEM_NAME(m);
1031 : struct token_fifo *atl, etl;
1032 : struct token t, *ct;
1033 0 : int i, save_nest = m->nest;
1034 : size_t save_art, save_tfi, etl_limit;
1035 : int ltwds, ntwds, ltwws;
1036 0 : int pragma_op = 0;
1037 :
1038 : /*
1039 : * Reject the replacement, if we are already inside the macro.
1040 : */
1041 0 : if (m->nest > reject_nested) {
1042 0 : t.type = NAME;
1043 0 : t.line = ls->line;
1044 0 : t.name = mname;
1045 0 : print_token(ls, &t, 0);
1046 0 : return 0;
1047 : }
1048 :
1049 : /*
1050 : * put a separation from preceeding tokens
1051 : */
1052 0 : print_space(ls);
1053 :
1054 : /*
1055 : * Check if the macro is a special one.
1056 : */
1057 0 : if ((i = check_special_macro(mname)) >= MAC_SPECIAL) {
1058 : /* we have a special macro */
1059 0 : switch (i) {
1060 : char buf[30], *bbuf, *cfn;
1061 :
1062 : case MAC_LINE:
1063 0 : t.type = NUMBER;
1064 0 : t.line = l;
1065 0 : sprintf(buf, "%ld", l);
1066 0 : t.name = buf;
1067 0 : print_space(ls);
1068 0 : print_token(ls, &t, 0);
1069 : break;
1070 : case MAC_FILE:
1071 0 : t.type = STRING;
1072 0 : t.line = l;
1073 0 : cfn = current_long_filename ?
1074 0 : current_long_filename : current_filename;
1075 0 : bbuf = getmem(2 * strlen(cfn) + 3);
1076 : {
1077 : char *c, *d;
1078 0 : int lcwb = 0;
1079 :
1080 0 : bbuf[0] = '"';
1081 0 : for (c = cfn, d = bbuf + 1; *c; c ++) {
1082 0 : if (*c == '\\') {
1083 0 : if (lcwb) continue;
1084 0 : *(d ++) = '\\';
1085 0 : lcwb = 1;
1086 0 : } else lcwb = 0;
1087 0 : *(d ++) = *c;
1088 : }
1089 0 : *(d ++) = '"';
1090 0 : *(d ++) = 0;
1091 : }
1092 0 : t.name = bbuf;
1093 0 : print_space(ls);
1094 0 : print_token(ls, &t, 0);
1095 0 : freemem(bbuf);
1096 : break;
1097 : case MAC_DATE:
1098 0 : t.type = STRING;
1099 0 : t.line = l;
1100 0 : t.name = compile_date;
1101 0 : print_space(ls);
1102 0 : print_token(ls, &t, 0);
1103 : break;
1104 : case MAC_TIME:
1105 0 : t.type = STRING;
1106 0 : t.line = l;
1107 0 : t.name = compile_time;
1108 0 : print_space(ls);
1109 0 : print_token(ls, &t, 0);
1110 : break;
1111 : case MAC_STDC:
1112 0 : t.type = NUMBER;
1113 0 : t.line = l;
1114 0 : t.name = "1";
1115 0 : print_space(ls);
1116 0 : print_token(ls, &t, 0);
1117 : break;
1118 : case MAC_PRAGMA:
1119 0 : if (reject_nested > 0) {
1120 : /* do not replace _Pragma() unless toplevel */
1121 0 : t.type = NAME;
1122 0 : t.line = ls->line;
1123 0 : t.name = mname;
1124 0 : print_token(ls, &t, 0);
1125 0 : return 0;
1126 : }
1127 0 : pragma_op = 1;
1128 : goto collect_args;
1129 : #ifdef AUDIT
1130 : default:
1131 : ouch("unbekanntes fliegendes macro");
1132 : #endif
1133 : }
1134 0 : return 0;
1135 : }
1136 :
1137 : /*
1138 : * If the macro has arguments, collect them.
1139 : */
1140 : collect_args:
1141 0 : if (m->narg >= 0) {
1142 0 : unsigned long save_flags = ls->flags;
1143 0 : int wr = 0;
1144 :
1145 0 : ls->flags |= LEXER;
1146 0 : if (m->narg > 0 || m->vaarg)
1147 0 : atl = getmem((m->narg + m->vaarg)
1148 : * sizeof(struct token_fifo));
1149 0 : switch (collect_arguments(ls, tfi, penury, atl,
1150 : m->narg, m->vaarg, &wr)) {
1151 : case 1:
1152 : /* the macro expected arguments, but we did not
1153 : find any; the last read token should be read
1154 : again. */
1155 0 : ls->flags = save_flags | READ_AGAIN;
1156 0 : goto no_argument_next;
1157 : case 2:
1158 0 : tfi->art --;
1159 : /* fall through */
1160 : case 3:
1161 0 : ls->flags = save_flags;
1162 : no_argument_next:
1163 0 : t.type = NAME;
1164 0 : t.line = l;
1165 0 : t.name = mname;
1166 0 : print_token_nailed(ls, &t, l);
1167 0 : if (wr) {
1168 0 : t.type = NONE;
1169 0 : t.line = l;
1170 : #ifdef SEMPER_FIDELIS
1171 : t.name = " ";
1172 : #endif
1173 0 : print_token(ls, &t, 0);
1174 : goto exit_macro_2;
1175 : }
1176 : goto exit_macro_1;
1177 : case 4:
1178 0 : ls->flags = save_flags;
1179 : goto exit_error_1;
1180 : }
1181 0 : ls->flags = save_flags;
1182 : }
1183 :
1184 : /*
1185 : * If the macro is _Pragma, and we got here, then we have
1186 : * exactly one argument. We check it, unstringize it, and
1187 : * emit a PRAGMA token.
1188 : */
1189 0 : if (pragma_op) {
1190 : char *pn;
1191 :
1192 0 : if (atl[0].nt != 1 || atl[0].t[0].type != STRING) {
1193 0 : error(ls->line, "invalid argument to _Pragma");
1194 0 : if (atl[0].nt) freemem(atl[0].t);
1195 0 : freemem(atl);
1196 0 : goto exit_error;
1197 : }
1198 0 : pn = atl[0].t[0].name;
1199 0 : if ((pn[0] == '"' && pn[1] == '"') || (pn[0] == 'L'
1200 0 : && pn[1] == '"' && pn[2] == '"')) {
1201 : /* void pragma -- just ignore it */
1202 0 : freemem(atl[0].t);
1203 0 : freemem(atl);
1204 0 : return 0;
1205 : }
1206 0 : if (ls->flags & TEXT_OUTPUT) {
1207 : #ifdef PRAGMA_DUMP
1208 : /*
1209 : * This code works because we actually evaluate arguments in a
1210 : * lazy way: we scan a macro argument only if it appears in the
1211 : * output, and exactly as many times as it appears. Therefore,
1212 : * _Pragma() will get evaluated just like they should.
1213 : */
1214 0 : char *c = atl[0].t[0].name, *d;
1215 :
1216 0 : for (d = "\n#pragma "; *d; d ++) put_char(ls, *d);
1217 0 : d = (*c == 'L') ? c + 2 : c + 1;
1218 0 : for (; *d != '"'; d ++) {
1219 0 : if (*d == '\\' && (*(d + 1) == '\\'
1220 0 : || *(d + 1) == '"')) {
1221 0 : d ++;
1222 : }
1223 0 : put_char(ls, *d);
1224 : }
1225 0 : put_char(ls, '\n');
1226 0 : ls->oline = ls->line;
1227 0 : enter_file(ls, ls->flags);
1228 : #else
1229 : if (ls->flags & WARN_PRAGMA)
1230 : warning(ls->line,
1231 : "_Pragma() ignored and not dumped");
1232 : #endif
1233 0 : } else if (ls->flags & HANDLE_PRAGMA) {
1234 0 : char *c = atl[0].t[0].name, *d, *buf;
1235 : struct token t;
1236 :
1237 : /* a wide string is a string */
1238 0 : if (*c == 'L') c ++;
1239 0 : c ++;
1240 0 : for (buf = d = getmem(strlen(c)); *c != '"'; c ++) {
1241 0 : if (*c == '\\' && (*(c + 1) == '\\'
1242 0 : || *(c + 1) == '"')) {
1243 0 : *(d ++) = *(++ c);
1244 0 : } else *(d ++) = *c;
1245 : }
1246 0 : *d = 0;
1247 0 : t.type = PRAGMA;
1248 0 : t.line = ls->line;
1249 : #ifdef PRAGMA_TOKENIZE
1250 0 : t.name = tokenize_string(ls, buf);
1251 0 : freemem(buf);
1252 0 : buf = t.name;
1253 0 : if (!buf) {
1254 0 : freemem(atl[0].t);
1255 0 : freemem(atl);
1256 : goto exit_error;
1257 : }
1258 : #else
1259 : t.name = buf;
1260 : #endif
1261 0 : aol(ls->toplevel_of->t, ls->toplevel_of->nt,
1262 : t, TOKEN_LIST_MEMG);
1263 0 : throw_away(ls->gf, buf);
1264 : }
1265 0 : freemem(atl[0].t);
1266 0 : freemem(atl);
1267 0 : return 0;
1268 : }
1269 :
1270 : /*
1271 : * Now we expand and replace the arguments in the macro; we
1272 : * also handle '#' and '##'. If we find an argument, that has
1273 : * to be replaced, we expand it in its own token list, then paste
1274 : * it. Tricky point: when we paste an argument, we must scan
1275 : * again the resulting list for further replacements. This
1276 : * implies problems with regards to nesting self-referencing
1277 : * macros.
1278 : *
1279 : * We do then YAUH (yet another ugly hack): if a macro is replaced,
1280 : * and nested replacement exhibit the same macro, we mark it with
1281 : * a negative line number. All produced negative line numbers
1282 : * must be cleaned in the end.
1283 : */
1284 :
1285 : #define ZAP_LINE(t) do { \
1286 : if ((t).type == NAME) { \
1287 : struct macro *zlm = HTT_get(¯os, (t).name); \
1288 : if (zlm && zlm->nest > reject_nested) \
1289 : (t).line = -1 - (t).line; \
1290 : } \
1291 : } while (0)
1292 :
1293 : #ifdef LOW_MEM
1294 0 : save_art = m->cval.rp;
1295 0 : m->cval.rp = 0;
1296 : #else
1297 : save_art = m->val.art;
1298 : m->val.art = 0;
1299 : #endif
1300 0 : etl.art = etl.nt = 0;
1301 0 : m->nest = reject_nested + 1;
1302 0 : ltwds = ntwds = 0;
1303 : #ifdef LOW_MEM
1304 0 : while (m->cval.rp < m->cval.length) {
1305 : #else
1306 : while (m->val.art < m->val.nt) {
1307 : #endif
1308 : size_t next, z;
1309 : #ifdef LOW_MEM
1310 : struct token uu;
1311 :
1312 0 : ct = &uu;
1313 0 : ct->line = 1;
1314 0 : t.type = ct->type = m->cval.t[m->cval.rp ++];
1315 0 : if (ct->type == MACROARG) {
1316 0 : unsigned anum = m->cval.t[m->cval.rp ++];
1317 :
1318 0 : if (anum >= 128U) anum = ((anum & 127U) << 8)
1319 0 : | (unsigned)m->cval.t[m->cval.rp ++];
1320 0 : ct->line = anum;
1321 0 : } else if (S_TOKEN(ct->type)) {
1322 0 : t.name = ct->name = (char *)(m->cval.t + m->cval.rp);
1323 0 : m->cval.rp += 1 + strlen(ct->name);
1324 : }
1325 : #ifdef SEMPER_FIDELIS
1326 : else if (ct->type == OPT_NONE) {
1327 : t.type = ct->type = NONE;
1328 : t.name = ct->name = " ";
1329 : }
1330 : #endif
1331 0 : t.line = ls->line;
1332 0 : next = m->cval.rp;
1333 0 : if ((next < m->cval.length && (m->cval.t[z = next] == DSHARP
1334 0 : || m->cval.t[z = next] == DIG_DSHARP))
1335 0 : || ((next + 1) < m->cval.length
1336 0 : && ttWHI(m->cval.t[next])
1337 0 : && (m->cval.t[z = next + 1] == DSHARP
1338 0 : || m->cval.t[z = next + 1] == DIG_DSHARP))) {
1339 0 : ntwds = 1;
1340 0 : m->cval.rp = z;
1341 0 : } else ntwds = 0;
1342 : #else
1343 : ct = m->val.t + (m->val.art ++);
1344 : next = m->val.art;
1345 : t.type = ct->type;
1346 : t.line = ls->line;
1347 : #ifdef SEMPER_FIDELIS
1348 : if (t.type == OPT_NONE) {
1349 : t.type = NONE;
1350 : t.name = " ";
1351 : } else
1352 : #endif
1353 : t.name = ct->name;
1354 : if ((next < m->val.nt && (m->val.t[z = next].type == DSHARP
1355 : || m->val.t[z = next].type == DIG_DSHARP))
1356 : || ((next + 1) < m->val.nt
1357 : && ttWHI(m->val.t[next].type)
1358 : && (m->val.t[z = next + 1].type == DSHARP
1359 : || m->val.t[z = next + 1].type == DIG_DSHARP))) {
1360 : ntwds = 1;
1361 : m->val.art = z;
1362 : } else ntwds = 0;
1363 : #endif
1364 0 : if (ct->type == MACROARG) {
1365 : #ifdef DSHARP_TOKEN_MERGE
1366 : int need_opt_space = 1;
1367 : #endif
1368 0 : z = ct->line; /* the argument number is there */
1369 0 : if (ltwds && atl[z].nt != 0 && etl.nt) {
1370 0 : if (concat_token(etl.t + (-- etl.nt),
1371 0 : atl[z].t)) {
1372 0 : warning(ls->line, "operator '##' "
1373 : "produced the invalid token "
1374 : "'%s%s'",
1375 0 : token_name(etl.t + etl.nt),
1376 0 : token_name(atl[z].t));
1377 : #if 0
1378 : /* obsolete */
1379 : #ifdef LOW_MEM
1380 : m->cval.rp = save_art;
1381 : #else
1382 : m->val.art = save_art;
1383 : #endif
1384 : etl.nt ++;
1385 : goto exit_error_2;
1386 : #endif
1387 0 : etl.nt ++;
1388 0 : atl[z].art = 0;
1389 : #ifdef DSHARP_TOKEN_MERGE
1390 : need_opt_space = 0;
1391 : #endif
1392 : } else {
1393 0 : if (etl.nt == 0) freemem(etl.t);
1394 0 : else if (!ttWHI(etl.t[etl.nt - 1]
1395 : .type)) {
1396 0 : t.type = OPT_NONE;
1397 0 : t.line = ls->line;
1398 0 : aol(etl.t, etl.nt, t,
1399 : TOKEN_LIST_MEMG);
1400 : }
1401 0 : t.type = dsharp_lexer.ctok->type;
1402 0 : t.line = ls->line;
1403 0 : if (S_TOKEN(t.type)) {
1404 0 : t.name = sdup(dsharp_lexer
1405 0 : .ctok->name);
1406 0 : throw_away(ls->gf, t.name);
1407 : }
1408 0 : ZAP_LINE(t);
1409 0 : aol(etl.t, etl.nt, t, TOKEN_LIST_MEMG);
1410 0 : atl[z].art = 1;
1411 : }
1412 0 : } else atl[z].art = 0;
1413 0 : if (
1414 : #ifdef DSHARP_TOKEN_MERGE
1415 : need_opt_space &&
1416 : #endif
1417 0 : atl[z].art < atl[z].nt && (!etl.nt
1418 0 : || !ttWHI(etl.t[etl.nt - 1].type))) {
1419 0 : t.type = OPT_NONE;
1420 0 : t.line = ls->line;
1421 0 : aol(etl.t, etl.nt, t, TOKEN_LIST_MEMG);
1422 : }
1423 0 : if (ltwds || ntwds) {
1424 0 : while (atl[z].art < atl[z].nt) {
1425 0 : t = atl[z].t[atl[z].art ++];
1426 0 : t.line = ls->line;
1427 0 : ZAP_LINE(t);
1428 0 : aol(etl.t, etl.nt, t, TOKEN_LIST_MEMG);
1429 : }
1430 : } else {
1431 : struct token_fifo *save_tf;
1432 : unsigned long save_flags;
1433 0 : int ret = 0;
1434 :
1435 0 : atl[z].art = 0;
1436 0 : save_tf = ls->output_fifo;
1437 0 : ls->output_fifo = &etl;
1438 0 : save_flags = ls->flags;
1439 0 : ls->flags |= LEXER;
1440 0 : while (atl[z].art < atl[z].nt) {
1441 : struct macro *nm;
1442 : struct token *cct;
1443 :
1444 0 : cct = atl[z].t + (atl[z].art ++);
1445 0 : if (cct->type == NAME
1446 0 : && cct->line >= 0
1447 0 : && (nm = HTT_get(¯os,
1448 : cct->name))
1449 0 : && nm->nest <=
1450 0 : (reject_nested + 1)) {
1451 0 : ret |= substitute_macro(ls,
1452 0 : nm, atl + z, 0,
1453 : reject_nested + 1, l);
1454 0 : continue;
1455 : }
1456 0 : t = *cct;
1457 0 : ZAP_LINE(t);
1458 0 : aol(etl.t, etl.nt, t, TOKEN_LIST_MEMG);
1459 : }
1460 0 : ls->output_fifo = save_tf;
1461 0 : ls->flags = save_flags;
1462 0 : if (ret) {
1463 : #ifdef LOW_MEM
1464 0 : m->cval.rp = save_art;
1465 : #else
1466 : m->val.art = save_art;
1467 : #endif
1468 : goto exit_error_2;
1469 : }
1470 : }
1471 0 : if (!ntwds && (!etl.nt
1472 0 : || !ttWHI(etl.t[etl.nt - 1].type))) {
1473 0 : t.type = OPT_NONE;
1474 0 : t.line = ls->line;
1475 0 : aol(etl.t, etl.nt, t, TOKEN_LIST_MEMG);
1476 : }
1477 0 : ltwds = 0;
1478 0 : continue;
1479 : }
1480 : /*
1481 : * This code is definitely cursed.
1482 : *
1483 : * For the extremely brave reader who tries to understand
1484 : * what is happening: ltwds is a flag meaning "last token
1485 : * was double-sharp" and ntwds means "next token will be
1486 : * double-sharp". The tokens are from the macro definition,
1487 : * and scanned from left to right. Arguments that are
1488 : * not implied into a #/## construction are macro-expanded
1489 : * seperately, then included into the token stream.
1490 : */
1491 0 : if (ct->type == DSHARP || ct->type == DIG_DSHARP) {
1492 0 : if (ltwds) {
1493 0 : error(ls->line, "quad sharp");
1494 : #ifdef LOW_MEM
1495 0 : m->cval.rp = save_art;
1496 : #else
1497 : m->val.art = save_art;
1498 : #endif
1499 : goto exit_error_2;
1500 : }
1501 : #ifdef LOW_MEM
1502 0 : if (m->cval.rp < m->cval.length
1503 0 : && ttMWS(m->cval.t[m->cval.rp]))
1504 0 : m->cval.rp ++;
1505 : #else
1506 : if (m->val.art < m->val.nt
1507 : && ttMWS(m->val.t[m->val.art].type))
1508 : m->val.art ++;
1509 : #endif
1510 0 : ltwds = 1;
1511 0 : continue;
1512 0 : } else if (ltwds && etl.nt != 0) {
1513 0 : if (concat_token(etl.t + (-- etl.nt), ct)) {
1514 0 : warning(ls->line, "operator '##' produced "
1515 : "the invalid token '%s%s'",
1516 0 : token_name(etl.t + etl.nt),
1517 : token_name(ct));
1518 : #if 0
1519 : /* obsolete */
1520 : #ifdef LOW_MEM
1521 : m->cval.rp = save_art;
1522 : #else
1523 : m->val.art = save_art;
1524 : #endif
1525 : etl.nt ++;
1526 : goto exit_error_2;
1527 : #endif
1528 0 : etl.nt ++;
1529 : } else {
1530 0 : if (etl.nt == 0) freemem(etl.t);
1531 0 : t.type = dsharp_lexer.ctok->type;
1532 0 : t.line = ls->line;
1533 0 : if (S_TOKEN(t.type)) {
1534 0 : t.name = sdup(dsharp_lexer.ctok->name);
1535 0 : throw_away(ls->gf, t.name);
1536 : }
1537 0 : ct = &t;
1538 : }
1539 : }
1540 0 : ltwds = 0;
1541 : #ifdef LOW_MEM
1542 0 : if ((ct->type == SHARP || ct->type == DIG_SHARP)
1543 0 : && next < m->cval.length
1544 0 : && (m->cval.t[next] == MACROARG
1545 0 : || (ttMWS(m->cval.t[next])
1546 0 : && (next + 1) < m->cval.length
1547 0 : && m->cval.t[next + 1] == MACROARG))) {
1548 :
1549 : unsigned anum;
1550 : #else
1551 : if ((ct->type == SHARP || ct->type == DIG_SHARP)
1552 : && next < m->val.nt
1553 : && (m->val.t[next].type == MACROARG
1554 : || (ttMWS(m->val.t[next].type)
1555 : && (next + 1) < m->val.nt
1556 : && m->val.t[next + 1].type == MACROARG))) {
1557 : #endif
1558 : /*
1559 : * We have a # operator followed by (an optional
1560 : * whitespace and) a macro argument; this means
1561 : * stringification. So be it.
1562 : */
1563 : #ifdef LOW_MEM
1564 0 : if (ttMWS(m->cval.t[next])) m->cval.rp ++;
1565 : #else
1566 : if (ttMWS(m->val.t[next].type)) m->val.art ++;
1567 : #endif
1568 0 : t.type = STRING;
1569 : #ifdef LOW_MEM
1570 0 : anum = m->cval.t[++ m->cval.rp];
1571 0 : if (anum >= 128U) anum = ((anum & 127U) << 8)
1572 0 : | (unsigned)m->cval.t[++ m->cval.rp];
1573 0 : t.name = stringify(atl + anum);
1574 0 : m->cval.rp ++;
1575 : #else
1576 : t.name = stringify(atl +
1577 : (size_t)(m->val.t[m->val.art ++].line));
1578 : #endif
1579 0 : throw_away(ls->gf, t.name);
1580 0 : ct = &t;
1581 : /*
1582 : * There is no need for extra spaces here.
1583 : */
1584 : }
1585 0 : t = *ct;
1586 0 : ZAP_LINE(t);
1587 0 : aol(etl.t, etl.nt, t, TOKEN_LIST_MEMG);
1588 : }
1589 : #ifdef LOW_MEM
1590 0 : m->cval.rp = save_art;
1591 : #else
1592 : m->val.art = save_art;
1593 : #endif
1594 :
1595 : /*
1596 : * Now etl contains the expanded macro, to be parsed again for
1597 : * further expansions -- much easier, since '#' and '##' have
1598 : * already been handled.
1599 : * However, we might need some input from tfi. So, we paste
1600 : * the contents of tfi after etl, and we put back what was
1601 : * not used.
1602 : *
1603 : * Some adjacent spaces are merged; only unique NONE, or sequences
1604 : * OPT_NONE NONE are emitted.
1605 : */
1606 0 : etl_limit = etl.nt;
1607 0 : if (tfi) {
1608 0 : save_tfi = tfi->art;
1609 0 : while (tfi->art < tfi->nt) aol(etl.t, etl.nt,
1610 : tfi->t[tfi->art ++], TOKEN_LIST_MEMG);
1611 : }
1612 0 : ltwws = 0;
1613 0 : while (etl.art < etl_limit) {
1614 : struct macro *nm;
1615 :
1616 0 : ct = etl.t + (etl.art ++);
1617 0 : if (ct->type == NAME && ct->line >= 0
1618 0 : && (nm = HTT_get(¯os, ct->name))) {
1619 0 : if (substitute_macro(ls, nm, &etl,
1620 : penury, reject_nested, l)) {
1621 0 : m->nest = save_nest;
1622 0 : goto exit_error_2;
1623 : }
1624 0 : ltwws = 0;
1625 0 : continue;
1626 : }
1627 0 : if (ttMWS(ct->type)) {
1628 0 : if (ltwws == 1) {
1629 0 : if (ct->type == OPT_NONE) continue;
1630 0 : ltwws = 2;
1631 0 : } else if (ltwws == 2) continue;
1632 0 : else if (ct->type == OPT_NONE) ltwws = 1;
1633 0 : else ltwws = 2;
1634 0 : } else ltwws = 0;
1635 0 : if (ct->line >= 0) ct->line = l;
1636 0 : print_token(ls, ct, reject_nested ? 0 : l);
1637 : }
1638 0 : if (etl.nt) freemem(etl.t);
1639 0 : if (tfi) {
1640 0 : tfi->art = save_tfi + (etl.art - etl_limit);
1641 : }
1642 :
1643 : exit_macro_1:
1644 0 : print_space(ls);
1645 : exit_macro_2:
1646 0 : for (i = 0; i < (m->narg + m->vaarg); i ++)
1647 0 : if (atl[i].nt) freemem(atl[i].t);
1648 0 : if (m->narg > 0 || m->vaarg) freemem(atl);
1649 0 : m->nest = save_nest;
1650 0 : return 0;
1651 :
1652 : exit_error_2:
1653 0 : if (etl.nt) freemem(etl.t);
1654 : exit_error_1:
1655 0 : for (i = 0; i < (m->narg + m->vaarg); i ++)
1656 0 : if (atl[i].nt) freemem(atl[i].t);
1657 0 : if (m->narg > 0 || m->vaarg) freemem(atl);
1658 0 : m->nest = save_nest;
1659 : exit_error:
1660 0 : return 1;
1661 : }
1662 :
1663 : /*
1664 : * print already defined macros
1665 : */
1666 0 : void print_defines(void)
1667 : {
1668 0 : HTT_scan(¯os, print_macro);
1669 0 : }
1670 :
1671 : /*
1672 : * define_macro() defines a new macro, whom definition is given in
1673 : * the command-line syntax: macro=def
1674 : * The '=def' part is optional.
1675 : *
1676 : * It returns non-zero on error.
1677 : */
1678 0 : int define_macro(struct lexer_state *ls, char *def)
1679 : {
1680 0 : char *c = sdup(def), *d;
1681 0 : int with_def = 0;
1682 0 : int ret = 0;
1683 :
1684 0 : for (d = c; *d && *d != '='; d ++);
1685 0 : if (*d) {
1686 0 : *d = ' ';
1687 0 : with_def = 1;
1688 : }
1689 0 : if (with_def) {
1690 : struct lexer_state lls;
1691 0 : size_t n = strlen(c) + 1;
1692 :
1693 0 : if (c == d) {
1694 0 : error(-1, "void macro name");
1695 0 : ret = 1;
1696 : } else {
1697 0 : *(c + n - 1) = '\n';
1698 0 : init_buf_lexer_state(&lls, 0);
1699 0 : lls.flags = ls->flags | LEXER;
1700 0 : lls.input = 0;
1701 0 : lls.input_string = (unsigned char *)c;
1702 0 : lls.pbuf = 0;
1703 0 : lls.ebuf = n;
1704 0 : lls.line = -1;
1705 0 : ret = handle_define(&lls);
1706 0 : free_lexer_state(&lls);
1707 : }
1708 : } else {
1709 : struct macro *m;
1710 :
1711 0 : if (!*c) {
1712 0 : error(-1, "void macro name");
1713 0 : ret = 1;
1714 0 : } else if ((m = HTT_get(¯os, c))
1715 : #ifdef LOW_MEM
1716 0 : && (m->cval.length != 3
1717 0 : || m->cval.t[0] != NUMBER
1718 0 : || strcmp((char *)(m->cval.t + 1), "1"))) {
1719 : #else
1720 : && (m->val.nt != 1
1721 : || m->val.t[0].type != NUMBER
1722 : || strcmp(m->val.t[0].name, "1"))) {
1723 : #endif
1724 0 : error(-1, "macro %s already defined", c);
1725 0 : ret = 1;
1726 : } else {
1727 : #ifndef LOW_MEM
1728 : struct token t;
1729 : #endif
1730 :
1731 0 : m = new_macro();
1732 : #ifdef LOW_MEM
1733 0 : m->cval.length = 3;
1734 0 : m->cval.t = getmem(3);
1735 0 : m->cval.t[0] = NUMBER;
1736 0 : m->cval.t[1] = '1';
1737 0 : m->cval.t[2] = 0;
1738 : #else
1739 : t.type = NUMBER;
1740 : t.name = sdup("1");
1741 : aol(m->val.t, m->val.nt, t, TOKEN_LIST_MEMG);
1742 : #endif
1743 0 : HTT_put(¯os, m, c);
1744 : }
1745 : }
1746 0 : freemem(c);
1747 0 : return ret;
1748 : }
1749 :
1750 : /*
1751 : * undef_macro() undefines the macro whom name is given as "def";
1752 : * it is not an error to try to undef a macro that does not exist.
1753 : *
1754 : * It returns non-zero on error (undefinition of a special macro,
1755 : * void macro name).
1756 : */
1757 0 : int undef_macro(struct lexer_state *ls, char *def)
1758 : {
1759 0 : char *c = def;
1760 :
1761 0 : if (!*c) {
1762 0 : error(-1, "void macro name");
1763 0 : return 1;
1764 : }
1765 0 : if (HTT_get(¯os, c)) {
1766 0 : if (check_special_macro(c)) {
1767 0 : error(-1, "trying to undef special macro %s", c);
1768 0 : return 1;
1769 0 : } else HTT_del(¯os, c);
1770 : }
1771 0 : return 0;
1772 : }
1773 :
1774 : /*
1775 : * We saw a #ifdef directive. Parse the line.
1776 : * return value: 1 if the macro is defined, 0 if it is not, -1 on error
1777 : */
1778 0 : int handle_ifdef(struct lexer_state *ls)
1779 : {
1780 0 : while (!next_token(ls)) {
1781 0 : int tgd = 1;
1782 :
1783 0 : if (ls->ctok->type == NEWLINE) break;
1784 0 : if (ttMWS(ls->ctok->type)) continue;
1785 0 : if (ls->ctok->type == NAME) {
1786 0 : int x = (HTT_get(¯os, ls->ctok->name) != 0);
1787 0 : while (!next_token(ls) && ls->ctok->type != NEWLINE)
1788 0 : if (tgd && !ttWHI(ls->ctok->type)
1789 0 : && (ls->flags & WARN_STANDARD)) {
1790 0 : warning(ls->line, "trailing garbage "
1791 : "in #ifdef");
1792 0 : tgd = 0;
1793 : }
1794 0 : return x;
1795 : }
1796 0 : error(ls->line, "illegal macro name for #ifdef");
1797 0 : while (!next_token(ls) && ls->ctok->type != NEWLINE)
1798 0 : if (tgd && !ttWHI(ls->ctok->type)
1799 0 : && (ls->flags & WARN_STANDARD)) {
1800 0 : warning(ls->line, "trailing garbage in "
1801 : "#ifdef");
1802 0 : tgd = 0;
1803 : }
1804 0 : return -1;
1805 : }
1806 0 : error(ls->line, "unfinished #ifdef");
1807 0 : return -1;
1808 : }
1809 :
1810 : /*
1811 : * for #undef
1812 : * return value: 1 on error, 0 on success. Undefining a macro that was
1813 : * already not defined is not an error.
1814 : */
1815 0 : int handle_undef(struct lexer_state *ls)
1816 : {
1817 0 : while (!next_token(ls)) {
1818 0 : if (ls->ctok->type == NEWLINE) break;
1819 0 : if (ttMWS(ls->ctok->type)) continue;
1820 0 : if (ls->ctok->type == NAME) {
1821 0 : struct macro *m = HTT_get(¯os, ls->ctok->name);
1822 0 : int tgd = 1;
1823 :
1824 0 : if (m != 0) {
1825 0 : if (check_special_macro(ls->ctok->name)) {
1826 0 : error(ls->line, "trying to undef "
1827 : "special macro %s",
1828 0 : ls->ctok->name);
1829 0 : goto undef_error;
1830 : }
1831 0 : if (emit_defines)
1832 0 : fprintf(emit_output, "#undef %s\n",
1833 0 : ls->ctok->name);
1834 0 : HTT_del(¯os, ls->ctok->name);
1835 : }
1836 0 : while (!next_token(ls) && ls->ctok->type != NEWLINE)
1837 0 : if (tgd && !ttWHI(ls->ctok->type)
1838 0 : && (ls->flags & WARN_STANDARD)) {
1839 0 : warning(ls->line, "trailing garbage "
1840 : "in #undef");
1841 0 : tgd = 0;
1842 : }
1843 0 : return 0;
1844 : }
1845 0 : error(ls->line, "illegal macro name for #undef");
1846 : undef_error:
1847 0 : while (!next_token(ls) && ls->ctok->type != NEWLINE);
1848 0 : return 1;
1849 : }
1850 0 : error(ls->line, "unfinished #undef");
1851 0 : return 1;
1852 : }
1853 :
1854 : /*
1855 : * for #ifndef
1856 : * return value: 0 if the macro is defined, 1 if it is not, -1 on error.
1857 : */
1858 0 : int handle_ifndef(struct lexer_state *ls)
1859 : {
1860 0 : while (!next_token(ls)) {
1861 0 : int tgd = 1;
1862 :
1863 0 : if (ls->ctok->type == NEWLINE) break;
1864 0 : if (ttMWS(ls->ctok->type)) continue;
1865 0 : if (ls->ctok->type == NAME) {
1866 0 : int x = (HTT_get(¯os, ls->ctok->name) == 0);
1867 :
1868 0 : while (!next_token(ls) && ls->ctok->type != NEWLINE)
1869 0 : if (tgd && !ttWHI(ls->ctok->type)
1870 0 : && (ls->flags & WARN_STANDARD)) {
1871 0 : warning(ls->line, "trailing garbage "
1872 : "in #ifndef");
1873 0 : tgd = 0;
1874 : }
1875 0 : if (protect_detect.state == 1) {
1876 0 : protect_detect.state = 2;
1877 0 : protect_detect.macro = sdup(ls->ctok->name);
1878 : }
1879 0 : return x;
1880 : }
1881 0 : error(ls->line, "illegal macro name for #ifndef");
1882 0 : while (!next_token(ls) && ls->ctok->type != NEWLINE)
1883 0 : if (tgd && !ttWHI(ls->ctok->type)
1884 0 : && (ls->flags & WARN_STANDARD)) {
1885 0 : warning(ls->line, "trailing garbage in "
1886 : "#ifndef");
1887 0 : tgd = 0;
1888 : }
1889 0 : return -1;
1890 : }
1891 0 : error(ls->line, "unfinished #ifndef");
1892 0 : return -1;
1893 : }
1894 :
1895 : /*
1896 : * erase the macro table.
1897 : */
1898 0 : void wipe_macros(void)
1899 : {
1900 0 : if (macros_init_done) HTT_kill(¯os);
1901 0 : macros_init_done = 0;
1902 0 : }
1903 :
1904 : /*
1905 : * initialize the macro table
1906 : */
1907 0 : void init_macros(void)
1908 : {
1909 0 : wipe_macros();
1910 0 : HTT_init(¯os, del_macro);
1911 0 : macros_init_done = 1;
1912 0 : if (!no_special_macros) add_special_macros();
1913 0 : }
1914 :
1915 : /*
1916 : * find a macro from its name
1917 : */
1918 0 : struct macro *get_macro(char *name)
1919 : {
1920 0 : return HTT_get(¯os, name);
1921 : }
|