diff options
author | Anders Magnusson <ragge@cvs.openbsd.org> | 2008-08-17 18:40:14 +0000 |
---|---|---|
committer | Anders Magnusson <ragge@cvs.openbsd.org> | 2008-08-17 18:40:14 +0000 |
commit | 5d1db54719c2465f76c6e5ded951bcd7fabeac5e (patch) | |
tree | 58dc770095d9b19c26c3aeb6e62b133ed2e0c744 /usr.bin/pcc/cpp | |
parent | 7c398eb4b48e74579c900aa088978ef883dcacc6 (diff) |
Updates from master repo. Can now compile both userland and kernel.
(with some patches...)
Diffstat (limited to 'usr.bin/pcc/cpp')
-rw-r--r-- | usr.bin/pcc/cpp/cpp.1 | 5 | ||||
-rw-r--r-- | usr.bin/pcc/cpp/cpp.c | 235 | ||||
-rw-r--r-- | usr.bin/pcc/cpp/cpp.h | 12 | ||||
-rw-r--r-- | usr.bin/pcc/cpp/cpy.y | 4 | ||||
-rw-r--r-- | usr.bin/pcc/cpp/scanner.l | 102 |
5 files changed, 292 insertions, 66 deletions
diff --git a/usr.bin/pcc/cpp/cpp.1 b/usr.bin/pcc/cpp/cpp.1 index 0c849dc8989..9d8f9728389 100644 --- a/usr.bin/pcc/cpp/cpp.1 +++ b/usr.bin/pcc/cpp/cpp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: cpp.1,v 1.5 2008/04/11 20:55:22 stefan Exp $ +.\" $OpenBSD: cpp.1,v 1.6 2008/08/17 18:40:13 ragge Exp $ ."\ .\" Copyright (c) 2007 Jeremy C. Reed <reed@reedmedia.net> .\" @@ -102,6 +102,9 @@ Include a file at the beginning by using Generate dependencies for .Xr make 1 . .\" TODO: explain and show example? +.It Fl P +Inhibit generation of line markers. This is sometimes useful when +running the preprocessor on something other than C code. .It Fl S Ar path Add .Ar path diff --git a/usr.bin/pcc/cpp/cpp.c b/usr.bin/pcc/cpp/cpp.c index 095b75da475..3e435aca41b 100644 --- a/usr.bin/pcc/cpp/cpp.c +++ b/usr.bin/pcc/cpp/cpp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpp.c,v 1.9 2008/04/11 20:45:52 stefan Exp $ */ +/* $OpenBSD: cpp.c,v 1.10 2008/08/17 18:40:13 ragge Exp $ */ /* * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se). @@ -99,12 +99,15 @@ int dflag; /* debug printouts */ #define DDPRINT(x) #endif +#define GCC_VARI + int ofd; usch outbuf[CPPBUF]; int obufp, istty, inmac; -int Cflag, Mflag, dMflag; +int Cflag, Mflag, dMflag, Pflag; usch *Mfile; struct initar *initar; +int readmac; /* avoid recursion */ struct recur { @@ -145,6 +148,7 @@ usch *stringbuf = sbf; * 1-> - number of args. */ +#define GCCARG 0xfd /* has gcc varargs that may be replaced with 0 */ #define VARG 0xfe /* has varargs */ #define OBJCT 0xff #define WARN 1 /* SOH, not legal char */ @@ -152,6 +156,8 @@ usch *stringbuf = sbf; #define SNUFF 3 /* ETX, not legal char */ #define NOEXP 4 /* EOT, not legal char */ #define EXPAND 5 /* ENQ, not legal char */ +#define PRAGS 6 /* start of converted pragma */ +#define PRAGE 14 /* end of converted pragma */ /* args for lookup() */ #define FIND 0 @@ -164,6 +170,9 @@ void include(void); void line(void); void flbuf(void); void usage(void); +usch *xstrdup(char *str); +usch *prtprag(usch *opb); + int main(int argc, char **argv) @@ -173,7 +182,7 @@ main(int argc, char **argv) struct symtab *nl; register int ch; - while ((ch = getopt(argc, argv, "CD:I:MS:U:d:i:tvV?")) != -1) + while ((ch = getopt(argc, argv, "CD:I:MPS:U:d:i:tvV?")) != -1) switch (ch) { case 'C': /* Do not discard comments */ Cflag++; @@ -195,6 +204,10 @@ main(int argc, char **argv) Mflag++; break; + case 'P': /* Inhibit generation of line numbers */ + Pflag++; + break; + case 'S': case 'I': if ((w = calloc(sizeof(struct incs), 1)) == NULL) @@ -315,6 +328,7 @@ gotident(struct symtab *nl) thisnl = NULL; slow = 1; + readmac++; base = osp = stringbuf; goto found; @@ -377,6 +391,10 @@ found: if (nl == 0 || subst(nl, NULL) == 0) { thisnl = NULL; break; + case CMNT: + getcmnt(); + break; + case STRING: case '\n': case NUMBER: @@ -394,11 +412,12 @@ found: if (nl == 0 || subst(nl, NULL) == 0) { } if (thisnl == NULL) { slow = 0; + readmac--; savch(0); return base; } } - error("preamture EOF"); + error("premature EOF"); /* NOTREACHED */ return NULL; /* XXX gcc */ } @@ -550,6 +569,55 @@ definp(void) } void +getcmnt(void) +{ + int c; + + savstr((usch *)yytext); + for (;;) { + c = cinput(); + if (c == '*') { + c = cinput(); + if (c == '/') { + savstr((usch *)"*/"); + return; + } + cunput(c); + c = '*'; + } + savch(c); + } +} + +/* + * Compare two replacement lists, taking in account comments etc. + */ +static int +cmprepl(usch *o, usch *n) +{ + for (; *o; o--, n--) { + /* comment skip */ + if (*o == '/' && o[-1] == '*') { + while (*o != '*' || o[-1] != '/') + o--; + o -= 2; + } + if (*n == '/' && n[-1] == '*') { + while (*n != '*' || n[-1] != '/') + n--; + n -= 2; + } + while (*o == ' ' || *o == '\t') + o--; + while (*n == ' ' || *n == '\t') + n--; + if (*o != *n) + return 1; + } + return 0; +} + +void define() { struct symtab *np; @@ -557,7 +625,10 @@ define() int c, i, redef; int mkstr = 0, narg = -1; int ellips = 0; - size_t len; +#ifdef GCC_VARI + usch *gccvari = NULL; + int wascon; +#endif if (flslvl) return; @@ -571,6 +642,7 @@ define() np = lookup((usch *)yytext, ENTER); redef = np->value != NULL; + readmac = 1; sbeg = stringbuf; if ((c = yylex()) == '(') { narg = 0; @@ -591,15 +663,20 @@ define() if (!strcmp((char *) args[i], yytext)) error("Duplicate macro " "parameter \"%s\"", yytext); - len = strlen(yytext); - args[narg] = alloca(len+1); - strlcpy((char *)args[narg], yytext, len+1); - narg++; + args[narg++] = xstrdup(yytext); if ((c = definp()) == ',') { if ((c = definp()) == ')') goto bad; continue; } +#ifdef GCC_VARI + if (c == ELLIPS) { + if (definp() != ')') + goto bad; + gccvari = args[--narg]; + break; + } +#endif if (c == ')') break; } @@ -622,6 +699,10 @@ define() /* parse replacement-list, substituting arguments */ savch('\0'); while (c != '\n') { +#ifdef GCC_VARI + wascon = 0; +loop: +#endif switch (c) { case WSPACE: /* remove spaces if it surrounds a ## directive */ @@ -633,6 +714,12 @@ define() savch(CONC); if ((c = yylex()) == WSPACE) c = yylex(); +#ifdef GCC_VARI + if (c == '\n') + break; + wascon = 1; + goto loop; +#endif } continue; @@ -641,7 +728,14 @@ define() savch(CONC); if ((c = yylex()) == WSPACE) c = yylex(); +#ifdef GCC_VARI + if (c == '\n') + break; + wascon = 1; + goto loop; +#else continue; +#endif case MKSTR: if (narg < 0) { @@ -666,6 +760,16 @@ define() if (strcmp(yytext, (char *)args[i]) == 0) break; if (i == narg) { +#ifdef GCC_VARI + if (gccvari && + strcmp(yytext, (char *)gccvari) == 0) { + savch(wascon ? GCCARG : VARG); + savch(WARN); + if (mkstr) + savch(SNUFF), mkstr = 0; + break; + } +#endif if (mkstr) error("not argument"); goto id; @@ -685,12 +789,17 @@ define() savch(SNUFF), mkstr = 0; break; + case CMNT: /* save comments */ + getcmnt(); + break; + default: id: savstr((usch *)yytext); break; } c = yylex(); } + readmac = 0; /* remove trailing whitespace */ while (stringbuf > sbeg) { if (stringbuf[-1] == ' ' || stringbuf[-1] == '\t') @@ -701,18 +810,19 @@ id: savstr((usch *)yytext); else break; } +#ifdef GCC_VARI + if (gccvari) { + savch(narg); + savch(VARG); + } else +#endif if (ellips) { savch(narg); savch(VARG); } else savch(narg < 0 ? OBJCT : narg); if (redef) { - usch *o = np->value, *n = stringbuf-1; - - /* Redefinition to identical replacement-list is allowed */ - while (*o && *o == *n) - o--, n--; - if (*o || *o != *n) + if (cmprepl(np->value, stringbuf-1)) error("%s redefined\nprevious define: %s:%d", np->namep, np->file, np->line); stringbuf = sbeg; /* forget this space */ @@ -740,6 +850,8 @@ id: savstr((usch *)yytext); } #endif slow = 0; + for (i = 0; i < narg; i++) + free(args[i]); return; bad: error("bad define"); @@ -801,8 +913,7 @@ pragoper(void) usch *opb; int t, plev; - slow = 1; - putstr((usch *)"\n#pragma "); + slow++; if ((t = yylex()) == WSPACE) t = yylex(); if (t != '(') @@ -828,23 +939,19 @@ pragoper(void) cunput('\n'); while (stringbuf > opb) cunput(*--stringbuf); + savch(PRAGS); while ((t = yylex()) != '\n') { if (t == WSPACE) continue; if (t != STRING) goto bad; - opb = (usch *)yytext; - if (*opb++ == 'L') - opb++; - while ((t = *opb++) != '\"') { - if (t == '\\' && (*opb == '\"' || *opb == '\\')) - t = *opb++; - putch(t); - } + savstr((usch *)yytext); } - putch('\n'); - prtline(); + savch(PRAGE); + while (stringbuf > opb) + cunput(*--stringbuf); + slow--; return; bad: error("bad pragma operator"); } @@ -946,7 +1053,6 @@ expmac(struct recur *rp) struct symtab *nl; int c, noexp = 0, orgexp; usch *och, *stksv; - extern int yyleng; #ifdef CPP_DEBUG if (dflag) { @@ -958,6 +1064,7 @@ expmac(struct recur *rp) } } #endif + readmac++; while ((c = yylex()) != WARN) { switch (c) { case NOEXP: noexp++; break; @@ -1018,6 +1125,8 @@ expmac(struct recur *rp) unpstr((usch *)yytext); if (orgexp == -1) cunput(EXPAND); + else if (orgexp == -2) + cunput(EXPAND), cunput(EXPAND); else if (orgexp == 1) cunput(NOEXP); unpstr(och); @@ -1048,8 +1157,7 @@ expmac(struct recur *rp) error("bad noexp %d", noexp); stksv = NULL; if ((c = yylex()) == WSPACE) { - stksv = alloca(yyleng+1); - strlcpy((char *)stksv, yytext, yyleng+1); + stksv = xstrdup(yytext); c = yylex(); } /* only valid for expansion if fun macro */ @@ -1066,6 +1174,12 @@ expmac(struct recur *rp) unpstr(stksv); savstr(nl->namep); } + if (stksv) + free(stksv); + break; + + case CMNT: + getcmnt(); break; case STRING: @@ -1087,6 +1201,7 @@ def: default: } if (noexp) error("expmac noexp=%d", noexp); + readmac--; DPRINT(("return from expmac\n")); } @@ -1113,7 +1228,8 @@ expdef(vp, rp, gotwarn) ellips = 1; } else narg = vp[1]; - args = alloca(sizeof(usch *) * (narg+ellips)); + if ((args = malloc(sizeof(usch *) * (narg+ellips))) == NULL) + error("expdef: out of mem"); /* * read arguments and store them on heap. @@ -1142,8 +1258,14 @@ expdef(vp, rp, gotwarn) savstr((usch *)yytext); while ((c = yylex()) == '\n') savch('\n'); + while (c == CMNT) { + getcmnt(); + c = yylex(); + } if (c == EXPAND) instr = 0; + if (c == 0) + error("eof in macro"); } while (args[i] < stringbuf && (stringbuf[-1] == ' ' || stringbuf[-1] == '\t')) @@ -1216,6 +1338,14 @@ expdef(vp, rp, gotwarn) if (sp[-1] == VARG) { bp = ap = args[narg]; sp--; +#ifdef GCC_VARI + } else if (sp[-1] == GCCARG) { + ap = args[narg]; + if (ap[0] == 0) + ap = (usch *)"0"; + bp = ap; + sp--; +#endif } else bp = ap = args[(int)*--sp]; if (sp[2] != CONC && !snuff && sp[-1] != CONC) { @@ -1261,6 +1391,7 @@ expdef(vp, rp, gotwarn) /* scan the input buffer (until WARN) and save result on heap */ expmac(rp); + free(args); } usch * @@ -1324,6 +1455,10 @@ void putstr(usch *s) { for (; *s; s++) { + if (*s == PRAGS) { + s = prtprag(s); + continue; + } outbuf[obufp++] = *s; if (obufp == CPPBUF || (istty && *s == '\n')) flbuf(); @@ -1549,3 +1684,41 @@ lookup(usch *key, int enterf) return (struct symtab *)new->lr[bit]; } +usch * +xstrdup(char *str) +{ + size_t len = strlen(str)+1; + usch *rv; + + if ((rv = malloc(len)) == NULL) + error("xstrdup: out of mem"); + strlcpy((char *)rv, str, len); + return rv; +} + +usch * +prtprag(usch *s) +{ + int ch; + + s++; + putstr((usch *)"\n#pragma "); + while (*s != PRAGE) { + if (*s == 'L') + s++; + if (*s == '\"') { + s++; + while ((ch = *s++) != '\"') { + if (ch == '\\' && (*s == '\"' || *s == '\\')) + ch = *s++; + putch(ch); + } + } else { + s++; + putch(*s); + } + } + putstr((usch *)"\n"); + prtline(); + return ++s; +} diff --git a/usr.bin/pcc/cpp/cpp.h b/usr.bin/pcc/cpp/cpp.h index 8b94abe9ac9..d0a84fb4935 100644 --- a/usr.bin/pcc/cpp/cpp.h +++ b/usr.bin/pcc/cpp/cpp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpp.h,v 1.5 2007/10/21 18:58:02 otto Exp $ */ +/* $OpenBSD: cpp.h,v 1.6 2008/08/17 18:40:13 ragge Exp $ */ /* * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se). @@ -43,7 +43,7 @@ extern int trulvl; extern int flslvl; extern int elflvl; extern int elslvl; -extern int tflag, Cflag; +extern int tflag, Cflag, Pflag; extern int Mflag, dMflag; extern usch *Mfile; extern int ofd; @@ -72,6 +72,7 @@ struct includ { int infil; usch *curptr; usch *maxread; + usch *ostr; usch *buffer; usch bbuf[NAMEMAX+CPPBUF+1]; } *ifiles; @@ -134,6 +135,13 @@ void line(void); usch *sheap(char *fmt, ...); void xwarning(usch *); void xerror(usch *); +#ifdef HAVE_CPP_VARARG_MACRO_GCC #define warning(...) xwarning(sheap(__VA_ARGS__)) #define error(...) xerror(sheap(__VA_ARGS__)) +#else +#define warning printf +#define error printf +#endif void expmac(struct recur *); +int cinput(void); +void getcmnt(void); diff --git a/usr.bin/pcc/cpp/cpy.y b/usr.bin/pcc/cpp/cpy.y index c4ff14092f4..a49a9c8ab3f 100644 --- a/usr.bin/pcc/cpp/cpy.y +++ b/usr.bin/pcc/cpp/cpy.y @@ -1,4 +1,4 @@ -/* $OpenBSD: cpy.y,v 1.4 2007/10/21 18:58:02 otto Exp $ */ +/* $OpenBSD: cpy.y,v 1.5 2008/08/17 18:40:13 ragge Exp $ */ /* * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se). @@ -87,7 +87,7 @@ int setd(int l, int r); /* * The following terminals are not used in the yacc code. */ -%term STRING FPOINT WSPACE VA_ARGS CONCAT MKSTR ELLIPS +%term STRING FPOINT WSPACE VA_ARGS CONCAT MKSTR ELLIPS CMNT %left ',' %right '?' ':' diff --git a/usr.bin/pcc/cpp/scanner.l b/usr.bin/pcc/cpp/scanner.l index e5dca5e9f26..c22e08a54b4 100644 --- a/usr.bin/pcc/cpp/scanner.l +++ b/usr.bin/pcc/cpp/scanner.l @@ -1,5 +1,5 @@ %{ -/* $OpenBSD: scanner.l,v 1.9 2008/04/11 20:45:52 stefan Exp $ */ +/* $OpenBSD: scanner.l,v 1.10 2008/08/17 18:40:13 ragge Exp $ */ /* * Copyright (c) 2004 Anders Magnusson. All rights reserved. @@ -40,7 +40,7 @@ %{ static void cvtdig(int rad); -static int charcon(void); +static int charcon(usch *); static void elsestmt(void); static void ifdefstmt(void); static void ifndefstmt(void); @@ -83,15 +83,17 @@ yyinput(char *b, int m) } #undef YY_INPUT #undef YY_BUF_SIZE -#define YY_BUF_SIZE 32768 +#define YY_BUF_SIZE (8*65536) #define YY_INPUT(b,r,m) (r = yyinput(b, m)) +#ifdef HAVE_CPP_VARARG_MACRO_GCC #define fprintf(x, ...) error(__VA_ARGS__) +#endif #define ECHO putstr((usch *)yytext) #undef fileno #define fileno(x) 0 #if YY_FLEX_SUBMINOR_VERSION >= 31 -/* Hack to avoid unneccessary warnings */ +/* Hack to avoid unnecessary warnings */ FILE *yyget_in (void); FILE *yyget_out (void); int yyget_leng (void); @@ -122,7 +124,7 @@ FS (f|F|l|L) IS (u|U|l|L)* WS [\t ] -%s IFR CONTR DEF +%s IFR CONTR DEF COMMENT %% @@ -177,7 +179,12 @@ WS [\t ] return NUMBER; } -[1-9][0-9]* { if (slow && !YYSTATE) return IDENT; scale = 10; goto num; } +[0-9][0-9]* { + if (slow && !YYSTATE) + return IDENT; + scale = yytext[0] == '0' ? 8 : 10; + goto num; + } 0[xX]{H}+{IS}? { scale = 16; num: if (YYSTATE == IFR) @@ -186,11 +193,16 @@ WS [\t ] } 0{D}+{IS}? { scale = 8; goto num; } {D}+{IS}? { scale = 10; goto num; } -L?'(\\.|[^\\'])+' { if (YYSTATE) { +'(\\.|[^\\'])+' { + if (YYSTATE || slow) { yylval.node.op = NUMBER; - yylval.node.nd_val = charcon(); + yylval.node.nd_val = charcon((usch *)yytext); + return (NUMBER); } - PRTOUT(NUMBER); + if (tflag) + yyless(1); + if (!flslvl) + putstr((usch *)yytext); } <IFR>. { return yytext[0]; } @@ -225,13 +237,19 @@ L?'(\\.|[^\\'])+' { if (YYSTATE) { "//".*$ { /* if (tflag) yyless(..) */ - if (Cflag && !flslvl) + if (Cflag && !flslvl && !slow) putstr((usch *)yytext); else if (!flslvl) putch(' '); } "/*" { int c, wrn; - if (Cflag && !flslvl) + int prtcm = Cflag && !flslvl && !slow; + extern int readmac; + + if (Cflag && !flslvl && readmac) + return CMNT; + + if (prtcm) putstr((usch *)yytext); wrn = 0; more: while ((c = input()) && c != '*') { @@ -239,20 +257,18 @@ L?'(\\.|[^\\'])+' { if (YYSTATE) { putch(c), ifiles->lineno++; else if (c == 1) /* WARN */ wrn = 1; - else if (Cflag && !flslvl) + else if (prtcm) putch(c); } if (c == 0) return 0; - if (Cflag && !flslvl) + if (prtcm) putch(c); if ((c = input()) && c != '/') { - if (Cflag && !flslvl) - putch('*'); unput(c); goto more; } - if (Cflag && !flslvl) + if (prtcm) putch(c); if (c == 0) return 0; @@ -296,7 +312,22 @@ L?\"(\\.|[^\\"])*\" { PRTOUT(STRING); } xx: ; } -. { PRTOUT(yytext[0]); } +. { + if (YYSTATE || slow) + return yytext[0]; + if (yytext[0] == 6) { /* PRAGS */ + usch *obp = stringbuf; + extern usch *prtprag(usch *); + *stringbuf++ = yytext[0]; + do { + *stringbuf = input(); + } while (*stringbuf++ != 14); + prtprag(obp); + stringbuf = obp; + } else { + PRTOUT(yytext[0]); + } + } %% @@ -424,12 +455,8 @@ pushfile(usch *file) slow = 0; if (file != NULL) { - if ((ic->infil = open((char *)file, O_RDONLY)) < 0) { - if (errno != ENOENT) - error("Cannot open '%s'. %s", file, - strerror(errno)); + if ((ic->infil = open((char *)file, O_RDONLY)) < 0) return -1; - } ic->orgfn = ic->fname = file; if (++inclevel > MAX_INCLEVEL) error("Limit for nested includes exceeded"); @@ -480,7 +507,7 @@ prtline() s = sheap("%s: %s\n", Mfile, ifiles->fname); write(ofd, s, strlen((char *)s)); } - } else + } else if (!Pflag) putstr(sheap("# %d \"%s\"\n", ifiles->lineno, ifiles->fname)); stringbuf = os; } @@ -490,7 +517,7 @@ cunput(int c) { #ifdef CPP_DEBUG extern int dflag; - if (dflag)printf(": '%c'(%d)", c, c); + if (dflag)printf(": '%c'(%d)", c > 31 ? c : ' ', c); #endif unput(c); } @@ -544,14 +571,11 @@ cvtdig(int rad) } static int -charcon(void) +charcon(usch *p) { - usch *p = (usch *)yytext; int val, c; - if (*p == 'L') - p++; - p++; /* first ' */ + p++; /* skip first ' */ val = 0; if (*p++ == '\\') { switch (*p++) { @@ -749,8 +773,20 @@ storepb(void) usch *opb = stringbuf; int c; - while ((c = input()) != '\n') + while ((c = input()) != '\n') { + if (c == '/') { + if ((c = input()) == '*') { + /* ignore comments here whatsoever */ + usch *g = stringbuf; + getcmnt(); + stringbuf = g; + continue; + } + unput(c); + c = '/'; + } savch(c); + } cunput('\n'); savch(0); fixdefined(opb); /* XXX can fail if #line? */ @@ -876,3 +912,9 @@ badop(const char *op) { error("invalid operator in preprocessor expression: %s", op); } + +int +cinput() +{ + return input(); +} |