comparison lwcc/preproc.c @ 296:83fcc1ed6ad6 ccdev

Checkpoint lwcc development Initial untested version of the preprocessor with macro expansion but without file inclusion.
author William Astle <lost@l-w.ca>
date Sat, 14 Sep 2013 20:04:38 -0600
parents
children 310df72c641d
comparison
equal deleted inserted replaced
295:4b17780f2777 296:83fcc1ed6ad6
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 *);
35
36 struct token *preproc_next_processed_token(struct preproc_info *pp)
37 {
38 struct token *ct;
39
40 again:
41 ct = preproc_next_token(pp);
42 if (ct -> ttype == TOK_EOF)
43 return ct;
44 if (ct -> ttype == TOK_EOL)
45 pp -> ppeolseen = 1;
46
47 if (ct -> ttype == TOK_HASH && pp -> eolseen == 1)
48 {
49 // preprocessor directive
50 process_directive(pp);
51 }
52 // if we're in a false section, don't return the token; keep scanning
53 if (pp -> skip_level)
54 goto again;
55
56 if (ct -> ttype != TOK_WSPACE)
57 pp -> ppeolseen = 0;
58
59 if (ct -> ttype == TOK_IDENT)
60 {
61 // possible macro expansion
62 if (expand_macro(pp, ct -> strval))
63 goto again;
64 }
65
66 return ct;
67 }
68
69 static struct token *preproc_next_processed_token_nws(struct preproc_info *pp)
70 {
71 struct token *t;
72
73 do
74 {
75 t = preproc_next_processed_token(pp);
76 } while (t -> ttype == TOK_WSPACE);
77 return t;
78 }
79
80 static struct token *preproc_next_token_nws(struct preproc_info *pp)
81 {
82 struct token *t;
83
84 do
85 {
86 t = preproc_next_token(pp);
87 } while (t -> ttype == TOK_WSPACE);
88 return t;
89 }
90
91 static void skip_eol(struct preproc_info *pp)
92 {
93 struct token *t;
94
95 if (pp -> curtok && pp -> curtok -> ttype == TOK_EOL)
96 return;
97 do
98 {
99 t = preproc_next_token(pp);
100 } while (t -> ttype != TOK_EOL);
101 }
102
103 static void check_eol(struct preproc_info *pp)
104 {
105 struct token *t;
106
107 t = preproc_next_token(pp);
108 if (t -> ttype != TOK_EOL)
109 preproc_throw_warning(pp, "Extra text after preprocessor directive");
110 skip_eol(pp);
111 }
112
113 static void dir_ifdef(struct preproc_info *pp)
114 {
115 struct token *ct;
116
117 if (pp -> skip_level)
118 {
119 pp -> skip_level++;
120 skip_eol(pp);
121 return;
122 }
123
124 do
125 {
126 ct = preproc_next_token(pp);
127 } while (ct -> ttype == TOK_WSPACE);
128
129 if (ct -> ttype != TOK_IDENT)
130 {
131 preproc_throw_error(pp, "Bad #ifdef");
132 skip_eol(pp);
133 }
134
135 if (symtab_find(pp, ct -> strval) == NULL)
136 {
137 pp -> skip_level++;
138 }
139 else
140 {
141 pp -> found_level++;
142 }
143 check_eol(pp);
144 }
145
146 static void dir_ifndef(struct preproc_info *pp)
147 {
148 struct token *ct;
149
150 if (pp -> skip_level)
151 {
152 pp -> skip_level++;
153 skip_eol(pp);
154 return;
155 }
156
157 do
158 {
159 ct = preproc_next_token(pp);
160 } while (ct -> ttype == TOK_WSPACE);
161
162 if (ct -> ttype != TOK_IDENT)
163 {
164 preproc_throw_error(pp, "Bad #ifdef");
165 skip_eol(pp);
166 }
167
168 if (symtab_find(pp, ct -> strval) != NULL)
169 {
170 pp -> skip_level++;
171 }
172 else
173 {
174 pp -> found_level++;
175 }
176 check_eol(pp);
177 }
178
179 static void dir_if(struct preproc_info *pp)
180 {
181 if (pp -> skip_level || !eval_expr(pp))
182 pp -> skip_level++;
183 else
184 pp -> found_level++;
185 }
186
187 static void dir_elif(struct preproc_info *pp)
188 {
189 if (pp -> skip_level == 0)
190 pp -> else_skip_level = pp -> found_level;
191 if (pp -> skip_level)
192 {
193 if (pp -> else_skip_level > pp -> found_level)
194 ;
195 else if (--(pp -> skip_level) != 0)
196 pp -> skip_level++;
197 else if (eval_expr(pp))
198 pp -> found_level++;
199 else
200 pp -> skip_level++;
201 }
202 else if (pp -> found_level)
203 {
204 pp -> skip_level++;
205 pp -> found_level--;
206 }
207 else
208 preproc_throw_error(pp, "#elif in non-conditional section");
209 }
210
211 static void dir_else(struct preproc_info *pp)
212 {
213 if (pp -> skip_level)
214 {
215 if (pp -> else_skip_level > pp -> found_level)
216 ;
217 else if (--(pp -> skip_level) != 0)
218 pp -> skip_level++;
219 else
220 pp -> found_level++;
221 }
222 else if (pp -> found_level)
223 {
224 pp -> skip_level++;
225 pp -> found_level--;
226 }
227 else
228 {
229 preproc_throw_error(pp, "#else in non-conditional section");
230 }
231 if (pp -> else_level == pp -> found_level + pp -> skip_level)
232 {
233 preproc_throw_error(pp, "Too many #else");
234 }
235 pp -> else_level = pp -> found_level + pp -> skip_level;
236 check_eol(pp);
237 }
238
239 static void dir_endif(struct preproc_info *pp)
240 {
241 if (pp -> skip_level)
242 pp -> skip_level--;
243 else if (pp -> found_level)
244 pp -> found_level--;
245 else
246 preproc_throw_error(pp, "#endif in non-conditional section");
247 if (pp -> skip_level == 0)
248 pp -> else_skip_level = 0;
249 pp -> else_level = 0;
250 check_eol(pp);
251 }
252
253 static void dir_define(struct preproc_info *pp)
254 {
255 struct token *tl = NULL;
256 struct token *ttl;
257 struct token *ct;
258 int nargs = -1;
259 int vargs = 0;
260 char *mname = NULL;
261
262 char **arglist = NULL;
263
264 if (pp -> skip_level)
265 {
266 skip_eol(pp);
267 return;
268 }
269
270 ct = preproc_next_token_nws(pp);
271 if (ct -> ttype != TOK_IDENT)
272 goto baddefine;
273
274 mname = lw_strdup(ct -> strval);
275 ct = preproc_next_token(pp);
276
277 if (ct -> ttype == TOK_WSPACE)
278 {
279 /* object like macro */
280 }
281 else if (ct -> ttype == TOK_EOL)
282 {
283 /* object like macro - empty value */
284 goto out;
285 }
286 else if (ct -> ttype == TOK_OPAREN)
287 {
288 /* function like macro - parse args */
289 nargs = 0;
290 vargs = 0;
291 for (;;)
292 {
293 ct = preproc_next_token_nws(pp);
294 if (ct -> ttype == TOK_EOL)
295 {
296 goto baddefine;
297 }
298 if (ct -> ttype == TOK_CPAREN)
299 break;
300
301 if (ct -> ttype == TOK_IDENT)
302 {
303 /* parameter name */
304 nargs++;
305 /* record argument name */
306 arglist = lw_realloc(arglist, sizeof(char *) * nargs);
307 arglist[nargs - 1] = lw_strdup(ct -> strval);
308
309 /* check for end of args or comma */
310 ct = preproc_next_token_nws(pp);
311 if (ct -> ttype == TOK_CPAREN)
312 break;
313 else if (ct -> ttype == TOK_COMMA)
314 continue;
315 else
316 goto baddefine;
317 }
318 else if (ct -> ttype == TOK_ELLIPSIS)
319 {
320 /* variadic macro */
321 vargs = 1;
322 ct = preproc_next_token_nws(pp);
323 if (ct -> ttype != TOK_CPAREN)
324 goto baddefine;
325 break;
326 }
327 else
328 goto baddefine;
329 }
330 }
331 else
332 {
333 baddefine:
334 preproc_throw_error(pp, "bad #define");
335 baddefine2:
336 skip_eol(pp);
337 lw_free(mname);
338 while (nargs > 0)
339 lw_free(arglist[--nargs]);
340 lw_free(arglist);
341 return;
342 }
343
344 for (;;)
345 {
346 ct = preproc_next_token(pp);
347 if (ct -> ttype == TOK_EOL)
348 break;
349 if (!tl)
350 tl = ct;
351 else
352 ttl -> next = ct;
353 ttl = ct;
354 pp -> curtok = NULL; // tell *_next_token* not to clobber token
355 }
356 out:
357 if (strcmp(mname, "defined") == 0)
358 {
359 preproc_throw_warning(pp, "attempt to define 'defined' as a macro not allowed");
360 goto baddefine2;
361 }
362 else if (symtab_find(pp, mname) != NULL)
363 {
364 /* need to do a token compare between the old value and the new value
365 to decide whether to complain */
366 preproc_throw_warning(pp, "%s previous defined", mname);
367 symtab_undef(pp, mname);
368 }
369 symtab_define(pp, mname, tl, nargs, arglist, vargs);
370 lw_free(mname);
371 while (nargs > 0)
372 lw_free(arglist[--nargs]);
373 lw_free(arglist);
374 /* no need to check for EOL here */
375 }
376
377 static void dir_undef(struct preproc_info *pp)
378 {
379 struct token *ct;
380 if (pp -> skip_level)
381 {
382 skip_eol(pp);
383 return;
384 }
385
386 do
387 {
388 ct = preproc_next_token(pp);
389 } while (ct -> ttype == TOK_WSPACE);
390
391 if (ct -> ttype != TOK_IDENT)
392 {
393 preproc_throw_error(pp, "Bad #undef");
394 skip_eol(pp);
395 }
396
397 symtab_undef(pp, ct -> strval);
398 check_eol(pp);
399 }
400
401 char *streol(struct preproc_info *pp)
402 {
403 struct strbuf *s;
404 struct token *ct;
405 int i;
406
407 s = strbuf_new();
408 do
409 {
410 ct = preproc_next_token(pp);
411 } while (ct -> ttype == TOK_WSPACE);
412
413 while (ct -> ttype != TOK_EOL)
414 {
415 for (i = 0; ct -> strval[i]; i++)
416 strbuf_add(s, ct -> strval[i]);
417 ct = preproc_next_token(pp);
418 }
419 return strbuf_end(s);
420 }
421
422 static void dir_error(struct preproc_info *pp)
423 {
424 char *s;
425
426 if (pp -> skip_level)
427 {
428 skip_eol(pp);
429 return;
430 }
431
432 s = streol(pp);
433 preproc_throw_error(pp, "%s", s);
434 lw_free(s);
435 }
436
437 static void dir_warning(struct preproc_info *pp)
438 {
439 char *s;
440
441 if (pp -> skip_level)
442 {
443 skip_eol(pp);
444 return;
445 }
446
447 s = streol(pp);
448 preproc_throw_warning(pp, "%s", s);
449 lw_free(s);
450 }
451
452 static void dir_include(struct preproc_info *pp)
453 {
454 }
455
456 static void dir_line(struct preproc_info *pp)
457 {
458 }
459
460 static void dir_pragma(struct preproc_info *pp)
461 {
462 if (pp -> skip_level)
463 {
464 skip_eol(pp);
465 return;
466 }
467
468 preproc_throw_warning(pp, "Unsupported #pragma");
469 skip_eol(pp);
470 }
471
472 struct { char *name; void (*fn)(struct preproc_info *); } dirlist[] =
473 {
474 { "ifdef", dir_ifdef },
475 { "ifndef", dir_ifndef },
476 { "if", dir_if },
477 { "else", dir_else },
478 { "elif", dir_elif },
479 { "endif", dir_endif },
480 { "define", dir_define },
481 { "undef", dir_undef },
482 { "include", dir_include },
483 { "error", dir_error },
484 { "warning", dir_warning },
485 { "line", dir_line },
486 { "pragma", dir_pragma },
487 { NULL, NULL }
488 };
489
490 static void process_directive(struct preproc_info *pp)
491 {
492 struct token *ct;
493 int i;
494
495 do
496 {
497 ct = preproc_next_token(pp);
498 } while (ct -> ttype == TOK_WSPACE);
499
500 // NULL directive
501 if (ct -> ttype == TOK_EOL)
502 return;
503
504 if (ct -> ttype != TOK_IDENT)
505 goto baddir;
506
507 for (i = 0; dirlist[i].name; i++)
508 {
509 if (strcmp(dirlist[i].name, ct -> strval) == 0)
510 {
511 (*(dirlist[i].fn))(pp);
512 return;
513 }
514 }
515 baddir:
516 preproc_throw_error(pp, "Bad preprocessor directive");
517 while (ct -> ttype != TOK_EOL)
518 ct = preproc_next_token(pp);
519 return;
520 }
521
522 /*
523 Evaluate a preprocessor expression
524 */
525
526 /* same as skip_eol() but the EOL token is not consumed */
527 static void skip_eoe(struct preproc_info *pp)
528 {
529 skip_eol(pp);
530 preproc_unget_token(pp, pp -> curtok);
531 }
532
533 static long eval_expr_real(struct preproc_info *, int);
534 static long preproc_numval(struct token *);
535
536 static long eval_term_real(struct preproc_info *pp)
537 {
538 long tval = 0;
539 struct token *ct;
540
541 eval_next:
542 ct = preproc_next_processed_token_nws(pp);
543 if (ct -> ttype == TOK_EOL)
544 {
545 preproc_throw_error(pp, "Bad expression");
546 return 0;
547 }
548
549 switch (ct -> ttype)
550 {
551 case TOK_OPAREN:
552 tval = eval_expr_real(pp, 0);
553 ct = preproc_next_processed_token_nws(pp);
554 if (ct -> ttype != ')')
555 {
556 preproc_throw_error(pp, "Unbalanced () in expression");
557 skip_eoe(pp);
558 return 0;
559 }
560 return tval;
561
562 case TOK_ADD: // unary +
563 goto eval_next;
564
565 case TOK_SUB: // unary -
566 tval = eval_expr_real(pp, 200);
567 return -tval;
568
569 /* NOTE: we should only get "TOK_IDENT" from an undefined macro */
570 case TOK_IDENT: // some sort of function, symbol, etc.
571 if (strcmp(ct -> strval, "defined"))
572 {
573 /* the defined operator */
574 /* any number in the "defined" bit will be
575 treated as a defined symbol, even zero */
576 ct = preproc_next_token_nws(pp);
577 if (ct -> ttype == TOK_OPAREN)
578 {
579 ct = preproc_next_token_nws(pp);
580 if (ct -> ttype != TOK_IDENT)
581 {
582 preproc_throw_error(pp, "Bad expression");
583 skip_eoe(pp);
584 return 0;
585 }
586 if (symtab_find(pp, ct -> strval) == NULL)
587 tval = 0;
588 else
589 tval = 1;
590 ct = preproc_next_token_nws(pp);
591 if (ct -> ttype != TOK_CPAREN)
592 {
593 preproc_throw_error(pp, "Bad expression");
594 skip_eoe(pp);
595 return 0;
596 }
597 return tval;
598 }
599 else if (ct -> ttype == TOK_IDENT)
600 {
601 return (symtab_find(pp, ct -> strval) != NULL) ? 1 : 0;
602 }
603 preproc_throw_error(pp, "Bad expression");
604 skip_eoe(pp);
605 return 0;
606 }
607 /* unknown identifier - it's zero */
608 return 0;
609
610 /* numbers */
611 case TOK_NUMBER:
612 return preproc_numval(ct);
613
614 default:
615 preproc_throw_error(pp, "Bad expression");
616 skip_eoe(pp);
617 return 0;
618 }
619 return 0;
620 }
621
622 static long eval_expr_real(struct preproc_info *pp, int p)
623 {
624 static const struct operinfo
625 {
626 int tok;
627 int prec;
628 } operators[] =
629 {
630 { TOK_ADD, 100 },
631 { TOK_SUB, 100 },
632 { TOK_STAR, 150 },
633 { TOK_DIV, 150 },
634 { TOK_MOD, 150 },
635 { TOK_LT, 75 },
636 { TOK_LE, 75 },
637 { TOK_GT, 75 },
638 { TOK_GE, 75 },
639 { TOK_EQ, 70 },
640 { TOK_NE, 70 },
641 { TOK_BAND, 30 },
642 { TOK_BOR, 25 },
643 { TOK_NONE, 0 }
644 };
645
646 int op;
647 long term1, term2, term3;
648 struct token *ct;
649
650 term1 = eval_term_real(pp);
651 eval_next:
652 ct = preproc_next_processed_token_nws(pp);
653 for (op = 0; operators[op].tok != TOK_NONE; op++)
654 {
655 if (operators[op].tok == ct -> ttype)
656 break;
657 }
658 /* if it isn't a recognized operator, assume end of expression */
659 if (operators[op].tok == TOK_NONE)
660 {
661 preproc_unget_token(pp, ct);
662 return term1;
663 }
664
665 /* if new operation is not higher than the current precedence, let the previous op finish */
666 if (operators[op].prec <= p)
667 return term1;
668
669 /* get the second term */
670 term2 = eval_expr_real(pp, operators[op].prec);
671
672 switch (operators[op].tok)
673 {
674 case TOK_ADD:
675 term3 = term1 + term2;
676 break;
677
678 case TOK_SUB:
679 term3 = term1 - term2;
680 break;
681
682 case TOK_STAR:
683 term3 = term1 * term2;
684 break;
685
686 case TOK_DIV:
687 if (!term2)
688 {
689 preproc_throw_warning(pp, "Division by zero");
690 term3 = 0;
691 break;
692 }
693 term3 = term1 / term2;
694 break;
695
696 case TOK_MOD:
697 if (!term2)
698 {
699 preproc_throw_warning(pp, "Division by zero");
700 term3 = 0;
701 break;
702 }
703 term3 = term1 % term2;
704 break;
705
706 case TOK_BAND:
707 term3 = (term1 && term2);
708 break;
709
710 case TOK_BOR:
711 term3 = (term1 || term2);
712 break;
713
714 case TOK_EQ:
715 term3 = (term1 == term2);
716 break;
717
718 case TOK_NE:
719 term3 = (term1 != term2);
720 break;
721
722 case TOK_GT:
723 term3 = (term1 > term2);
724 break;
725
726 case TOK_GE:
727 term3 = (term1 >= term2);
728 break;
729
730 case TOK_LT:
731 term3 = (term1 < term2);
732 break;
733
734 case TOK_LE:
735 term3 = (term1 <= term2);
736 break;
737
738 default:
739 term3 = 0;
740 break;
741 }
742 term1 = term3;
743 goto eval_next;
744 }
745
746 static long eval_expr(struct preproc_info *pp)
747 {
748 long rv;
749
750 rv = eval_expr_real(pp, 0);
751 if (pp -> curtok -> ttype != TOK_EOL)
752 {
753 preproc_throw_error(pp, "Bad expression");
754 skip_eol(pp);
755 }
756 return rv;
757 }
758
759 /* convert a numeric string to a number */
760 long preproc_numval(struct token *t)
761 {
762 return 0;
763 }
764
765 /*
766 Below here is the logic for expanding a macro
767 */
768 static int expand_macro(struct preproc_info *pp, char *mname)
769 {
770 struct symtab_e *s;
771 struct token *t, *t2, *t3;
772 struct token **arglist = NULL;
773 int nargs = 0;
774 struct expand_e *e;
775 struct token **exparglist = NULL;
776 int i;
777
778 s = symtab_find(pp, mname);
779 if (!s)
780 return 0;
781
782 for (e = pp -> expand_list; e; e = e -> next)
783 {
784 /* don't expand if we're already expanding the same macro */
785 if (e -> s == s)
786 return 0;
787 }
788
789 if (s -> nargs == -1)
790 {
791 /* short circuit NULL expansion */
792 if (s -> tl == NULL)
793 return 1;
794
795 goto expandmacro;
796 }
797
798 // look for opening paren after optional whitespace
799 t2 = NULL;
800 t = NULL;
801 for (;;)
802 {
803 t = preproc_next_token(pp);
804 if (t -> ttype != TOK_WSPACE && t -> ttype != TOK_EOL)
805 break;
806 t -> next = t2;
807 t2 = t2;
808 }
809 if (t -> ttype != TOK_OPAREN)
810 {
811 // not a function-like invocation
812 while (t2)
813 {
814 t = t2 -> next;
815 preproc_unget_token(pp, t2);
816 t2 = t;
817 }
818 return 0;
819 }
820
821 // parse parameters here
822 t = preproc_next_token_nws(pp);
823 nargs = 1;
824 arglist = lw_alloc(sizeof(struct token *));
825 arglist[0] = NULL;
826 t2 = NULL;
827
828 while (t -> ttype != TOK_CPAREN)
829 {
830 if (t -> ttype == TOK_EOF)
831 {
832 preproc_throw_error(pp, "Unexpected EOF in macro call");
833 break;
834 }
835 if (t -> ttype == TOK_EOL)
836 continue;
837 if (t -> ttype == TOK_COMMA)
838 {
839 if (!(s -> vargs) || (nargs > s -> nargs))
840 {
841 nargs++;
842 arglist = lw_realloc(arglist, sizeof(struct token *) * nargs);
843 arglist[nargs - 1] = NULL;
844 t2 = NULL;
845 continue;
846 }
847 }
848 if (t2)
849 {
850 t2 -> next = token_dup(t);
851 t2 = t2 -> next;
852 }
853 else
854 {
855 t2 = token_dup(t);
856 arglist[nargs - 1] = t2;
857 }
858 }
859
860 if (s -> vargs)
861 {
862 if (nargs <= s -> nargs)
863 {
864 preproc_throw_error(pp, "Wrong number of arguments (%d) for variadic macro %s which takes %d arguments", nargs, mname, s -> nargs);
865 }
866 }
867 else
868 {
869 if (s -> nargs != nargs && !(s -> nargs == 0 && nargs == 1 && arglist[nargs - 1]))
870 {
871 preproc_throw_error(pp, "Wrong number of arguments (%d) for macro %s which takes %d arguments", nargs, mname, s -> nargs);
872 }
873 }
874
875 /* now calculate the pre-expansions of the arguments */
876 exparglist = lw_alloc(nargs);
877 for (i = 0; i < nargs; i++)
878 {
879 t2 = NULL;
880 exparglist[i] = NULL;
881 // NOTE: do nothing if empty argument
882 if (arglist[i] == NULL)
883 continue;
884 pp -> sourcelist = arglist[i];
885 for (;;)
886 {
887 t = preproc_next_processed_token(pp);
888 if (t -> ttype == TOK_EOF)
889 break;
890 if (t2)
891 {
892 t2 -> next = token_dup(t);
893 t2 = t2 -> next;
894 }
895 else
896 {
897 t2 = token_dup(t);
898 exparglist[i] = t2;
899 }
900 }
901 }
902
903 expandmacro:
904 t2 = NULL;
905 t3 = NULL;
906
907 for (t = s -> tl; t; t = t -> next)
908 {
909 if (t -> ttype == TOK_IDENT)
910 {
911 /* identifiers might need expansion to arguments */
912 if (strcmp(t -> strval, "__VA_ARGS__") == 0)
913 {
914 i = s -> nargs;
915 }
916 else
917 {
918 for (i = 0; i < nargs; i++)
919 {
920 if (strcmp(t -> strval, s -> params[i]) == 0)
921 break;
922 }
923 }
924 if ((i == s -> nargs) && !(s -> vargs))
925 {
926 struct token *te;
927 // expand argument
928 // FIXME: handle # and ##
929 for (te = exparglist[i]; te; te = te -> next)
930 {
931 if (t2)
932 {
933 t2 -> next = token_dup(te);
934 t2 = t2 -> next;
935 }
936 else
937 {
938 t3 = token_dup(te);
939 t2 = t2;
940 }
941 }
942 continue;
943 }
944 }
945 if (t2)
946 {
947 t2 -> next = token_dup(t);
948 t2 = t2 -> next;
949 }
950 else
951 {
952 t3 = token_dup(t);
953 t2 = t3;
954 }
955 }
956
957 /* put the new expansion in front of the input, if relevant; if we
958 expanded to nothing, no need to create an expansion record or
959 put anything into the input queue */
960 if (t3)
961 {
962 t2 -> next = token_create(TOK_ENDEXPAND, "", -1, -1, "");
963 t2 -> next -> next = pp -> tokqueue;
964 pp -> tokqueue = t3;
965
966 /* set up expansion record */
967 e = lw_alloc(sizeof(struct expand_e));
968 e -> next = pp -> expand_list;
969 pp -> expand_list = e;
970 e -> s = s;
971 }
972
973 /* now clean up */
974 for (i = 0; i < nargs; i++)
975 {
976 lw_free(arglist[i]);
977 lw_free(exparglist[i]);
978 }
979 lw_free(arglist);
980 lw_free(exparglist);
981
982 return 1;
983 }