Mercurial > hg > index.cgi
annotate lwcc/preproc.c @ 299:856caf91ffaa ccdev
Added token list structure and switched some stuff to use it
Swithced to using a token list structure instead of manually fiddling
pointers throughout the macro expansion code. Also fixed up some problematic
things related to stringification and concatenation.
author | William Astle <lost@l-w.ca> |
---|---|
date | Sun, 15 Sep 2013 13:06:00 -0600 |
parents | 6112c67728ba |
children | 8d6c47395653 |
rev | line source |
---|---|
296 | 1 /* |
2 lwcc/preproc.c | |
3 | |
4 Copyright © 2013 William Astle | |
5 | |
6 This file is part of LWTOOLS. | |
7 | |
8 LWTOOLS is free software: you can redistribute it and/or modify it under the | |
9 terms of the GNU General Public License as published by the Free Software | |
10 Foundation, either version 3 of the License, or (at your option) any later | |
11 version. | |
12 | |
13 This program is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
16 more details. | |
17 | |
18 You should have received a copy of the GNU General Public License along with | |
19 this program. If not, see <http://www.gnu.org/licenses/>. | |
20 */ | |
21 | |
22 #include <string.h> | |
23 | |
24 #include <lw_alloc.h> | |
25 #include <lw_string.h> | |
26 | |
27 #include "cpp.h" | |
28 #include "strbuf.h" | |
29 #include "symbol.h" | |
30 #include "token.h" | |
31 | |
32 static int expand_macro(struct preproc_info *, char *); | |
33 static void process_directive(struct preproc_info *); | |
34 static long eval_expr(struct preproc_info *); | |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
35 extern struct token *preproc_lex_next_token(struct preproc_info *); |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
36 |
296 | 37 |
38 struct token *preproc_next_processed_token(struct preproc_info *pp) | |
39 { | |
40 struct token *ct; | |
41 | |
42 again: | |
43 ct = preproc_next_token(pp); | |
44 if (ct -> ttype == TOK_EOF) | |
45 return ct; | |
46 if (ct -> ttype == TOK_EOL) | |
47 pp -> ppeolseen = 1; | |
48 | |
49 if (ct -> ttype == TOK_HASH && pp -> eolseen == 1) | |
50 { | |
51 // preprocessor directive | |
52 process_directive(pp); | |
53 } | |
54 // if we're in a false section, don't return the token; keep scanning | |
55 if (pp -> skip_level) | |
56 goto again; | |
57 | |
58 if (ct -> ttype != TOK_WSPACE) | |
59 pp -> ppeolseen = 0; | |
60 | |
61 if (ct -> ttype == TOK_IDENT) | |
62 { | |
63 // possible macro expansion | |
64 if (expand_macro(pp, ct -> strval)) | |
65 goto again; | |
66 } | |
67 | |
68 return ct; | |
69 } | |
70 | |
71 static struct token *preproc_next_processed_token_nws(struct preproc_info *pp) | |
72 { | |
73 struct token *t; | |
74 | |
75 do | |
76 { | |
77 t = preproc_next_processed_token(pp); | |
78 } while (t -> ttype == TOK_WSPACE); | |
79 return t; | |
80 } | |
81 | |
82 static struct token *preproc_next_token_nws(struct preproc_info *pp) | |
83 { | |
84 struct token *t; | |
85 | |
86 do | |
87 { | |
88 t = preproc_next_token(pp); | |
89 } while (t -> ttype == TOK_WSPACE); | |
90 return t; | |
91 } | |
92 | |
93 static void skip_eol(struct preproc_info *pp) | |
94 { | |
95 struct token *t; | |
96 | |
97 if (pp -> curtok && pp -> curtok -> ttype == TOK_EOL) | |
98 return; | |
99 do | |
100 { | |
101 t = preproc_next_token(pp); | |
102 } while (t -> ttype != TOK_EOL); | |
103 } | |
104 | |
105 static void check_eol(struct preproc_info *pp) | |
106 { | |
107 struct token *t; | |
108 | |
109 t = preproc_next_token(pp); | |
110 if (t -> ttype != TOK_EOL) | |
111 preproc_throw_warning(pp, "Extra text after preprocessor directive"); | |
112 skip_eol(pp); | |
113 } | |
114 | |
115 static void dir_ifdef(struct preproc_info *pp) | |
116 { | |
117 struct token *ct; | |
118 | |
119 if (pp -> skip_level) | |
120 { | |
121 pp -> skip_level++; | |
122 skip_eol(pp); | |
123 return; | |
124 } | |
125 | |
126 do | |
127 { | |
128 ct = preproc_next_token(pp); | |
129 } while (ct -> ttype == TOK_WSPACE); | |
130 | |
131 if (ct -> ttype != TOK_IDENT) | |
132 { | |
133 preproc_throw_error(pp, "Bad #ifdef"); | |
134 skip_eol(pp); | |
135 } | |
136 | |
137 if (symtab_find(pp, ct -> strval) == NULL) | |
138 { | |
139 pp -> skip_level++; | |
140 } | |
141 else | |
142 { | |
143 pp -> found_level++; | |
144 } | |
145 check_eol(pp); | |
146 } | |
147 | |
148 static void dir_ifndef(struct preproc_info *pp) | |
149 { | |
150 struct token *ct; | |
151 | |
152 if (pp -> skip_level) | |
153 { | |
154 pp -> skip_level++; | |
155 skip_eol(pp); | |
156 return; | |
157 } | |
158 | |
159 do | |
160 { | |
161 ct = preproc_next_token(pp); | |
162 } while (ct -> ttype == TOK_WSPACE); | |
163 | |
164 if (ct -> ttype != TOK_IDENT) | |
165 { | |
166 preproc_throw_error(pp, "Bad #ifdef"); | |
167 skip_eol(pp); | |
168 } | |
169 | |
170 if (symtab_find(pp, ct -> strval) != NULL) | |
171 { | |
172 pp -> skip_level++; | |
173 } | |
174 else | |
175 { | |
176 pp -> found_level++; | |
177 } | |
178 check_eol(pp); | |
179 } | |
180 | |
181 static void dir_if(struct preproc_info *pp) | |
182 { | |
183 if (pp -> skip_level || !eval_expr(pp)) | |
184 pp -> skip_level++; | |
185 else | |
186 pp -> found_level++; | |
187 } | |
188 | |
189 static void dir_elif(struct preproc_info *pp) | |
190 { | |
191 if (pp -> skip_level == 0) | |
192 pp -> else_skip_level = pp -> found_level; | |
193 if (pp -> skip_level) | |
194 { | |
195 if (pp -> else_skip_level > pp -> found_level) | |
196 ; | |
197 else if (--(pp -> skip_level) != 0) | |
198 pp -> skip_level++; | |
199 else if (eval_expr(pp)) | |
200 pp -> found_level++; | |
201 else | |
202 pp -> skip_level++; | |
203 } | |
204 else if (pp -> found_level) | |
205 { | |
206 pp -> skip_level++; | |
207 pp -> found_level--; | |
208 } | |
209 else | |
210 preproc_throw_error(pp, "#elif in non-conditional section"); | |
211 } | |
212 | |
213 static void dir_else(struct preproc_info *pp) | |
214 { | |
215 if (pp -> skip_level) | |
216 { | |
217 if (pp -> else_skip_level > pp -> found_level) | |
218 ; | |
219 else if (--(pp -> skip_level) != 0) | |
220 pp -> skip_level++; | |
221 else | |
222 pp -> found_level++; | |
223 } | |
224 else if (pp -> found_level) | |
225 { | |
226 pp -> skip_level++; | |
227 pp -> found_level--; | |
228 } | |
229 else | |
230 { | |
231 preproc_throw_error(pp, "#else in non-conditional section"); | |
232 } | |
233 if (pp -> else_level == pp -> found_level + pp -> skip_level) | |
234 { | |
235 preproc_throw_error(pp, "Too many #else"); | |
236 } | |
237 pp -> else_level = pp -> found_level + pp -> skip_level; | |
238 check_eol(pp); | |
239 } | |
240 | |
241 static void dir_endif(struct preproc_info *pp) | |
242 { | |
243 if (pp -> skip_level) | |
244 pp -> skip_level--; | |
245 else if (pp -> found_level) | |
246 pp -> found_level--; | |
247 else | |
248 preproc_throw_error(pp, "#endif in non-conditional section"); | |
249 if (pp -> skip_level == 0) | |
250 pp -> else_skip_level = 0; | |
251 pp -> else_level = 0; | |
252 check_eol(pp); | |
253 } | |
254 | |
255 static void dir_define(struct preproc_info *pp) | |
256 { | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
257 struct token_list *tl = NULL; |
296 | 258 struct token *ct; |
259 int nargs = -1; | |
260 int vargs = 0; | |
261 char *mname = NULL; | |
262 | |
263 char **arglist = NULL; | |
264 | |
265 if (pp -> skip_level) | |
266 { | |
267 skip_eol(pp); | |
268 return; | |
269 } | |
270 | |
271 ct = preproc_next_token_nws(pp); | |
272 if (ct -> ttype != TOK_IDENT) | |
273 goto baddefine; | |
274 | |
275 mname = lw_strdup(ct -> strval); | |
276 ct = preproc_next_token(pp); | |
277 | |
278 if (ct -> ttype == TOK_WSPACE) | |
279 { | |
280 /* object like macro */ | |
281 } | |
282 else if (ct -> ttype == TOK_EOL) | |
283 { | |
284 /* object like macro - empty value */ | |
285 goto out; | |
286 } | |
287 else if (ct -> ttype == TOK_OPAREN) | |
288 { | |
289 /* function like macro - parse args */ | |
290 nargs = 0; | |
291 vargs = 0; | |
292 for (;;) | |
293 { | |
294 ct = preproc_next_token_nws(pp); | |
295 if (ct -> ttype == TOK_EOL) | |
296 { | |
297 goto baddefine; | |
298 } | |
299 if (ct -> ttype == TOK_CPAREN) | |
300 break; | |
301 | |
302 if (ct -> ttype == TOK_IDENT) | |
303 { | |
304 /* parameter name */ | |
305 nargs++; | |
306 /* record argument name */ | |
307 arglist = lw_realloc(arglist, sizeof(char *) * nargs); | |
308 arglist[nargs - 1] = lw_strdup(ct -> strval); | |
309 | |
310 /* check for end of args or comma */ | |
311 ct = preproc_next_token_nws(pp); | |
312 if (ct -> ttype == TOK_CPAREN) | |
313 break; | |
314 else if (ct -> ttype == TOK_COMMA) | |
315 continue; | |
316 else | |
317 goto baddefine; | |
318 } | |
319 else if (ct -> ttype == TOK_ELLIPSIS) | |
320 { | |
321 /* variadic macro */ | |
322 vargs = 1; | |
323 ct = preproc_next_token_nws(pp); | |
324 if (ct -> ttype != TOK_CPAREN) | |
325 goto baddefine; | |
326 break; | |
327 } | |
328 else | |
329 goto baddefine; | |
330 } | |
331 } | |
332 else | |
333 { | |
334 baddefine: | |
335 preproc_throw_error(pp, "bad #define"); | |
336 baddefine2: | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
337 token_list_destroy(tl); |
296 | 338 skip_eol(pp); |
339 lw_free(mname); | |
340 while (nargs > 0) | |
341 lw_free(arglist[--nargs]); | |
342 lw_free(arglist); | |
343 return; | |
344 } | |
345 | |
346 for (;;) | |
347 { | |
348 ct = preproc_next_token(pp); | |
349 if (ct -> ttype == TOK_EOL) | |
350 break; | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
351 token_list_append(tl, token_dup(ct)); |
296 | 352 } |
353 out: | |
354 if (strcmp(mname, "defined") == 0) | |
355 { | |
356 preproc_throw_warning(pp, "attempt to define 'defined' as a macro not allowed"); | |
357 goto baddefine2; | |
358 } | |
359 else if (symtab_find(pp, mname) != NULL) | |
360 { | |
361 /* need to do a token compare between the old value and the new value | |
362 to decide whether to complain */ | |
363 preproc_throw_warning(pp, "%s previous defined", mname); | |
364 symtab_undef(pp, mname); | |
365 } | |
366 symtab_define(pp, mname, tl, nargs, arglist, vargs); | |
367 lw_free(mname); | |
368 while (nargs > 0) | |
369 lw_free(arglist[--nargs]); | |
370 lw_free(arglist); | |
371 /* no need to check for EOL here */ | |
372 } | |
373 | |
374 static void dir_undef(struct preproc_info *pp) | |
375 { | |
376 struct token *ct; | |
377 if (pp -> skip_level) | |
378 { | |
379 skip_eol(pp); | |
380 return; | |
381 } | |
382 | |
383 do | |
384 { | |
385 ct = preproc_next_token(pp); | |
386 } while (ct -> ttype == TOK_WSPACE); | |
387 | |
388 if (ct -> ttype != TOK_IDENT) | |
389 { | |
390 preproc_throw_error(pp, "Bad #undef"); | |
391 skip_eol(pp); | |
392 } | |
393 | |
394 symtab_undef(pp, ct -> strval); | |
395 check_eol(pp); | |
396 } | |
397 | |
398 char *streol(struct preproc_info *pp) | |
399 { | |
400 struct strbuf *s; | |
401 struct token *ct; | |
402 int i; | |
403 | |
404 s = strbuf_new(); | |
405 do | |
406 { | |
407 ct = preproc_next_token(pp); | |
408 } while (ct -> ttype == TOK_WSPACE); | |
409 | |
410 while (ct -> ttype != TOK_EOL) | |
411 { | |
412 for (i = 0; ct -> strval[i]; i++) | |
413 strbuf_add(s, ct -> strval[i]); | |
414 ct = preproc_next_token(pp); | |
415 } | |
416 return strbuf_end(s); | |
417 } | |
418 | |
419 static void dir_error(struct preproc_info *pp) | |
420 { | |
421 char *s; | |
422 | |
423 if (pp -> skip_level) | |
424 { | |
425 skip_eol(pp); | |
426 return; | |
427 } | |
428 | |
429 s = streol(pp); | |
430 preproc_throw_error(pp, "%s", s); | |
431 lw_free(s); | |
432 } | |
433 | |
434 static void dir_warning(struct preproc_info *pp) | |
435 { | |
436 char *s; | |
437 | |
438 if (pp -> skip_level) | |
439 { | |
440 skip_eol(pp); | |
441 return; | |
442 } | |
443 | |
444 s = streol(pp); | |
445 preproc_throw_warning(pp, "%s", s); | |
446 lw_free(s); | |
447 } | |
448 | |
449 static void dir_include(struct preproc_info *pp) | |
450 { | |
451 } | |
452 | |
453 static void dir_line(struct preproc_info *pp) | |
454 { | |
455 } | |
456 | |
457 static void dir_pragma(struct preproc_info *pp) | |
458 { | |
459 if (pp -> skip_level) | |
460 { | |
461 skip_eol(pp); | |
462 return; | |
463 } | |
464 | |
465 preproc_throw_warning(pp, "Unsupported #pragma"); | |
466 skip_eol(pp); | |
467 } | |
468 | |
469 struct { char *name; void (*fn)(struct preproc_info *); } dirlist[] = | |
470 { | |
471 { "ifdef", dir_ifdef }, | |
472 { "ifndef", dir_ifndef }, | |
473 { "if", dir_if }, | |
474 { "else", dir_else }, | |
475 { "elif", dir_elif }, | |
476 { "endif", dir_endif }, | |
477 { "define", dir_define }, | |
478 { "undef", dir_undef }, | |
479 { "include", dir_include }, | |
480 { "error", dir_error }, | |
481 { "warning", dir_warning }, | |
482 { "line", dir_line }, | |
483 { "pragma", dir_pragma }, | |
484 { NULL, NULL } | |
485 }; | |
486 | |
487 static void process_directive(struct preproc_info *pp) | |
488 { | |
489 struct token *ct; | |
490 int i; | |
491 | |
492 do | |
493 { | |
494 ct = preproc_next_token(pp); | |
495 } while (ct -> ttype == TOK_WSPACE); | |
496 | |
497 // NULL directive | |
498 if (ct -> ttype == TOK_EOL) | |
499 return; | |
500 | |
501 if (ct -> ttype != TOK_IDENT) | |
502 goto baddir; | |
503 | |
504 for (i = 0; dirlist[i].name; i++) | |
505 { | |
506 if (strcmp(dirlist[i].name, ct -> strval) == 0) | |
507 { | |
508 (*(dirlist[i].fn))(pp); | |
509 return; | |
510 } | |
511 } | |
512 baddir: | |
513 preproc_throw_error(pp, "Bad preprocessor directive"); | |
514 while (ct -> ttype != TOK_EOL) | |
515 ct = preproc_next_token(pp); | |
516 return; | |
517 } | |
518 | |
519 /* | |
520 Evaluate a preprocessor expression | |
521 */ | |
522 | |
523 /* same as skip_eol() but the EOL token is not consumed */ | |
524 static void skip_eoe(struct preproc_info *pp) | |
525 { | |
526 skip_eol(pp); | |
527 preproc_unget_token(pp, pp -> curtok); | |
528 } | |
529 | |
530 static long eval_expr_real(struct preproc_info *, int); | |
531 static long preproc_numval(struct token *); | |
532 | |
533 static long eval_term_real(struct preproc_info *pp) | |
534 { | |
535 long tval = 0; | |
536 struct token *ct; | |
537 | |
538 eval_next: | |
539 ct = preproc_next_processed_token_nws(pp); | |
540 if (ct -> ttype == TOK_EOL) | |
541 { | |
542 preproc_throw_error(pp, "Bad expression"); | |
543 return 0; | |
544 } | |
545 | |
546 switch (ct -> ttype) | |
547 { | |
548 case TOK_OPAREN: | |
549 tval = eval_expr_real(pp, 0); | |
550 ct = preproc_next_processed_token_nws(pp); | |
551 if (ct -> ttype != ')') | |
552 { | |
553 preproc_throw_error(pp, "Unbalanced () in expression"); | |
554 skip_eoe(pp); | |
555 return 0; | |
556 } | |
557 return tval; | |
558 | |
559 case TOK_ADD: // unary + | |
560 goto eval_next; | |
561 | |
562 case TOK_SUB: // unary - | |
563 tval = eval_expr_real(pp, 200); | |
564 return -tval; | |
565 | |
566 /* NOTE: we should only get "TOK_IDENT" from an undefined macro */ | |
567 case TOK_IDENT: // some sort of function, symbol, etc. | |
568 if (strcmp(ct -> strval, "defined")) | |
569 { | |
570 /* the defined operator */ | |
571 /* any number in the "defined" bit will be | |
572 treated as a defined symbol, even zero */ | |
573 ct = preproc_next_token_nws(pp); | |
574 if (ct -> ttype == TOK_OPAREN) | |
575 { | |
576 ct = preproc_next_token_nws(pp); | |
577 if (ct -> ttype != TOK_IDENT) | |
578 { | |
579 preproc_throw_error(pp, "Bad expression"); | |
580 skip_eoe(pp); | |
581 return 0; | |
582 } | |
583 if (symtab_find(pp, ct -> strval) == NULL) | |
584 tval = 0; | |
585 else | |
586 tval = 1; | |
587 ct = preproc_next_token_nws(pp); | |
588 if (ct -> ttype != TOK_CPAREN) | |
589 { | |
590 preproc_throw_error(pp, "Bad expression"); | |
591 skip_eoe(pp); | |
592 return 0; | |
593 } | |
594 return tval; | |
595 } | |
596 else if (ct -> ttype == TOK_IDENT) | |
597 { | |
598 return (symtab_find(pp, ct -> strval) != NULL) ? 1 : 0; | |
599 } | |
600 preproc_throw_error(pp, "Bad expression"); | |
601 skip_eoe(pp); | |
602 return 0; | |
603 } | |
604 /* unknown identifier - it's zero */ | |
605 return 0; | |
606 | |
607 /* numbers */ | |
608 case TOK_NUMBER: | |
609 return preproc_numval(ct); | |
610 | |
611 default: | |
612 preproc_throw_error(pp, "Bad expression"); | |
613 skip_eoe(pp); | |
614 return 0; | |
615 } | |
616 return 0; | |
617 } | |
618 | |
619 static long eval_expr_real(struct preproc_info *pp, int p) | |
620 { | |
621 static const struct operinfo | |
622 { | |
623 int tok; | |
624 int prec; | |
625 } operators[] = | |
626 { | |
627 { TOK_ADD, 100 }, | |
628 { TOK_SUB, 100 }, | |
629 { TOK_STAR, 150 }, | |
630 { TOK_DIV, 150 }, | |
631 { TOK_MOD, 150 }, | |
632 { TOK_LT, 75 }, | |
633 { TOK_LE, 75 }, | |
634 { TOK_GT, 75 }, | |
635 { TOK_GE, 75 }, | |
636 { TOK_EQ, 70 }, | |
637 { TOK_NE, 70 }, | |
638 { TOK_BAND, 30 }, | |
639 { TOK_BOR, 25 }, | |
640 { TOK_NONE, 0 } | |
641 }; | |
642 | |
643 int op; | |
644 long term1, term2, term3; | |
645 struct token *ct; | |
646 | |
647 term1 = eval_term_real(pp); | |
648 eval_next: | |
649 ct = preproc_next_processed_token_nws(pp); | |
650 for (op = 0; operators[op].tok != TOK_NONE; op++) | |
651 { | |
652 if (operators[op].tok == ct -> ttype) | |
653 break; | |
654 } | |
655 /* if it isn't a recognized operator, assume end of expression */ | |
656 if (operators[op].tok == TOK_NONE) | |
657 { | |
658 preproc_unget_token(pp, ct); | |
659 return term1; | |
660 } | |
661 | |
662 /* if new operation is not higher than the current precedence, let the previous op finish */ | |
663 if (operators[op].prec <= p) | |
664 return term1; | |
665 | |
666 /* get the second term */ | |
667 term2 = eval_expr_real(pp, operators[op].prec); | |
668 | |
669 switch (operators[op].tok) | |
670 { | |
671 case TOK_ADD: | |
672 term3 = term1 + term2; | |
673 break; | |
674 | |
675 case TOK_SUB: | |
676 term3 = term1 - term2; | |
677 break; | |
678 | |
679 case TOK_STAR: | |
680 term3 = term1 * term2; | |
681 break; | |
682 | |
683 case TOK_DIV: | |
684 if (!term2) | |
685 { | |
686 preproc_throw_warning(pp, "Division by zero"); | |
687 term3 = 0; | |
688 break; | |
689 } | |
690 term3 = term1 / term2; | |
691 break; | |
692 | |
693 case TOK_MOD: | |
694 if (!term2) | |
695 { | |
696 preproc_throw_warning(pp, "Division by zero"); | |
697 term3 = 0; | |
698 break; | |
699 } | |
700 term3 = term1 % term2; | |
701 break; | |
702 | |
703 case TOK_BAND: | |
704 term3 = (term1 && term2); | |
705 break; | |
706 | |
707 case TOK_BOR: | |
708 term3 = (term1 || term2); | |
709 break; | |
710 | |
711 case TOK_EQ: | |
712 term3 = (term1 == term2); | |
713 break; | |
714 | |
715 case TOK_NE: | |
716 term3 = (term1 != term2); | |
717 break; | |
718 | |
719 case TOK_GT: | |
720 term3 = (term1 > term2); | |
721 break; | |
722 | |
723 case TOK_GE: | |
724 term3 = (term1 >= term2); | |
725 break; | |
726 | |
727 case TOK_LT: | |
728 term3 = (term1 < term2); | |
729 break; | |
730 | |
731 case TOK_LE: | |
732 term3 = (term1 <= term2); | |
733 break; | |
734 | |
735 default: | |
736 term3 = 0; | |
737 break; | |
738 } | |
739 term1 = term3; | |
740 goto eval_next; | |
741 } | |
742 | |
743 static long eval_expr(struct preproc_info *pp) | |
744 { | |
745 long rv; | |
746 | |
747 rv = eval_expr_real(pp, 0); | |
748 if (pp -> curtok -> ttype != TOK_EOL) | |
749 { | |
750 preproc_throw_error(pp, "Bad expression"); | |
751 skip_eol(pp); | |
752 } | |
753 return rv; | |
754 } | |
755 | |
756 /* convert a numeric string to a number */ | |
757 long preproc_numval(struct token *t) | |
758 { | |
759 return 0; | |
760 } | |
761 | |
762 /* | |
763 Below here is the logic for expanding a macro | |
764 */ | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
765 static char *stringify(struct token_list *tli) |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
766 { |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
767 struct strbuf *s; |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
768 int ws = 0; |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
769 struct token *tl = tli -> head; |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
770 |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
771 s = strbuf_new(); |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
772 strbuf_add(s, '"'); |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
773 |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
774 while (tl && tl -> ttype == TOK_WSPACE) |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
775 tl = tl -> next; |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
776 |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
777 for (; tl; tl = tl -> next) |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
778 { |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
779 if (tl -> ttype == TOK_WSPACE) |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
780 { |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
781 ws = 1; |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
782 continue; |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
783 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
784 if (ws) |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
785 { |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
786 strbuf_add(s, ' '); |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
787 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
788 for (ws = 0; tl -> strval[ws]; ws++) |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
789 { |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
790 if (tl -> ttype == TOK_STRING || tl -> ttype == TOK_CHR_LIT) |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
791 { |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
792 if (tl -> strval[ws] == '"' || tl -> strval[ws] == '\\') |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
793 strbuf_add(s, '\\'); |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
794 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
795 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
796 ws = 0; |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
797 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
798 |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
799 strbuf_add(s, '"'); |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
800 return strbuf_end(s); |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
801 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
802 |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
803 static int macro_arg(struct symtab_e *s, char *str) |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
804 { |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
805 int i; |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
806 if (strcmp(str, "__VA_ARGS__") == 0) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
807 i = s -> nargs; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
808 else |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
809 for (i = 0; i < s -> nargs; i++) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
810 if (strcmp(s -> params[i], str) == 0) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
811 break; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
812 if (i == s -> nargs) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
813 if (s -> vargs == 0) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
814 return -1; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
815 return i; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
816 } |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
817 |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
818 /* return list to tokens as a result of ## expansion */ |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
819 static struct token_list *paste_tokens(struct preproc_info *pp, struct symtab_e *s, struct token_list **arglist, struct token *t1, struct token *t2) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
820 { |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
821 struct token_list *left; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
822 struct token_list *right; |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
823 char *tstr; |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
824 struct token *ttok; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
825 int i; |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
826 |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
827 if (t1 -> ttype == TOK_IDENT) |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
828 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
829 i = macro_arg(s, t1 -> strval); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
830 if (i == -1) |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
831 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
832 left = token_list_create(); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
833 token_list_append(left, token_dup(t1)); |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
834 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
835 else |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
836 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
837 left = token_list_dup(arglist[i]); |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
838 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
839 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
840 else |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
841 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
842 left = token_list_create(); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
843 token_list_append(left, token_dup(t1)); |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
844 } |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
845 // munch trailing white space |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
846 while (left -> tail && left -> tail -> ttype == TOK_WSPACE) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
847 { |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
848 token_list_remove(left -> tail); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
849 } |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
850 |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
851 if (t2 -> ttype == TOK_IDENT) |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
852 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
853 i = macro_arg(s, t2 -> strval); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
854 if (i == -1) |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
855 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
856 right = token_list_create(); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
857 token_list_append(right, token_dup(t2)); |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
858 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
859 else |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
860 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
861 right = token_list_dup(arglist[i]); |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
862 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
863 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
864 else |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
865 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
866 right = token_list_create(); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
867 token_list_append(right, token_dup(t2)); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
868 } |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
869 // munch leading white space |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
870 while (right -> head && right -> head -> ttype == TOK_WSPACE) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
871 { |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
872 token_list_remove(right -> head); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
873 } |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
874 |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
875 // nothing to append at all |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
876 if (left -> head != NULL && right -> head == NULL) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
877 { |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
878 // right arg is empty - use left |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
879 token_list_destroy(right); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
880 return left; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
881 } |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
882 if (left -> head == NULL && right -> head != NULL) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
883 { |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
884 // left arg is empty, use right |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
885 token_list_destroy(left); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
886 return right; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
887 } |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
888 if (left -> head == NULL && right -> head == NULL) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
889 { |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
890 // both empty, use left |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
891 token_list_destroy(right); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
892 return left; |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
893 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
894 |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
895 // both non-empty - past left tail with right head |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
896 // then past the right list onto the left |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
897 tstr = lw_alloc(strlen(left -> tail -> strval) + strlen(right -> head -> strval) + 1); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
898 strcpy(tstr, left -> tail -> strval); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
899 strcat(tstr, right -> head -> strval); |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
900 |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
901 pp -> lexstr = tstr; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
902 pp -> lexstrloc = 0; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
903 |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
904 ttok = preproc_lex_next_token(pp); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
905 if (ttok -> ttype != TOK_ERROR && pp -> lexstr[pp -> lexstrloc] == 0) |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
906 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
907 // we have a new token here |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
908 token_list_remove(left -> tail); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
909 token_list_remove(right -> head); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
910 token_list_append(left, token_dup(ttok)); |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
911 } |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
912 lw_free(tstr); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
913 pp -> lexstr = NULL; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
914 pp -> lexstrloc = 0; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
915 for (ttok = right -> head; ttok; ttok = ttok -> next) |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
916 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
917 token_list_append(left, token_dup(ttok)); |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
918 } |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
919 token_list_destroy(right); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
920 return left; |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
921 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
922 |
296 | 923 static int expand_macro(struct preproc_info *pp, char *mname) |
924 { | |
925 struct symtab_e *s; | |
926 struct token *t, *t2, *t3; | |
927 int nargs = 0; | |
928 struct expand_e *e; | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
929 struct token_list **exparglist = NULL; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
930 struct token_list **arglist = NULL; |
296 | 931 int i; |
297
310df72c641d
Handle () surrounding macro args on invocation
William Astle <lost@l-w.ca>
parents:
296
diff
changeset
|
932 int pcount; |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
933 char *tstr; |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
934 struct token_list *expand_list; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
935 int repl; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
936 struct token_list *rtl; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
937 |
296 | 938 s = symtab_find(pp, mname); |
939 if (!s) | |
940 return 0; | |
941 | |
942 for (e = pp -> expand_list; e; e = e -> next) | |
943 { | |
944 /* don't expand if we're already expanding the same macro */ | |
945 if (e -> s == s) | |
946 return 0; | |
947 } | |
948 | |
949 if (s -> nargs == -1) | |
950 { | |
951 /* short circuit NULL expansion */ | |
952 if (s -> tl == NULL) | |
953 return 1; | |
954 | |
955 goto expandmacro; | |
956 } | |
957 | |
958 // look for opening paren after optional whitespace | |
959 t2 = NULL; | |
960 t = NULL; | |
961 for (;;) | |
962 { | |
963 t = preproc_next_token(pp); | |
964 if (t -> ttype != TOK_WSPACE && t -> ttype != TOK_EOL) | |
965 break; | |
966 t -> next = t2; | |
967 t2 = t2; | |
968 } | |
969 if (t -> ttype != TOK_OPAREN) | |
970 { | |
971 // not a function-like invocation | |
972 while (t2) | |
973 { | |
974 t = t2 -> next; | |
975 preproc_unget_token(pp, t2); | |
976 t2 = t; | |
977 } | |
978 return 0; | |
979 } | |
980 | |
981 // parse parameters here | |
982 t = preproc_next_token_nws(pp); | |
983 nargs = 1; | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
984 arglist = lw_alloc(sizeof(struct token_list *)); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
985 arglist[0] = token_list_create(); |
296 | 986 t2 = NULL; |
987 | |
988 while (t -> ttype != TOK_CPAREN) | |
989 { | |
297
310df72c641d
Handle () surrounding macro args on invocation
William Astle <lost@l-w.ca>
parents:
296
diff
changeset
|
990 pcount = 0; |
296 | 991 if (t -> ttype == TOK_EOF) |
992 { | |
993 preproc_throw_error(pp, "Unexpected EOF in macro call"); | |
994 break; | |
995 } | |
996 if (t -> ttype == TOK_EOL) | |
997 continue; | |
297
310df72c641d
Handle () surrounding macro args on invocation
William Astle <lost@l-w.ca>
parents:
296
diff
changeset
|
998 if (t -> ttype == TOK_OPAREN) |
310df72c641d
Handle () surrounding macro args on invocation
William Astle <lost@l-w.ca>
parents:
296
diff
changeset
|
999 pcount++; |
310df72c641d
Handle () surrounding macro args on invocation
William Astle <lost@l-w.ca>
parents:
296
diff
changeset
|
1000 else if (t -> ttype == TOK_CPAREN && pcount) |
310df72c641d
Handle () surrounding macro args on invocation
William Astle <lost@l-w.ca>
parents:
296
diff
changeset
|
1001 pcount--; |
310df72c641d
Handle () surrounding macro args on invocation
William Astle <lost@l-w.ca>
parents:
296
diff
changeset
|
1002 if (t -> ttype == TOK_COMMA && pcount == 0) |
296 | 1003 { |
1004 if (!(s -> vargs) || (nargs > s -> nargs)) | |
1005 { | |
1006 nargs++; | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1007 arglist = lw_realloc(arglist, sizeof(struct token_list *) * nargs); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1008 arglist[nargs - 1] = token_list_create(); |
296 | 1009 t2 = NULL; |
1010 continue; | |
1011 } | |
1012 } | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1013 token_list_append(arglist[nargs - 1], token_dup(t)); |
296 | 1014 } |
1015 | |
1016 if (s -> vargs) | |
1017 { | |
1018 if (nargs <= s -> nargs) | |
1019 { | |
1020 preproc_throw_error(pp, "Wrong number of arguments (%d) for variadic macro %s which takes %d arguments", nargs, mname, s -> nargs); | |
1021 } | |
1022 } | |
1023 else | |
1024 { | |
1025 if (s -> nargs != nargs && !(s -> nargs == 0 && nargs == 1 && arglist[nargs - 1])) | |
1026 { | |
1027 preproc_throw_error(pp, "Wrong number of arguments (%d) for macro %s which takes %d arguments", nargs, mname, s -> nargs); | |
1028 } | |
1029 } | |
1030 | |
1031 /* now calculate the pre-expansions of the arguments */ | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1032 exparglist = lw_alloc(nargs * sizeof(struct token_list *)); |
296 | 1033 for (i = 0; i < nargs; i++) |
1034 { | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1035 exparglist[i] = token_list_create(); |
296 | 1036 // NOTE: do nothing if empty argument |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1037 if (arglist[i] == NULL || arglist[i] -> head == NULL) |
296 | 1038 continue; |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1039 pp -> sourcelist = arglist[i]->head; |
296 | 1040 for (;;) |
1041 { | |
1042 t = preproc_next_processed_token(pp); | |
1043 if (t -> ttype == TOK_EOF) | |
1044 break; | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1045 token_list_append(exparglist[i], token_dup(t)); |
296 | 1046 } |
1047 } | |
1048 | |
1049 expandmacro: | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1050 expand_list = token_list_dup(s -> tl); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1051 |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1052 // scan for stringification and handle it |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1053 repl = 0; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1054 while (repl == 0) |
296 | 1055 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1056 for (t = expand_list -> head; t; t = t -> next) |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1057 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1058 if (t -> ttype == TOK_HASH && t -> next && t -> next -> ttype == TOK_IDENT) |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1059 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1060 i = macro_arg(s, t -> next -> strval); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1061 if (i != -1) |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1062 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1063 repl = 1; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1064 tstr = stringify(arglist[i]); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1065 token_list_remove(t -> next); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1066 token_list_insert(expand_list, t, token_create(TOK_STRING, tstr, t -> lineno, t -> column, t -> fn)); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1067 token_list_remove(t); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1068 lw_free(tstr); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1069 break; |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1070 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1071 } |
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1072 } |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1073 } |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1074 |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1075 |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1076 // scan for concatenation and handle it |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1077 |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1078 for (t = expand_list -> head; t; t = t -> next) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1079 { |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1080 if (t -> ttype == TOK_DBLHASH) |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1081 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1082 // have a concatenation operator here |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1083 for (t2 = t -> prev; t2; t2 = t2 -> prev) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1084 { |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1085 if (t2 -> ttype != TOK_WSPACE) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1086 break; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1087 } |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1088 for (t3 = t -> next; t3; t3 = t3 -> next); |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1089 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1090 if (t3 -> ttype != TOK_WSPACE) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1091 break; |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1092 } |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1093 // if no non-whitespace before or after, ignore it |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1094 if (!t2 || !t3) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1095 continue; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1096 // eat the whitespace before and after |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1097 while (t -> prev != t2) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1098 token_list_remove(t -> prev); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1099 while (t -> next != t3) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1100 token_list_remove(t -> next); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1101 // now paste t -> prev with t -> next and replace t with the result |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1102 // continue scanning for ## at t -> next -> next |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1103 t3 = t -> next -> next; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1104 |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1105 rtl = paste_tokens(pp, s, arglist, t -> prev, t -> next); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1106 token_list_remove(t -> next); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1107 token_list_remove(t -> prev); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1108 t2 = t -> prev; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1109 token_list_remove(t); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1110 for (t = rtl -> head; t; t = t -> next) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1111 { |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1112 token_list_insert(expand_list, t2, token_dup(t)); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1113 } |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1114 t = t3 -> prev; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1115 token_list_destroy(rtl); |
298
6112c67728ba
Add stringification and token concatenation
William Astle <lost@l-w.ca>
parents:
297
diff
changeset
|
1116 } |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1117 } |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1118 |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1119 // now scan for arguments and expand them |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1120 for (t = expand_list -> head; t; t = t -> next) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1121 { |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1122 again: |
296 | 1123 if (t -> ttype == TOK_IDENT) |
1124 { | |
1125 /* identifiers might need expansion to arguments */ | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1126 i = macro_arg(s, t -> strval); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1127 if (i != -1) |
296 | 1128 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1129 t3 = t -> next; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1130 for (t2 = exparglist[i] -> tail; t2; t2 = t2 -> prev) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1131 token_list_insert(expand_list, t, token_dup(t2)); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1132 token_list_remove(t); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1133 t = t3; |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1134 goto again; |
296 | 1135 } |
1136 } | |
1137 } | |
1138 | |
1139 /* put the new expansion in front of the input, if relevant; if we | |
1140 expanded to nothing, no need to create an expansion record or | |
1141 put anything into the input queue */ | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1142 if (expand_list -> head) |
296 | 1143 { |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1144 token_list_append(expand_list, token_create(TOK_ENDEXPAND, "", -1, -1, "")); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1145 |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1146 // move the expanded list into the token queue |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1147 for (t = expand_list -> tail; t; t = t -> prev) |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1148 preproc_unget_token(pp, token_dup(t)); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1149 |
296 | 1150 /* set up expansion record */ |
1151 e = lw_alloc(sizeof(struct expand_e)); | |
1152 e -> next = pp -> expand_list; | |
1153 pp -> expand_list = e; | |
1154 e -> s = s; | |
1155 } | |
1156 | |
1157 /* now clean up */ | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1158 token_list_destroy(expand_list); |
296 | 1159 for (i = 0; i < nargs; i++) |
1160 { | |
299
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1161 token_list_destroy(arglist[i]); |
856caf91ffaa
Added token list structure and switched some stuff to use it
William Astle <lost@l-w.ca>
parents:
298
diff
changeset
|
1162 token_list_destroy(exparglist[i]); |
296 | 1163 } |
1164 lw_free(arglist); | |
1165 lw_free(exparglist); | |
1166 | |
1167 return 1; | |
1168 } |