more cleanups (#55)

* More cleanups:
- sprinkle const
- add a macro (setptr) that cheats const to temporarily NUL terminate strings
  remove casts from allocations
- use strdup instead of strlen+strcpy
- use x = malloc(sizeof(*x)) instead of x = malloc(sizeof(type of *x)))
- add -Wcast-qual (and casts through unitptr_t in the two macros we
  cheat (xfree, setptr)).

* More cleanups:
- add const
- use bounded sscanf
- use snprintf instead of sprintf

* More cleanup:
- use snprintf/strlcat instead of sprintf/strcat
- use %j instead of %l since we are casting to intmax_t/uintmax_t

* Merge the 3 copies of the code that evaluated array strings with separators
and convert them to keep track of lengths and use memcpy instead of strcat.
This commit is contained in:
zoulasc 2019-10-25 10:59:10 -04:00 committed by Arnold Robbins
parent 1d6ddfd9c0
commit 0d8778bbbb
4 changed files with 83 additions and 89 deletions

4
lib.c
View File

@ -79,7 +79,7 @@ void makefields(int n1, int n2) /* create $n1..$n2 inclusive */
if (fldtab[i] == NULL) if (fldtab[i] == NULL)
FATAL("out of space in makefields %d", i); FATAL("out of space in makefields %d", i);
*fldtab[i] = dollar1; *fldtab[i] = dollar1;
sprintf(temp, "%d", i); snprintf(temp, sizeof(temp), "%d", i);
fldtab[i]->nval = tostring(temp); fldtab[i]->nval = tostring(temp);
} }
} }
@ -259,7 +259,7 @@ char *getargv(int n) /* get ARGV[n] */
char *s, temp[50]; char *s, temp[50];
extern Array *ARGVtab; extern Array *ARGVtab;
sprintf(temp, "%d", n); snprintf(temp, sizeof(temp), "%d", n);
if (lookup(temp, ARGVtab) == NULL) if (lookup(temp, ARGVtab) == NULL)
return NULL; return NULL;
x = setsymtab(temp, "", 0.0, STR, ARGVtab); x = setsymtab(temp, "", 0.0, STR, ARGVtab);

View File

@ -133,10 +133,11 @@ int main(int argc, char *argv[])
fprintf(stderr, "maketab can't open %s!\n", argv[1]); fprintf(stderr, "maketab can't open %s!\n", argv[1]);
exit(1); exit(1);
} }
printf("static char *printname[%d] = {\n", SIZE); printf("static const char * const printname[%d] = {\n", SIZE);
i = 0; i = 0;
while (fgets(buf, sizeof buf, fp) != NULL) { while (fgets(buf, sizeof buf, fp) != NULL) {
n = sscanf(buf, "%1c %s %s %d", &c, def, name, &tok); // 199 is sizeof(def) - 1
n = sscanf(buf, "%1c %199s %199s %d", &c, def, name, &tok);
if (c != '#' || (n != 4 && strcmp(def,"define") != 0)) /* not a valid #define */ if (c != '#' || (n != 4 && strcmp(def,"define") != 0)) /* not a valid #define */
continue; continue;
if (strcmp(name, "YYSTYPE_IS_DECLARED") == 0) if (strcmp(name, "YYSTYPE_IS_DECLARED") == 0)
@ -146,7 +147,11 @@ int main(int argc, char *argv[])
continue; continue;
} }
names[tok-FIRSTTOKEN] = strdup(name); names[tok-FIRSTTOKEN] = strdup(name);
printf("\t(char *) \"%s\",\t/* %d */\n", name, tok); if (names[tok-FIRSTTOKEN] == NULL) {
fprintf(stderr, "maketab out of space copying %s", name);
continue;
}
printf("\t\"%s\",\t/* %d */\n", name, tok);
i++; i++;
} }
printf("};\n\n"); printf("};\n\n");
@ -161,14 +166,14 @@ int main(int argc, char *argv[])
printf("\t%s,\t/* %s */\n", table[i], names[i]); printf("\t%s,\t/* %s */\n", table[i], names[i]);
printf("};\n\n"); printf("};\n\n");
printf("char *tokname(int n)\n"); /* print a tokname() function */ printf("const char *tokname(int n)\n"); /* print a tokname() function */
printf("{\n"); printf("{\n");
printf(" static char buf[100];\n\n"); printf("\tstatic char buf[100];\n\n");
printf(" if (n < FIRSTTOKEN || n > LASTTOKEN) {\n"); printf("\tif (n < FIRSTTOKEN || n > LASTTOKEN) {\n");
printf(" sprintf(buf, \"token %%d\", n);\n"); printf("\t\tsnprintf(buf, sizeof(buf), \"token %%d\", n);\n");
printf(" return buf;\n"); printf("\t\treturn buf;\n");
printf(" }\n"); printf("\t}\n");
printf(" return printname[n-FIRSTTOKEN];\n"); printf("\treturn printname[n-FIRSTTOKEN];\n");
printf("}\n"); printf("}\n");
return 0; return 0;
} }

