Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20040821135113

Diff

Diff from 1.3 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/cc/cpp/cpp.c

Annotated File View

ragge
1.3
1 /*      $Id: cpp.c,v 1.3 2004/08/21 13:51:13 ragge Exp $        */
ragge
1.1
2
3 /*
4  * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 /*
31  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
32  *
33  * Redistribution and use in source and binary forms, with or without
34  * modification, are permitted provided that the following conditions
35  * are met:
36  *
37  * Redistributions of source code and documentation must retain the above
38  * copyright notice, this list of conditions and the following disclaimer.
39  * Redistributions in binary form must reproduce the above copyright
40  * notice, this list of conditions and the following disclaimer in the
41  * documentation and/or other materials provided with the distribution.
42  * All advertising materials mentioning features or use of this software
43  * must display the following acknowledgement:
44  *      This product includes software developed or owned by Caldera
45  *      International, Inc.
46  * Neither the name of Caldera International, Inc. nor the names of other
47  * contributors may be used to endorse or promote products derived from
48  * this software without specific prior written permission.
49  *
50  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
51  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
52  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
53  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
54  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
55  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
59  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
60  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
61  * POSSIBILITY OF SUCH DAMAGE.
62  */
63 /*
64  * The C preprocessor.
65  * This code originates from the V6 preprocessor with some additions
66  * from V7 cpp, and at last ansi/c99 support.
67  */
68 #include <sys/wait.h>
69
70 #include <fcntl.h>
71 #include <unistd.h>
72 #include <stdio.h>
73 #include <stdarg.h>
74 #include <stdlib.h>
75 #include <string.h>
76 #include <unistd.h>
77
78 #include "cpp.h"
79
80 typedef unsigned char usch;
81
82 #define MAXARG  250     /* # of args to a macro, limited by char value */
83 #define SBSIZE  2000
84 #define SYMSIZ  200
85 #define MAXREC  200     /* max recursive macros to avoid expansion */
86
87 static usch     sbf[SBSIZE];
88 /* C command */
89
90 /* buffer used internally */
91 #ifndef CPPBUF
92 #define CPPBUF  BUFSIZ
93 #endif
94
95 int tflag;      /* traditional cpp syntax */
96 #ifdef CPP_DEBUG
97 int dflag;      /* debug printouts */
98 #endif
99 FILE *obuf;
100 static int exfail;
101 static struct symtab {
102         usch *namep;
103         char *value;
104 symtab[SYMSIZ];
105
106 /* avoid recursion */
107 struct recur {
108         struct recur *next;
109         struct symtab *sp;
110 };
111
112 static struct symtab *defloc;
113 static struct symtab *eifloc;
114 static struct symtab *elfloc;
115 static struct symtab *elsloc;
116 static struct symtab *ifdloc;
117 static struct symtab *ifloc;
118 static struct symtab *ifnloc;
119 static struct symtab *incloc;
120 static struct symtab *undloc;
121 static struct symtab *filloc;
122 static struct symtab *linloc;
123 static int      trulvl;
124 static int      flslvl;
125 static usch *stringbuf = sbf;
126
127 /*
128  * Macro replacement list syntax:
129  * - For object-type macros, replacement strings are stored as-is.
130  * - For function-type macros, macro args are substituted for the
131  *   character WARN followed by the argument number.
132  * 
133  * The first character in the replacement list is the number of arguments:
134  *   OBJCT - object-type macro
135  *   0     - empty parenthesis, foo()
136  *   1->   - number of args.
137  */
138
139 #define OBJCT   0xff
140 #define WARN    1       /* SOH, not legal char */
141 #define CONC    2       /* STX, not legal char */
142 #define SNUFF   3       /* ETX, not legal char */
143 #define NOEXP   4       /* EOT, not legal char */
144 #define EXPAND  5       /* ENQ, not legal char */
145
146 /* args for lookup() */
147 #define FIND    0
148 #define ENTER   1
149 #define FORGET  3
150
151 static void expdef(usch *protostruct recur *, int gotwarn);
152 static int subst(char *, struct symtab *, struct recur *);
153 static void savch(int c);
154 static void insym(struct symtab **spchar *namep);
155 static void expand(char *, char *);
156 static struct symtab *lookup(char *namepint enterf);
157 static void control(void);
158 static usch *savstr(usch *str);
159 static void define(void);
160 static void expmac(struct recur *);
161 static int canexpand(struct recur *, struct symtab *np);
162 static void unpstr(usch *);
ragge
1.3
163 static void include(void);
ragge
1.1
164
165 int
166 main(int argcchar **argv)
167 {
168         char *infil = NULL, *utfil = NULL;
169         int ch;
170
171         while ((ch = getopt(argcargv"I:U:td")) != -1)
172                 switch (ch) {
173 #ifdef CPP_DEBUG
174                 case 'd':
175                         dflag = 1;
176                         break;
177 #endif
178                 case 't':
179                         tflag = 1;
180                         break;
181
182                 default:
183                         fprintf(stderr"bad arg %c\n"ch);
184                         exit(1);
185                 }
186         argc -= optind;
187         argv += optind;
188
189         if (argc)
190                 infil = argv[0];
191         if (argc == 2)
192                 utfil = argv[1];
193         expand(infilutfil);
194         return exfail;
195 }
196
197 void
198 expand(char *infilchar *utfil)
199 {
200         struct symtab *nl, *thisnl;
ragge
1.2
201         register int cgotspc;
ragge
1.1
202         usch *osp;
203
204         exfail = 0;
205         if (infil != NULL) {
206                 if (freopen(infil"r"stdin) == NULL) {
207                         fprintf(stderr"Can't open %s"infil);
208                         exit(8);
209                 }
210         }
211         pushfile(infil ? infil : "<stdin>");
212
213         if (utfil != NULL) {
214                 if ((obuf = fopen(utfil"w")) == 0) {
215                         fprintf(stderr"Can't creat %s\n"utfil);
216                         exit(8);
217                 }
218         } else
219                 obuf = stdout;
220
221         prtline();
222
223         insym(&defloc"define");
224         insym(&incloc"include");
225         insym(&eifloc"endif");
226         insym(&ifdloc"ifdef");
227         insym(&ifnloc"ifndef");
228         insym(&elsloc"else");
229         insym(&elfloc"elif");
230         insym(&undloc"undef");
231         insym(&filloc"__FILE__");
232         insym(&linloc"__LINE__");
233         trulvl = 0;
234         flslvl = 0;
235
236         thisnl = NULL;
237         while ((c = yylex()) != 0) {
238                 switch (c) {
239                 case CONTROL:
240                         control();
241                         break;
242
243                 case BEGCOM:
244                 case ENDCOM:
245                 case LINECOM:
246                         error("special: %d\n"c);
247
248                 case IDENT:
249                         osp = stringbuf;
250                         nl = lookup(yytextFIND);
251                         if (nl == 0 || thisnl == 0)
252                                 goto found;
253                         if (thisnl == nl) {
254                                 nl = 0;
255                                 goto found;
256                         }
ragge
1.2
257                         gotspc = 0;
ragge
1.1
258                         if ((c = yylex()) == WSPACE)
ragge
1.2
259                                 gotspc = 1c = yylex();
ragge
1.1
260                         if (c != EXPAND) {
261                                 unpstr(yytext);
ragge
1.2
262                                 if (gotspc)
263                                         cunput(' ');
ragge
1.1
264                                 unpstr(nl->namep);
265                                 (void)yylex(); /* get yytext correct */
266                                 nl = 0/* ignore */
267                         } else
268                                 thisnl = NULL;
269
270 found:                  if (nl == 0 || subst(yytextnlNULL) == 0) {
271                                 fputs(yytextobuf);
272                         } else if (osp != stringbuf) {
273                                 cunput(EXPAND);
274                                 while (stringbuf > osp)
275                                         cunput(*--stringbuf);
276                                 thisnl = nl;
277                         }
278                         stringbuf = osp/* clean up heap */
279                         break;
280
281                 case EXPAND:
282                         thisnl = NULL;
283                         break;
284
285                 case CHARCON:
286                 case NUMBER:
287                 case FPOINT:
288                 case STRING:
289                 case WSPACE:
290                 case NL:
ragge
1.3
291                 default:
ragge
1.1
292                         fputs(yytextobuf);
293                         break;
294                 }
295         }
296         fclose(obuf);
297 }
298
299 /*
300  * do something when a '#' is found.
301  */
302 void
303 control()
304 {
305         struct symtab *np;
306         int t;
307
308         if ((t = yylex()) == WSPACE)
309                 t = yylex();
310         if (t != IDENT)
311                 return error("bad control '%s'"yytext);
312
313         np = lookup(yytextFIND);
314         if (np == 0)
315                 return/* ignore empty controls */
316         if (np == incloc) {
317                 if (flslvl)
318                         goto exit;
ragge
1.3
319                 include();
ragge
1.1
320                 return;
321         } else if (np == elsloc) {
322                 if (flslvl) {
323                         if (--flslvl!=0)
324                                 flslvl++;
325                         else
326                                 trulvl++;
327                 } else if (trulvl) {
328                         flslvl++;
329                         trulvl--;
330                 } else
331                         error("If-less else");
332         } else {
333                 if (yylex() != WSPACE || yylex() != IDENT)
334                         return error("bad control2");
335                 
336                 if (np == defloc) {
337                         define();
338                         return;
339                 } else if (np == ifdloc) {
340                         if (flslvl == 0 && lookup(yytextFIND) != 0)
341                                 trulvl++;
342                         else
343                                 flslvl++;
344                 } else if (np == ifnloc) {
345                         if (flslvl == 0 && lookup(yytextFIND) == 0)
346                                 trulvl++;
347                         else
348                                 flslvl++;
349                 } else if (np == eifloc) {
350                         if (flslvl)
351                                 flslvl--;
352                         else if (trulvl)
353                                 trulvl--;
354                         else
355                                 error("If-less endif");
356                 } else if (np == undloc) {
357                         if (flslvl == 0 && (np = lookup(yytextFIND)))
358                                 np->value = 0;
359                 } else if (np == elfloc) {
360
361                 } else if (np == ifloc) {
362
363                 } else
364                         error("undefined control '%s'"np->namep);
365         }
366
367 exit:
368         while (yylex() != NL)
369                 ;
370 }
371
372 void
ragge
1.3
373 include()
374 {
375         struct symtab *nl;
376         usch *osp, *instr;
377         int c;
378
379         if (yylex() != WSPACE)
380                 goto bad;
381         if ((c = yylex()) != STRING && c != '<' && c != IDENT)
382                 goto bad;
383
384         if (c == IDENT) {
385                 instr = osp = stringbuf;
386                 if ((nl = lookup(yytextFIND)) == NULL)
387                         goto bad;
388                 if (subst(yytextnlNULL) == 0)
389                         goto bad;
390                 savch('\0');
391         } else {
392                 yytext[strlen(yytext)-1] = 0;
393                 instr = &yytext[1];
394         }
395         pushfile(instr);
396         if (c == IDENT)
397                 stringbuf = osp;
398         return;
399
400 bad:    error("bad include");
401 }
402
403 void
ragge
1.1
404 define()
405 {
406         struct symtab *np;
ragge
1.2
407         usch *args[MAXARG], *ubuf;
ragge
1.1
408         int ci;
409         int mkstr = 0narg = -1;
410
411         np = lookup(yytextENTER);
412
413         if ((c = yylex()) == '(') {
414                 narg = 0;
415                 /* function-like macros, deal with identifiers */
416                 while ((c = yylex()) != ')') {
417                         if (c == WSPACEc = yylex();
418                         if (c == ','c = yylex();
419                         if (c == WSPACEc = yylex();
420                         if (c == ')')
421                                 break;
422                                 if (c != IDENT)
423                         error("define error");
424                         args[narg] = alloca(strlen(yytext)+1);
425                         strcpy(args[narg], yytext);
426                         narg++;
427                 }
428         } else if (c != WSPACE)
429                 error("bad define");
430
431         if ((c = yylex()) == WSPACE)
432                 c = yylex();
433
434         /* parse replacement-list, substituting arguments */
435         savch('\0');
436         while (c != NL) {
437                 switch (c) {
438                 case WSPACE:
439                         /* remove spaces if it surrounds a ## directive */
ragge
1.2
440                         ubuf = stringbuf;
ragge
1.1
441                         savstr(yytext);
442                         c = yylex();
443                         if (c == CONCAT) {
ragge
1.2
444                                 stringbuf = ubuf;
ragge
1.1
445                                 savch(CONC);
446                                 if ((c = yylex()) == WSPACE)
447                                         c = yylex();
448                         }
449                         continue;
450
451                 case CONCAT:
452                         /* No spaces before concat op */
453                         savch(CONC);
454                         if ((c = yylex()) == WSPACE)
455                                 c = yylex();
456                         continue;
457
458                 case MKSTR:
459                         if (narg < 0) {
460                                 /* no meaning in object-type macro */
461                                 savch('#');
462                                 break;
463                         }
464                         /* remove spaces between # and arg */
465                         savch(SNUFF);
466                         if ((c = yylex()) == WSPACE)
467                                 c = yylex(); /* whitespace, ignore */
468                         mkstr = 1;
469
470                         /* FALLTHROUGH */
471                 case IDENT:
472                         if (narg < 0)
473                                 goto id/* just add it if object */
474                         /* check if its an argument */
475                         for (i = 0i < nargi++)
476                                 if (strcmp(yytextargs[i]) == 0)
477                                         break;
478                         if (i == narg) {
479                                 if (mkstr)
480                                         error("not argument");
481                                 goto id;
482                         }
483                         savch(i);
484                         savch(WARN);
485                         if (mkstr)
486                                 savch(SNUFF), mkstr = 0;
487                         break;
488
489                 default:
490 id:                     savstr(yytext);
491                         break;
492                 }
493                 c = yylex();
494         }
495         savch(narg < 0 ? OBJCT : narg);
496         np->value = stringbuf-1;
ragge
1.2
497         putc('\n'obuf);
ragge
1.1
498
499 #ifdef CPP_DEBUG
500         if (dflag) {
501                 usch *w = np->value;
502
503                 printf("!define: ");
504                 if (*w == OBJCT)
505                         printf("[object]");
506                 else
507                         printf("[%d]", *w);
508                 while (*--w) {
509                         switch (*w) {
510                         case WARNprintf("<%d>", *--w); break;
511                         case CONCprintf("<##>"); break;
512                         case SNUFFprintf("<\">"); break;
513                         defaultputchar(*w); break;
514                         }
515                 }
516                 putchar('\n');
517         }
518 #endif
519 }
520
521 void
522 insym(spnamep)
523 struct symtab **sp;
524 char *namep;
525 {
526         register struct symtab *np;
527
528         *sp = np = lookup(namepENTER);
529         np->value = np->namep/* XXX */
530 }
531
532 void
533 error(char *s, ...)
534 {
535         va_list ap;
536
537         va_start(aps);
538         fprintf(stderr"%s:%d: "curfile(), curline());
539         vfprintf(stderrsap);
540         fputc('\n'stderr);
541         exfail++;
542         va_end(ap);
543         exit(8);
544 }
545
546 /*
547  * store a character into the "define" buffer.
548  */
549 void
550 savch(c)
551 {
552         *stringbuf++ = c;
553         if (stringbuf-sbf < SBSIZE)
554                 return;
555         error("Too much defining");
556         exit(1);
557 }
558
559 /*
560  * Do a symbol lookup.
561  * If enterf == FIND, only lookup.
562  */
563 struct symtab *
564 lookup(namepenterf)
565         char *namep;
566 {
567         register char *np;
568         register struct symtab *sp;
569         int icaround;
570
ragge
1.3
571 if (dflag)printf("lookup '%s'\n"namep);
ragge
1.1
572         np = namep;
573         around = i = 0;
574         while ((c = *np++))
575                 i =+ c;
576         i %= SYMSIZ;
577         sp = &symtab[i];
578
579         while (sp->namep) {
580                 if (*sp->namep == *namep && strcmp(sp->namepnamep) == 0)
581                         return(sp);
582                 if (++sp >= &symtab[SYMSIZ]) {
583                         if (around++)
584                                 error("too many defines");
585                         else
586                                 sp = symtab;
587                 }
588         }
589         if (enterf == ENTER)
590                 sp->namep = savstr(namep), savch('\0');
591         return(sp->namep ? sp : 0);
592 }
593
594 /*
595  * substitute namep for sp->value.
596  */
597 int
598 subst(npsprp)
599 char *np;
600 struct symtab *sp;
601 struct recur *rp;
602 {
603         struct recur rp2;
604         register usch *vp, *cp;
605         int crv = 0;
606
607 if (dflag)printf("subst\n");
608         if ((vp = sp->value) == 0)
609                 return 0;
610         if (sp == filloc) {
611                 fprintf(obuf"\"%s\""curfile());
612                 return 1;
613         } else if (sp == linloc) {
614                 fprintf(obuf"%d"curline());
615                 return 1;
616         }
617
618         rp2.next = rp;
619         rp2.sp = sp;
620
621         if (*vp-- != OBJCT) {
622                 int gotwarn = 0;
623
624                 /* should we be here at all? */
625                 /* check if identifier is followed by parentheses */
626                 rv = 1;
627                 do {
628                         if ((c = yylex()) == NL)
629                                 putc('\n'obuf);
630                         if (c == WARN) {
631                                 gotwarn++;
632                                 if (rp == NULL)
633                                         goto noid;
634                         }
635                 } while (c == WSPACE || c == NL || c == WARN);
636
637                 cp = yytext;
638                 while (*cp)
639                         cp++;
640                 while ((char *)cp > yytext)
641                         cunput(*--cp);
642 if (dflag)printf("c %d\n"c);
643                 if (c == '(' ) {
644                         expdef(vp, &rp2gotwarn);
645                         return rv;
646                 } else {
647                         /* restore identifier */
648 noid:                   while (gotwarn--)
649                                 cunput(WARN);
650                         cunput(' ');
651                         cp = sp->namep;
652                         while (*cp)
653                                 cp++;
654                         while (cp > sp->namep)
655                                 cunput(*--cp);
656                         if ((c = yylex()) != IDENT)
657                                 error("internal sync error");
658                         return 0;
659                 }
660         } else {
661                 cunput(WARN);
662                 cp = vp;
663                 while (*cp) {
664                         if (*cp != CONC)
665                                 cunput(*cp);
666                         cp--;
667                 }
668                 expmac(&rp2);
669         }
670         return 1;
671 }
672
673 /*
674  * do macro-expansion until WARN character read.
675  * will recurse into lookup() for recursive expansion.
676  * when returning all expansions on the token list is done.
677  */
678 void
679 expmac(struct recur *rp)
680 {
681         struct symtab *nl;
ragge
1.2
682         int cnoexp = 0gotspc;
ragge
1.1
683
684 if (dflag)printf("expmac\n");
685 if (dflag && rp)printf("do not expand %s\n"rp->sp->namep);
686         while ((c = yylex()) != WARN) {
687                 switch (c) {
688                 case NOEXPnoexp++; break;
689                 case EXPANDnoexp--; break;
690
691                 case IDENT:
692                         if ((nl = lookup(yytextFIND)) == NULL)
693                                 goto def;
694                         if (canexpand(rpnl) == 0)
695                                 goto def;
696                         if (noexp == 0) {
697                                 if ((c = subst(nl->namepnlrp)) == 0)
698                                         goto def;
699                                 break;
700                         }
701                         if (noexp != 1)
702                                 error("bad noexp %d"noexp);
ragge
1.2
703                         gotspc = 0;
ragge
1.1
704                         if ((c = yylex()) == WSPACE)
ragge
1.2
705                                 gotspc = 1c = yylex();
ragge
1.1
706                         if (c == EXPAND) {
707                                 noexp--;
708                                 if (subst(nl->namepnlrp))
709                                         break;
710                                 savstr(nl->namep);
ragge
1.2
711                                 if (gotspc)
712                                         savch(' ');
ragge
1.1
713                         } else {
714                                 unpstr(yytext);
ragge
1.2
715                                 if (gotspc)
716                                         cunput(' ');
ragge
1.1
717                                 savstr(nl->namep);
718                         }
719                         break;
720
721 def:            default:
722                         savstr(yytext);
723                         break;
724                 }
725         }
726 if (dflag)printf("return from expmac\n");
727 }
728
729 /*
730  * expand a function-like macro.
731  * vp points to end of replacement-list
732  * reads function arguments from yylex()
733  * result is written on top of heap
734  */
735 void
736 expdef(vprpgotwarn)
737         usch *vp;
738         struct recur *rp;
739 {
740         usch **args, *obuf, *ap, *bp, *sp;
741         int nargciplevinstrsnuff;
742
743 if (dflag)printf("expdef %s rp %s\n"vp, (rp ? (char *)rp->sp->namep : ""));
744         if ((c = yylex()) != '(')
745                 error("got %c, expected )"c);
746         narg = vp[1];
747         args = alloca(sizeof(usch *) * narg);
748
749
750         /*
751          * read arguments and store them on heap.
752          * will be removed just before return from this function.
753          */
754         obuf = stringbuf;
755         for (i = 0i < narg && c != ')'i++) {
756                 args[i] = stringbuf;
757                 plev = 0;
ragge
1.2
758                 if ((c = yylex()) == WSPACE)
759                         c = yylex();
ragge
1.1
760                 for (;;) {
761                         if (plev == 0 && (c == ')' || c == ','))
762                                 break;
763                         if (c == '(')
764                                 plev++;
765                         if (c == ')')
766                                 plev--;
767                         savstr(yytext);
ragge
1.2
768                         c = yylex();
ragge
1.1
769                 }
ragge
1.2
770                 while (args[i] < stringbuf &&
771                     (stringbuf[-1] == ' ' || stringbuf[-1] == '\t'))
772                         stringbuf--;
ragge
1.1
773                 savch('\0');
774         }
775         if (narg == 0)
776                 c = yylex();
777         if (c != ')' || i != narg)
778                 error("wrong arg count");
779
780         while (gotwarn--)
781                 cunput(WARN);
782
783 #ifdef CPP_DEBUG
784         if (dflag) {
785
786         }
787 #endif
788         sp = vp;
789         instr = snuff = 0;
790
791         /*
792          * push-back replacement-list onto lex buffer while replacing
793          * arguments. 
794          */
795         cunput(WARN);
796         while (*sp != 0) {
797                 if (*sp == SNUFF)
798                         cunput('\"'), snuff ^= 1;
799                 else if (*sp == CONC)
800                         ;
801                 else if (*sp == WARN) {
802
803                         bp = ap = args[(int)*--sp];
804                         if (sp[2] != CONC && !snuff && sp[-1] != CONC) {
805                                 cunput(WARN);
806                                 while (*bp)
807                                         bp++;
808                                 while (bp > ap)
809                                         cunput(*--bp);
810 if (dflagprintf("expand arg %d string %s\n", *spap);
811                                 bp = ap = stringbuf;
812                                 savch(NOEXP);
813                                 expmac(NULL);
814                                 savch(EXPAND);
815                                 savch('\0');
816                         }
817                         while (*bp)
818                                 bp++;
819                         while (bp > ap) {
820                                 cunput(*--bp);
821                                 if (snuff && (*bp == '\\' || *bp == '"'))
822                                         cunput('\\');
823                         }
824                 } else {
825                         cunput(*sp);
826                         if (instr && (*sp == '"' || *sp == '\\'))
827                                         cunput('\\');
828                 }
829                 sp--;
830         }
831         stringbuf = obuf;
832
833         /* scan the input buffer (until WARN) and save result on heap */
834         expmac(rp);
835 }
836
837 usch *
838 savstr(usch *str)
839 {
840         char *rv = stringbuf;
841
842         while ((*stringbuf++ = *str++))
843                 if (stringbuf >= &sbf[SBSIZE])
844                         error("out of macro space!");
845         stringbuf--;
846         return rv;
847 }
848
849 int
850 canexpand(struct recur *rpstruct symtab *np)
851 {
852         struct recur *w;
853
854         for (w = rpw && w->sp != npw = w->next)
855                 ;
856         if (w != NULL)
857                 return 0;
858         return 1;
859 }
860
861 void
862 unpstr(usch *c)
863 {
864         usch *d = c;
865
866         while (*d)
867                 d++;
868         while (d > c) {
869                 cunput(*--d);
870         }
871 }
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-10-01 08:05 +0200