Branch data 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 : 121938 : static void del_macro(void *m)
47 : : {
48 : 121938 : struct macro *n = m;
49 : : size_t i;
50 : :
51 [ + + ]: 127916 : for (i = 0; (int)i < n->narg; i ++) freemem(n->arg[i]);
52 [ + + ]: 121938 : if (n->narg > 0) freemem(n->arg);
53 : : #ifdef LOW_MEM
54 [ + + ]: 121938 : 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 : 121938 : freemem(n);
64 : 121938 : }
65 : :
66 : 121938 : static inline struct macro *new_macro(void)
67 : : {
68 : 121938 : struct macro *m = getmem(sizeof(struct macro));
69 : :
70 : 121938 : m->narg = -1;
71 : 121938 : m->nest = 0;
72 : : #ifdef LOW_MEM
73 : 121938 : m->cval.length = 0;
74 : : #else
75 : : m->val.nt = m->val.art = 0;
76 : : #endif
77 : 121938 : m->vaarg = 0;
78 : 121938 : 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 : 68136 : static inline int check_special_macro(char *name)
96 : : {
97 [ - + ]: 68136 : if (!strcmp(name, "defined")) return MAC_DEFINED;
98 [ + + ]: 68136 : if (*name != '_') return MAC_NONE;
99 [ - + ]: 66956 : if (*(name + 1) == 'P') {
100 [ # # ]: 0 : if (!strcmp(name, "_Pragma")) return MAC_PRAGMA;
101 : 0 : return MAC_NONE;
102 [ + + ]: 66956 : } else if (*(name + 1) != '_') return MAC_NONE;
103 [ - + ]: 66840 : if (no_special_macros) return MAC_NONE;
104 [ - + ]: 66840 : if (!strcmp(name, "__LINE__")) return MAC_LINE;
105 [ - + ]: 66840 : else if (!strcmp(name, "__FILE__")) return MAC_FILE;
106 [ - + ]: 66840 : else if (!strcmp(name, "__DATE__")) return MAC_DATE;
107 [ - + ]: 66840 : else if (!strcmp(name, "__TIME__")) return MAC_TIME;
108 [ - + ]: 66840 : else if (!strcmp(name, "__STDC__")) return MAC_STDC;
109 : 68136 : 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 : 5978 : static void add_special_macros(void)
119 : : {
120 : : struct macro *m;
121 : :
122 : 5978 : HTT_put(¯os, new_macro(), "__LINE__");
123 : 5978 : HTT_put(¯os, new_macro(), "__FILE__");
124 : 5978 : HTT_put(¯os, new_macro(), "__DATE__");
125 : 5978 : HTT_put(¯os, new_macro(), "__TIME__");
126 : 5978 : HTT_put(¯os, new_macro(), "__STDC__");
127 : 5978 : m = new_macro(); m->narg = 1;
128 : 5978 : m->arg = getmem(sizeof(char *)); m->arg[0] = sdup("foo");
129 : 5978 : HTT_put(¯os, m, "_Pragma");
130 [ + - ]: 5978 : if (c99_compliant) {
131 : : #ifndef LOW_MEM
132 : : struct token t;
133 : : #endif
134 : :
135 : 5978 : m = new_macro();
136 : : #ifdef LOW_MEM
137 : 5978 : m->cval.t = getmem(9);
138 : 5978 : m->cval.t[0] = NUMBER;
139 : 5978 : mmv(m->cval.t + 1, "199901L", 8);
140 : 5978 : 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 : 5978 : HTT_put(¯os, m, "__STDC_VERSION__");
148 : : }
149 [ + - ]: 5978 : if (c99_hosted) {
150 : : #ifndef LOW_MEM
151 : : struct token t;
152 : : #endif
153 : :
154 : 5978 : m = new_macro();
155 : : #ifdef LOW_MEM
156 : 5978 : m->cval.t = getmem(3);
157 : 5978 : m->cval.t[0] = NUMBER;
158 : 5978 : mmv(m->cval.t + 1, "1", 2);
159 : 5978 : 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 : 5978 : HTT_put(¯os, m, "__STDC_HOSTED__");
167 : : }
168 : 5978 : }
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 : 2415999 : void print_token(struct lexer_state *ls, struct token *t, long uz_line)
256 : : {
257 : 2415999 : char *x = t->name;
258 : :
259 [ - + ][ # # ]: 2415999 : if (uz_line && t->line < 0) t->line = uz_line;
260 [ - + ]: 2415999 : 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 : 2415999 : return;
271 : : }
272 [ + - ]: 2415999 : if (ls->flags & KEEP_OUTPUT) {
273 [ - + ]: 2415999 : for (; ls->oline < ls->line;) put_char(ls, '\n');
274 : : }
275 [ + - ][ - + ]: 2415999 : if (!S_TOKEN(t->type)) x = operators_name[t->type];
276 [ + + ]: 18439750 : 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 : 68136 : int handle_define(struct lexer_state *ls)
319 : : {
320 : 68136 : struct macro *m = 0, *n;
321 : : #ifdef LOW_MEM
322 : : struct token_fifo mv;
323 : : #endif
324 : 68136 : int ltwws = 1, redef = 0;
325 : 68136 : char *mname = 0;
326 : : int narg;
327 : : size_t nt;
328 : 68136 : long l = ls->line;
329 : :
330 : : #ifdef LOW_MEM
331 : 68136 : 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 [ + - ][ + - ]: 136272 : while (!next_token(ls) && ls->ctok->type != NEWLINE) {
336 [ + + ][ + - ]: 136272 : if (ttMWS(ls->ctok->type)) continue;
[ - + ]
337 [ + - ]: 68136 : if (ls->ctok->type == NAME) mname = sdup(ls->ctok->name);
338 : 68136 : break;
339 : : }
340 [ - + ]: 68136 : if (mname == 0) {
341 : 0 : error(l, "missing macro name");
342 : 0 : return 1;
343 : : }
344 [ - + ]: 68136 : 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 [ - + ]: 68136 : 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 [ + - ]: 68136 : if (!redef) {
370 : 68136 : m = new_macro();
371 : 68136 : m->narg = -1;
372 : : #ifdef LOW_MEM
373 : : #define mval mv
374 : : #else
375 : : #define mval (m->val)
376 : : #endif
377 : : }
378 [ - + ]: 68136 : 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 [ - + ]: 68136 : 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 [ + - ][ + - ]: 68136 : if (!ttWHI(ls->ctok->type) && (ls->flags & WARN_STANDARD))
[ + - ][ - + ]
[ # # ]
484 : 0 : warning(ls->line, "identifier not followed by "
485 : : "whitespace in #define");
486 : 68136 : ls->flags |= READ_AGAIN;
487 : 68136 : narg = 0;
488 : : }
489 [ - + ]: 68136 : if (redef) nt = 0;
490 : :
491 : : /* now, we have the arguments. Let's get the macro contents. */
492 [ + - ][ - + ]: 68136 : 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 [ - + ]: 68136 : 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 [ - + ][ # # ]: 68136 : 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 [ - + ]: 68136 : 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 [ - + ]: 68136 : 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 : 68136 : m->cval.length = l;
648 [ - + ]: 68136 : if (l) m->cval.t = getmem(l);
649 [ - + ]: 68136 : 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 [ - + ]: 68136 : if (mval.nt) freemem(mval.t);
670 : : }
671 : : #endif
672 : 68136 : HTT_put(¯os, m, mname);
673 : 68136 : freemem(mname);
674 [ - + ]: 68136 : if (emit_defines) print_macro(m);
675 : 68136 : 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 : 68136 : 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 : 5978 : int define_macro(struct lexer_state *ls, char *def)
1679 : : {
1680 : 5978 : char *c = sdup(def), *d;
1681 : 5978 : int with_def = 0;
1682 : 5978 : int ret = 0;
1683 : :
1684 [ + + ][ + - ]: 23912 : for (d = c; *d && *d != '='; d ++);
1685 [ - + ]: 5978 : if (*d) {
1686 : 0 : *d = ' ';
1687 : 0 : with_def = 1;
1688 : : }
1689 [ - + ]: 5978 : 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 [ - + ]: 5978 : if (!*c) {
1712 : 0 : error(-1, "void macro name");
1713 : 0 : ret = 1;
1714 [ - + ]: 5978 : } 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 : 5978 : m = new_macro();
1732 : : #ifdef LOW_MEM
1733 : 5978 : m->cval.length = 3;
1734 : 5978 : m->cval.t = getmem(3);
1735 : 5978 : m->cval.t[0] = NUMBER;
1736 : 5978 : m->cval.t[1] = '1';
1737 : 5978 : 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 : 5978 : HTT_put(¯os, m, c);
1744 : : }
1745 : : }
1746 : 5978 : freemem(c);
1747 : 5978 : 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 : 68340 : int handle_ifndef(struct lexer_state *ls)
1859 : : {
1860 [ + - ]: 136680 : while (!next_token(ls)) {
1861 : 136680 : int tgd = 1;
1862 : :
1863 [ - + ]: 136680 : if (ls->ctok->type == NEWLINE) break;
1864 [ + + ][ + - ]: 136680 : if (ttMWS(ls->ctok->type)) continue;
[ - + ]
1865 [ + - ]: 68340 : if (ls->ctok->type == NAME) {
1866 : 68340 : int x = (HTT_get(¯os, ls->ctok->name) == 0);
1867 : :
1868 [ + - ][ - + ]: 68340 : 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 [ + + ]: 68340 : if (protect_detect.state == 1) {
1876 : 68137 : protect_detect.state = 2;
1877 : 68137 : protect_detect.macro = sdup(ls->ctok->name);
1878 : : }
1879 : 68340 : 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 : 68340 : return -1;
1893 : : }
1894 : :
1895 : : /*
1896 : : * erase the macro table.
1897 : : */
1898 : 11956 : void wipe_macros(void)
1899 : : {
1900 [ + + ]: 11956 : if (macros_init_done) HTT_kill(¯os);
1901 : 11956 : macros_init_done = 0;
1902 : 11956 : }
1903 : :
1904 : : /*
1905 : : * initialize the macro table
1906 : : */
1907 : 5978 : void init_macros(void)
1908 : : {
1909 : 5978 : wipe_macros();
1910 : 5978 : HTT_init(¯os, del_macro);
1911 : 5978 : macros_init_done = 1;
1912 [ + - ]: 5978 : if (!no_special_macros) add_special_macros();
1913 : 5978 : }
1914 : :
1915 : : /*
1916 : : * find a macro from its name
1917 : : */
1918 : 2465597 : struct macro *get_macro(char *name)
1919 : : {
1920 : 2465597 : return HTT_get(¯os, name);
1921 : : }
|