View File

@ -89,7 +89,7 @@ extern Node *pa2stat(Node *, Node *, Node *);
extern Node *linkum(Node *, Node *); extern Node *linkum(Node *, Node *);
extern void defn(Cell *, Node *, Node *); extern void defn(Cell *, Node *, Node *);
extern int isarg(const char *); extern int isarg(const char *);
extern char *tokname(int); extern const char *tokname(int);
extern Cell *(*proctab[])(Node **, int); extern Cell *(*proctab[])(Node **, int);
extern int ptoi(void *); extern int ptoi(void *);
extern Node *itonp(int); extern Node *itonp(int);

141
run.c
View File

@ -462,31 +462,50 @@ Cell *getnf(Node **a, int n) /* get NF */
return (Cell *) a[0]; return (Cell *) a[0];
} }
Cell *array(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */ static char *
makearraystring(Node *p, const char *func)
{ {
Cell *x, *y, *z;
char *s;
Node *np;
char *buf; char *buf;
int bufsz = recsize; int bufsz = recsize;
int nsub; size_t blen, seplen;
if ((buf = malloc(bufsz)) == NULL) if ((buf = malloc(bufsz)) == NULL) {
FATAL("out of memory in array"); FATAL("%s: out of memory", func);
}
blen = 0;
buf[blen] = '\0';
seplen = strlen(getsval(subseploc));
for (; p; p = p->nnext) {
Cell *x = execute(p); /* expr */
char *s = getsval(x);
size_t nsub = p->nnext ? seplen : 0;
size_t slen = strlen(s);
size_t tlen = blen + slen + nsub;
if (!adjbuf(&buf, &bufsz, tlen + 1, recsize, 0, func)) {
FATAL("%s: out of memory %s[%s...]",
func, x->nval, buf);
}
memcpy(buf + blen, s, slen);
if (nsub) {
memcpy(buf + blen + slen, *SUBSEP, nsub);
}
buf[tlen] = '\0';
blen = tlen;
tempfree(x);
}
return buf;
}
Cell *array(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */
{
Cell *x, *z;
char *buf;
x = execute(a[0]); /* Cell* for symbol table */ x = execute(a[0]); /* Cell* for symbol table */
buf[0] = 0; buf = makearraystring(a[1], __func__);
for (np = a[1]; np; np = np->nnext) {
y = execute(np); /* subscript */
s = getsval(y);
nsub = strlen(getsval(subseploc));
if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "array"))
FATAL("out of memory for %s[%s...]", x->nval, buf);
strcat(buf, s);
if (np->nnext)
strcat(buf, *SUBSEP);
tempfree(y);
}
if (!isarr(x)) { if (!isarr(x)) {
dprintf( ("making %s into an array\n", NN(x->nval)) ); dprintf( ("making %s into an array\n", NN(x->nval)) );
if (freeable(x)) if (freeable(x))
@ -505,10 +524,7 @@ Cell *array(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */
Cell *awkdelete(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */ Cell *awkdelete(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */
{ {
Cell *x, *y; Cell *x;
Node *np;
char *s;
int nsub;
x = execute(a[0]); /* Cell* for symbol table */ x = execute(a[0]); /* Cell* for symbol table */
if (x == symtabloc) { if (x == symtabloc) {
@ -522,22 +538,7 @@ Cell *awkdelete(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts *
x->tval |= ARR; x->tval |= ARR;
x->sval = (char *) makesymtab(NSYMTAB); x->sval = (char *) makesymtab(NSYMTAB);
} else { } else {
int bufsz = recsize; char *buf = makearraystring(a[1], __func__);
char *buf;
if ((buf = malloc(bufsz)) == NULL)
FATAL("out of memory in adelete");
buf[0] = 0;
for (np = a[1]; np; np = np->nnext) {
y = execute(np); /* subscript */
s = getsval(y);
nsub = strlen(getsval(subseploc));
if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "awkdelete"))
FATAL("out of memory deleting %s[%s...]", x->nval, buf);
strcat(buf, s);
if (np->nnext)
strcat(buf, *SUBSEP);
tempfree(y);
}
freeelem(x, buf); freeelem(x, buf);
free(buf); free(buf);
} }
@ -547,12 +548,8 @@ Cell *awkdelete(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts *
Cell *intest(Node **a, int n) /* a[0] is index (list), a[1] is symtab */ Cell *intest(Node **a, int n) /* a[0] is index (list), a[1] is symtab */
{ {
Cell *x, *ap, *k; Cell *ap, *k;
Node *p;
char *buf; char *buf;
char *s;
int bufsz = recsize;
int nsub;
ap = execute(a[1]); /* array name */ ap = execute(a[1]); /* array name */
if (!isarr(ap)) { if (!isarr(ap)) {
@ -563,21 +560,7 @@ Cell *intest(Node **a, int n) /* a[0] is index (list), a[1] is symtab */
ap->tval |= ARR; ap->tval |= ARR;
ap->sval = (char *) makesymtab(NSYMTAB); ap->sval = (char *) makesymtab(NSYMTAB);
} }
if ((buf = malloc(bufsz)) == NULL) { buf = makearraystring(a[0], __func__);
FATAL("out of memory in intest");
}
buf[0] = 0;
for (p = a[0]; p; p = p->nnext) {
x = execute(p); /* expr */
s = getsval(x);
nsub = strlen(getsval(subseploc));
if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "intest"))
FATAL("out of memory deleting %s[%s...]", x->nval, buf);
strcat(buf, s);
tempfree(x);
if (p->nnext)
strcat(buf, *SUBSEP);
}
k = lookup(buf, (Array *) ap->sval); k = lookup(buf, (Array *) ap->sval);
tempfree(ap); tempfree(ap);
free(buf); free(buf);
@ -835,6 +818,8 @@ int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like co
int fmtsz = recsize; int fmtsz = recsize;
char *buf = *pbuf; char *buf = *pbuf;
int bufsize = *pbufsize; int bufsize = *pbufsize;
#define FMTSZ(a) (fmtsz - ((a) - fmt))
#define BUFSZ(a) (bufsize - ((a) - buf))
static int first = 1; static int first = 1;
static int have_a_format = 0; static int have_a_format = 0;
@ -842,7 +827,7 @@ int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like co
if (first) { if (first) {
char buf[100]; char buf[100];
sprintf(buf, "%a", 42.0); snprintf(buf, sizeof(buf), "%a", 42.0);
have_a_format = (strcmp(buf, "0x1.5p+5") == 0); have_a_format = (strcmp(buf, "0x1.5p+5") == 0);
first = 0; first = 0;
} }
@ -881,7 +866,8 @@ int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like co
} }
x = execute(a); x = execute(a);
a = a->nnext; a = a->nnext;
sprintf(t-1, "%d", fmtwd=(int) getfval(x)); snprintf(t - 1, FMTSZ(t - 1),
"%d", fmtwd=(int) getfval(x));
if (fmtwd < 0) if (fmtwd < 0)
fmtwd = -fmtwd; fmtwd = -fmtwd;
adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format"); adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format");
@ -906,12 +892,15 @@ int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like co
case 'd': case 'i': case 'd': case 'i':
flag = 'd'; flag = 'd';
if(*(s-1) == 'l') break; if(*(s-1) == 'l') break;
*(t-1) = 'l'; *(t-1) = 'j';
*t = 'd'; *t = 'd';
*++t = '\0'; *++t = '\0';
break; break;
case 'o': case 'x': case 'X': case 'u': case 'o': case 'x': case 'X': case 'u':
flag = *(s-1) == 'l' ? 'd' : 'u'; flag = *(s-1) == 'l' ? 'd' : 'u';
*(t-1) = 'j';
*t = *s;
*++t = '\0';
break; break;
case 's': case 's':
flag = 's'; flag = 's';
@ -933,20 +922,20 @@ int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like co
n = fmtwd; n = fmtwd;
adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format5"); adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format5");
switch (flag) { switch (flag) {
case '?': sprintf(p, "%s", fmt); /* unknown, so dump it too */ case '?': snprintf(p, BUFSZ(p), "%s", fmt); /* unknown, so dump it too */
t = getsval(x); t = getsval(x);
n = strlen(t); n = strlen(t);
if (fmtwd > n) if (fmtwd > n)
n = fmtwd; n = fmtwd;
adjbuf(&buf, &bufsize, 1+strlen(p)+n+p-buf, recsize, &p, "format6"); adjbuf(&buf, &bufsize, 1+strlen(p)+n+p-buf, recsize, &p, "format6");
p += strlen(p); p += strlen(p);
sprintf(p, "%s", t); snprintf(p, BUFSZ(p), "%s", t);
break; break;
case 'a': case 'a':
case 'A': case 'A':
case 'f': sprintf(p, fmt, getfval(x)); break; case 'f': snprintf(p, BUFSZ(p), fmt, getfval(x)); break;
case 'd': sprintf(p, fmt, (long) getfval(x)); break; case 'd': snprintf(p, BUFSZ(p), fmt, (long) getfval(x)); break;
case 'u': sprintf(p, fmt, (int) getfval(x)); break; case 'u': snprintf(p, BUFSZ(p), fmt, (int) getfval(x)); break;
case 's': case 's':
t = getsval(x); t = getsval(x);
n = strlen(t); n = strlen(t);
@ -954,18 +943,18 @@ int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like co
n = fmtwd; n = fmtwd;
if (!adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format7")) if (!adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format7"))
FATAL("huge string/format (%d chars) in printf %.30s... ran format() out of memory", n, t); FATAL("huge string/format (%d chars) in printf %.30s... ran format() out of memory", n, t);
sprintf(p, fmt, t); snprintf(p, BUFSZ(p), fmt, t);
break; break;
case 'c': case 'c':
if (isnum(x)) { if (isnum(x)) {
if ((int)getfval(x)) if ((int)getfval(x))
sprintf(p, fmt, (int) getfval(x)); snprintf(p, BUFSZ(p), fmt, (int) getfval(x));
else { else {
*p++ = '\0'; /* explicit null byte */ *p++ = '\0'; /* explicit null byte */
*p = '\0'; /* next output will start here */ *p = '\0'; /* next output will start here */
} }
} else } else
sprintf(p, fmt, getsval(x)[0]); snprintf(p, BUFSZ(p), fmt, getsval(x)[0]);
break; break;
default: default:
FATAL("can't happen: bad conversion %c in format()", flag); FATAL("can't happen: bad conversion %c in format()", flag);
@ -1303,7 +1292,7 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
pfa->initstat = 2; pfa->initstat = 2;
do { do {
n++; n++;
sprintf(num, "%d", n); snprintf(num, sizeof(num), "%d", n);
temp = *patbeg; temp = *patbeg;
setptr(patbeg, '\0'); setptr(patbeg, '\0');
if (is_number(s)) if (is_number(s))
@ -1314,7 +1303,7 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
s = patbeg + patlen; s = patbeg + patlen;
if (*(patbeg+patlen-1) == 0 || *s == 0) { if (*(patbeg+patlen-1) == 0 || *s == 0) {
n++; n++;
sprintf(num, "%d", n); snprintf(num, sizeof(num), "%d", n);
setsymtab(num, "", 0.0, STR, (Array *) ap->sval); setsymtab(num, "", 0.0, STR, (Array *) ap->sval);
pfa->initstat = tempstat; pfa->initstat = tempstat;
goto spdone; goto spdone;
@ -1324,7 +1313,7 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
/* cf gsub and refldbld */ /* cf gsub and refldbld */
} }
n++; n++;
sprintf(num, "%d", n); snprintf(num, sizeof(num), "%d", n);
if (is_number(s)) if (is_number(s))
setsymtab(num, s, atof(s), STR|NUM, (Array *) ap->sval); setsymtab(num, s, atof(s), STR|NUM, (Array *) ap->sval);
else else
@ -1344,7 +1333,7 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0'); while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0');
temp = *s; temp = *s;
setptr(s, '\0'); setptr(s, '\0');
sprintf(num, "%d", n); snprintf(num, sizeof(num), "%d", n);
if (is_number(t)) if (is_number(t))
setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval); setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval);
else else
@ -1357,7 +1346,7 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
for (n = 0; *s != 0; s++) { for (n = 0; *s != 0; s++) {
char buf[2]; char buf[2];
n++; n++;
sprintf(num, "%d", n); snprintf(num, sizeof(num), "%d", n);
buf[0] = *s; buf[0] = *s;
buf[1] = 0; buf[1] = 0;
if (isdigit((uschar)buf[0])) if (isdigit((uschar)buf[0]))
@ -1373,7 +1362,7 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
s++; s++;
temp = *s; temp = *s;
setptr(s, '\0'); setptr(s, '\0');
sprintf(num, "%d", n); snprintf(num, sizeof(num), "%d", n);
if (is_number(t)) if (is_number(t))
setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval); setsymtab(num, t, atof(t), STR|NUM, (Array *) ap->sval);
else else