Fix issues with numeric SUBSEP and large SUBSEP values

This commit is contained in:
Cody Peter Mello 2018-09-17 11:59:04 -07:00
parent 2dc7e5ff1a
commit 97a4b7ed21
9 changed files with 53 additions and 5 deletions

1
awk.h
View File

@ -100,6 +100,7 @@ extern Cell *fnrloc; /* FNR */
extern Cell *nfloc; /* NF */ extern Cell *nfloc; /* NF */
extern Cell *rstartloc; /* RSTART */ extern Cell *rstartloc; /* RSTART */
extern Cell *rlengthloc; /* RLENGTH */ extern Cell *rlengthloc; /* RLENGTH */
extern Cell *subseploc; /* SUBSEP */
/* Cell.tval values: */ /* Cell.tval values: */
#define NUM 01 /* number value is valid */ #define NUM 01 /* number value is valid */

View File

@ -23,3 +23,9 @@ and also if CONVFMT changed.
7. unary-plus: Unary plus on a string constant returned the string. 7. unary-plus: Unary plus on a string constant returned the string.
Instead, it should convert the value to numeric and give that value. Instead, it should convert the value to numeric and give that value.
X. numeric-subsep: If SUBSEP was set to a numeric value, then its string
value wouldn't always be generated before being needed.
X. subsep-overflow: The length of SUBSEP needs to be rechecked after
calling execute(), in case SUBSEP itself has been changed.

View File

@ -0,0 +1,5 @@
BEGIN {
SUBSEP = 123.456;
a["hello", "world"] = "foo";
print a["hello" SUBSEP "world"];
}

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@
foo

View File

@ -0,0 +1,24 @@
function foo(c, n) {
s = "";
for (i = 0; i < n; i++) {
s = s c;
}
return s;
}
BEGIN {
str1 = foo("a", 4500);
str2 = foo("b", 9000);
a[(SUBSEP = str1), (SUBSEP = str2), "c"] = 1;
for (k in a) {
print length(k);
}
print (((SUBSEP = str1), (SUBSEP = str2), "c") in a);
print (((SUBSEP = str1) SUBSEP (SUBSEP = str2) SUBSEP "c") in a);
delete a[(SUBSEP = str1), (SUBSEP = str2), "c"];
print (((SUBSEP = str1), (SUBSEP = str2), "c") in a);
print (((SUBSEP = str1) SUBSEP (SUBSEP = str2) SUBSEP "c") in a);
}

View File

@ -0,0 +1,5 @@
27001
1
1
0
0

9
run.c
View File

@ -462,7 +462,7 @@ Cell *array(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */
Node *np; Node *np;
char *buf; char *buf;
int bufsz = recsize; int bufsz = recsize;
int nsub = strlen(*SUBSEP); int nsub;
if ((buf = (char *) malloc(bufsz)) == NULL) if ((buf = (char *) malloc(bufsz)) == NULL)
FATAL("out of memory in array"); FATAL("out of memory in array");
@ -472,6 +472,7 @@ Cell *array(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */
for (np = a[1]; np; np = np->nnext) { for (np = a[1]; np; np = np->nnext) {
y = execute(np); /* subscript */ y = execute(np); /* subscript */
s = getsval(y); s = getsval(y);
nsub = strlen(getsval(subseploc));
if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "array")) if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "array"))
FATAL("out of memory for %s[%s...]", x->nval, buf); FATAL("out of memory for %s[%s...]", x->nval, buf);
strcat(buf, s); strcat(buf, s);
@ -500,7 +501,7 @@ Cell *awkdelete(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts *
Cell *x, *y; Cell *x, *y;
Node *np; Node *np;
char *s; char *s;
int nsub = strlen(*SUBSEP); int nsub;
x = execute(a[0]); /* Cell* for symbol table */ x = execute(a[0]); /* Cell* for symbol table */
if (!isarr(x)) if (!isarr(x))
@ -519,6 +520,7 @@ Cell *awkdelete(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts *
for (np = a[1]; np; np = np->nnext) { for (np = a[1]; np; np = np->nnext) {
y = execute(np); /* subscript */ y = execute(np); /* subscript */
s = getsval(y); s = getsval(y);
nsub = strlen(getsval(subseploc));
if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "awkdelete")) if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "awkdelete"))
FATAL("out of memory deleting %s[%s...]", x->nval, buf); FATAL("out of memory deleting %s[%s...]", x->nval, buf);
strcat(buf, s); strcat(buf, s);
@ -540,7 +542,7 @@ Cell *intest(Node **a, int n) /* a[0] is index (list), a[1] is symtab */
char *buf; char *buf;
char *s; char *s;
int bufsz = recsize; int bufsz = recsize;
int nsub = strlen(*SUBSEP); int nsub;
ap = execute(a[1]); /* array name */ ap = execute(a[1]); /* array name */
if (!isarr(ap)) { if (!isarr(ap)) {
@ -558,6 +560,7 @@ Cell *intest(Node **a, int n) /* a[0] is index (list), a[1] is symtab */
for (p = a[0]; p; p = p->nnext) { for (p = a[0]; p; p = p->nnext) {
x = execute(p); /* expr */ x = execute(p); /* expr */
s = getsval(x); s = getsval(x);
nsub = strlen(getsval(subseploc));
if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "intest")) if (!adjbuf(&buf, &bufsz, strlen(buf)+strlen(s)+nsub+1, recsize, 0, "intest"))
FATAL("out of memory deleting %s[%s...]", x->nval, buf); FATAL("out of memory deleting %s[%s...]", x->nval, buf);
strcat(buf, s); strcat(buf, s);

4
tran.c
View File

@ -59,6 +59,7 @@ Array *ARGVtab; /* symbol table containing ARGV[...] */
Array *ENVtab; /* symbol table containing ENVIRON[...] */ Array *ENVtab; /* symbol table containing ENVIRON[...] */
Cell *rstartloc; /* RSTART */ Cell *rstartloc; /* RSTART */
Cell *rlengthloc; /* RLENGTH */ Cell *rlengthloc; /* RLENGTH */
Cell *subseploc; /* SUBSEP */
Cell *symtabloc; /* SYMTAB */ Cell *symtabloc; /* SYMTAB */
Cell *nullloc; /* a guaranteed empty cell */ Cell *nullloc; /* a guaranteed empty cell */
@ -100,7 +101,8 @@ void syminit(void) /* initialize symbol table with builtin vars */
NR = &nrloc->fval; NR = &nrloc->fval;
fnrloc = setsymtab("FNR", "", 0.0, NUM, symtab); fnrloc = setsymtab("FNR", "", 0.0, NUM, symtab);
FNR = &fnrloc->fval; FNR = &fnrloc->fval;
SUBSEP = &setsymtab("SUBSEP", "\034", 0.0, STR|DONTFREE, symtab)->sval; subseploc = setsymtab("SUBSEP", "\034", 0.0, STR|DONTFREE, symtab);
SUBSEP = &subseploc->sval;
rstartloc = setsymtab("RSTART", "", 0.0, NUM, symtab); rstartloc = setsymtab("RSTART", "", 0.0, NUM, symtab);
RSTART = &rstartloc->fval; RSTART = &rstartloc->fval;
rlengthloc = setsymtab("RLENGTH", "", 0.0, NUM, symtab); rlengthloc = setsymtab("RLENGTH", "", 0.0, NUM, symtab);