From d1206876476162c52d8abae13ad94216377a5e84 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Thu, 1 Oct 2015 13:21:39 -0400 Subject: [PATCH 1/7] fix file mode --- cpp/cpp.c | 0 cpp/cpp.h | 0 cpp/eval.c | 0 cpp/getopt.c | 0 cpp/hideset.c | 0 cpp/include.c | 0 cpp/lex.c | 0 cpp/macro.c | 0 cpp/nlist.c | 0 cpp/tokens.c | 0 cpp/unix.c | 0 11 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 cpp/cpp.c mode change 100755 => 100644 cpp/cpp.h mode change 100755 => 100644 cpp/eval.c mode change 100755 => 100644 cpp/getopt.c mode change 100755 => 100644 cpp/hideset.c mode change 100755 => 100644 cpp/include.c mode change 100755 => 100644 cpp/lex.c mode change 100755 => 100644 cpp/macro.c mode change 100755 => 100644 cpp/nlist.c mode change 100755 => 100644 cpp/tokens.c mode change 100755 => 100644 cpp/unix.c diff --git a/cpp/cpp.c b/cpp/cpp.c old mode 100755 new mode 100644 diff --git a/cpp/cpp.h b/cpp/cpp.h old mode 100755 new mode 100644 diff --git a/cpp/eval.c b/cpp/eval.c old mode 100755 new mode 100644 diff --git a/cpp/getopt.c b/cpp/getopt.c old mode 100755 new mode 100644 diff --git a/cpp/hideset.c b/cpp/hideset.c old mode 100755 new mode 100644 diff --git a/cpp/include.c b/cpp/include.c old mode 100755 new mode 100644 diff --git a/cpp/lex.c b/cpp/lex.c old mode 100755 new mode 100644 diff --git a/cpp/macro.c b/cpp/macro.c old mode 100755 new mode 100644 diff --git a/cpp/nlist.c b/cpp/nlist.c old mode 100755 new mode 100644 diff --git a/cpp/tokens.c b/cpp/tokens.c old mode 100755 new mode 100644 diff --git a/cpp/unix.c b/cpp/unix.c old mode 100755 new mode 100644 From aaead7647c5ea2465dfd8e5b0b29f7964a2c6dd8 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 4 Oct 2015 16:00:48 -0400 Subject: [PATCH 2/7] cpp - call dorealloc front-end to realloc. exits if allocation failed. --- cpp/cpp.c | 10 ++++++++++ cpp/cpp.h | 1 + cpp/hideset.c | 4 +--- cpp/tokens.c | 4 +--- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/cpp/cpp.c b/cpp/cpp.c index 1e5d0125..bccc18f1 100644 --- a/cpp/cpp.c +++ b/cpp/cpp.c @@ -249,6 +249,16 @@ control(Tokenrow *trp) return; } +void * +dorealloc(void *ptr, int size) +{ + void *p = realloc(ptr, size); + + if (p==NULL) + error(FATAL, "Out of memory from realloc"); + return p; +} + void * domalloc(int size) { diff --git a/cpp/cpp.h b/cpp/cpp.h index b1ff8b88..22b0c5f2 100644 --- a/cpp/cpp.h +++ b/cpp/cpp.h @@ -98,6 +98,7 @@ Source *setsource(char *, FILE *, char *); void unsetsource(void); void puttokens(Tokenrow *); void process(Tokenrow *); +void *dorealloc(void *, int); void *domalloc(int); void dofree(void *); void error(enum errtype, char *, ...); diff --git a/cpp/hideset.c b/cpp/hideset.c index 9b9d7ba4..9cf37915 100644 --- a/cpp/hideset.c +++ b/cpp/hideset.c @@ -53,9 +53,7 @@ newhideset(int hs, Nlist *np) return hs; if (nhidesets >= maxhidesets) { maxhidesets = 3*maxhidesets/2+1; - hidesets = (Hideset *)realloc(hidesets, (sizeof (Hideset *))*maxhidesets); - if (hidesets == NULL) - error(FATAL, "Out of memory from realloc"); + hidesets = (Hideset *)dorealloc(hidesets, (sizeof (Hideset *))*maxhidesets); } hs1 = (Hideset)domalloc(len*sizeof *hs1); memmove(hs1, nhs, len*sizeof *hs1); diff --git a/cpp/tokens.c b/cpp/tokens.c index d4fe054d..27f9368b 100644 --- a/cpp/tokens.c +++ b/cpp/tokens.c @@ -92,9 +92,7 @@ growtokenrow(Tokenrow *trp) int nlast = trp->lp - trp->bp; trp->max = 3*trp->max/2 + 1; - trp->bp = (Token *)realloc(trp->bp, trp->max*sizeof(Token)); - if (trp->bp == NULL) - error(FATAL, "Out of memory from realloc"); + trp->bp = (Token *)dorealloc(trp->bp, trp->max*sizeof(Token)); trp->lp = &trp->bp[nlast]; trp->tp = &trp->bp[ncur]; return trp->lp; From 4caa14461fc5b43dc62b7271272683e2ae48c903 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 4 Oct 2015 16:08:36 -0400 Subject: [PATCH 3/7] cpp - add #warning directive. --- cpp/cpp.c | 7 ++++++- cpp/cpp.h | 2 +- cpp/nlist.c | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/cpp/cpp.c b/cpp/cpp.c index bccc18f1..82d67935 100644 --- a/cpp/cpp.c +++ b/cpp/cpp.c @@ -207,7 +207,12 @@ control(Tokenrow *trp) case KERROR: trp->tp = tp+1; - error(WARNING, "#error directive: %r", trp); + error(ERROR, "#error directive: %r", trp); + break; + + case KWARNING: + trp->tp = tp+1; + error(WARNING, "#warning directive: %r", trp); break; case KLINE: diff --git a/cpp/cpp.h b/cpp/cpp.h index 22b0c5f2..d307cd68 100644 --- a/cpp/cpp.h +++ b/cpp/cpp.h @@ -26,7 +26,7 @@ enum toktype { END, UNCLASS, NAME, NUMBER, STRING, CCON, NL, WS, DSHARP, DSHARP1, NAME1, DEFINED, UMINUS }; enum kwtype { KIF, KIFDEF, KIFNDEF, KELIF, KELSE, KENDIF, KINCLUDE, KDEFINE, - KUNDEF, KLINE, KERROR, KPRAGMA, KDEFINED, + KUNDEF, KLINE, KERROR, KWARNING, KPRAGMA, KDEFINED, KLINENO, KFILE, KDATE, KTIME, KSTDC, KEVAL }; #define ISDEFINED 01 /* has #defined value */ diff --git a/cpp/nlist.c b/cpp/nlist.c index 01b001e1..757305f3 100644 --- a/cpp/nlist.c +++ b/cpp/nlist.c @@ -30,6 +30,7 @@ struct kwtab { "undef", KUNDEF, ISKW, "line", KLINE, ISKW, "error", KERROR, ISKW, + "warning", KWARNING, ISKW, // extension to ANSI "pragma", KPRAGMA, ISKW, "eval", KEVAL, ISKW, "defined", KDEFINED, ISDEFINED+ISUNCHANGE, From f926d88524bd2ab490932e608b972f9dddf1536f Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 4 Oct 2015 16:11:16 -0400 Subject: [PATCH 4/7] cpp - fix error messages (#elsif -> #elif) --- cpp/eval.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cpp/eval.c b/cpp/eval.c index fd0ad868..9cfbfa6e 100644 --- a/cpp/eval.c +++ b/cpp/eval.c @@ -159,7 +159,7 @@ eval(Tokenrow *trp, int kw) if (tp->type==MINUS) *op++ = UMINUS; if (tp->type==STAR || tp->type==AND) { - error(ERROR, "Illegal operator * or & in #if/#elsif"); + error(ERROR, "Illegal operator * or & in #if/#elif"); return 0; } continue; @@ -197,7 +197,7 @@ eval(Tokenrow *trp, int kw) continue; default: - error(ERROR,"Bad operator (%t) in #if/#elsif", tp); + error(ERROR,"Bad operator (%t) in #if/#elif", tp); return 0; } } @@ -206,14 +206,14 @@ eval(Tokenrow *trp, int kw) if (evalop(priority[END])!=0) return 0; if (op!=&ops[1] || vp!=&vals[1]) { - error(ERROR, "Botch in #if/#elsif"); + error(ERROR, "Botch in #if/#elif"); return 0; } if (vals[0].type==UND) error(ERROR, "Undefined expression value"); return vals[0].val; syntax: - error(ERROR, "Syntax error in #if/#elsif"); + error(ERROR, "Syntax error in #if/#elif"); return 0; } @@ -444,7 +444,7 @@ tokval(Token *tp) ; else { error(ERROR, - "Bad number %t in #if/#elsif", tp); + "Bad number %t in #if/#elif", tp); break; } } @@ -508,7 +508,7 @@ tokval(Token *tp) break; case STRING: - error(ERROR, "String in #if/#elsif"); + error(ERROR, "String in #if/#elif"); break; } return v; From 9961b0a59e3c8c7db56fc269a857d5568a85a368 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 4 Oct 2015 16:13:03 -0400 Subject: [PATCH 5/7] cpp - long literal characters. L'\x80' won't error because character > 127. --- cpp/eval.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cpp/eval.c b/cpp/eval.c index 9cfbfa6e..9f64f072 100644 --- a/cpp/eval.c +++ b/cpp/eval.c @@ -395,7 +395,7 @@ tokval(Token *tp) { struct value v; Nlist *np; - int i, base, c; + int i, base, c, longcc; unsigned long n; uchar *p; @@ -455,9 +455,10 @@ tokval(Token *tp) case CCON: n = 0; p = tp->t; + longcc = 0; if (*p=='L') { p += 1; - error(WARNING, "Wide char constant value undefined"); + longcc = 1; } p += 1; if (*p=='\\') { @@ -502,7 +503,7 @@ tokval(Token *tp) n = *p++; if (*p!='\'') error(WARNING, "Multibyte character constant undefined"); - else if (n>127) + else if (n>127 && longcc==0) error(WARNING, "Character constant taken as not signed"); v.val = n; break; From be40edf56b433321ab64d350593d94880ce3bb12 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 4 Oct 2015 16:13:27 -0400 Subject: [PATCH 6/7] cpp - support \a in string literals. --- cpp/eval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/eval.c b/cpp/eval.c index 9f64f072..7c067e89 100644 --- a/cpp/eval.c +++ b/cpp/eval.c @@ -485,7 +485,7 @@ tokval(Token *tp) } } else { static char cvcon[] - = "b\bf\fn\nr\rt\tv\v''\"\"??\\\\"; + = "a\ab\bf\fn\nr\rt\tv\v''\"\"??\\\\"; for (i=0; i Date: Sun, 4 Oct 2015 16:17:48 -0400 Subject: [PATCH 7/7] cpp - variadic macros (c99) and updates to prevent ## concatenation when inappropriate. --- cpp/cpp.c | 4 ++-- cpp/cpp.h | 9 ++++++--- cpp/eval.c | 4 ++-- cpp/include.c | 2 +- cpp/macro.c | 40 +++++++++++++++++++++++++++++----------- 5 files changed, 40 insertions(+), 19 deletions(-) diff --git a/cpp/cpp.c b/cpp/cpp.c index 82d67935..d3ec8bcc 100644 --- a/cpp/cpp.c +++ b/cpp/cpp.c @@ -73,7 +73,7 @@ process(Tokenrow *trp) trp->tp += 1; control(trp); } else if (!skipping && anymacros) - expandrow(trp, NULL); + expandrow(trp, NULL, Notinmacro); if (skipping) setempty(trp); puttokens(trp); @@ -217,7 +217,7 @@ control(Tokenrow *trp) case KLINE: trp->tp = tp+1; - expandrow(trp, ""); + expandrow(trp, "", Notinmacro); tp = trp->bp+2; kline: if (tp+1>=trp->lp || tp->type!=NUMBER || tp+3lp diff --git a/cpp/cpp.h b/cpp/cpp.h index d307cd68..39e86a62 100644 --- a/cpp/cpp.h +++ b/cpp/cpp.h @@ -33,11 +33,14 @@ enum kwtype { KIF, KIFDEF, KIFNDEF, KELIF, KELSE, KENDIF, KINCLUDE, KDEFINE, #define ISKW 02 /* is PP keyword */ #define ISUNCHANGE 04 /* can't be #defined in PP */ #define ISMAC 010 /* builtin macro, e.g. __LINE__ */ +#define ISVARMAC 020 /* variadic macro */ #define EOB 0xFE /* sentinel for end of input buffer */ #define EOFC 0xFD /* sentinel for end of input file */ #define XPWS 1 /* token flag: white space to assure token sep. */ +enum { Notinmacro, Inmacro }; + typedef struct token { unsigned char type; unsigned char flag; @@ -112,11 +115,11 @@ void dodefine(Tokenrow *); void doadefine(Tokenrow *, int); void doinclude(Tokenrow *); void doif(Tokenrow *, enum kwtype); -void expand(Tokenrow *, Nlist *); +void expand(Tokenrow *, Nlist *, int); void builtin(Tokenrow *, int); -int gatherargs(Tokenrow *, Tokenrow **, int *); +int gatherargs(Tokenrow *, Tokenrow **, int, int *); void substargs(Nlist *, Tokenrow *, Tokenrow **); -void expandrow(Tokenrow *, char *); +void expandrow(Tokenrow *, char *, int); void maketokenrow(int, Tokenrow *); Tokenrow *copytokenrow(Tokenrow *, Tokenrow *); Token *growtokenrow(Tokenrow *); diff --git a/cpp/eval.c b/cpp/eval.c index 7c067e89..02fa4bec 100644 --- a/cpp/eval.c +++ b/cpp/eval.c @@ -117,7 +117,7 @@ eval(Tokenrow *trp, int kw) } ntok = trp->tp - trp->bp; kwdefined->val = KDEFINED; /* activate special meaning of defined */ - expandrow(trp, ""); + expandrow(trp, "", Notinmacro); kwdefined->val = NAME; vp = vals; op = ops; @@ -441,7 +441,7 @@ tokval(Token *tp) if (*p=='u' || *p=='U') v.type = UNS; else if (*p=='l' || *p=='L') - ; + {} else { error(ERROR, "Bad number %t in #if/#elif", tp); diff --git a/cpp/include.c b/cpp/include.c index 3bae83f1..136ed941 100644 --- a/cpp/include.c +++ b/cpp/include.c @@ -20,7 +20,7 @@ doinclude(Tokenrow *trp) goto syntax; if (trp->tp->type!=STRING && trp->tp->type!=LT) { len = trp->tp - trp->bp; - expandrow(trp, ""); + expandrow(trp, "", Notinmacro); trp->tp = trp->bp+len; } if (trp->tp->type==STRING) { diff --git a/cpp/macro.c b/cpp/macro.c index 78e0e63c..1e3470a9 100644 --- a/cpp/macro.c +++ b/cpp/macro.c @@ -12,7 +12,9 @@ dodefine(Tokenrow *trp) Token *tp; Nlist *np; Tokenrow *def, *args; + int dots; + dots = 0; tp = trp->tp+1; if (tp>=trp->lp || tp->type!=NAME) { error(ERROR, "#defined token is not a name"); @@ -36,7 +38,9 @@ dodefine(Tokenrow *trp) int err = 0; for (;;) { Token *atp; - if (tp->type!=NAME) { + if (tp->type == ELLIPS) + dots++; + else if (tp->type!=NAME) { err++; break; } @@ -51,6 +55,8 @@ dodefine(Tokenrow *trp) tp += 1; if (tp->type==RP) break; + if (dots) + error(ERROR, "arguments after '...' in macro"); if (tp->type!=COMMA) { err++; break; @@ -83,6 +89,8 @@ dodefine(Tokenrow *trp) np->ap = args; np->vp = def; np->flag |= ISDEFINED; + if(dots) + np->flag |= ISVARMAC; } /* @@ -130,7 +138,7 @@ doadefine(Tokenrow *trp, int type) * Flag is NULL if more input can be gathered. */ void -expandrow(Tokenrow *trp, char *flag) +expandrow(Tokenrow *trp, char *flag, int inmacro) { Token *tp; Nlist *np; @@ -162,7 +170,7 @@ expandrow(Tokenrow *trp, char *flag) if (np->flag&ISMAC) builtin(trp, np->val); else { - expand(trp, np); + expand(trp, np, inmacro); } tp = trp->tp; } @@ -176,7 +184,7 @@ expandrow(Tokenrow *trp, char *flag) * (ordinarily the beginning of the expansion) */ void -expand(Tokenrow *trp, Nlist *np) +expand(Tokenrow *trp, Nlist *np, int inmacro) { Tokenrow ntr; int ntokc, narg, i; @@ -188,8 +196,9 @@ expand(Tokenrow *trp, Nlist *np) if (np->ap==NULL) /* parameterless */ ntokc = 1; else { - ntokc = gatherargs(trp, atr, &narg); + ntokc = gatherargs(trp, atr, (np->flag&ISVARMAC) ? rowlen(np->ap) : 0, &narg); if (narg<0) { /* not actually a call (no '(') */ +/* error(WARNING, "%d %r\n", narg, trp); */ /* gatherargs has already pushed trp->tr to the next token */ return; } @@ -205,7 +214,8 @@ expand(Tokenrow *trp, Nlist *np) dofree(atr[i]); } } - doconcat(&ntr); /* execute ## operators */ + if(!inmacro) + doconcat(&ntr); /* execute ## operators */ hs = newhideset(trp->tp->hideset, np); for (tp=ntr.bp; tptype==NAME) { @@ -228,7 +238,7 @@ expand(Tokenrow *trp, Nlist *np) * trp->tp is not changed relative to the tokenrow. */ int -gatherargs(Tokenrow *trp, Tokenrow **atr, int *narg) +gatherargs(Tokenrow *trp, Tokenrow **atr, int dots, int *narg) { int parens = 1; int ntok = 0; @@ -245,8 +255,10 @@ gatherargs(Tokenrow *trp, Tokenrow **atr, int *narg) if (trp->tp >= trp->lp) { gettokens(trp, 0); if ((trp->lp-1)->type==END) { +/* error(WARNING, "reach END\n"); */ trp->lp -= 1; - trp->tp -= ntok; + if (*narg>=0) + trp->tp -= ntok; return ntok; } } @@ -301,7 +313,9 @@ gatherargs(Tokenrow *trp, Tokenrow **atr, int *narg) parens--; if (lp->type==DSHARP) lp->type = DSHARP1; /* ## not special in arg */ - if (lp->type==COMMA && parens==0 || parens<0 && (lp-1)->type!=LP) { + if ((lp->type==COMMA && parens==0) || (parens<0 && (lp-1)->type!=LP)) { + if (lp->type == COMMA && dots && *narg == dots-1) + continue; if (*narg>=NARG-1) error(FATAL, "Sorry, too many macro arguments"); ttr.bp = ttr.tp = bp; @@ -339,12 +353,14 @@ substargs(Nlist *np, Tokenrow *rtr, Tokenrow **atr) } if (rtr->tp->type==NAME && (argno = lookuparg(np, rtr->tp)) >= 0) { + if (rtr->tp < rtr->bp) + error(ERROR, "access out of bounds"); if ((rtr->tp+1)lp && (rtr->tp+1)->type==DSHARP /* don't look beyond end */ || rtr->tp!=rtr->bp && (rtr->tp-1)->type==DSHARP) /* don't look before beginning */ insertrow(rtr, 1, atr[argno]); else { copytokenrow(&tatr, atr[argno]); - expandrow(&tatr, ""); + expandrow(&tatr, "", Inmacro); insertrow(rtr, 1, &tatr); dofree(tatr.bp); } @@ -407,6 +423,8 @@ lookuparg(Nlist *mac, Token *tp) if (tp->type!=NAME || mac->ap==NULL) return -1; + if((mac->flag & ISVARMAC) && strcmp((char*)tp->t, "__VA_ARGS__") == 0) + return rowlen(mac->ap) - 1; for (ap=mac->ap->bp; apap->lp; ap++) { if (ap->len==tp->len && strncmp((char*)ap->t,(char*)tp->t,ap->len)==0) return ap - mac->ap->bp; @@ -435,7 +453,7 @@ stringify(Tokenrow *vp) error(ERROR, "Stringified macro arg is too long"); break; } - if (tp->wslen && (tp->flag&XPWS)==0) + if (tp->wslen /* && (tp->flag&XPWS)==0 */) *sp++ = ' '; for (i=0, cp=tp->t; ilen; i++) { if (instring && (*cp=='"' || *cp=='\\'))