Merge pull request #27 from junghans/fix_parallel_build
fixed parallel build
diff --git a/ChangeLog b/ChangeLog
index 17715fc..59d4b07 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-08-29 Arnold D. Robbins <arnold@skeeve.com>
+
+ * REGRESS: Check for existence of a.out. If not there, run
+ make. Enable core dumps for T.arnold system status test
+ to work on MacOS X.
+
2018-08-22 Arnold D. Robbins <arnold@skeeve.com>
* awktest.tar (testdir/T.expr): Fix test for unary plus.
diff --git a/REGRESS b/REGRESS
index facbd83..7d3ded6 100755
--- a/REGRESS
+++ b/REGRESS
@@ -1,5 +1,15 @@
#! /bin/sh
+case `uname` in
+CYGWIN) EXE=a.exe ;;
+*) EXE=a.out ;;
+esac
+
+if [ ! -f $EXE ]
+then
+ make || exit 1
+fi
+
if [ -d testdir ]
then
true # do nothing
@@ -16,5 +26,10 @@
pwd
PATH=.:$PATH
export PATH
+if (ulimit -c unlimited > /dev/null 2>&1)
+then
+ # Workaround broken default on MacOS X
+ ulimit -c unlimited
+fi
REGRESS
diff --git a/awk.h b/awk.h
index 70097b9..ddf2466 100644
--- a/awk.h
+++ b/awk.h
@@ -97,9 +97,14 @@
extern Cell *nrloc; /* NR */
extern Cell *fnrloc; /* FNR */
+extern Cell *fsloc; /* FS */
extern Cell *nfloc; /* NF */
+extern Cell *ofsloc; /* OFS */
+extern Cell *orsloc; /* ORS */
+extern Cell *rsloc; /* RS */
extern Cell *rstartloc; /* RSTART */
extern Cell *rlengthloc; /* RLENGTH */
+extern Cell *subseploc; /* SUBSEP */
/* Cell.tval values: */
#define NUM 01 /* number value is valid */
diff --git a/b.c b/b.c
index 89a7841..a54a234 100644
--- a/b.c
+++ b/b.c
@@ -823,7 +823,15 @@
if (cc->cc_name != NULL && prestr[1 + cc->cc_namelen] == ':' &&
prestr[2 + cc->cc_namelen] == ']') {
prestr += cc->cc_namelen + 3;
- for (i = 0; i < NCHARS; i++) {
+ /*
+ * BUG: We begin at 1, instead of 0, since we
+ * would otherwise prematurely terminate the
+ * string for classes like [[:cntrl:]]. This
+ * means that we can't match the NUL character,
+ * not without first adapting the entire
+ * program to track each string's length.
+ */
+ for (i = 1; i < NCHARS; i++) {
if (!adjbuf((char **) &buf, &bufsz, bp-buf+1, 100, (char **) &bp, "relex2"))
FATAL("out of space for reg expr %.10s...", lastre);
if (cc->cc_func(i)) {
diff --git a/bugs-fixed/README b/bugs-fixed/README
index 222ef68..9c644f9 100644
--- a/bugs-fixed/README
+++ b/bugs-fixed/README
@@ -23,3 +23,32 @@
7. unary-plus: Unary plus on a string constant returned the string.
Instead, it should convert the value to numeric and give that value.
+
+8. concat-assign-same: Concatenation previously evaluated both sides of the
+expression before doing its work, which, since assign() evaluates to the cell
+being assigned to, meant that expressions like "print (a = 1) (a = 2)" would
+print "22" rather than "12".
+
+9. missing-precision: When using the format string "%*s", the precision
+argument was used without checking if it was present first.
+
+10. missing-precision: When using the format string "%*s", the precision
+argument was used without checking if it was present first.
+
+11. fmt-overflow: The buffer used for OFMT/CONVFMT conversions was written
+to with sprintf(), which meant that some conversions could write past the
+end.
+
+12. numeric-subsep, numeric-fs, numeric-output-seps, numerics-rs: If SUBSEP,
+FS, RS, OFS, or ORS were set to a numeric value, then their string values
+wouldn't always be generated before being needed.
+
+13. subsep-overflow: The length of SUBSEP needs to be rechecked after
+calling execute(), in case SUBSEP itself has been changed.
+
+14. split-fs-from-array: If the third argument to split() comes from the
+array passed as the second argument, then split() would previously read
+from the freed memory and possibly produce incorrect results (depending
+on the system's malloc()/free() behaviour.)
+
+
diff --git a/bugs-fixed/concat-assign-same.awk b/bugs-fixed/concat-assign-same.awk
new file mode 100644
index 0000000..ed19f35
--- /dev/null
+++ b/bugs-fixed/concat-assign-same.awk
@@ -0,0 +1,4 @@
+BEGIN {
+ print (a = 1) (a = 2) (a = 3) (a = 4) (a = 5);
+ print (a = 1), (a = 2), (a = 3), (a = 4), (a = 5);
+}
diff --git a/bugs-fixed/concat-assign-same.bad b/bugs-fixed/concat-assign-same.bad
new file mode 100644
index 0000000..294725b
--- /dev/null
+++ b/bugs-fixed/concat-assign-same.bad
@@ -0,0 +1,2 @@
+22345
+1 2 3 4 5
diff --git a/bugs-fixed/concat-assign-same.ok b/bugs-fixed/concat-assign-same.ok
new file mode 100644
index 0000000..4475052
--- /dev/null
+++ b/bugs-fixed/concat-assign-same.ok
@@ -0,0 +1,2 @@
+12345
+1 2 3 4 5
diff --git a/bugs-fixed/fmt-overflow.awk b/bugs-fixed/fmt-overflow.awk
new file mode 100644
index 0000000..bf5877e
--- /dev/null
+++ b/bugs-fixed/fmt-overflow.awk
@@ -0,0 +1 @@
+BEGIN { OFMT = "%.1000f"; print 1.25; }
diff --git a/bugs-fixed/fmt-overflow.ok b/bugs-fixed/fmt-overflow.ok
new file mode 100644
index 0000000..5f7449e
--- /dev/null
+++ b/bugs-fixed/fmt-overflow.ok
@@ -0,0 +1 @@
+1.2500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
diff --git a/bugs-fixed/fs-overflow.awk b/bugs-fixed/fs-overflow.awk
new file mode 100644
index 0000000..be10f5a
--- /dev/null
+++ b/bugs-fixed/fs-overflow.awk
@@ -0,0 +1,13 @@
+function foo() {
+ a = "";
+ for (i = 0; i < 10000; i++) {
+ a = a "c";
+ }
+ return a;
+}
+
+BEGIN {
+ FS = foo();
+ $0="foo";
+ print $1;
+}
diff --git a/bugs-fixed/missing-precision.awk b/bugs-fixed/missing-precision.awk
new file mode 100644
index 0000000..4e7a74b
--- /dev/null
+++ b/bugs-fixed/missing-precision.awk
@@ -0,0 +1 @@
+BEGIN { printf("%*s"); }
diff --git a/bugs-fixed/missing-precision.ok b/bugs-fixed/missing-precision.ok
new file mode 100644
index 0000000..608b4fa
--- /dev/null
+++ b/bugs-fixed/missing-precision.ok
@@ -0,0 +1,2 @@
+./a.out: not enough args in printf(%*s)
+ source line number 1
diff --git a/bugs-fixed/negative-nf.awk b/bugs-fixed/negative-nf.awk
new file mode 100644
index 0000000..6caeee4
--- /dev/null
+++ b/bugs-fixed/negative-nf.awk
@@ -0,0 +1 @@
+BEGIN { NF = -5; }
diff --git a/bugs-fixed/negative-nf.ok b/bugs-fixed/negative-nf.ok
new file mode 100644
index 0000000..71c8604
--- /dev/null
+++ b/bugs-fixed/negative-nf.ok
@@ -0,0 +1,2 @@
+./a.out: cannot set NF to a negative value
+ source line number 1
diff --git a/bugs-fixed/nf-self-assign.awk b/bugs-fixed/nf-self-assign.awk
new file mode 100644
index 0000000..6ae29ee
--- /dev/null
+++ b/bugs-fixed/nf-self-assign.awk
@@ -0,0 +1,6 @@
+BEGIN {
+ $0="a b c";
+ OFS=",";
+ NF = NF;
+ print;
+}
diff --git a/bugs-fixed/nf-self-assign.bad b/bugs-fixed/nf-self-assign.bad
new file mode 100644
index 0000000..3774da6
--- /dev/null
+++ b/bugs-fixed/nf-self-assign.bad
@@ -0,0 +1 @@
+a b c
diff --git a/bugs-fixed/nf-self-assign.ok b/bugs-fixed/nf-self-assign.ok
new file mode 100644
index 0000000..b2ffb02
--- /dev/null
+++ b/bugs-fixed/nf-self-assign.ok
@@ -0,0 +1 @@
+a,b,c
diff --git a/bugs-fixed/numeric-fs.awk b/bugs-fixed/numeric-fs.awk
new file mode 100644
index 0000000..01e438d
--- /dev/null
+++ b/bugs-fixed/numeric-fs.awk
@@ -0,0 +1,5 @@
+BEGIN {
+ FS = 0; split("20202", a); print a[1];
+ FS = 1; $0="31313"; print $1;
+ FS = 2; "echo 42424" | getline; print $1;
+}
diff --git a/bugs-fixed/numeric-fs.ok b/bugs-fixed/numeric-fs.ok
new file mode 100644
index 0000000..dcf37cd
--- /dev/null
+++ b/bugs-fixed/numeric-fs.ok
@@ -0,0 +1,3 @@
+2
+3
+4
diff --git a/bugs-fixed/numeric-output-seps.awk b/bugs-fixed/numeric-output-seps.awk
new file mode 100644
index 0000000..daa0f72
--- /dev/null
+++ b/bugs-fixed/numeric-output-seps.awk
@@ -0,0 +1,8 @@
+BEGIN {
+ $0 = "a b c";
+ OFS = 1;
+ ORS = 2;
+ NF = 2;
+ print;
+ print "d", "e";
+}
diff --git a/bugs-fixed/numeric-output-seps.bad b/bugs-fixed/numeric-output-seps.bad
new file mode 100644
index 0000000..95310f7
--- /dev/null
+++ b/bugs-fixed/numeric-output-seps.bad
@@ -0,0 +1,2 @@
+a b
+d e
diff --git a/bugs-fixed/numeric-output-seps.ok b/bugs-fixed/numeric-output-seps.ok
new file mode 100644
index 0000000..de6b202
--- /dev/null
+++ b/bugs-fixed/numeric-output-seps.ok
@@ -0,0 +1 @@
+a1b2d1e2
\ No newline at end of file
diff --git a/bugs-fixed/numeric-rs.awk b/bugs-fixed/numeric-rs.awk
new file mode 100644
index 0000000..cc7a0a0
--- /dev/null
+++ b/bugs-fixed/numeric-rs.awk
@@ -0,0 +1,6 @@
+BEGIN {
+ RS = 1;
+ while ("echo a1b1c1d" | getline > 0) {
+ print $1;
+ }
+}
diff --git a/bugs-fixed/numeric-rs.bad b/bugs-fixed/numeric-rs.bad
new file mode 100644
index 0000000..2027bc6
--- /dev/null
+++ b/bugs-fixed/numeric-rs.bad
@@ -0,0 +1 @@
+a1b1c1d
diff --git a/bugs-fixed/numeric-rs.ok b/bugs-fixed/numeric-rs.ok
new file mode 100644
index 0000000..d68dd40
--- /dev/null
+++ b/bugs-fixed/numeric-rs.ok
@@ -0,0 +1,4 @@
+a
+b
+c
+d
diff --git a/bugs-fixed/numeric-subsep.awk b/bugs-fixed/numeric-subsep.awk
new file mode 100644
index 0000000..1252e4a
--- /dev/null
+++ b/bugs-fixed/numeric-subsep.awk
@@ -0,0 +1,5 @@
+BEGIN {
+ SUBSEP = 123.456;
+ a["hello", "world"] = "foo";
+ print a["hello" SUBSEP "world"];
+}
diff --git a/bugs-fixed/numeric-subsep.bad b/bugs-fixed/numeric-subsep.bad
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/bugs-fixed/numeric-subsep.bad
@@ -0,0 +1 @@
+
diff --git a/bugs-fixed/numeric-subsep.ok b/bugs-fixed/numeric-subsep.ok
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/bugs-fixed/numeric-subsep.ok
@@ -0,0 +1 @@
+foo
diff --git a/bugs-fixed/split-fs-from-array.awk b/bugs-fixed/split-fs-from-array.awk
new file mode 100644
index 0000000..fce1607
--- /dev/null
+++ b/bugs-fixed/split-fs-from-array.awk
@@ -0,0 +1,5 @@
+BEGIN {
+ a[1] = "elephantie"
+ a[2] = "e"
+ print split(a[1],a,a[2]), a[2], a[3], split(a[2],a,a[2])
+}
diff --git a/bugs-fixed/split-fs-from-array.ok b/bugs-fixed/split-fs-from-array.ok
new file mode 100644
index 0000000..9402b94
--- /dev/null
+++ b/bugs-fixed/split-fs-from-array.ok
@@ -0,0 +1 @@
+4 l phanti 2
diff --git a/bugs-fixed/subsep-overflow.awk b/bugs-fixed/subsep-overflow.awk
new file mode 100644
index 0000000..66c7c24
--- /dev/null
+++ b/bugs-fixed/subsep-overflow.awk
@@ -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);
+}
diff --git a/bugs-fixed/subsep-overflow.ok b/bugs-fixed/subsep-overflow.ok
new file mode 100644
index 0000000..ddbbd78
--- /dev/null
+++ b/bugs-fixed/subsep-overflow.ok
@@ -0,0 +1,5 @@
+27001
+1
+1
+0
+0
diff --git a/lex.c b/lex.c
index d09f550..ad8e878 100644
--- a/lex.c
+++ b/lex.c
@@ -198,6 +198,7 @@
yylval.i = c;
switch (c) {
case '\n': /* {EOL} */
+ lineno++;
RET(NL);
case '\r': /* assume \n is coming */
case ' ': /* {WS}+ */
@@ -213,6 +214,7 @@
case '\\':
if (peek() == '\n') {
input();
+ lineno++;
} else if (peek() == '\r') {
input(); input(); /* \n */
lineno++;
@@ -370,10 +372,11 @@
case '\n':
case '\r':
case 0:
+ *bp = '\0';
SYNTAX( "non-terminated string %.10s...", buf );
- lineno++;
if (c == 0) /* hopeless */
FATAL( "giving up" );
+ lineno++;
break;
case '\\':
c = input();
@@ -515,6 +518,7 @@
if (!adjbuf(&buf, &bufsz, bp-buf+3, 500, &bp, "regexpr"))
FATAL("out of space for reg expr %.10s...", buf);
if (c == '\n') {
+ *bp = '\0';
SYNTAX( "newline in regular expression %.10s...", buf );
unput('\n');
break;
@@ -553,19 +557,19 @@
lexprog++;
} else /* awk -f ... */
c = pgetc();
- if (c == '\n')
- lineno++;
- else if (c == EOF)
+ if (c == EOF)
c = 0;
if (ep >= ebuf + sizeof ebuf)
ep = ebuf;
- return *ep++ = c;
+ *ep = c;
+ if (c != 0) {
+ ep++;
+ }
+ return (c);
}
void unput(int c) /* put lexical character back on input */
{
- if (c == '\n')
- lineno--;
if (yysptr >= yysbuf + sizeof(yysbuf))
FATAL("pushed back too much: %.20s...", yysbuf);
*yysptr++ = c;
diff --git a/lib.c b/lib.c
index ba6ebd4..f9cb6ca 100644
--- a/lib.c
+++ b/lib.c
@@ -59,7 +59,7 @@
{
if ( (record = (char *) malloc(n)) == NULL
|| (fields = (char *) malloc(n+1)) == NULL
- || (fldtab = (Cell **) malloc((nfields+1) * sizeof(Cell *))) == NULL
+ || (fldtab = (Cell **) malloc((nfields+2) * sizeof(Cell *))) == NULL
|| (fldtab[0] = (Cell *) malloc(sizeof(Cell))) == NULL )
FATAL("out of space for $0 and fields");
*fldtab[0] = dollar0;
@@ -189,12 +189,13 @@
int sep, c;
char *rr, *buf = *pbuf;
int bufsize = *pbufsize;
+ char *rs = getsval(rsloc);
- if (strlen(*FS) >= sizeof(inputFS))
+ if (strlen(getsval(fsloc)) >= sizeof (inputFS))
FATAL("field separator %.10s... is too long", *FS);
/*fflush(stdout); avoids some buffering problem but makes it 25% slower*/
strcpy(inputFS, *FS); /* for subsequent field splitting */
- if ((sep = **RS) == 0) {
+ if ((sep = *rs) == 0) {
sep = '\n';
while ((c=getc(inf)) == '\n' && c != EOF) /* skip leading \n's */
;
@@ -208,7 +209,7 @@
FATAL("input record `%.30s...' too long", buf);
*rr++ = c;
}
- if (**RS == sep || c == EOF)
+ if (*rs == sep || c == EOF)
break;
if ((c = getc(inf)) == '\n' || c == EOF) /* 2 in a row */
break;
@@ -283,6 +284,8 @@
}
fr = fields;
i = 0; /* number of fields accumulated here */
+ if (strlen(getsval(fsloc)) >= sizeof (inputFS))
+ FATAL("field separator %.10s... is too long", *FS);
strcpy(inputFS, *FS);
if (strlen(inputFS) > 1) { /* it's a regular expression */
i = refldbld(r, inputFS);
@@ -390,6 +393,8 @@
void setlastfld(int n) /* set lastfld cleaning fldtab cells if necessary */
{
+ if (n < 0)
+ FATAL("cannot set NF to a negative value");
if (n > nfields)
growfldtab(n);
@@ -479,6 +484,7 @@
{
int i;
char *r, *p;
+ char *sep = getsval(ofsloc);
if (donerec == 1)
return;
@@ -490,9 +496,9 @@
while ((*r = *p++) != 0)
r++;
if (i < *NF) {
- if (!adjbuf(&record, &recsize, 2+strlen(*OFS)+r-record, recsize, &r, "recbld 2"))
+ if (!adjbuf(&record, &recsize, 2+strlen(sep)+r-record, recsize, &r, "recbld 2"))
FATAL("created $0 `%.30s...' too long", record);
- for (p = *OFS; (*r = *p++) != 0; )
+ for (p = sep; (*r = *p++) != 0; )
r++;
}
}
diff --git a/main.c b/main.c
index a183c45..1c38a1e 100644
--- a/main.c
+++ b/main.c
@@ -88,7 +88,7 @@
exit(0);
break;
}
- if (strncmp(argv[1], "--", 2) == 0) { /* explicit end of args */
+ if (strcmp(argv[1], "--") == 0) { /* explicit end of args */
argc--;
argv++;
break;
diff --git a/run.c b/run.c
index 81b75da..ce30e93 100644
--- a/run.c
+++ b/run.c
@@ -462,7 +462,7 @@
Node *np;
char *buf;
int bufsz = recsize;
- int nsub = strlen(*SUBSEP);
+ int nsub;
if ((buf = (char *) malloc(bufsz)) == NULL)
FATAL("out of memory in array");
@@ -472,6 +472,7 @@
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);
@@ -500,7 +501,7 @@
Cell *x, *y;
Node *np;
char *s;
- int nsub = strlen(*SUBSEP);
+ int nsub;
x = execute(a[0]); /* Cell* for symbol table */
if (!isarr(x))
@@ -519,9 +520,10 @@
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);
+ strcat(buf, s);
if (np->nnext)
strcat(buf, *SUBSEP);
tempfree(y);
@@ -540,7 +542,7 @@
char *buf;
char *s;
int bufsz = recsize;
- int nsub = strlen(*SUBSEP);
+ int nsub;
ap = execute(a[1]); /* array name */
if (!isarr(ap)) {
@@ -558,6 +560,7 @@
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);
@@ -863,6 +866,9 @@
FATAL("'$' not permitted in awk formats");
}
if (*s == '*') {
+ if (a == NULL) {
+ FATAL("not enough args in printf(%s)", os);
+ }
x = execute(a);
a = a->nnext;
sprintf(t-1, "%d", fmtwd=(int) getfval(x));
@@ -1117,8 +1123,8 @@
y = execute(a[1]);
x = execute(a[0]);
if (n == ASSIGN) { /* ordinary assignment */
- if (x == y && !(x->tval & (FLD|REC))) /* self-assignment: */
- ; /* leave alone unless it's a field */
+ if (x == y && !(x->tval & (FLD|REC)) && x != nfloc)
+ ; /* self-assignment: leave alone unless it's a field or NF */
else if ((y->tval & (STR|NUM)) == (STR|NUM)) {
setsval(x, getsval(y));
x->fval = getfval(y);
@@ -1175,25 +1181,26 @@
{
Cell *x, *y, *z;
int n1, n2;
- char *s;
+ char *s = NULL;
+ int ssz = 0;
x = execute(a[0]);
+ n1 = strlen(getsval(x));
+ adjbuf(&s, &ssz, n1 + 1, recsize, 0, "cat1");
+ (void) strncpy(s, x->sval, ssz);
+
y = execute(a[1]);
- getsval(x);
- getsval(y);
- n1 = strlen(x->sval);
- n2 = strlen(y->sval);
- s = (char *) malloc(n1 + n2 + 1);
- if (s == NULL)
- FATAL("out of space concatenating %.15s... and %.15s...",
- x->sval, y->sval);
- strcpy(s, x->sval);
- strcpy(s+n1, y->sval);
+ n2 = strlen(getsval(y));
+ adjbuf(&s, &ssz, n1 + n2 + 1, recsize, 0, "cat2");
+ (void) strncpy(s + n1, y->sval, ssz - n1);
+
tempfree(x);
tempfree(y);
+
z = gettemp();
z->sval = s;
z->tval = STR;
+
return(z);
}
@@ -1240,18 +1247,20 @@
{
Cell *x = 0, *y, *ap;
char *s, *origs;
+ char *fs, *origfs = NULL;
int sep;
- char *t, temp, num[50], *fs = 0;
+ char *t, temp, num[50];
int n, tempstat, arg3type;
y = execute(a[0]); /* source string */
origs = s = strdup(getsval(y));
arg3type = ptoi(a[3]);
if (a[2] == 0) /* fs string */
- fs = *FS;
+ fs = getsval(fsloc);
else if (arg3type == STRING) { /* split(str,arr,"string") */
x = execute(a[2]);
- fs = getsval(x);
+ origfs = fs = strdup(getsval(x));
+ tempfree(x);
} else if (arg3type == REGEXPR)
fs = "(regexpr)"; /* split(str,arr,/regexpr/) */
else
@@ -1366,9 +1375,7 @@
tempfree(ap);
tempfree(y);
free(origs);
- if (a[2] != 0 && arg3type == STRING) {
- tempfree(x);
- }
+ free(origfs);
x = gettemp();
x->tval = NUM;
x->fval = n;
@@ -1630,9 +1637,9 @@
fputs(getpssval(y), fp);
tempfree(y);
if (x->nnext == NULL)
- fputs(*ORS, fp);
+ fputs(getsval(orsloc), fp);
else
- fputs(*OFS, fp);
+ fputs(getsval(ofsloc), fp);
}
if (a[1] != 0)
fflush(fp);
diff --git a/tran.c b/tran.c
index 72ca6ff..d1dfe2b 100644
--- a/tran.c
+++ b/tran.c
@@ -55,10 +55,14 @@
Cell *nrloc; /* NR */
Cell *nfloc; /* NF */
Cell *fnrloc; /* FNR */
+Cell *ofsloc; /* OFS */
+Cell *orsloc; /* ORS */
+Cell *rsloc; /* RS */
Array *ARGVtab; /* symbol table containing ARGV[...] */
Array *ENVtab; /* symbol table containing ENVIRON[...] */
Cell *rstartloc; /* RSTART */
Cell *rlengthloc; /* RLENGTH */
+Cell *subseploc; /* SUBSEP */
Cell *symtabloc; /* SYMTAB */
Cell *nullloc; /* a guaranteed empty cell */
@@ -88,9 +92,12 @@
fsloc = setsymtab("FS", " ", 0.0, STR|DONTFREE, symtab);
FS = &fsloc->sval;
- RS = &setsymtab("RS", "\n", 0.0, STR|DONTFREE, symtab)->sval;
- OFS = &setsymtab("OFS", " ", 0.0, STR|DONTFREE, symtab)->sval;
- ORS = &setsymtab("ORS", "\n", 0.0, STR|DONTFREE, symtab)->sval;
+ rsloc = setsymtab("RS", "\n", 0.0, STR|DONTFREE, symtab);
+ RS = &rsloc->sval;
+ ofsloc = setsymtab("OFS", " ", 0.0, STR|DONTFREE, symtab);
+ OFS = &ofsloc->sval;
+ orsloc = setsymtab("ORS", "\n", 0.0, STR|DONTFREE, symtab);
+ ORS = &orsloc->sval;
OFMT = &setsymtab("OFMT", "%.6g", 0.0, STR|DONTFREE, symtab)->sval;
CONVFMT = &setsymtab("CONVFMT", "%.6g", 0.0, STR|DONTFREE, symtab)->sval;
FILENAME = &setsymtab("FILENAME", "", 0.0, STR|DONTFREE, symtab)->sval;
@@ -100,7 +107,8 @@
NR = &nrloc->fval;
fnrloc = setsymtab("FNR", "", 0.0, NUM, symtab);
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);
RSTART = &rstartloc->fval;
rlengthloc = setsymtab("RLENGTH", "", 0.0, NUM, symtab);
@@ -310,6 +318,9 @@
} else if (isrec(vp)) {
donefld = 0; /* mark $1... invalid */
donerec = 1;
+ } else if (vp == ofsloc) {
+ if (donerec == 0)
+ recbld();
}
if (freeable(vp))
xfree(vp->sval); /* free any previous string */
@@ -351,7 +362,7 @@
} else if (isrec(vp)) {
donefld = 0; /* mark $1... invalid */
donerec = 1;
- } else if (&vp->sval == OFS) {
+ } else if (vp == ofsloc) {
if (donerec == 0)
recbld();
}
@@ -395,7 +406,7 @@
static char *get_str_val(Cell *vp, char **fmt) /* get string val of a Cell */
{
- char s[100]; /* BUG: unchecked */
+ char s[256];
double dtemp;
if ((vp->tval & (NUM | STR)) == 0)
@@ -434,9 +445,9 @@
if (freeable(vp)) \
xfree(vp->sval); \
if (modf(vp->fval, &dtemp) == 0) /* it's integral */ \
- sprintf(s, "%.30g", vp->fval); \
+ snprintf(s, sizeof (s), "%.30g", vp->fval); \
else \
- sprintf(s, *fmt, vp->fval); \
+ snprintf(s, sizeof (s), *fmt, vp->fval); \
vp->sval = tostring(s); \
vp->tval &= ~DONTFREE; \
vp->tval |= STR; \