Bug Summary

File:workdir/unxlngi6.pro/CustomTarget/ucpp/source/macro.c
Location:line 257, column 2
Description:Assigned value is garbage or undefined

Annotated 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 */
43static HTT macros;
44static int macros_init_done = 0;
45
46static void del_macro(void *m)
47{
48 struct macro *n = m;
49 size_t i;
50
51 for (i = 0; (int)i < n->narg; i ++) freememfree(n->arg[i]);
52 if (n->narg > 0) freememfree(n->arg);
53#ifdef LOW_MEM
54 if (n->cval.length) freememfree(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)((n->val.t[i].type) >= NUMBER && (n->val.t[i
].type) <= CHAR)
)
59 freememfree(n->val.t[i].name);
60 freememfree(n->val.t);
61 }
62#endif
63 freememfree(n);
64}
65
66static inline struct macro *new_macro(void)
67{
68 struct macro *m = getmemmalloc(sizeof(struct macro));
69
70 m->narg = -1;
71 m->nest = 0;
72#ifdef LOW_MEM
73 m->cval.length = 0;
74#else
75 m->val.nt = m->val.art = 0;
76#endif
77 m->vaarg = 0;
78 return m;
79}
80
81/*
82 * for special macros, and the "defined" operator
83 */
84enum {
85 MAC_NONE, MAC_DEFINED,
86 MAC_LINE, MAC_FILE, MAC_DATE, MAC_TIME, MAC_STDC, MAC_PRAGMA
87};
88#define MAC_SPECIALMAC_LINE 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 */
95static inline int check_special_macro(char *name)
96{
97 if (!strcmp(name, "defined")) return MAC_DEFINED;
98 if (*name != '_') return MAC_NONE;
99 if (*(name + 1) == 'P') {
100 if (!strcmp(name, "_Pragma")) return MAC_PRAGMA;
101 return MAC_NONE;
102 } else if (*(name + 1) != '_') return MAC_NONE;
103 if (no_special_macros) return MAC_NONE;
104 if (!strcmp(name, "__LINE__")) return MAC_LINE;
105 else if (!strcmp(name, "__FILE__")) return MAC_FILE;
106 else if (!strcmp(name, "__DATE__")) return MAC_DATE;
107 else if (!strcmp(name, "__TIME__")) return MAC_TIME;
108 else if (!strcmp(name, "__STDC__")) return MAC_STDC;
109 return MAC_NONE;
110}
111
112int c99_compliant = 1;
113int c99_hosted = 1;
114
115/*
116 * add the special macros to the macro table
117 */
118static void add_special_macros(void)
119{
120 struct macro *m;
121
122 HTT_put(&macros, new_macro(), "__LINE__");
123 HTT_put(&macros, new_macro(), "__FILE__");
124 HTT_put(&macros, new_macro(), "__DATE__");
125 HTT_put(&macros, new_macro(), "__TIME__");
126 HTT_put(&macros, new_macro(), "__STDC__");
127 m = new_macro(); m->narg = 1;
128 m->arg = getmemmalloc(sizeof(char *)); m->arg[0] = sdup("foo");
129 HTT_put(&macros, m, "_Pragma");
130 if (c99_compliant) {
131#ifndef LOW_MEM
132 struct token t;
133#endif
134
135 m = new_macro();
136#ifdef LOW_MEM
137 m->cval.t = getmemmalloc(9);
138 m->cval.t[0] = NUMBER;
139 mmvmemcpy(m->cval.t + 1, "199901L", 8);
140 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)do { if (((m->val.nt) % (32)) == 0) { if ((m->val.nt) !=
0) { (m->val.t) = incmem((m->val.t), (m->val.nt) * sizeof
(t), ((m->val.nt) + (32)) * sizeof(t)); } else { (m->val
.t) = malloc((32) * sizeof(t)); } } (m->val.t)[(m->val.
nt) ++] = (t); } while (0)
;
146#endif
147 HTT_put(&macros, m, "__STDC_VERSION__");
148 }
149 if (c99_hosted) {
150#ifndef LOW_MEM
151 struct token t;
152#endif
153
154 m = new_macro();
155#ifdef LOW_MEM
156 m->cval.t = getmemmalloc(3);
157 m->cval.t[0] = NUMBER;
158 mmvmemcpy(m->cval.t + 1, "1", 2);
159 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)do { if (((m->val.nt) % (32)) == 0) { if ((m->val.nt) !=
0) { (m->val.t) = incmem((m->val.t), (m->val.nt) * sizeof
(t), ((m->val.nt) + (32)) * sizeof(t)); } else { (m->val
.t) = malloc((32) * sizeof(t)); } } (m->val.t)[(m->val.
nt) ++] = (t); } while (0)
;
165#endif
166 HTT_put(&macros, m, "__STDC_HOSTED__");
167 }
168}
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 */
184static void print_macro(void *vm)
185{
186 struct macro *m = vm;
187 char *mname = HASH_ITEM_NAME(m)(((hash_item_header *)(m))->ident + sizeof(unsigned));
188 int x = check_special_macro(mname);
189 size_t i;
190
191 if (x != MAC_NONE) {
192 fprintf(emit_output, "/* #define %s */ /* special */\n",
193 mname);
194 return;
195 }
196 fprintf(emit_output, "#define %s", mname);
197 if (m->narg >= 0) {
198 fprintf(emit_output, "(");
199 for (i = 0; i < (size_t)(m->narg); i ++) {
200 fprintf(emit_output, i ? ", %s" : "%s", m->arg[i]);
201 }
202 if (m->vaarg) {
203 fputs(m->narg ? ", ..." : "...", emit_output);
204 }
205 fprintf(emit_output, ")");
206 }
207#ifdef LOW_MEM
208 if (m->cval.length == 0) {
209 fputc('\n', emit_output);
210 return;
211 }
212 fputc(' ', emit_output);
213 for (i = 0; i < m->cval.length;) {
214 int tt = m->cval.t[i ++];
215
216 if (tt == MACROARG) {
217 unsigned anum = m->cval.t[i];
218
219 if (anum >= 128) anum = ((anum & 127U) << 8)
220 | m->cval.t[++ i];
221 if (anum == (unsigned)m->narg)
222 fputs("__VA_ARGS__", emit_output);
223 else
224 fputs(m->arg[anum], emit_output);
225 i ++;
226 }
227 else if (S_TOKEN(tt)((tt) >= NUMBER && (tt) <= CHAR)) {
228 fputs((char *)(m->cval.t + i), emit_output);
229 i += 1 + strlen((char *)(m->cval.t + i));
230 } 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_nameucpp_token_name(m->val.t + i), emit_output);
246 }
247#endif
248 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 */
255void print_tokenucpp_print_token(struct lexer_state *ls, struct token *t, long uz_line)
256{
257 char *x = t->name;
3
Assigned value is garbage or undefined
258
259 if (uz_line && t->line < 0) t->line = uz_line;
260 if (ls->flags & LEXER0x010000UL) {
261 struct token at;
262
263 at = *t;
264 if (S_TOKEN(t->type)((t->type) >= NUMBER && (t->type) <= CHAR
)
) {
265 at.name = sdup(at.name);
266 throw_awayucpp_throw_away(ls->gf, at.name);
267 }
268 aol(ls->output_fifo->t, ls->output_fifo->nt, at,do { if (((ls->output_fifo->nt) % (32)) == 0) { if ((ls
->output_fifo->nt) != 0) { (ls->output_fifo->t) =
incmem((ls->output_fifo->t), (ls->output_fifo->nt
) * sizeof(at), ((ls->output_fifo->nt) + (32)) * sizeof
(at)); } else { (ls->output_fifo->t) = malloc((32) * sizeof
(at)); } } (ls->output_fifo->t)[(ls->output_fifo->
nt) ++] = (at); } while (0)
269 TOKEN_LIST_MEMG)do { if (((ls->output_fifo->nt) % (32)) == 0) { if ((ls
->output_fifo->nt) != 0) { (ls->output_fifo->t) =
incmem((ls->output_fifo->t), (ls->output_fifo->nt
) * sizeof(at), ((ls->output_fifo->nt) + (32)) * sizeof
(at)); } else { (ls->output_fifo->t) = malloc((32) * sizeof
(at)); } } (ls->output_fifo->t)[(ls->output_fifo->
nt) ++] = (at); } while (0)
;
270 return;
271 }
272 if (ls->flags & KEEP_OUTPUT0x020000UL) {
273 for (; ls->oline < ls->line;) put_charucpp_put_char(ls, '\n');
274 }
275 if (!S_TOKEN(t->type)((t->type) >= NUMBER && (t->type) <= CHAR
)
) x = operators_name[t->type];
276 for (; *x; x ++) put_charucpp_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 */
283static void print_token_nailed(struct lexer_state *ls, struct token *t,
284 long nail_line)
285{
286 char *x = t->name;
287
288 if (ls->flags & LEXER0x010000UL) {
289 print_tokenucpp_print_token(ls, t, 0);
290 return;
291 }
292 if (ls->flags & KEEP_OUTPUT0x020000UL) {
293 for (; ls->oline < nail_line;) put_charucpp_put_char(ls, '\n');
294 }
295 if (!S_TOKEN(t->type)((t->type) >= NUMBER && (t->type) <= CHAR
)
) x = operators_name[t->type];
296 for (; *x; x ++) put_charucpp_put_char(ls, *x);
297}
298
299/*
300 * send a reduced whitespace token to the output
301 */
302#define print_space(ls)do { struct token lt; lt.type = OPT_NONE; lt.line = (ls)->
line; ucpp_print_token((ls), &lt, 0); } while (0)
do { \
303 struct token lt; \
304 lt.type = OPT_NONE; \
305 lt.line = (ls)->line; \
306 print_tokenucpp_print_token((ls), &lt, 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 */
318int handle_defineucpp_handle_define(struct lexer_state *ls)
319{
320 struct macro *m = 0, *n;
321#ifdef LOW_MEM
322 struct token_fifo mv;
323#endif
324 int ltwws = 1, redef = 0;
325 char *mname = 0;
326 int narg;
327 size_t nt;
328 long l = ls->line;
329
330#ifdef LOW_MEM
331 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 while (!next_tokenucpp_next_token(ls) && ls->ctok->type != NEWLINE) {
336 if (ttMWS(ls->ctok->type)((ls->ctok->type) == NONE || (ls->ctok->type) == COMMENT
|| (ls->ctok->type) == OPT_NONE)
) continue;
337 if (ls->ctok->type == NAME) mname = sdup(ls->ctok->name);
338 break;
339 }
340 if (mname == 0) {
341 errorucpp_error(l, "missing macro name");
342 return 1;
343 }
344 if (check_special_macro(mname)) {
345 errorucpp_error(l, "trying to redefine the special macro %s", mname);
346 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 if ((n = HTT_get(&macros, mname)) != 0) {
360 /* redefinition of a macro: we must check that we define
361 it identical */
362 redef = 1;
363#ifdef LOW_MEM
364 n->cval.rp = 0;
365#endif
366 freememfree(mname);
367 mname = 0;
368 }
369 if (!redef) {
370 m = new_macro();
371 m->narg = -1;
372#ifdef LOW_MEM
373#define mval mv
374#else
375#define mval (m->val)
376#endif
377 }
378 if (next_tokenucpp_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 if (ls->ctok->type == LPAR) {
385 int i, j;
386 int need_comma = 0, saw_mdots = 0;
387
388 narg = 0;
389 while (!next_tokenucpp_next_token(ls)) {
390 if (ls->ctok->type == NEWLINE) {
391 errorucpp_error(l, "truncated macro definition");
392 goto define_error;
393 }
394 if (ls->ctok->type == COMMA) {
395 if (saw_mdots) {
396 errorucpp_error(l, "'...' must end the macro "
397 "argument list");
398 goto warp_error;
399 }
400 if (!need_comma) {
401 errorucpp_error(l, "void macro argument");
402 goto warp_error;
403 }
404 need_comma = 0;
405 continue;
406 } else if (ls->ctok->type == NAME) {
407 if (saw_mdots) {
408 errorucpp_error(l, "'...' must end the macro "
409 "argument list");
410 goto warp_error;
411 }
412 if (need_comma) {
413 errorucpp_error(l, "missing comma in "
414 "macro argument list");
415 goto warp_error;
416 }
417 if (!redef) {
418 aol(m->arg, narg,do { if (((narg) % (8)) == 0) { if ((narg) != 0) { (m->arg
) = incmem((m->arg), (narg) * sizeof(sdup(ls->ctok->
name)), ((narg) + (8)) * sizeof(sdup(ls->ctok->name)));
} else { (m->arg) = malloc((8) * sizeof(sdup(ls->ctok->
name))); } } (m->arg)[(narg) ++] = (sdup(ls->ctok->name
)); } while (0)
419 sdup(ls->ctok->name), 8)do { if (((narg) % (8)) == 0) { if ((narg) != 0) { (m->arg
) = incmem((m->arg), (narg) * sizeof(sdup(ls->ctok->
name)), ((narg) + (8)) * sizeof(sdup(ls->ctok->name)));
} else { (m->arg) = malloc((8) * sizeof(sdup(ls->ctok->
name))); } } (m->arg)[(narg) ++] = (sdup(ls->ctok->name
)); } while (0)
;
420 /* we must keep track of m->narg
421 so that cleanup in case of
422 error works. */
423 m->narg = narg;
424 if (narg == 128
425 && (ls->flags & WARN_STANDARD0x000001UL))
426 warningucpp_warning(l, "more arguments to "
427 "macro than the ISO "
428 "limit (127)");
429#ifdef LOW_MEM
430 if (narg == 32767) {
431 errorucpp_error(l, "too many arguments "
432 "in macro definition "
433 "(max 32766)");
434 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 if (narg >= n->narg) goto redef_error;
442 if (strcmp(ls->ctok->name,
443 n->arg[narg ++]))
444 goto redef_error;
445 }
446 need_comma = 1;
447 continue;
448 } else if ((ls->flags & MACRO_VAARG0x002000UL)
449 && ls->ctok->type == MDOTS) {
450 if (need_comma) {
451 errorucpp_error(l, "missing comma before '...'");
452 goto warp_error;
453 }
454 if (redef && !n->vaarg) goto redef_error;
455 if (!redef) m->vaarg = 1;
456 saw_mdots = 1;
457 need_comma = 1;
458 continue;
459 } else if (ls->ctok->type == RPAR) {
460 if (narg > 0 && !need_comma) {
461 errorucpp_error(l, "void macro argument");
462 goto warp_error;
463 }
464 if (redef && n->vaarg && !saw_mdots)
465 goto redef_error;
466 break;
467 } else if (ttMWS(ls->ctok->type)((ls->ctok->type) == NONE || (ls->ctok->type) == COMMENT
|| (ls->ctok->type) == OPT_NONE)
) {
468 continue;
469 }
470 errorucpp_error(l, "invalid macro argument");
471 goto warp_error;
472 }
473 if (!redef) {
474 for (i = 1; i < narg; i ++) for (j = 0; j < i; j ++)
475 if (!strcmp(m->arg[i], m->arg[j])) {
476 errorucpp_error(l, "duplicate macro "
477 "argument");
478 goto warp_error;
479 }
480 }
481 if (!redef) m->narg = narg;
482 } else {
483 if (!ttWHI(ls->ctok->type)(((ls->ctok->type) == NONE || (ls->ctok->type) ==
COMMENT || (ls->ctok->type) == OPT_NONE) || (ls->ctok
->type) == NEWLINE)
&& (ls->flags & WARN_STANDARD0x000001UL))
484 warningucpp_warning(ls->line, "identifier not followed by "
485 "whitespace in #define");
486 ls->flags |= READ_AGAIN0x080000UL;
487 narg = 0;
488 }
489 if (redef) nt = 0;
490
491 /* now, we have the arguments. Let's get the macro contents. */
492 while (!next_tokenucpp_next_token(ls) && ls->ctok->type != NEWLINE) {
493 struct token t;
494
495 t.type = ls->ctok->type;
496 if (ltwws && ttMWS(t.type)((t.type) == NONE || (t.type) == COMMENT || (t.type) == OPT_NONE
)
) continue;
497 t.line = 0;
498 if (t.type == NAME) {
499 int i;
500
501 if ((ls->flags & MACRO_VAARG0x002000UL)
502 && !strcmp(ls->ctok->name, "__VA_ARGS__")) {
503 if (redef) {
504 if (!n->vaarg) goto redef_error;
505 } else if (!m->vaarg) {
506 errorucpp_error(l, "'__VA_ARGS__' is forbidden "
507 "in macros with a fixed "
508 "number of arguments");
509 goto warp_error;
510 }
511 t.type = MACROARG;
512 t.line = redef ? n->narg : m->narg;
513 }
514 for (i = 0; i < narg; i ++)
515 if (!strcmp(redef ? n->arg[i] : m->arg[i],
516 ls->ctok->name)) {
517 t.type = MACROARG;
518 /* this is a hack: we store the
519 argument number in the line field */
520 t.line = i;
521 break;
522 }
523 }
524 if (!redef && S_TOKEN(t.type)((t.type) >= NUMBER && (t.type) <= CHAR)) t.name = sdup(ls->ctok->name);
525 if (ttMWS(t.type)((t.type) == NONE || (t.type) == COMMENT || (t.type) == OPT_NONE
)
) {
526 if (ltwws) continue;
527#ifdef SEMPER_FIDELIS
528 t.type = OPT_NONE;
529#else
530 t.type = NONE;
531#endif
532 ltwws = 1;
533 } else ltwws = 0;
534 if (!redef) {
535 /* we ensure that each macro token has a correct
536 line number */
537 if (t.type != MACROARG) t.line = 1;
538 aol(mval.t, mval.nt, t, TOKEN_LIST_MEMG)do { if (((mval.nt) % (32)) == 0) { if ((mval.nt) != 0) { (mval
.t) = incmem((mval.t), (mval.nt) * sizeof(t), ((mval.nt) + (32
)) * sizeof(t)); } else { (mval.t) = malloc((32) * sizeof(t))
; } } (mval.t)[(mval.nt) ++] = (t); } while (0)
;
539 } else {
540#ifdef LOW_MEM
541 int tt;
542
543 if (n->cval.rp >= n->cval.length) {
544#ifdef SEMPER_FIDELIS
545 if (t.type != OPT_NONE) goto redef_error;
546#else
547 if (t.type != NONE) goto redef_error;
548#endif
549 } else if (t.type != n->cval.t[n->cval.rp]) {
550 goto redef_error;
551 } else if (t.type == MACROARG) {
552 unsigned anum = n->cval.t[n->cval.rp + 1];
553
554 if (anum >= 128U) anum = ((anum & 127U) << 8)
555 | m->cval.t[n->cval.rp + 2];
556 if (anum != (unsigned)t.line) goto redef_error;
557 } else if (S_TOKEN(t.type)((t.type) >= NUMBER && (t.type) <= CHAR) && strcmp(ls->ctok->name,
558 (char *)(n->cval.t + n->cval.rp + 1))) {
559 goto redef_error;
560 }
561 tt = n->cval.t[n->cval.rp ++];
562 if (S_TOKEN(tt)((tt) >= NUMBER && (tt) <= CHAR)) n->cval.rp += 1
563 + strlen((char *)(n->cval.t + n->cval.rp));
564 else if (tt == MACROARG) {
565 if (n->cval.t[++ n->cval.rp] >= 128)
566 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)((t.type) >= NUMBER && (t.type) <= CHAR) && strcmp(ls->ctok->name,
579 n->val.t[nt].name))) {
580 goto redef_error;
581 }
582#endif
583 nt ++;
584 }
585 }
586
587 if (redef) {
588#ifdef LOW_MEM
589 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 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 */
599define_end:
600#ifdef SEMPER_FIDELIS
601 if (mval.nt && mval.t[mval.nt - 1].type == OPT_NONE) {
602#else
603 if (mval.nt && mval.t[mval.nt - 1].type == NONE) {
604#endif
605 mval.nt --;
606 if (mval.nt == 0) freememfree(mval.t);
607 }
608 if (mval.nt != 0) {
609 size_t i;
610
611 /* some checks about the macro */
612 if (mval.t[0].type == DSHARP
613 || mval.t[0].type == DIG_DSHARP
614 || mval.t[mval.nt - 1].type == DSHARP
615 || mval.t[mval.nt - 1].type == DIG_DSHARP) {
616 errorucpp_error(l, "operator '##' may neither begin "
617 "nor end a macro");
618 goto define_error;
619 }
620 if (m->narg >= 0) for (i = 0; i < mval.nt; i ++)
621 if ((mval.t[i].type == SHARP
622 || mval.t[i].type == DIG_SHARP) &&
623 (i == (mval.nt - 1)
624 || (ttMWS(mval.t[i + 1].type)((mval.t[i + 1].type) == NONE || (mval.t[i + 1].type) == COMMENT
|| (mval.t[i + 1].type) == OPT_NONE)
&&
625 (i == mval.nt - 2
626 || mval.t[i + 2].type != MACROARG))
627 || (!ttMWS(mval.t[i + 1].type)((mval.t[i + 1].type) == NONE || (mval.t[i + 1].type) == COMMENT
|| (mval.t[i + 1].type) == OPT_NONE)
628 && mval.t[i + 1].type != MACROARG))) {
629 errorucpp_error(l, "operator '#' not followed "
630 "by a macro argument");
631 goto define_error;
632 }
633 }
634#ifdef LOW_MEM
635 {
636 size_t i, l;
637
638 for (i = 0, l = 0; i < mval.nt; i ++) {
639 l ++;
640 if (S_TOKEN(mval.t[i].type)((mval.t[i].type) >= NUMBER && (mval.t[i].type) <=
CHAR)
)
641 l += 1 + strlen(mval.t[i].name);
642 else if (mval.t[i].type == MACROARG) {
643 l ++;
644 if (mval.t[i].line >= 128) l ++;
645 }
646 }
647 m->cval.length = l;
648 if (l) m->cval.t = getmemmalloc(l);
649 for (i = 0, l = 0; i < mval.nt; i ++) {
650 m->cval.t[l ++] = mval.t[i].type;
651 if (S_TOKEN(mval.t[i].type)((mval.t[i].type) >= NUMBER && (mval.t[i].type) <=
CHAR)
) {
652 size_t x = 1 + strlen(mval.t[i].name);
653
654 mmvmemcpy(m->cval.t + l, mval.t[i].name, x);
655 l += x;
656 freememfree(mval.t[i].name);
657 }
658 else if (mval.t[i].type == MACROARG) {
659 unsigned anum = mval.t[i].line;
660
661 if (anum >= 128) {
662 m->cval.t[l ++] = 128 | (anum >> 8);
663 m->cval.t[l ++] = anum & 0xFF;
664 } else {
665 m->cval.t[l ++] = anum;
666 }
667 }
668 }
669 if (mval.nt) freememfree(mval.t);
670 }
671#endif
672 HTT_put(&macros, m, mname);
673 freememfree(mname);
674 if (emit_defines) print_macro(m);
675 return 0;
676
677redef_error:
678 while (ls->ctok->type != NEWLINE && !next_tokenucpp_next_token(ls));
679redef_error_2:
680 errorucpp_error(l, "macro '%s' redefined unidentically", HASH_ITEM_NAME(n)(((hash_item_header *)(n))->ident + sizeof(unsigned)));
681 return 1;
682warp_error:
683 while (ls->ctok->type != NEWLINE && !next_tokenucpp_next_token(ls));
684define_error:
685 if (m) del_macro(m);
686 if (mname) freememfree(mname);
687#ifdef LOW_MEM
688 if (mv.nt) {
689 size_t i;
690
691 for (i = 0; i < mv.nt; i ++)
692 if (S_TOKEN(mv.t[i].type)((mv.t[i].type) >= NUMBER && (mv.t[i].type) <= CHAR
)
) freememfree(mv.t[i].name);
693 freememfree(mv.t);
694 }
695#endif
696 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 */
714static 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 int ltwws = 1, npar = 0, i;
718 struct token *ct = 0;
719 int read_from_fifo = 0;
720 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_tokenucpp_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 for (i = 0; i < narg; i ++) atl[i].art = atl[i].nt = 0;
731 if (vaarg) atl[narg].art = atl[narg].nt = 0;
732 *wr = 0;
733 while (!unravel(ls)) {
734 if (!read_from_fifo && ct->type == NEWLINE) ls->ltwnl = 1;
735 if (ttWHI(ct->type)(((ct->type) == NONE || (ct->type) == COMMENT || (ct->
type) == OPT_NONE) || (ct->type) == NEWLINE)
) {
736 *wr = 1;
737 continue;
738 }
739 if (ct->type == LPAR) {
740 npar = 1;
741 }
742 break;
743 }
744 if (!npar) {
745 if (ct == ls->ctok) return 1;
746 if (read_from_fifo) return 2;
747 return 3;
748 }
749 if (!read_from_fifo && ct == ls->ctok) ls->ltwnl = 0;
750 i = 0;
751 if ((narg + vaarg) == 0) {
752 while(!unravel(ls)) {
753 if (ttWHI(ct->type)(((ct->type) == NONE || (ct->type) == COMMENT || (ct->
type) == OPT_NONE) || (ct->type) == NEWLINE)
) continue;
754 if (ct->type == RPAR) goto harvested;
755 npar = 1;
756 goto too_many_args;
757 }
758 }
759 while (!unravel(ls)) {
760 struct token t;
761
762 if (ct->type == LPAR) npar ++;
763 else if (ct->type == RPAR && (-- npar) == 0) {
764 if (atl[i].nt != 0
765 && ttMWS(atl[i].t[atl[i].nt - 1].type)((atl[i].t[atl[i].nt - 1].type) == NONE || (atl[i].t[atl[i].nt
- 1].type) == COMMENT || (atl[i].t[atl[i].nt - 1].type) == OPT_NONE
)
)
766 atl[i].nt --;
767 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 if (i < (narg + vaarg)) {
774 errorucpp_error(begin_line, "not enough arguments "
775 "to macro");
776 return 4;
777 }
778 if (i > narg) {
779 if (!(ls->flags & MACRO_VAARG0x002000UL) || !vaarg)
780 goto too_many_args;
781 }
782 goto harvested;
783 } else if (ct->type == COMMA && npar <= 1 && i < narg) {
784 if (atl[i].nt != 0
785 && ttMWS(atl[i].t[atl[i].nt - 1].type)((atl[i].t[atl[i].nt - 1].type) == NONE || (atl[i].t[atl[i].nt
- 1].type) == COMMENT || (atl[i].t[atl[i].nt - 1].type) == OPT_NONE
)
)
786 atl[i].nt --;
787 if (++ i == narg) {
788 if (!(ls->flags & MACRO_VAARG0x002000UL) || !vaarg)
789 goto too_many_args;
790 }
791 if (i > 30000) goto too_many_args;
792 ltwws = 1;
793 continue;
794 } else if (ltwws && ttWHI(ct->type)(((ct->type) == NONE || (ct->type) == COMMENT || (ct->
type) == OPT_NONE) || (ct->type) == NEWLINE)
) continue;
795
796 t.type = ct->type;
797 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 if (ttWHI(t.type)(((t.type) == NONE || (t.type) == COMMENT || (t.type) == OPT_NONE
) || (t.type) == NEWLINE)
) {
808 if (t.type != OPT_NONE) {
809 t.type = NONE;
810#ifdef SEMPER_FIDELIS
811 t.name = sdup(" ");
812 throw_awayucpp_throw_away(ls->gf, t.name);
813#endif
814 ltwws = 1;
815 }
816 if (atl[i].nt > 0
817 && atl[i].t[atl[i].nt - 1].type == OPT_NONE)
818 atl[i].nt --;
819 } else {
820 ltwws = 0;
821 if (S_TOKEN(t.type)((t.type) >= NUMBER && (t.type) <= CHAR)) {
822 t.name = ct->name;
823 if (ct == (ls)->ctok) {
824 t.name = sdup(t.name);
825 throw_awayucpp_throw_away(ls->gf, t.name);
826 }
827 }
828 }
829 aol(atl[i].t, atl[i].nt, t, TOKEN_LIST_MEMG)do { if (((atl[i].nt) % (32)) == 0) { if ((atl[i].nt) != 0) {
(atl[i].t) = incmem((atl[i].t), (atl[i].nt) * sizeof(t), ((atl
[i].nt) + (32)) * sizeof(t)); } else { (atl[i].t) = malloc((32
) * sizeof(t)); } } (atl[i].t)[(atl[i].nt) ++] = (t); } while
(0)
;
830 }
831 errorucpp_error(begin_line, "unfinished macro call");
832 return 4;
833too_many_args:
834 errorucpp_error(begin_line, "too many arguments to macro");
835 while (npar && !unravel(ls)) {
836 if (ct->type == LPAR) npar ++;
837 else if (ct->type == RPAR) npar --;
838 }
839 return 4;
840harvested:
841 if (i > 127 && (ls->flags & WARN_STANDARD0x000001UL))
842 warningucpp_warning(begin_line, "macro call with %d arguments (ISO "
843 "specifies 127 max)", i);
844 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 */
856struct lexer_state dsharp_lexerucpp_dsharp_lexer;
857
858static inline int concat_token(struct token *t1, struct token *t2)
859{
860 char *n1 = token_nameucpp_token_name(t1), *n2 = token_nameucpp_token_name(t2);
861 size_t l1 = strlen(n1), l2 = strlen(n2);
862 unsigned char *x = getmemmalloc(l1 + l2 + 1);
863 int r;
864
865 mmvmemcpy(x, n1, l1);
866 mmvmemcpy(x + l1, n2, l2);
867 x[l1 + l2] = 0;
868 dsharp_lexerucpp_dsharp_lexer.input = 0;
869 dsharp_lexerucpp_dsharp_lexer.input_string = x;
870 dsharp_lexerucpp_dsharp_lexer.pbuf = 0;
871 dsharp_lexerucpp_dsharp_lexer.ebuf = l1 + l2;
872 dsharp_lexerucpp_dsharp_lexer.discard = 1;
873 dsharp_lexerucpp_dsharp_lexer.flags = DEFAULT_LEXER_FLAGS(0x000080UL | 0x000001UL | 0x000020UL | 0x002000UL | 0x000100UL
| 0x010000UL | 0x008000UL | 0x000800UL)
;
874 dsharp_lexerucpp_dsharp_lexer.pending_token = 0;
875 r = next_tokenucpp_next_token(&dsharp_lexerucpp_dsharp_lexer);
876 freememfree(x);
877 return (r == 1 || dsharp_lexerucpp_dsharp_lexer.pbuf < (l1 + l2)
878 || dsharp_lexerucpp_dsharp_lexer.pending_token
879 || (dsharp_lexerucpp_dsharp_lexer.pbuf == (l1 + l2) && !dsharp_lexerucpp_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 */
888struct lexer_state tokenize_lexerucpp_tokenize_lexer;
889
890static char *tokenize_string(struct lexer_state *ls, char *buf)
891{
892 struct token_fifo tf;
893 size_t bl = strlen(buf);
894 int r;
895
896 tokenize_lexerucpp_tokenize_lexer.input = 0;
897 tokenize_lexerucpp_tokenize_lexer.input_string = (unsigned char *)buf;
898 tokenize_lexerucpp_tokenize_lexer.pbuf = 0;
899 tokenize_lexerucpp_tokenize_lexer.ebuf = bl;
900 tokenize_lexerucpp_tokenize_lexer.discard = 1;
901 tokenize_lexerucpp_tokenize_lexer.flags = ls->flags | LEXER0x010000UL;
902 tokenize_lexerucpp_tokenize_lexer.pending_token = 0;
903 tf.art = tf.nt = 0;
904 while (!(r = next_tokenucpp_next_token(&tokenize_lexerucpp_tokenize_lexer))) {
905 struct token t, *ct = tokenize_lexerucpp_tokenize_lexer.ctok;
906
907 if (ttWHI(ct->type)(((ct->type) == NONE || (ct->type) == COMMENT || (ct->
type) == OPT_NONE) || (ct->type) == NEWLINE)
) continue;
908 t = *ct;
909 if (S_TOKEN(t.type)((t.type) >= NUMBER && (t.type) <= CHAR)) t.name = sdup(t.name);
910 aol(tf.t, tf.nt, t, TOKEN_LIST_MEMG)do { if (((tf.nt) % (32)) == 0) { if ((tf.nt) != 0) { (tf.t) =
incmem((tf.t), (tf.nt) * sizeof(t), ((tf.nt) + (32)) * sizeof
(t)); } else { (tf.t) = malloc((32) * sizeof(t)); } } (tf.t)[
(tf.nt) ++] = (t); } while (0)
;
911 }
912 if (tokenize_lexerucpp_tokenize_lexer.pbuf < bl) goto tokenize_error;
913 return (char *)((compress_token_listucpp_compress_token_list(&tf)).t);
914
915tokenize_error:
916 if (tf.nt) {
917 for (tf.art = 0; tf.art < tf.nt; tf.art ++)
918 if (S_TOKEN(tf.t[tf.art].type)((tf.t[tf.art].type) >= NUMBER && (tf.t[tf.art].type
) <= CHAR)
)
919 freememfree(tf.t[tf.art].name);
920 freememfree(tf.t);
921 }
922 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 */
931static inline char *stringify_string(char *x)
932{
933 size_t l;
934 int i, inside_str = 0, inside_cc = 0, must_quote, has_quoted = 0;
935 char *y, *d;
936
937 for (i = 0; i < 2; i ++) {
938 if (i) d[0] = '"';
939 for (l = 1, y = x; *y; y ++, l ++) {
940 must_quote = 0;
941 if (inside_cc) {
942 if (*y == '\\') {
943 must_quote = 1;
944 has_quoted = 1;
945 } else if (!has_quoted && *y == '\'')
946 inside_cc = 0;
947 } else if (inside_str) {
948 if (*y == '"' || *y == '\\') must_quote = 1;
949 if (*y == '\\') has_quoted = 1;
950 else if (!has_quoted && *y == '"')
951 inside_str = 0;
952 } else if (*y == '"') {
953 inside_str = 1;
954 must_quote = 1;
955 } else if (*y == '\'') {
956 inside_cc = 1;
957 }
958 if (must_quote) {
959 if (i) d[l] = '\\';
960 l ++;
961 }
962 if (i) d[l] = *y;
963 }
964 if (!i) d = getmemmalloc(l + 2);
965 if (i) {
966 d[l] = '"';
967 d[l + 1] = 0;
968 }
969 }
970 return d;
971}
972
973/*
974 * stringify() produces a constant string, result of the # operator
975 * on a list of tokens.
976 */
977static char *stringify(struct token_fifo *tf)
978{
979 size_t tlen;
980 size_t i;
981 char *x, *y;
982
983 for (tlen = 0, i = 0; i < tf->nt; i ++)
984 if (tf->t[i].type < CPPERR512 && tf->t[i].type != OPT_NONE)
985 tlen += strlen(token_nameucpp_token_name(tf->t + i));
986 if (tlen == 0) return sdup("\"\"");
987 x = getmemmalloc(tlen + 1);
988 for (tlen = 0, i = 0; i < tf->nt; i ++) {
989 if (tf->t[i].type >= CPPERR512 || tf->t[i].type == OPT_NONE)
990 continue;
991 strcpy(x + tlen, token_nameucpp_token_name(tf->t + i));
992 tlen += strlen(token_nameucpp_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 y = stringify_string(x);
997 freememfree(x);
998 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 */
1008char compile_timeucpp_compile_time[12], compile_dateucpp_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 */
1027int substitute_macroucpp_substitute_macro(struct lexer_state *ls, struct macro *m,
1028 struct token_fifo *tfi, int penury, int reject_nested, long l)
1029{
1030 char *mname = HASH_ITEM_NAME(m)(((hash_item_header *)(m))->ident + sizeof(unsigned));
1031 struct token_fifo *atl, etl;
1032 struct token t, *ct;
1033 int i, save_nest = m->nest;
1034 size_t save_art, save_tfi, etl_limit;
1035 int ltwds, ntwds, ltwws;
1036 int pragma_op = 0;
1037
1038 /*
1039 * Reject the replacement, if we are already inside the macro.
1040 */
1041 if (m->nest > reject_nested) {
1
Taking false branch
1042 t.type = NAME;
1043 t.line = ls->line;
1044 t.name = mname;
1045 print_tokenucpp_print_token(ls, &t, 0);
1046 return 0;
1047 }
1048
1049 /*
1050 * put a separation from preceeding tokens
1051 */
1052 print_space(ls)do { struct token lt; lt.type = OPT_NONE; lt.line = (ls)->
line; ucpp_print_token((ls), &lt, 0); } while (0)
;
2
Within the expansion of the macro 'print_space':
a
Calling 'ucpp_print_token'
1053
1054 /*
1055 * Check if the macro is a special one.
1056 */
1057 if ((i = check_special_macro(mname)) >= MAC_SPECIALMAC_LINE) {
1058 /* we have a special macro */
1059 switch (i) {
1060 char buf[30], *bbuf, *cfn;
1061
1062 case MAC_LINE:
1063 t.type = NUMBER;
1064 t.line = l;
1065 sprintf(buf, "%ld", l);
1066 t.name = buf;
1067 print_space(ls)do { struct token lt; lt.type = OPT_NONE; lt.line = (ls)->
line; ucpp_print_token((ls), &lt, 0); } while (0)
;
1068 print_tokenucpp_print_token(ls, &t, 0);
1069 break;
1070 case MAC_FILE:
1071 t.type = STRING;
1072 t.line = l;
1073 cfn = current_long_filename ?
1074 current_long_filename : current_filename;
1075 bbuf = getmemmalloc(2 * strlen(cfn) + 3);
1076 {
1077 char *c, *d;
1078 int lcwb = 0;
1079
1080 bbuf[0] = '"';
1081 for (c = cfn, d = bbuf + 1; *c; c ++) {
1082 if (*c == '\\') {
1083 if (lcwb) continue;
1084 *(d ++) = '\\';
1085 lcwb = 1;
1086 } else lcwb = 0;
1087 *(d ++) = *c;
1088 }
1089 *(d ++) = '"';
1090 *(d ++) = 0;
1091 }
1092 t.name = bbuf;
1093 print_space(ls)do { struct token lt; lt.type = OPT_NONE; lt.line = (ls)->
line; ucpp_print_token((ls), &lt, 0); } while (0)
;
1094 print_tokenucpp_print_token(ls, &t, 0);
1095 freememfree(bbuf);
1096 break;
1097 case MAC_DATE:
1098 t.type = STRING;
1099 t.line = l;
1100 t.name = compile_dateucpp_compile_date;
1101 print_space(ls)do { struct token lt; lt.type = OPT_NONE; lt.line = (ls)->
line; ucpp_print_token((ls), &lt, 0); } while (0)
;
1102 print_tokenucpp_print_token(ls, &t, 0);
1103 break;
1104 case MAC_TIME:
1105 t.type = STRING;
1106 t.line = l;
1107 t.name = compile_timeucpp_compile_time;
1108 print_space(ls)do { struct token lt; lt.type = OPT_NONE; lt.line = (ls)->
line; ucpp_print_token((ls), &lt, 0); } while (0)
;
1109 print_tokenucpp_print_token(ls, &t, 0);
1110 break;
1111 case MAC_STDC:
1112 t.type = NUMBER;
1113 t.line = l;
1114 t.name = "1";
1115 print_space(ls)do { struct token lt; lt.type = OPT_NONE; lt.line = (ls)->
line; ucpp_print_token((ls), &lt, 0); } while (0)
;
1116 print_tokenucpp_print_token(ls, &t, 0);
1117 break;
1118 case MAC_PRAGMA:
1119 if (reject_nested > 0) {
1120 /* do not replace _Pragma() unless toplevel */
1121 t.type = NAME;
1122 t.line = ls->line;
1123 t.name = mname;
1124 print_tokenucpp_print_token(ls, &t, 0);
1125 return 0;
1126 }
1127 pragma_op = 1;
1128 goto collect_args;
1129#ifdef AUDIT
1130 default:
1131 ouchucpp_ouch("unbekanntes fliegendes macro");
1132#endif
1133 }
1134 return 0;
1135 }
1136
1137 /*
1138 * If the macro has arguments, collect them.
1139 */
1140collect_args:
1141 if (m->narg >= 0) {
1142 unsigned long save_flags = ls->flags;
1143 int wr = 0;
1144
1145 ls->flags |= LEXER0x010000UL;
1146 if (m->narg > 0 || m->vaarg)
1147 atl = getmemmalloc((m->narg + m->vaarg)
1148 * sizeof(struct token_fifo));
1149 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 ls->flags = save_flags | READ_AGAIN0x080000UL;
1156 goto no_argument_next;
1157 case 2:
1158 tfi->art --;
1159 /* fall through */
1160 case 3:
1161 ls->flags = save_flags;
1162 no_argument_next:
1163 t.type = NAME;
1164 t.line = l;
1165 t.name = mname;
1166 print_token_nailed(ls, &t, l);
1167 if (wr) {
1168 t.type = NONE;
1169 t.line = l;
1170#ifdef SEMPER_FIDELIS
1171 t.name = " ";
1172#endif
1173 print_tokenucpp_print_token(ls, &t, 0);
1174 goto exit_macro_2;
1175 }
1176 goto exit_macro_1;
1177 case 4:
1178 ls->flags = save_flags;
1179 goto exit_error_1;
1180 }
1181 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 if (pragma_op) {
1190 char *pn;
1191
1192 if (atl[0].nt != 1 || atl[0].t[0].type != STRING) {
1193 errorucpp_error(ls->line, "invalid argument to _Pragma");
1194 if (atl[0].nt) freememfree(atl[0].t);
1195 freememfree(atl);
1196 goto exit_error;
1197 }
1198 pn = atl[0].t[0].name;
1199 if ((pn[0] == '"' && pn[1] == '"') || (pn[0] == 'L'
1200 && pn[1] == '"' && pn[2] == '"')) {
1201 /* void pragma -- just ignore it */
1202 freememfree(atl[0].t);
1203 freememfree(atl);
1204 return 0;
1205 }
1206 if (ls->flags & TEXT_OUTPUT0x100000UL) {
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 char *c = atl[0].t[0].name, *d;
1215
1216 for (d = "\n#pragma "; *d; d ++) put_charucpp_put_char(ls, *d);
1217 d = (*c == 'L') ? c + 2 : c + 1;
1218 for (; *d != '"'; d ++) {
1219 if (*d == '\\' && (*(d + 1) == '\\'
1220 || *(d + 1) == '"')) {
1221 d ++;
1222 }
1223 put_charucpp_put_char(ls, *d);
1224 }
1225 put_charucpp_put_char(ls, '\n');
1226 ls->oline = ls->line;
1227 enter_file(ls, ls->flags);
1228#else
1229 if (ls->flags & WARN_PRAGMA0x000010UL)
1230 warningucpp_warning(ls->line,
1231 "_Pragma() ignored and not dumped");
1232#endif
1233 } else if (ls->flags & HANDLE_PRAGMA0x001000UL) {
1234 char *c = atl[0].t[0].name, *d, *buf;
1235 struct token t;
1236
1237 /* a wide string is a string */
1238 if (*c == 'L') c ++;
1239 c ++;
1240 for (buf = d = getmemmalloc(strlen(c)); *c != '"'; c ++) {
1241 if (*c == '\\' && (*(c + 1) == '\\'
1242 || *(c + 1) == '"')) {
1243 *(d ++) = *(++ c);
1244 } else *(d ++) = *c;
1245 }
1246 *d = 0;
1247 t.type = PRAGMA;
1248 t.line = ls->line;
1249#ifdef PRAGMA_TOKENIZE
1250 t.name = tokenize_string(ls, buf);
1251 freememfree(buf);
1252 buf = t.name;
1253 if (!buf) {
1254 freememfree(atl[0].t);
1255 freememfree(atl);
1256 goto exit_error;
1257 }
1258#else
1259 t.name = buf;
1260#endif
1261 aol(ls->toplevel_of->t, ls->toplevel_of->nt,do { if (((ls->toplevel_of->nt) % (32)) == 0) { if ((ls
->toplevel_of->nt) != 0) { (ls->toplevel_of->t) =
incmem((ls->toplevel_of->t), (ls->toplevel_of->nt
) * sizeof(t), ((ls->toplevel_of->nt) + (32)) * sizeof(
t)); } else { (ls->toplevel_of->t) = malloc((32) * sizeof
(t)); } } (ls->toplevel_of->t)[(ls->toplevel_of->
nt) ++] = (t); } while (0)
1262 t, TOKEN_LIST_MEMG)do { if (((ls->toplevel_of->nt) % (32)) == 0) { if ((ls
->toplevel_of->nt) != 0) { (ls->toplevel_of->t) =
incmem((ls->toplevel_of->t), (ls->toplevel_of->nt
) * sizeof(t), ((ls->toplevel_of->nt) + (32)) * sizeof(
t)); } else { (ls->toplevel_of->t) = malloc((32) * sizeof
(t)); } } (ls->toplevel_of->t)[(ls->toplevel_of->
nt) ++] = (t); } while (0)
;
1263 throw_awayucpp_throw_away(ls->gf, buf);
1264 }
1265 freememfree(atl[0].t);
1266 freememfree(atl);
1267 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 { if ((t).type == NAME) { struct macro *zlm = HTT_get(&
macros, (t).name); if (zlm && zlm->nest > reject_nested
) (t).line = -1 - (t).line; } } while (0)
do { \
1286 if ((t).type == NAME) { \
1287 struct macro *zlm = HTT_get(&macros, (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 save_art = m->cval.rp;
1295 m->cval.rp = 0;
1296#else
1297 save_art = m->val.art;
1298 m->val.art = 0;
1299#endif
1300 etl.art = etl.nt = 0;
1301 m->nest = reject_nested + 1;
1302 ltwds = ntwds = 0;
1303#ifdef LOW_MEM
1304 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 ct = &uu;
1313 ct->line = 1;
1314 t.type = ct->type = m->cval.t[m->cval.rp ++];
1315 if (ct->type == MACROARG) {
1316 unsigned anum = m->cval.t[m->cval.rp ++];
1317
1318 if (anum >= 128U) anum = ((anum & 127U) << 8)
1319 | (unsigned)m->cval.t[m->cval.rp ++];
1320 ct->line = anum;
1321 } else if (S_TOKEN(ct->type)((ct->type) >= NUMBER && (ct->type) <= CHAR
)
) {
1322 t.name = ct->name = (char *)(m->cval.t + m->cval.rp);
1323 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 t.line = ls->line;
1332 next = m->cval.rp;
1333 if ((next < m->cval.length && (m->cval.t[z = next] == DSHARP
1334 || m->cval.t[z = next] == DIG_DSHARP))
1335 || ((next + 1) < m->cval.length
1336 && ttWHI(m->cval.t[next])(((m->cval.t[next]) == NONE || (m->cval.t[next]) == COMMENT
|| (m->cval.t[next]) == OPT_NONE) || (m->cval.t[next])
== NEWLINE)
1337 && (m->cval.t[z = next + 1] == DSHARP
1338 || m->cval.t[z = next + 1] == DIG_DSHARP))) {
1339 ntwds = 1;
1340 m->cval.rp = z;
1341 } 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)(((m->val.t[next].type) == NONE || (m->val.t[next].type
) == COMMENT || (m->val.t[next].type) == OPT_NONE) || (m->
val.t[next].type) == NEWLINE)
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 if (ct->type == MACROARG) {
1365#ifdef DSHARP_TOKEN_MERGE
1366 int need_opt_space = 1;
1367#endif
1368 z = ct->line; /* the argument number is there */
1369 if (ltwds && atl[z].nt != 0 && etl.nt) {
1370 if (concat_token(etl.t + (-- etl.nt),
1371 atl[z].t)) {
1372 warningucpp_warning(ls->line, "operator '##' "
1373 "produced the invalid token "
1374 "'%s%s'",
1375 token_nameucpp_token_name(etl.t + etl.nt),
1376 token_nameucpp_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 etl.nt ++;
1388 atl[z].art = 0;
1389#ifdef DSHARP_TOKEN_MERGE
1390 need_opt_space = 0;
1391#endif
1392 } else {
1393 if (etl.nt == 0) freememfree(etl.t);
1394 else if (!ttWHI(etl.t[etl.nt - 1](((etl.t[etl.nt - 1] .type) == NONE || (etl.t[etl.nt - 1] .type
) == COMMENT || (etl.t[etl.nt - 1] .type) == OPT_NONE) || (etl
.t[etl.nt - 1] .type) == NEWLINE)
1395 .type)(((etl.t[etl.nt - 1] .type) == NONE || (etl.t[etl.nt - 1] .type
) == COMMENT || (etl.t[etl.nt - 1] .type) == OPT_NONE) || (etl
.t[etl.nt - 1] .type) == NEWLINE)
) {
1396 t.type = OPT_NONE;
1397 t.line = ls->line;
1398 aol(etl.t, etl.nt, t,do { if (((etl.nt) % (32)) == 0) { if ((etl.nt) != 0) { (etl.
t) = incmem((etl.t), (etl.nt) * sizeof(t), ((etl.nt) + (32)) *
sizeof(t)); } else { (etl.t) = malloc((32) * sizeof(t)); } }
(etl.t)[(etl.nt) ++] = (t); } while (0)
1399 TOKEN_LIST_MEMG)do { if (((etl.nt) % (32)) == 0) { if ((etl.nt) != 0) { (etl.
t) = incmem((etl.t), (etl.nt) * sizeof(t), ((etl.nt) + (32)) *
sizeof(t)); } else { (etl.t) = malloc((32) * sizeof(t)); } }
(etl.t)[(etl.nt) ++] = (t); } while (0)
;
1400 }
1401 t.type = dsharp_lexerucpp_dsharp_lexer.ctok->type;
1402 t.line = ls->line;
1403 if (S_TOKEN(t.type)((t.type) >= NUMBER && (t.type) <= CHAR)) {
1404 t.name = sdup(dsharp_lexerucpp_dsharp_lexer
1405 .ctok->name);
1406 throw_awayucpp_throw_away(ls->gf, t.name);
1407 }
1408 ZAP_LINE(t)do { if ((t).type == NAME) { struct macro *zlm = HTT_get(&
macros, (t).name); if (zlm && zlm->nest > reject_nested
) (t).line = -1 - (t).line; } } while (0)
;
1409 aol(etl.t, etl.nt, t, TOKEN_LIST_MEMG)do { if (((etl.nt) % (32)) == 0) { if ((etl.nt) != 0) { (etl.
t) = incmem((etl.t), (etl.nt) * sizeof(t), ((etl.nt) + (32)) *
sizeof(t)); } else { (etl.t) = malloc((32) * sizeof(t)); } }
(etl.t)[(etl.nt) ++] = (t); } while (0)
;
1410 atl[z].art = 1;
1411 }
1412 } else atl[z].art = 0;
1413 if (
1414#ifdef DSHARP_TOKEN_MERGE
1415 need_opt_space &&
1416#endif
1417 atl[z].art < atl[z].nt && (!etl.nt
1418 || !ttWHI(etl.t[etl.nt - 1].type)(((etl.t[etl.nt - 1].type) == NONE || (etl.t[etl.nt - 1].type
) == COMMENT || (etl.t[etl.nt - 1].type) == OPT_NONE) || (etl
.t[etl.nt - 1].type) == NEWLINE)
)) {
1419 t.type = OPT_NONE;
1420 t.line = ls->line;
1421 aol(etl.t, etl.nt, t, TOKEN_LIST_MEMG)do { if (((etl.nt) % (32)) == 0) { if ((etl.nt) != 0) { (etl.
t) = incmem((etl.t), (etl.nt) * sizeof(t), ((etl.nt) + (32)) *
sizeof(t)); } else { (etl.t) = malloc((32) * sizeof(t)); } }
(etl.t)[(etl.nt) ++] = (t); } while (0)
;
1422 }
1423 if (ltwds || ntwds) {
1424 while (atl[z].art < atl[z].nt) {
1425 t = atl[z].t[atl[z].art ++];
1426 t.line = ls->line;
1427 ZAP_LINE(t)do { if ((t).type == NAME) { struct macro *zlm = HTT_get(&
macros, (t).name); if (zlm && zlm->nest > reject_nested
) (t).line = -1 - (t).line; } } while (0)
;
1428 aol(etl.t, etl.nt, t, TOKEN_LIST_MEMG)do { if (((etl.nt) % (32)) == 0) { if ((etl.nt) != 0) { (etl.
t) = incmem((etl.t), (etl.nt) * sizeof(t), ((etl.nt) + (32)) *
sizeof(t)); } else { (etl.t) = malloc((32) * sizeof(t)); } }
(etl.t)[(etl.nt) ++] = (t); } while (0)
;
1429 }
1430 } else {
1431 struct token_fifo *save_tf;
1432 unsigned long save_flags;
1433 int ret = 0;
1434
1435 atl[z].art = 0;
1436 save_tf = ls->output_fifo;
1437 ls->output_fifo = &etl;
1438 save_flags = ls->flags;
1439 ls->flags |= LEXER0x010000UL;
1440 while (atl[z].art < atl[z].nt) {
1441 struct macro *nm;
1442 struct token *cct;
1443
1444 cct = atl[z].t + (atl[z].art ++);
1445 if (cct->type == NAME
1446 && cct->line >= 0
1447 && (nm = HTT_get(&macros,
1448 cct->name))
1449 && nm->nest <=
1450 (reject_nested + 1)) {
1451 ret |= substitute_macroucpp_substitute_macro(ls,
1452 nm, atl + z, 0,
1453 reject_nested + 1, l);
1454 continue;
1455 }
1456 t = *cct;
1457 ZAP_LINE(t)do { if ((t).type == NAME) { struct macro *zlm = HTT_get(&
macros, (t).name); if (zlm && zlm->nest > reject_nested
) (t).line = -1 - (t).line; } } while (0)
;
1458 aol(etl.t, etl.nt, t, TOKEN_LIST_MEMG)do { if (((etl.nt) % (32)) == 0) { if ((etl.nt) != 0) { (etl.
t) = incmem((etl.t), (etl.nt) * sizeof(t), ((etl.nt) + (32)) *
sizeof(t)); } else { (etl.t) = malloc((32) * sizeof(t)); } }
(etl.t)[(etl.nt) ++] = (t); } while (0)
;
1459 }
1460 ls->output_fifo = save_tf;
1461 ls->flags = save_flags;
1462 if (ret) {
1463#ifdef LOW_MEM
1464 m->cval.rp = save_art;
1465#else
1466 m->val.art = save_art;
1467#endif
1468 goto exit_error_2;
1469 }
1470 }
1471 if (!ntwds && (!etl.nt
1472 || !ttWHI(etl.t[etl.nt - 1].type)(((etl.t[etl.nt - 1].type) == NONE || (etl.t[etl.nt - 1].type
) == COMMENT || (etl.t[etl.nt - 1].type) == OPT_NONE) || (etl
.t[etl.nt - 1].type) == NEWLINE)
)) {
1473 t.type = OPT_NONE;
1474 t.line = ls->line;
1475 aol(etl.t, etl.nt, t, TOKEN_LIST_MEMG)do { if (((etl.nt) % (32)) == 0) { if ((etl.nt) != 0) { (etl.
t) = incmem((etl.t), (etl.nt) * sizeof(t), ((etl.nt) + (32)) *
sizeof(t)); } else { (etl.t) = malloc((32) * sizeof(t)); } }
(etl.t)[(etl.nt) ++] = (t); } while (0)
;
1476 }
1477 ltwds = 0;
1478 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 if (ct->type == DSHARP || ct->type == DIG_DSHARP) {
1492 if (ltwds) {
1493 errorucpp_error(ls->line, "quad sharp");
1494#ifdef LOW_MEM
1495 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 if (m->cval.rp < m->cval.length
1503 && ttMWS(m->cval.t[m->cval.rp])((m->cval.t[m->cval.rp]) == NONE || (m->cval.t[m->
cval.rp]) == COMMENT || (m->cval.t[m->cval.rp]) == OPT_NONE
)
)
1504 m->cval.rp ++;
1505#else
1506 if (m->val.art < m->val.nt
1507 && ttMWS(m->val.t[m->val.art].type)((m->val.t[m->val.art].type) == NONE || (m->val.t[m->
val.art].type) == COMMENT || (m->val.t[m->val.art].type
) == OPT_NONE)
)
1508 m->val.art ++;
1509#endif
1510 ltwds = 1;
1511 continue;
1512 } else if (ltwds && etl.nt != 0) {
1513 if (concat_token(etl.t + (-- etl.nt), ct)) {
1514 warningucpp_warning(ls->line, "operator '##' produced "
1515 "the invalid token '%s%s'",
1516 token_nameucpp_token_name(etl.t + etl.nt),
1517 token_nameucpp_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 etl.nt ++;
1529 } else {
1530 if (etl.nt == 0) freememfree(etl.t);
1531 t.type = dsharp_lexerucpp_dsharp_lexer.ctok->type;
1532 t.line = ls->line;
1533 if (S_TOKEN(t.type)((t.type) >= NUMBER && (t.type) <= CHAR)) {
1534 t.name = sdup(dsharp_lexerucpp_dsharp_lexer.ctok->name);
1535 throw_awayucpp_throw_away(ls->gf, t.name);
1536 }
1537 ct = &t;
1538 }
1539 }
1540 ltwds = 0;
1541#ifdef LOW_MEM
1542 if ((ct->type == SHARP || ct->type == DIG_SHARP)
1543 && next < m->cval.length
1544 && (m->cval.t[next] == MACROARG
1545 || (ttMWS(m->cval.t[next])((m->cval.t[next]) == NONE || (m->cval.t[next]) == COMMENT
|| (m->cval.t[next]) == OPT_NONE)
1546 && (next + 1) < m->cval.length
1547 && 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)((m->val.t[next].type) == NONE || (m->val.t[next].type)
== COMMENT || (m->val.t[next].type) == OPT_NONE)
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 if (ttMWS(m->cval.t[next])((m->cval.t[next]) == NONE || (m->cval.t[next]) == COMMENT
|| (m->cval.t[next]) == OPT_NONE)
) m->cval.rp ++;
1565#else
1566 if (ttMWS(m->val.t[next].type)((m->val.t[next].type) == NONE || (m->val.t[next].type)
== COMMENT || (m->val.t[next].type) == OPT_NONE)
) m->val.art ++;
1567#endif
1568 t.type = STRING;
1569#ifdef LOW_MEM
1570 anum = m->cval.t[++ m->cval.rp];
1571 if (anum >= 128U) anum = ((anum & 127U) << 8)
1572 | (unsigned)m->cval.t[++ m->cval.rp];
1573 t.name = stringify(atl + anum);
1574 m->cval.rp ++;
1575#else
1576 t.name = stringify(atl +
1577 (size_t)(m->val.t[m->val.art ++].line));
1578#endif
1579 throw_awayucpp_throw_away(ls->gf, t.name);
1580 ct = &t;
1581 /*
1582 * There is no need for extra spaces here.
1583 */
1584 }
1585 t = *ct;
1586 ZAP_LINE(t)do { if ((t).type == NAME) { struct macro *zlm = HTT_get(&
macros, (t).name); if (zlm && zlm->nest > reject_nested
) (t).line = -1 - (t).line; } } while (0)
;
1587 aol(etl.t, etl.nt, t, TOKEN_LIST_MEMG)do { if (((etl.nt) % (32)) == 0) { if ((etl.nt) != 0) { (etl.
t) = incmem((etl.t), (etl.nt) * sizeof(t), ((etl.nt) + (32)) *
sizeof(t)); } else { (etl.t) = malloc((32) * sizeof(t)); } }
(etl.t)[(etl.nt) ++] = (t); } while (0)
;
1588 }
1589#ifdef LOW_MEM
1590 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 etl_limit = etl.nt;
1607 if (tfi) {
1608 save_tfi = tfi->art;
1609 while (tfi->art < tfi->nt) aol(etl.t, etl.nt,do { if (((etl.nt) % (32)) == 0) { if ((etl.nt) != 0) { (etl.
t) = incmem((etl.t), (etl.nt) * sizeof(tfi->t[tfi->art ++
]), ((etl.nt) + (32)) * sizeof(tfi->t[tfi->art ++])); }
else { (etl.t) = malloc((32) * sizeof(tfi->t[tfi->art ++
])); } } (etl.t)[(etl.nt) ++] = (tfi->t[tfi->art ++]); }
while (0)
1610 tfi->t[tfi->art ++], TOKEN_LIST_MEMG)do { if (((etl.nt) % (32)) == 0) { if ((etl.nt) != 0) { (etl.
t) = incmem((etl.t), (etl.nt) * sizeof(tfi->t[tfi->art ++
]), ((etl.nt) + (32)) * sizeof(tfi->t[tfi->art ++])); }
else { (etl.t) = malloc((32) * sizeof(tfi->t[tfi->art ++
])); } } (etl.t)[(etl.nt) ++] = (tfi->t[tfi->art ++]); }
while (0)
;
1611 }
1612 ltwws = 0;
1613 while (etl.art < etl_limit) {
1614 struct macro *nm;
1615
1616 ct = etl.t + (etl.art ++);
1617 if (ct->type == NAME && ct->line >= 0
1618 && (nm = HTT_get(&macros, ct->name))) {
1619 if (substitute_macroucpp_substitute_macro(ls, nm, &etl,
1620 penury, reject_nested, l)) {
1621 m->nest = save_nest;
1622 goto exit_error_2;
1623 }
1624 ltwws = 0;
1625 continue;
1626 }
1627 if (ttMWS(ct->type)((ct->type) == NONE || (ct->type) == COMMENT || (ct->
type) == OPT_NONE)
) {
1628 if (ltwws == 1) {
1629 if (ct->type == OPT_NONE) continue;
1630 ltwws = 2;
1631 } else if (ltwws == 2) continue;
1632 else if (ct->type == OPT_NONE) ltwws = 1;
1633 else ltwws = 2;
1634 } else ltwws = 0;
1635 if (ct->line >= 0) ct->line = l;
1636 print_tokenucpp_print_token(ls, ct, reject_nested ? 0 : l);
1637 }
1638 if (etl.nt) freememfree(etl.t);
1639 if (tfi) {
1640 tfi->art = save_tfi + (etl.art - etl_limit);
1641 }
1642
1643exit_macro_1:
1644 print_space(ls)do { struct token lt; lt.type = OPT_NONE; lt.line = (ls)->
line; ucpp_print_token((ls), &lt, 0); } while (0)
;
1645exit_macro_2:
1646 for (i = 0; i < (m->narg + m->vaarg); i ++)
1647 if (atl[i].nt) freememfree(atl[i].t);
1648 if (m->narg > 0 || m->vaarg) freememfree(atl);
1649 m->nest = save_nest;
1650 return 0;
1651
1652exit_error_2:
1653 if (etl.nt) freememfree(etl.t);
1654exit_error_1:
1655 for (i = 0; i < (m->narg + m->vaarg); i ++)
1656 if (atl[i].nt) freememfree(atl[i].t);
1657 if (m->narg > 0 || m->vaarg) freememfree(atl);
1658 m->nest = save_nest;
1659exit_error:
1660 return 1;
1661}
1662
1663/*
1664 * print already defined macros
1665 */
1666void print_defines(void)
1667{
1668 HTT_scan(&macros, print_macro);
1669}
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 */
1678int define_macro(struct lexer_state *ls, char *def)
1679{
1680 char *c = sdup(def), *d;
1681 int with_def = 0;
1682 int ret = 0;
1683
1684 for (d = c; *d && *d != '='; d ++);
1685 if (*d) {
1686 *d = ' ';
1687 with_def = 1;
1688 }
1689 if (with_def) {
1690 struct lexer_state lls;
1691 size_t n = strlen(c) + 1;
1692
1693 if (c == d) {
1694 errorucpp_error(-1, "void macro name");
1695 ret = 1;
1696 } else {
1697 *(c + n - 1) = '\n';
1698 init_buf_lexer_stateucpp_init_buf_lexer_state(&lls, 0);
1699 lls.flags = ls->flags | LEXER0x010000UL;
1700 lls.input = 0;
1701 lls.input_string = (unsigned char *)c;
1702 lls.pbuf = 0;
1703 lls.ebuf = n;
1704 lls.line = -1;
1705 ret = handle_defineucpp_handle_define(&lls);
1706 free_lexer_state(&lls);
1707 }
1708 } else {
1709 struct macro *m;
1710
1711 if (!*c) {
1712 errorucpp_error(-1, "void macro name");
1713 ret = 1;
1714 } else if ((m = HTT_get(&macros, c))
1715#ifdef LOW_MEM
1716 && (m->cval.length != 3
1717 || m->cval.t[0] != NUMBER
1718 || 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 errorucpp_error(-1, "macro %s already defined", c);
1725 ret = 1;
1726 } else {
1727#ifndef LOW_MEM
1728 struct token t;
1729#endif
1730
1731 m = new_macro();
1732#ifdef LOW_MEM
1733 m->cval.length = 3;
1734 m->cval.t = getmemmalloc(3);
1735 m->cval.t[0] = NUMBER;
1736 m->cval.t[1] = '1';
1737 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)do { if (((m->val.nt) % (32)) == 0) { if ((m->val.nt) !=
0) { (m->val.t) = incmem((m->val.t), (m->val.nt) * sizeof
(t), ((m->val.nt) + (32)) * sizeof(t)); } else { (m->val
.t) = malloc((32) * sizeof(t)); } } (m->val.t)[(m->val.
nt) ++] = (t); } while (0)
;
1742#endif
1743 HTT_put(&macros, m, c);
1744 }
1745 }
1746 freememfree(c);
1747 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 */
1757int undef_macro(struct lexer_state *ls, char *def)
1758{
1759 char *c = def;
1760
1761 if (!*c) {
1762 errorucpp_error(-1, "void macro name");
1763 return 1;
1764 }
1765 if (HTT_get(&macros, c)) {
1766 if (check_special_macro(c)) {
1767 errorucpp_error(-1, "trying to undef special macro %s", c);
1768 return 1;
1769 } else HTT_del(&macros, c);
1770 }
1771 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 */
1778int handle_ifdefucpp_handle_ifdef(struct lexer_state *ls)
1779{
1780 while (!next_tokenucpp_next_token(ls)) {
1781 int tgd = 1;
1782
1783 if (ls->ctok->type == NEWLINE) break;
1784 if (ttMWS(ls->ctok->type)((ls->ctok->type) == NONE || (ls->ctok->type) == COMMENT
|| (ls->ctok->type) == OPT_NONE)
) continue;
1785 if (ls->ctok->type == NAME) {
1786 int x = (HTT_get(&macros, ls->ctok->name) != 0);
1787 while (!next_tokenucpp_next_token(ls) && ls->ctok->type != NEWLINE)
1788 if (tgd && !ttWHI(ls->ctok->type)(((ls->ctok->type) == NONE || (ls->ctok->type) ==
COMMENT || (ls->ctok->type) == OPT_NONE) || (ls->ctok
->type) == NEWLINE)
1789 && (ls->flags & WARN_STANDARD0x000001UL)) {
1790 warningucpp_warning(ls->line, "trailing garbage "
1791 "in #ifdef");
1792 tgd = 0;
1793 }
1794 return x;
1795 }
1796 errorucpp_error(ls->line, "illegal macro name for #ifdef");
1797 while (!next_tokenucpp_next_token(ls) && ls->ctok->type != NEWLINE)
1798 if (tgd && !ttWHI(ls->ctok->type)(((ls->ctok->type) == NONE || (ls->ctok->type) ==
COMMENT || (ls->ctok->type) == OPT_NONE) || (ls->ctok
->type) == NEWLINE)
1799 && (ls->flags & WARN_STANDARD0x000001UL)) {
1800 warningucpp_warning(ls->line, "trailing garbage in "
1801 "#ifdef");
1802 tgd = 0;
1803 }
1804 return -1;
1805 }
1806 errorucpp_error(ls->line, "unfinished #ifdef");
1807 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 */
1815int handle_undefucpp_handle_undef(struct lexer_state *ls)
1816{
1817 while (!next_tokenucpp_next_token(ls)) {
1818 if (ls->ctok->type == NEWLINE) break;
1819 if (ttMWS(ls->ctok->type)((ls->ctok->type) == NONE || (ls->ctok->type) == COMMENT
|| (ls->ctok->type) == OPT_NONE)
) continue;
1820 if (ls->ctok->type == NAME) {
1821 struct macro *m = HTT_get(&macros, ls->ctok->name);
1822 int tgd = 1;
1823
1824 if (m != 0) {
1825 if (check_special_macro(ls->ctok->name)) {
1826 errorucpp_error(ls->line, "trying to undef "
1827 "special macro %s",
1828 ls->ctok->name);
1829 goto undef_error;
1830 }
1831 if (emit_defines)
1832 fprintf(emit_output, "#undef %s\n",
1833 ls->ctok->name);
1834 HTT_del(&macros, ls->ctok->name);
1835 }
1836 while (!next_tokenucpp_next_token(ls) && ls->ctok->type != NEWLINE)
1837 if (tgd && !ttWHI(ls->ctok->type)(((ls->ctok->type) == NONE || (ls->ctok->type) ==
COMMENT || (ls->ctok->type) == OPT_NONE) || (ls->ctok
->type) == NEWLINE)
1838 && (ls->flags & WARN_STANDARD0x000001UL)) {
1839 warningucpp_warning(ls->line, "trailing garbage "
1840 "in #undef");
1841 tgd = 0;
1842 }
1843 return 0;
1844 }
1845 errorucpp_error(ls->line, "illegal macro name for #undef");
1846 undef_error:
1847 while (!next_tokenucpp_next_token(ls) && ls->ctok->type != NEWLINE);
1848 return 1;
1849 }
1850 errorucpp_error(ls->line, "unfinished #undef");
1851 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 */
1858int handle_ifndefucpp_handle_ifndef(struct lexer_state *ls)
1859{
1860 while (!next_tokenucpp_next_token(ls)) {
1861 int tgd = 1;
1862
1863 if (ls->ctok->type == NEWLINE) break;
1864 if (ttMWS(ls->ctok->type)((ls->ctok->type) == NONE || (ls->ctok->type) == COMMENT
|| (ls->ctok->type) == OPT_NONE)
) continue;
1865 if (ls->ctok->type == NAME) {
1866 int x = (HTT_get(&macros, ls->ctok->name) == 0);
1867
1868 while (!next_tokenucpp_next_token(ls) && ls->ctok->type != NEWLINE)
1869 if (tgd && !ttWHI(ls->ctok->type)(((ls->ctok->type) == NONE || (ls->ctok->type) ==
COMMENT || (ls->ctok->type) == OPT_NONE) || (ls->ctok
->type) == NEWLINE)
1870 && (ls->flags & WARN_STANDARD0x000001UL)) {
1871 warningucpp_warning(ls->line, "trailing garbage "
1872 "in #ifndef");
1873 tgd = 0;
1874 }
1875 if (protect_detect.state == 1) {
1876 protect_detect.state = 2;
1877 protect_detect.macro = sdup(ls->ctok->name);
1878 }
1879 return x;
1880 }
1881 errorucpp_error(ls->line, "illegal macro name for #ifndef");
1882 while (!next_tokenucpp_next_token(ls) && ls->ctok->type != NEWLINE)
1883 if (tgd && !ttWHI(ls->ctok->type)(((ls->ctok->type) == NONE || (ls->ctok->type) ==
COMMENT || (ls->ctok->type) == OPT_NONE) || (ls->ctok
->type) == NEWLINE)
1884 && (ls->flags & WARN_STANDARD0x000001UL)) {
1885 warningucpp_warning(ls->line, "trailing garbage in "
1886 "#ifndef");
1887 tgd = 0;
1888 }
1889 return -1;
1890 }
1891 errorucpp_error(ls->line, "unfinished #ifndef");
1892 return -1;
1893}
1894
1895/*
1896 * erase the macro table.
1897 */
1898void wipe_macrosucpp_wipe_macros(void)
1899{
1900 if (macros_init_done) HTT_kill(&macros);
1901 macros_init_done = 0;
1902}
1903
1904/*
1905 * initialize the macro table
1906 */
1907void init_macros(void)
1908{
1909 wipe_macrosucpp_wipe_macros();
1910 HTT_init(&macros, del_macro);
1911 macros_init_done = 1;
1912 if (!no_special_macros) add_special_macros();
1913}
1914
1915/*
1916 * find a macro from its name
1917 */
1918struct macro *get_macroucpp_get_macro(char *name)
1919{
1920 return HTT_get(&macros, name);
1921}