1 /* $Id: cpp.c,v 1.124.2.2 2011/03/27 13:17:19 ragge Exp $ */
4 * Copyright (c) 2004,2010 Anders Magnusson (ragge@ludd.luth.se).
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * This code originates from the V6 preprocessor with some additions
31 * from V7 cpp, and at last ansi/c99 support.
36 #ifdef HAVE_SYS_WAIT_H
56 #define SBSIZE 1000000
58 static usch sbf
[SBSIZE
];
61 int tflag
; /* traditional cpp syntax */
63 int dflag
; /* debug printouts */
64 #define DPRINT(x) if (dflag) printf x
65 #define DDPRINT(x) if (dflag > 1) printf x
74 int Cflag
, Mflag
, dMflag
, Pflag
;
76 struct initar
*initar
;
89 static struct symtab
*filloc
;
90 static struct symtab
*linloc
;
91 static struct symtab
*pragloc
;
96 usch
*stringbuf
= sbf
;
99 * Macro replacement list syntax:
100 * - For object-type macros, replacement strings are stored as-is.
101 * - For function-type macros, macro args are substituted for the
102 * character WARN followed by the argument number.
103 * - The value element points to the end of the string, to simplify
104 * pushback onto the input queue.
106 * The first character (from the end) in the replacement list is
107 * the number of arguments:
108 * VARG - ends with ellipsis, next char is argcount without ellips.
109 * OBJCT - object-type macro
110 * 0 - empty parenthesis, foo()
111 * 1-> - number of args.
114 * - in stored replacement lists to tell that an argument comes
115 * - When expanding replacement lists to tell that the list ended.
117 * To ensure that an already expanded identifier won't get expanded
118 * again a EBLOCK char + its number is stored directly before any
119 * expanded identifier.
122 /* args for lookup() */
126 static int readargs(struct symtab
*sp
, const usch
**args
);
127 void prline(const usch
*s
);
128 static void prrep(const usch
*s
);
129 static void exparg(int);
130 static void subarg(struct symtab
*sp
, const usch
**args
, int);
133 void include_next(void);
137 usch
*xstrdup(const usch
*str
);
138 static void addidir(char *idir
, struct incs
**ww
);
139 void imp(const char *);
140 #define IMP(x) if (dflag>1) imp(x)
143 main(int argc
, char **argv
)
148 const usch
*fn1
, *fn2
;
151 struct timeval t1
, t2
;
153 (void)gettimeofday(&t1
, NULL
);
156 while ((ch
= getopt(argc
, argv
, "CD:I:MPS:U:d:i:tvV?")) != -1)
158 case 'C': /* Do not discard comments */
162 case 'i': /* include */
163 case 'U': /* undef */
164 case 'D': /* define something */
165 /* XXX should not need malloc() here */
166 if ((it
= malloc(sizeof(struct initar
))) == NULL
)
167 error("couldn't apply -%c %s", ch
, optarg
);
174 case 'M': /* Generate dependencies for make */
178 case 'P': /* Inhibit generation of line numbers */
184 addidir(optarg
, &incdir
[ch
== 'I' ? INCINC
: SYSINC
]);
193 printf("cpp: %s\n", VERSSTR
);
196 if (optarg
[0] == 'M') {
210 error("bad arg %c\n", ch
);
215 filloc
= lookup((const usch
*)"__FILE__", ENTER
);
216 linloc
= lookup((const usch
*)"__LINE__", ENTER
);
217 filloc
->value
= linloc
->value
= stringbuf
;
220 /* create a complete macro for pragma */
221 pragloc
= lookup((const usch
*)"_Pragma", ENTER
);
223 savstr((const usch
*)"_Pragma(");
227 pragloc
->value
= stringbuf
;
231 time_t t
= time(NULL
);
232 usch
*n
= (usch
*)ctime(&t
);
235 * Manually move in the predefined macros.
237 nl
= lookup((const usch
*)"__TIME__", ENTER
);
238 savch(0); savch('"'); n
[19] = 0; savstr(&n
[11]); savch('"');
240 nl
->value
= stringbuf
-1;
242 nl
= lookup((const usch
*)"__DATE__", ENTER
);
243 savch(0); savch('"'); n
[24] = n
[11] = 0; savstr(&n
[4]);
244 savstr(&n
[20]); savch('"'); savch(OBJCT
);
245 nl
->value
= stringbuf
-1;
247 nl
= lookup((const usch
*)"__STDC__", ENTER
);
248 savch(0); savch('1'); savch(OBJCT
);
249 nl
->value
= stringbuf
-1;
251 nl
= lookup((const usch
*)"__STDC_VERSION__", ENTER
);
252 savch(0); savstr((const usch
*)"199901L"); savch(OBJCT
);
253 nl
->value
= stringbuf
-1;
256 if (Mflag
&& !dMflag
) {
260 error("-M and no infile");
261 if ((c
= (usch
*)strrchr(argv
[0], '/')) == NULL
)
267 if ((c
= (usch
*)strrchr((char *)Mfile
, '.')) == NULL
)
268 error("-M and no extension: ");
274 if ((ofd
= open(argv
[1], O_WRONLY
|O_CREAT
, 0600)) < 0)
275 error("Can't creat %s", argv
[1]);
277 ofd
= 1; /* stdout */
280 if (argc
&& strcmp(argv
[0], "-")) {
281 fn1
= fn2
= (usch
*)argv
[0];
284 fn2
= (const usch
*)"";
286 if (pushfile(fn1
, fn2
, 0, NULL
))
287 error("cannot open %s", argv
[0]);
292 (void)gettimeofday(&t2
, NULL
);
293 t2
.tv_sec
-= t1
.tv_sec
;
294 t2
.tv_usec
-= t1
.tv_usec
;
295 if (t2
.tv_usec
< 0) {
296 t2
.tv_usec
+= 1000000;
299 fprintf(stderr
, "cpp total time: %ld s %ld us\n",
300 t2
.tv_sec
, t2
.tv_usec
);
306 addidir(char *idir
, struct incs
**ww
)
311 if (stat(idir
, &st
) == -1 || S_ISDIR(st
.st_mode
) == 0)
314 for (w
= *ww
; w
->next
; w
= w
->next
) {
315 if (w
->dev
== st
.st_dev
&& w
->ino
== st
.st_ino
)
318 if (w
->dev
== st
.st_dev
&& w
->ino
== st
.st_ino
)
322 if ((w
= calloc(sizeof(struct incs
), 1)) == NULL
)
323 error("couldn't add path %s", idir
);
324 w
->dir
= (usch
*)idir
;
338 if ((c
= yylex()) != NUMBER
)
340 ifiles
->lineno
= (int)(yylval
.node
.nd_val
- 1);
342 if ((c
= yylex()) == '\n')
351 c
= strlen((char *)p
);
353 /* XXX may loose heap space */
358 p
[strlen((char *)p
)-1] = 0;
359 if (strlcpy((char *)lbuf
, (char *)&p
[1], SBSIZE
) >= SBSIZE
)
360 error("line exceeded buffer size");
362 ifiles
->fname
= lbuf
;
366 bad
: error("bad line directive");
370 * Search for and include next file.
371 * Return 1 on success.
374 fsrch(const usch
*fn
, int idx
, struct incs
*w
)
378 for (i
= idx
; i
< 2; i
++) {
381 for (; w
; w
= w
->next
) {
382 usch
*nm
= stringbuf
;
384 savstr(w
->dir
); savch('/');
385 savstr(fn
); savch(0);
386 if (pushfile(nm
, fn
, i
, w
->next
) == 0)
395 * Include a file. Include order:
396 * - For <...> files, first search -I directories, then system directories.
397 * - For "..." files, first search "current" dir, then as <...> files.
411 while ((c
= sloscan()) == WSPACE
)
414 /* sloscan() will not expand idents */
415 if ((nl
= lookup((usch
*)yytext
, FIND
)) == NULL
)
424 if (c
!= STRING
&& c
!= '<')
429 while ((c
= sloscan()) != '>' && c
!= '\n') {
430 if (c
== '\n') /* XXX check - cannot reach */
432 savstr((usch
*)yytext
);
435 while ((c
= sloscan()) == WSPACE
)
442 usch
*nm
= stringbuf
;
444 yytext
[strlen((char *)yytext
)-1] = 0;
445 fn
= (usch
*)&yytext
[1];
446 /* first try to open file relative to previous file */
447 /* but only if it is not an absolute path */
449 savstr(ifiles
->orgfn
);
451 (usch
*)strrchr((char *)nm
, '/')) == NULL
)
457 savstr(fn
); savch(0);
461 if (pushfile(nm
, safefn
, 0, NULL
) == 0)
463 /* XXX may loose stringbuf space */
466 if (fsrch(safefn
, 0, incdir
[0]))
469 error("cannot find '%s'", safefn
);
470 /* error() do not return */
472 bad
: error("bad include");
473 /* error() do not return */
489 while ((c
= sloscan()) == WSPACE
)
492 /* sloscan() will not expand idents */
493 if ((nl
= lookup((usch
*)yytext
, FIND
)) == NULL
)
502 if (c
!= STRING
&& c
!= '<')
507 savstr((usch
*)&yytext
[1]);
510 while ((c
= sloscan()) != '>') {
513 savstr((usch
*)yytext
);
517 while ((c
= sloscan()) == WSPACE
)
522 if (fsrch(fn
, ifiles
->idx
, ifiles
->incs
) == 0)
523 error("cannot find '%s'", fn
);
527 bad
: error("bad include");
528 /* error() do not return */
547 savstr((usch
*)yytext
);
548 savch(cinput()); /* Lost * */
554 savstr((const usch
*)"*/");
565 * Compare two replacement lists, taking in account comments etc.
568 cmprepl(const usch
*o
, const usch
*n
)
570 for (; *o
; o
--, n
--) {
572 if (*o
== '/' && o
[-1] == '*') {
573 while (*o
!= '*' || o
[-1] != '/')
577 if (*n
== '/' && n
[-1] == '*') {
578 while (*n
!= '*' || n
[-1] != '/')
582 while (*o
== ' ' || *o
== '\t')
584 while (*n
== ' ' || *n
== '\t')
597 if ((ch
= cinput()) != '.') {
601 if ((ch
= cinput()) != '.') {
613 usch
*args
[MAXARGS
+1], *ubuf
, *sbeg
;
615 int mkstr
= 0, narg
= -1;
618 usch
*gccvari
= NULL
;
624 if (sloscan() != WSPACE
|| sloscan() != IDENT
)
627 if (isdigit((int)yytext
[0]))
630 np
= lookup((usch
*)yytext
, ENTER
);
631 redef
= np
->value
!= NULL
;
635 if ((c
= sloscan()) == '(') {
637 /* function-like macros, deal with identifiers */
642 if (c
== '.' && isell()) {
649 /* make sure there is no arg of same name */
650 for (i
= 0; i
< narg
; i
++)
651 if (!strcmp((char *) args
[i
], (char *)yytext
))
652 error("Duplicate macro "
653 "parameter \"%s\"", yytext
);
655 error("Too many macro args");
656 args
[narg
++] = xstrdup(yytext
);
657 if ((c
= definp()) == ',') {
658 if ((c
= definp()) == ')')
663 if (c
== '.' && isell()) {
666 gccvari
= args
[--narg
];
676 } else if (c
== '\n') {
679 } else if (c
!= WSPACE
)
685 /* replacement list cannot start with ## operator */
687 if ((c
= sloscan()) == '#')
696 /* parse replacement-list, substituting arguments */
705 /* remove spaces if it surrounds a ## directive */
707 savstr((usch
*)yytext
);
710 if ((c
= sloscan()) != '#')
714 if ((c
= sloscan()) == WSPACE
)
730 if ((c
= sloscan()) == WSPACE
)
742 /* no meaning in object-type macro */
746 /* remove spaces between # and arg */
749 c
= sloscan(); /* whitespace, ignore */
751 if (c
== IDENT
&& strcmp((char *)yytext
, "__VA_ARGS__") == 0)
756 if (strcmp((char *)yytext
, "__VA_ARGS__") == 0) {
758 error("unwanted %s", yytext
);
760 savch(wascon
? GCCARG
: VARG
);
767 savch(SNUFF
), mkstr
= 0;
771 goto id
; /* just add it if object */
772 /* check if its an argument */
773 for (i
= 0; i
< narg
; i
++)
774 if (strcmp((char *)yytext
, (char *)args
[i
]) == 0)
779 strcmp((char *)yytext
, (char *)gccvari
) == 0) {
780 savch(wascon
? GCCARG
: VARG
);
783 savch(SNUFF
), mkstr
= 0;
788 error("not argument");
794 savch(SNUFF
), mkstr
= 0;
797 case CMNT
: /* save comments */
802 id
: savstr((usch
*)yytext
);
808 /* remove trailing whitespace */
809 while (stringbuf
> sbeg
) {
810 if (stringbuf
[-1] == ' ' || stringbuf
[-1] == '\t')
812 /* replacement list cannot end with ## operator */
813 else if (stringbuf
[-1] == CONC
)
828 savch(narg
< 0 ? OBJCT
: narg
);
829 if (redef
&& ifiles
->idx
!= SYSINC
) {
830 if (cmprepl(np
->value
, stringbuf
-1)) {
832 np
->value
= stringbuf
-1;
833 warning("%s redefined\nprevious define: %s:%d",
834 np
->namep
, np
->file
, np
->line
);
836 stringbuf
= sbeg
; /* forget this space */
838 np
->value
= stringbuf
-1;
842 const usch
*w
= np
->value
;
848 printf("[VARG%d]", *--w
);
851 case WARN
: printf("<%d>", *--w
); break;
852 case CONC
: printf("<##>"); break;
853 case SNUFF
: printf("<\">"); break;
854 default: putchar(*w
); break;
860 for (i
= 0; i
< narg
; i
++)
864 bad
: error("bad define");
871 usch
*sb
= stringbuf
;
876 if (ifiles
!= NULL
) {
877 t
= sheap("%s:%d: warning: ", ifiles
->fname
, ifiles
->lineno
);
878 write (2, t
, strlen((char *)t
));
880 dummy
= write (2, s
, strlen((char *)s
));
881 dummy
= write (2, "\n", 1);
893 if (ifiles
!= NULL
) {
894 t
= sheap("%s:%d: error: ", ifiles
->fname
, ifiles
->lineno
);
895 dummy
= write (2, t
, strlen((char *)t
));
897 dummy
= write (2, s
, strlen((char *)s
));
898 dummy
= write (2, "\n", 1);
911 addmac(struct symtab
*sp
)
915 /* Check if it exists; then save some space */
916 /* May be more difficult to debug cpp */
917 for (i
= 1; i
< norepptr
; i
++)
920 if (norepptr
>= RECMAX
)
921 error("too many macros");
923 if ((norepptr
& 255) == 0)
925 if (((norepptr
>> 8) & 255) == 0)
928 norep
[norepptr
++] = sp
;
939 } while ((c
= sloscan()) == EBLOCK
);
941 error("EBLOCK sync error");
944 /* Block next nr in lex buffer to expand */
951 error("too deep macro recursion");
953 n
= MKB(n
, cinput());
954 for (i
= 0; i
< bidx
; i
++)
956 return n
; /* already blocked */
958 /* XXX - check for sp buffer overflow */
960 printf("donex %d (%d) blocking:\n", bidx
, n
);
961 printf("donex %s(%d) blocking:", norep
[n
]->namep
, n
);
962 for (i
= bidx
-1; i
>= 0; i
--)
963 printf(" '%s'", norep
[bptr
[i
]]->namep
);
970 * store a character into the "define" buffer.
975 if (stringbuf
-sbf
< SBSIZE
) {
976 *stringbuf
++ = (usch
)c
;
978 stringbuf
= sbf
; /* need space to write error message */
979 error("Too much defining");
984 * convert _Pragma to #pragma for output.
985 * Syntax is already correct.
993 while ((t
= sloscan()) != '(')
996 while ((t
= sloscan()) == WSPACE
)
999 error("pragma must have string argument");
1000 savstr((const usch
*)"\n#pragma ");
1007 if (*s
== '\\' && (s
[1] == '\"' || s
[1] == '\\'))
1011 sheap("\n# %d \"%s\"\n", ifiles
->lineno
, ifiles
->fname
);
1012 while ((t
= sloscan()) == WSPACE
)
1015 error("pragma syntax error");
1019 * Return true if it is OK to expand this symbol.
1022 okexp(struct symtab
*sp
)
1028 for (i
= 0; i
< bidx
; i
++)
1029 if (norep
[bptr
[i
]] == sp
)
1035 * Insert block(s) before each expanded name.
1036 * Input is in lex buffer, output on lex buffer.
1041 usch
*bp
= stringbuf
;
1045 while ((c
= sloscan()) != WARN
) {
1051 savch(EBLOCK
), savch(bnr
& 255), savch(bnr
>> 8);
1052 for (i
= 0; i
< bidx
; i
++)
1053 savch(EBLOCK
), savch(bptr
[i
] & 255),
1054 savch(bptr
[i
] >> 8);
1056 savstr((const usch
*)yytext
);
1067 /* Delete next WARN on the input stream */
1071 usch
*bp
= stringbuf
;
1075 while ((c
= sloscan()) != WARN
) {
1088 * Handle defined macro keywords found on input stream.
1089 * When finished print out the full expanded line.
1090 * Everything on lex buffer except for the symtab.
1093 kfind(struct symtab
*sp
)
1096 const usch
*argary
[MAXARGS
+1], *cbp
;
1100 DPRINT(("%d:enter kfind(%s)\n",0,sp
->namep
));
1102 if (*sp
->value
== OBJCT
) {
1104 unpstr(sheap("\"%s\"", ifiles
->fname
));
1106 } else if (sp
== linloc
) {
1107 unpstr(sheap("%d", ifiles
->lineno
));
1112 for (cbp
= sp
->value
-1; *cbp
; cbp
--)
1114 insblock(addmac(sp
));
1118 upp
: sbp
= stringbuf
;
1121 lastoch
= outbuf
[obufp
-1];
1122 if (iswsnl(lastoch
))
1124 while ((c
= sloscan()) != WARN
) {
1127 /* Remove embedded directives */
1128 for (cbp
= (usch
*)yytext
; *cbp
; cbp
++) {
1131 else if (*cbp
!= CONC
)
1141 * Tricky: if this is the last identifier
1142 * in the expanded list, and it is defined
1143 * as a function-like macro, then push it
1144 * back on the input stream and let fastscan
1145 * handle it as a new macro.
1146 * BUT: if this macro is blocked then this
1147 * should not be done.
1149 nl
= lookup((usch
*)yytext
, FIND
);
1152 /* Deal with pragmas here */
1153 if (nl
== pragloc
) {
1157 if (nl
== NULL
|| !o
|| *nl
->value
== OBJCT
) {
1158 /* Not fun-like macro */
1164 /* succeeded, push back */
1173 if (chkf
&& c
< 127)
1186 /* Is a function-like macro */
1188 /* Search for '(' */
1190 while (iswsnl(c
= cinput()))
1197 return 0; /* Failed */
1200 /* Found one, output \n to be in sync */
1201 for (; *sbp
; sbp
++) {
1203 putch('\n'), ifiles
->lineno
++;
1206 /* fetch arguments */
1207 if (readargs(sp
, argary
))
1215 subarg(sp
, argary
, 1);
1231 * Replace and push-back on input stream the eventual replaced macro.
1232 * The check for whether it can expand or not should already have been done.
1233 * Blocks for this identifier will be added via insblock() after expansion.
1236 submac(struct symtab
*sp
, int lvl
)
1238 const usch
*argary
[MAXARGS
+1];
1243 DPRINT(("%d:submac1: trying '%s'\n", lvl
, sp
->namep
));
1244 if (*sp
->value
== OBJCT
) {
1246 unpstr(sheap("\"%s\"", ifiles
->fname
));
1248 } else if (sp
== linloc
) {
1249 unpstr(sheap("%d", ifiles
->lineno
));
1253 DPRINT(("submac: exp object macro '%s'\n",sp
->namep
));
1254 /* expand object-type macros */
1258 for (cp
= sp
->value
-1; *cp
; cp
--)
1266 * Function-like macro; see if it is followed by a (
1267 * Be careful about the expand/noexpand balance.
1268 * Store read data on heap meanwhile.
1269 * For directive #define foo() kaka
1270 * If input is <NEX><NEX>foo<EXP>()<EXP> then
1271 * output should be <NEX><NEX><EXP>kaka<EXP>.
1274 while (iswsnl(ch
= cinput()))
1281 return 0; /* Failed */
1284 /* no \n should be here */
1287 * A function-like macro has been found. Read in the arguments,
1288 * expand them and push-back everything for another scan.
1290 DPRINT(("%d:submac: continue macro '%s'\n", lvl
, sp
->namep
));
1292 if (readargs(sp
, argary
)) {
1293 /* Bailed out in the middle of arg list */
1295 if (dflag
>1)printf("%d:noreadargs\n", lvl
);
1300 /* when all args are read from input stream */
1303 DDPRINT(("%d:submac pre\n", lvl
));
1306 subarg(sp
, argary
, lvl
+1);
1308 DDPRINT(("%d:submac post\n", lvl
));
1312 stringbuf
= bp
; /* Reset heap */
1313 DPRINT(("%d:Return submac\n", lvl
));
1319 * Read arguments and put in argument array.
1320 * If WARN is encountered return 1, otherwise 0.
1323 readargs(struct symtab
*sp
, const usch
**args
)
1325 const usch
*vp
= sp
->value
;
1326 int c
, i
, plev
, narg
, ellips
= 0;
1329 DPRINT(("readargs\n"));
1339 * read arguments and store them on heap.
1343 for (i
= 0; i
< narg
&& c
!= ')'; i
++) {
1344 args
[i
] = stringbuf
;
1346 while ((c
= sloscan()) == WSPACE
|| c
== '\n')
1350 while (c
== EBLOCK
) {
1358 if (plev
== 0 && (c
== ')' || c
== ','))
1364 savstr((usch
*)yytext
);
1365 oho
: while ((c
= sloscan()) == '\n') {
1374 error("eof in macro");
1376 while (args
[i
] < stringbuf
&&
1377 iswsnl(stringbuf
[-1]) && stringbuf
[-3] != EBLOCK
)
1381 printf("readargs: save arg %d '", i
);
1388 /* Handle varargs readin */
1390 args
[i
] = (const usch
*)"";
1391 if (ellips
&& c
!= ')') {
1392 args
[i
] = stringbuf
;
1394 while ((c
= sloscan()) == WSPACE
)
1397 if (plev
== 0 && c
== ')')
1406 savstr((usch
*)yytext
);
1407 while ((c
= sloscan()) == '\n') {
1412 while (args
[i
] < stringbuf
&& iswsnl(stringbuf
[-1]))
1417 if (narg
== 0 && ellips
== 0)
1418 while ((c
= sloscan()) == WSPACE
|| c
== '\n')
1422 if (c
!= ')' || (i
!= narg
&& ellips
== 0) || (i
< narg
&& ellips
== 1))
1423 error("wrong arg count");
1425 cunput(WARN
), warn
--;
1431 * Maybe an indentifier (for macro expansion).
1437 if (!isdigit(*s
) && !isalpha(*s
) && *s
!= '_')
1444 * expand a function-like macro.
1445 * vp points to end of replacement-list
1446 * reads function arguments from sloscan()
1447 * result is pushed-back for more scanning.
1450 subarg(struct symtab
*nl
, const usch
**args
, int lvl
)
1452 int narg
, instr
, snuff
;
1453 const usch
*sp
, *bp
, *ap
, *vp
;
1455 DPRINT(("%d:subarg '%s'\n", lvl
, nl
->namep
));
1464 printf("%d:subarg ARGlist for %s: '", lvl
, nl
->namep
);
1470 * push-back replacement-list onto lex buffer while replacing
1471 * arguments. Arguments are macro-expanded if required.
1475 cunput('\"'), snuff
^= 1;
1476 else if (*sp
== CONC
)
1478 else if (*sp
== WARN
) {
1480 if (sp
[-1] == VARG
) {
1481 bp
= ap
= args
[narg
];
1484 } else if (sp
[-1] == GCCARG
) {
1487 ap
= (const usch
*)"0";
1492 bp
= ap
= args
[(int)*--sp
];
1494 printf("%d:subarg GOTwarn; arglist '", lvl
);
1498 if (sp
[2] != CONC
&& !snuff
&& sp
[-1] != CONC
) {
1500 * Expand an argument; 6.10.3.1:
1501 * "A parameter in the replacement list,
1502 * is replaced by the corresponding argument
1503 * after all macros contained therein have
1515 if (snuff
&& !instr
&& iswsnl(*bp
)) {
1522 if ((*bp
== '\'' || *bp
== '"')
1523 && bp
[-1] != '\\' && snuff
) {
1525 if (instr
== 0 && *bp
== '"')
1528 if (instr
&& (*bp
== '\\' || *bp
== '"'))
1536 DPRINT(("%d:Return subarg\n", lvl
));
1541 * Do a (correct) expansion of a WARN-terminated buffer of tokens.
1542 * Data is read from the lex buffer, result on lex buffer, WARN-terminated.
1543 * Expansion blocking is not altered here unless when tokens are
1544 * concatenated, in which case they are removed.
1552 usch
*osb
= stringbuf
;
1555 DPRINT(("%d:exparg\n", lvl
));
1561 while ((c
= sloscan()) != WARN
) {
1562 DDPRINT(("%d:exparg swdata %d\n", lvl
, c
));
1571 * Handle argument concatenation here.
1572 * In case of concatenation, scratch all blockings.
1574 DDPRINT(("%d:exparg ident %d\n", lvl
, c
));
1577 sav
: savstr(yytext
);
1579 if ((c
= cinput()) == EBLOCK
) {
1580 /* yep, are concatenating; forget blocks */
1584 } while ((c
= sloscan()) == EBLOCK
);
1590 DPRINT(("%d:exparg: str '%s'\n", lvl
, och
));
1592 /* see if ident is expandable */
1593 if ((nl
= lookup(och
, FIND
)) && okexp(nl
)) {
1594 if (submac(nl
, lvl
+1)) {
1595 /* Could expand, result on lexbuffer */
1596 stringbuf
= och
; /* clear saved name */
1600 /* must restore blocks */
1602 for (i
= 0; i
< bidx
; i
++)
1603 savch(EBLOCK
), savch(bptr
[i
] & 255),
1604 savch(bptr
[i
] >> 8);
1621 savstr((usch
*)yytext
);
1628 DPRINT(("%d:exparg return: change %d\n", lvl
, anychange
));
1637 imp(const char *str
)
1639 printf("%s (%d) '", str
, bidx
);
1640 prline(ifiles
->curptr
);
1645 prrep(const usch
*s
)
1649 case WARN
: printf("<ARG(%d)>", *--s
); break;
1650 case CONC
: printf("<CONC>"); break;
1651 case SNUFF
: printf("<SNUFF>"); break;
1652 case EBLOCK
: printf("<E(%d)>",s
[-1] + s
[-2] * 256); s
-=2; break;
1653 default: printf("%c", *s
); break;
1660 prline(const usch
*s
)
1664 case WARN
: printf("<WARN>"); break;
1665 case CONC
: printf("<CONC>"); break;
1666 case SNUFF
: printf("<SNUFF>"); break;
1667 case EBLOCK
: printf("<E(%d)>",s
[1] + s
[2] * 256); s
+=2; break;
1668 case '\n': printf("<NL>"); break;
1669 default: printf("%c", *s
); break;
1676 savstr(const usch
*str
)
1678 usch
*rv
= stringbuf
;
1681 if (stringbuf
>= &sbf
[SBSIZE
]) {
1682 stringbuf
= sbf
; /* need space to write error message */
1683 error("out of macro space!");
1685 } while ((*stringbuf
++ = *str
++));
1691 unpstr(const usch
*c
)
1697 printf("Xunpstr: '");
1717 if (Mflag
== 0 && write(ofd
, outbuf
, obufp
) < 0)
1718 error("obuf write error");
1719 lastoch
= outbuf
[obufp
-1];
1726 outbuf
[obufp
++] = (usch
)ch
;
1727 if (obufp
== CPPBUF
|| (istty
&& ch
== '\n'))
1732 putstr(const usch
*s
)
1735 outbuf
[obufp
++] = *s
;
1736 if (obufp
== CPPBUF
|| (istty
&& *s
== '\n'))
1742 * convert a number to an ascii string. Store it on the heap.
1747 static usch buf
[12];
1754 *b
++ = (usch
)(num
% 10 + '0');
1764 * similar to sprintf, but only handles %s and %d.
1765 * saves result on heap.
1768 sheap(const char *fmt
, ...)
1771 usch
*op
= stringbuf
;
1774 for (; *fmt
; fmt
++) {
1779 savstr(va_arg(ap
, usch
*));
1782 num2str(va_arg(ap
, int));
1785 savch(va_arg(ap
, int));
1788 break; /* cannot call error() here */
1801 error("Usage: cpp [-Cdt] [-Dvar=val] [-Uvar] [-Ipath] [-Spath]");
1806 * Symbol table stuff.
1807 * The data structure used is a patricia tree implementation using only
1808 * bytes to store offsets.
1809 * The information stored is (lower address to higher):
1811 * unsigned char bitno[2]; bit number in the string
1812 * unsigned char left[3]; offset from base to left element
1813 * unsigned char right[3]; offset from base to right element
1818 * This patricia implementation is more-or-less the same as
1819 * used in ccom for string matching.
1826 #define BITNO(x) ((x) & ~(LEFT_IS_LEAF|RIGHT_IS_LEAF))
1827 #define LEFT_IS_LEAF 0x80000000
1828 #define RIGHT_IS_LEAF 0x40000000
1829 #define IS_LEFT_LEAF(x) (((x) & LEFT_IS_LEAF) != 0)
1830 #define IS_RIGHT_LEAF(x) (((x) & RIGHT_IS_LEAF) != 0)
1831 #define P_BIT(key, bit) (key[bit >> 3] >> (bit & 7)) & 1
1834 static struct tree
*sympole
;
1838 * Allocate a symtab struct and store the string.
1840 static struct symtab
*
1841 getsymtab(const usch
*str
)
1843 struct symtab
*sp
= malloc(sizeof(struct symtab
));
1846 error("getsymtab: couldn't allocate symtab");
1847 sp
->namep
= savstr(str
);
1850 sp
->file
= ifiles
? ifiles
->orgfn
: (const usch
*)"<initial>";
1851 sp
->line
= ifiles
? ifiles
->lineno
: 0;
1856 * Do symbol lookup in a patricia tree.
1857 * Only do full string matching, no pointer optimisations.
1860 lookup(const usch
*key
, int enterf
)
1863 struct tree
*w
, *new, *last
;
1864 int len
, cix
, bit
, fbit
, svbit
, ix
, bitno
;
1865 const usch
*k
, *m
, *sm
;
1867 /* Count full string length */
1868 for (k
= key
, len
= 0; *k
; k
++, len
++)
1872 case 0: /* no symbols yet */
1873 if (enterf
!= ENTER
)
1875 sympole
= (struct tree
*)getsymtab(key
);
1877 return (struct symtab
*)sympole
;
1881 svbit
= 0; /* XXX gcc */
1886 bitno
= len
* CHECKBITS
;
1888 bit
= BITNO(w
->bitno
);
1889 fbit
= bit
> bitno
? 0 : P_BIT(key
, bit
);
1890 svbit
= fbit
? IS_RIGHT_LEAF(w
->bitno
) :
1891 IS_LEFT_LEAF(w
->bitno
);
1898 sp
= (struct symtab
*)w
;
1903 /* Check for correct string and return */
1904 for (cix
= 0; *m
&& *k
&& *m
== *k
; m
++, k
++, cix
+= CHECKBITS
)
1906 if (*m
== 0 && *k
== 0) {
1907 if (enterf
!= ENTER
&& sp
->value
== NULL
)
1912 if (enterf
!= ENTER
)
1913 return NULL
; /* no string found and do not enter */
1916 while ((ix
& 1) == 0)
1919 /* Create new node */
1920 if ((new = malloc(sizeof *new)) == NULL
)
1921 error("getree: couldn't allocate tree");
1922 bit
= P_BIT(key
, cix
);
1923 new->bitno
= cix
| (bit
? RIGHT_IS_LEAF
: LEFT_IS_LEAF
);
1924 new->lr
[bit
] = (struct tree
*)getsymtab(key
);
1926 if (numsyms
++ == 1) {
1927 new->lr
[!bit
] = sympole
;
1928 new->bitno
|= (bit
? LEFT_IS_LEAF
: RIGHT_IS_LEAF
);
1930 return (struct symtab
*)new->lr
[bit
];
1937 bitno
= BITNO(w
->bitno
);
1939 error("bitno == cix");
1942 svbit
= P_BIT(key
, bitno
);
1945 if (fbit
& (svbit
? RIGHT_IS_LEAF
: LEFT_IS_LEAF
))
1953 last
->lr
[svbit
] = new;
1954 last
->bitno
&= ~(svbit
? RIGHT_IS_LEAF
: LEFT_IS_LEAF
);
1957 new->bitno
|= (bit
? LEFT_IS_LEAF
: RIGHT_IS_LEAF
);
1958 return (struct symtab
*)new->lr
[bit
];
1962 xstrdup(const usch
*str
)
1964 size_t len
= strlen((const char *)str
)+1;
1967 if ((rv
= malloc(len
)) == NULL
)
1968 error("xstrdup: out of mem");
1969 strlcpy((char *)rv
, (const char *)str
, len
);