aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2020-07-14 16:28:57 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-07-14 16:28:57 +0000
commit6d5400ecd75c83b97cfc956a8dbf3a0b73ab5559 (patch)
tree70e0904adf9530c2f0364095d7dc1516874dfd12
parent72a53614090734b362a59cc0c0820cbff3f9c025 (diff)
parenteb2cd7ae68a6e71a430ae136fa36a9d79a7b36c5 (diff)
downloadone-true-awk-6d5400ecd75c83b97cfc956a8dbf3a0b73ab5559.tar.gz
Merge "Upgrade one-true-awk to 2a4146ec3027d12e375209e03ed1c5a9ab230da4" am: 58e430dccd am: e38169383e am: dea496d8b1 am: eb2cd7ae68
Original change: https://android-review.googlesource.com/c/platform/external/one-true-awk/+/1361101 Change-Id: I46b31fb14f42bfe93759b13997f62dce091292a5
-rw-r--r--FIXES30
-rw-r--r--METADATA6
-rw-r--r--README.md13
-rwxr-xr-xREGRESS4
-rw-r--r--awk.h11
-rw-r--r--b.c10
-rwxr-xr-xbugs-fixed/REGRESS28
-rw-r--r--bugs-fixed/fs-overflow.ok1
-rw-r--r--bugs-fixed/missing-precision.ok2
-rw-r--r--bugs-fixed/negative-nf.ok2
-rw-r--r--lib.c36
-rw-r--r--main.c8
-rw-r--r--parse.c2
-rw-r--r--run.c59
-rw-r--r--tran.c34
15 files changed, 173 insertions, 73 deletions
diff --git a/FIXES b/FIXES
index e96cf33..9516a36 100644
--- a/FIXES
+++ b/FIXES
@@ -25,6 +25,36 @@ THIS SOFTWARE.
This file lists all bug fixes, changes, etc., made since the AWK book
was sent to the printers in August, 1987.
+July 2, 2020:
+ Merge PRs 85 and 86 which fix regressions. Thanks to
+ Tim van der Molen for the fixes.
+
+June 25, 2020:
+ Merge PRs 82 and 84. The latter fixes issue #83. Thanks to
+ Todd Miller and awkfan77.
+
+June 12, 2020:
+ Clear errno before calling errcheck to avoid any spurious errors
+ left over from previous calls that may have set it. Thanks to
+ Todd Miller for the fix, from PR #80.
+
+ Fix Issue #78 by allowing \r to follow floating point numbers in
+ lib.c:is_number. Thanks to GitHub user ajcarr for the report
+ and to Arnold Robbins for the fix.
+
+June 5, 2020:
+ In fldbld(), make sure that inputFS is set before trying to
+ use it. Thanks to Steffen Nurpmeso <steffen@sdaoden.eu>
+ for the report.
+
+May 5, 2020:
+ Fix checks for compilers that can handle noreturn. Thanks to
+ GitHub user enh-google for pointing it out. Closes Issue #79.
+
+April 16, 2020:
+ Handle old compilers that don't support C11 (for noreturn).
+ Thanks to Arnold Robbins.
+
April 5, 2020:
Use <stdnoreturn.h> and noreturn instead of GCC attributes.
Thanks to GitHub user awkfan77. Closes PR #77.
diff --git a/METADATA b/METADATA
index 8e26074..b15dff8 100644
--- a/METADATA
+++ b/METADATA
@@ -5,11 +5,11 @@ third_party {
type: GIT
value: "https://github.com/onetrueawk/awk.git"
}
- version: "c3d8f9c50011b7e8e19449b0712e700c0aeb8543"
+ version: "2a4146ec3027d12e375209e03ed1c5a9ab230da4"
license_type: NOTICE
last_upgrade_date {
year: 2020
- month: 4
- day: 6
+ month: 7
+ day: 10
}
}
diff --git a/README.md b/README.md
index ab6aae1..d451b82 100644
--- a/README.md
+++ b/README.md
@@ -104,5 +104,16 @@ astonishly slow. If `awk` seems slow, you might try fixing that.
More generally, turning on optimization can significantly improve
`awk`'s speed, perhaps by 1/3 for highest levels.
+## A Note About Maintenance
+
+NOTICE! Maintenance of this program is on a ``best effort''
+basis. We try to get to issues and pull requests as quickly
+as we can. Unfortunately, however, keeping this program going
+is not at the top of our priority list.
+
+_If_ you (yes, you!) are interested in taking over active maintenance of
+`awk`, please open an issue to indicate that fact, give a little bit of
+your background and some idea of your plans and dreams. Thanks!
+
#### Last Updated
-Wed Jan 1 22:44:38 IST 2020
+Thu Jul 2 21:39:31 IDT 2020
diff --git a/REGRESS b/REGRESS
index 7d3ded6..eb3b5d7 100755
--- a/REGRESS
+++ b/REGRESS
@@ -33,3 +33,7 @@ then
fi
REGRESS
+
+cd ..
+cd bugs-fixed
+REGRESS
diff --git a/awk.h b/awk.h
index 4e01325..cc30249 100644
--- a/awk.h
+++ b/awk.h
@@ -25,7 +25,11 @@ THIS SOFTWARE.
#include <assert.h>
#include <stdint.h>
#include <stdbool.h>
+#if __STDC_VERSION__ <= 199901L
+#define noreturn
+#else
#include <stdnoreturn.h>
+#endif
typedef double Awkfloat;
@@ -40,14 +44,13 @@ typedef unsigned char uschar;
*/
#define setptr(ptr, a) (*(char *)(intptr_t)(ptr)) = (a)
-#define NN(p) ((p) ? (p) : "(null)") /* guaranteed non-null for dprintf
+#define NN(p) ((p) ? (p) : "(null)") /* guaranteed non-null for DPRINTF
*/
#define DEBUG
#ifdef DEBUG
- /* uses have to be doubly parenthesized */
-# define dprintf(x) if (dbg) printf x
+# define DPRINTF(...) if (dbg) printf(__VA_ARGS__)
#else
-# define dprintf(x)
+# define DPRINTF(...)
#endif
extern enum compile_states {
diff --git a/b.c b/b.c
index 545fb7d..c167b50 100644
--- a/b.c
+++ b/b.c
@@ -397,7 +397,7 @@ char *cclenter(const char *argp) /* add a character class */
i++;
}
*bp = 0;
- dprintf( ("cclenter: in = |%s|, out = |%s|\n", op, buf) );
+ DPRINTF("cclenter: in = |%s|, out = |%s|\n", op, buf);
xfree(op);
return (char *) tostring((char *) buf);
}
@@ -733,7 +733,7 @@ Node *reparse(const char *p) /* parses regular expression pointed to by p */
{ /* uses relex() to scan regular expression */
Node *np;
- dprintf( ("reparse <%s>\n", p) );
+ DPRINTF("reparse <%s>\n", p);
lastre = prestr = (const uschar *) p; /* prestr points to string to be parsed */
rtok = relex();
/* GNU compatibility: an empty regexp matches anything */
@@ -1105,6 +1105,12 @@ rescan:
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)) {
+ /* escape backslash */
+ if (i == '\\') {
+ *bp++ = '\\';
+ n++;
+ }
+
*bp++ = i;
n++;
}
diff --git a/bugs-fixed/REGRESS b/bugs-fixed/REGRESS
new file mode 100755
index 0000000..0716003
--- /dev/null
+++ b/bugs-fixed/REGRESS
@@ -0,0 +1,28 @@
+#! /bin/bash
+
+if [ ! -f ../a.out ]
+then
+ echo Making executable
+ (cd .. ; make) || exit 0
+fi
+
+for i in *.awk
+do
+ echo === $i
+ OUT=${i%.awk}.OUT
+ OK=${i%.awk}.ok
+ IN=${i%.awk}.in
+ input=
+ if [ -f $IN ]
+ then
+ input=$IN
+ fi
+
+ ../a.out -f $i $input > $OUT 2>&1
+ if cmp -s $OK $OUT
+ then
+ rm -f $OUT
+ else
+ echo ++++ $i failed!
+ fi
+done
diff --git a/bugs-fixed/fs-overflow.ok b/bugs-fixed/fs-overflow.ok
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/bugs-fixed/fs-overflow.ok
@@ -0,0 +1 @@
+foo
diff --git a/bugs-fixed/missing-precision.ok b/bugs-fixed/missing-precision.ok
index 608b4fa..75e1e3d 100644
--- a/bugs-fixed/missing-precision.ok
+++ b/bugs-fixed/missing-precision.ok
@@ -1,2 +1,2 @@
-./a.out: not enough args in printf(%*s)
+../a.out: not enough args in printf(%*s)
source line number 1
diff --git a/bugs-fixed/negative-nf.ok b/bugs-fixed/negative-nf.ok
index 71c8604..de97f8b 100644
--- a/bugs-fixed/negative-nf.ok
+++ b/bugs-fixed/negative-nf.ok
@@ -1,2 +1,2 @@
-./a.out: cannot set NF to a negative value
+../a.out: cannot set NF to a negative value
source line number 1
diff --git a/lib.c b/lib.c
index 9665244..ab3ae53 100644
--- a/lib.c
+++ b/lib.c
@@ -147,8 +147,8 @@ int getrec(char **pbuf, int *pbufsize, bool isrecord) /* get next input record *
firsttime = false;
initgetrec();
}
- dprintf( ("RS=<%s>, FS=<%s>, ARGC=%g, FILENAME=%s\n",
- *RS, *FS, *ARGC, *FILENAME) );
+ DPRINTF("RS=<%s>, FS=<%s>, ARGC=%g, FILENAME=%s\n",
+ *RS, *FS, *ARGC, *FILENAME);
if (isrecord) {
donefld = false;
donerec = true;
@@ -157,7 +157,7 @@ int getrec(char **pbuf, int *pbufsize, bool isrecord) /* get next input record *
saveb0 = buf[0];
buf[0] = 0;
while (argno < *ARGC || infile == stdin) {
- dprintf( ("argno=%d, file=|%s|\n", argno, file) );
+ DPRINTF("argno=%d, file=|%s|\n", argno, file);
if (infile == NULL) { /* have to open a new file */
file = getargv(argno);
if (file == NULL || *file == '\0') { /* deleted or zapped */
@@ -170,7 +170,7 @@ int getrec(char **pbuf, int *pbufsize, bool isrecord) /* get next input record *
continue;
}
*FILENAME = file;
- dprintf( ("opening file %s\n", file) );
+ DPRINTF("opening file %s\n", file);
if (*file == '-' && *(file+1) == '\0')
infile = stdin;
else if ((infile = fopen(file, "r")) == NULL)
@@ -271,7 +271,7 @@ int readrec(char **pbuf, int *pbufsize, FILE *inf, bool newflag) /* read one rec
*pbuf = buf;
*pbufsize = bufsize;
isrec = *buf || !feof(inf);
- dprintf( ("readrec saw <%s>, returns %d\n", buf, isrec) );
+ DPRINTF("readrec saw <%s>, returns %d\n", buf, isrec);
return isrec;
}
@@ -286,7 +286,7 @@ char *getargv(int n) /* get ARGV[n] */
return NULL;
x = setsymtab(temp, "", 0.0, STR, ARGVtab);
s = getsval(x);
- dprintf( ("getargv(%d) returns |%s|\n", n, s) );
+ DPRINTF("getargv(%d) returns |%s|\n", n, s);
return s;
}
@@ -305,7 +305,7 @@ void setclvar(char *s) /* set var=value from s */
q->fval = atof(q->sval);
q->tval |= NUM;
}
- dprintf( ("command line set %s to |%s|\n", s, p) );
+ DPRINTF("command line set %s to |%s|\n", s, p);
}
@@ -332,6 +332,8 @@ void fldbld(void) /* create fields from current record */
}
fr = fields;
i = 0; /* number of fields accumulated here */
+ if (inputFS == NULL) /* make sure we have a copy of FS */
+ savefs();
if (strlen(inputFS) > 1) { /* it's a regular expression */
i = refldbld(r, inputFS);
} else if ((sep = *inputFS) == ' ') { /* default whitespace */
@@ -502,7 +504,7 @@ int refldbld(const char *rec, const char *fs) /* build fields from reg expr in F
if (*rec == '\0')
return 0;
pfa = makedfa(fs, 1);
- dprintf( ("into refldbld, rec = <%s>, pat = <%s>\n", rec, fs) );
+ DPRINTF("into refldbld, rec = <%s>, pat = <%s>\n", rec, fs);
tempstat = pfa->initstat;
for (i = 1; ; i++) {
if (i > nfields)
@@ -511,16 +513,16 @@ int refldbld(const char *rec, const char *fs) /* build fields from reg expr in F
xfree(fldtab[i]->sval);
fldtab[i]->tval = FLD | STR | DONTFREE;
fldtab[i]->sval = fr;
- dprintf( ("refldbld: i=%d\n", i) );
+ DPRINTF("refldbld: i=%d\n", i);
if (nematch(pfa, rec)) {
pfa->initstat = 2; /* horrible coupling to b.c */
- dprintf( ("match %s (%d chars)\n", patbeg, patlen) );
+ DPRINTF("match %s (%d chars)\n", patbeg, patlen);
strncpy(fr, rec, patbeg-rec);
fr += patbeg - rec + 1;
*(fr-1) = '\0';
rec = patbeg + patlen;
} else {
- dprintf( ("no match %s\n", rec) );
+ DPRINTF("no match %s\n", rec);
strcpy(fr, rec);
pfa->initstat = tempstat;
break;
@@ -554,15 +556,15 @@ void recbld(void) /* create $0 from $1..$NF if necessary */
if (!adjbuf(&record, &recsize, 2+r-record, recsize, &r, "recbld 3"))
FATAL("built giant record `%.30s...'", record);
*r = '\0';
- dprintf( ("in recbld inputFS=%s, fldtab[0]=%p\n", inputFS, (void*)fldtab[0]) );
+ DPRINTF("in recbld inputFS=%s, fldtab[0]=%p\n", inputFS, (void*)fldtab[0]);
if (freeable(fldtab[0]))
xfree(fldtab[0]->sval);
fldtab[0]->tval = REC | STR | DONTFREE;
fldtab[0]->sval = record;
- dprintf( ("in recbld inputFS=%s, fldtab[0]=%p\n", inputFS, (void*)fldtab[0]) );
- dprintf( ("recbld = |%s|\n", record) );
+ DPRINTF("in recbld inputFS=%s, fldtab[0]=%p\n", inputFS, (void*)fldtab[0]);
+ DPRINTF("recbld = |%s|\n", record);
donerec = true;
}
@@ -756,6 +758,9 @@ int isclvar(const char *s) /* is s of form var=something ? */
/* strtod is supposed to be a proper test of what's a valid number */
/* appears to be broken in gcc on linux: thinks 0x123 is a valid FP number */
/* wrong: violates 4.10.1.4 of ansi C standard */
+/* well, not quite. As of C99, hex floating point is allowed. so this is
+ * a bit of a mess.
+ */
#include <math.h>
int is_number(const char *s)
@@ -766,7 +771,8 @@ int is_number(const char *s)
r = strtod(s, &ep);
if (ep == s || r == HUGE_VAL || errno == ERANGE)
return 0;
- while (*ep == ' ' || *ep == '\t' || *ep == '\n')
+ /* allow \r as well. windows files aren't going to go away. */
+ while (*ep == ' ' || *ep == '\t' || *ep == '\n' || *ep == '\r')
ep++;
if (*ep == '\0')
return 1;
diff --git a/main.c b/main.c
index ce0a412..535f1aa 100644
--- a/main.c
+++ b/main.c
@@ -22,7 +22,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
-const char *version = "version 20200405";
+const char *version = "version 20200702";
#define DEBUG
#include <stdio.h>
@@ -200,7 +200,7 @@ int main(int argc, char *argv[])
exit(0);
FATAL("no program given");
}
- dprintf( ("program = |%s|\n", argv[1]) );
+ DPRINTF("program = |%s|\n", argv[1]);
lexprog = argv[1];
argc--;
argv++;
@@ -209,7 +209,7 @@ int main(int argc, char *argv[])
syminit();
compile_time = COMPILING;
argv[0] = cmdname; /* put prog name at front of arglist */
- dprintf( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
+ DPRINTF("argc=%d, argv[0]=%s\n", argc, argv[0]);
arginit(argc, argv);
if (!safe)
envinit(environ);
@@ -221,7 +221,7 @@ int main(int argc, char *argv[])
#endif
if (fs)
*FS = qstring(fs, '\0');
- dprintf( ("errorflag=%d\n", errorflag) );
+ DPRINTF("errorflag=%d\n", errorflag);
if (errorflag == 0) {
compile_time = RUNNING;
run(winner);
diff --git a/parse.c b/parse.c
index 18556e3..b13e0c4 100644
--- a/parse.c
+++ b/parse.c
@@ -250,7 +250,7 @@ void defn(Cell *v, Node *vl, Node *st) /* turn on FCN bit in definition, */
for (p = vl; p; p = p->nnext)
n++;
v->fval = n;
- dprintf( ("defining func %s (%d args)\n", v->nval, n) );
+ DPRINTF("defining func %s (%d args)\n", v->nval, n);
}
int isarg(const char *s) /* is s in argument list for current function? */
diff --git a/run.c b/run.c
index 26e8c4f..98787f1 100644
--- a/run.c
+++ b/run.c
@@ -25,6 +25,7 @@ THIS SOFTWARE.
#define DEBUG
#include <stdio.h>
#include <ctype.h>
+#include <errno.h>
#include <wchar.h>
#include <wctype.h>
#include <fcntl.h>
@@ -118,7 +119,7 @@ int adjbuf(char **pbuf, int *psiz, int minlen, int quantum, char **pbptr,
if (rminlen)
minlen += quantum - rminlen;
tbuf = realloc(*pbuf, minlen);
- dprintf( ("adjbuf %s: %d %d (pbuf=%p, tbuf=%p)\n", whatrtn, *psiz, minlen, *pbuf, tbuf) );
+ DPRINTF("adjbuf %s: %d %d (pbuf=%p, tbuf=%p)\n", whatrtn, *psiz, minlen, *pbuf, tbuf);
if (tbuf == NULL) {
if (whatrtn)
FATAL("out of memory in %s", whatrtn);
@@ -246,18 +247,18 @@ Cell *call(Node **a, int n) /* function call. very kludgy and fragile */
for (ncall = 0, x = a[1]; x != NULL; x = x->nnext) /* args in call */
ncall++;
ndef = (int) fcn->fval; /* args in defn */
- dprintf( ("calling %s, %d args (%d in defn), frp=%d\n", s, ncall, ndef, (int) (frp-frame)) );
+ DPRINTF("calling %s, %d args (%d in defn), frp=%d\n", s, ncall, ndef, (int) (frp-frame));
if (ncall > ndef)
WARNING("function %s called with %d args, uses only %d",
s, ncall, ndef);
if (ncall + ndef > NARGS)
FATAL("function %s has %d arguments, limit %d", s, ncall+ndef, NARGS);
for (i = 0, x = a[1]; x != NULL; i++, x = x->nnext) { /* get call args */
- dprintf( ("evaluate args[%d], frp=%d:\n", i, (int) (frp-frame)) );
+ DPRINTF("evaluate args[%d], frp=%d:\n", i, (int) (frp-frame));
y = execute(x);
oargs[i] = y;
- dprintf( ("args[%d]: %s %f <%s>, t=%o\n",
- i, NN(y->nval), y->fval, isarr(y) ? "(array)" : NN(y->sval), y->tval) );
+ DPRINTF("args[%d]: %s %f <%s>, t=%o\n",
+ i, NN(y->nval), y->fval, isarr(y) ? "(array)" : NN(y->sval), y->tval);
if (isfcn(y))
FATAL("can't use function %s as argument in %s", y->nval, s);
if (isarr(y))
@@ -283,9 +284,9 @@ Cell *call(Node **a, int n) /* function call. very kludgy and fragile */
frp->nargs = ndef; /* number defined with (excess are locals) */
frp->retval = gettemp();
- dprintf( ("start exec of %s, frp=%d\n", s, (int) (frp-frame)) );
+ DPRINTF("start exec of %s, frp=%d\n", s, (int) (frp-frame));
y = execute((Node *)(fcn->sval)); /* execute body */
- dprintf( ("finished exec of %s, frp=%d\n", s, (int) (frp-frame)) );
+ DPRINTF("finished exec of %s, frp=%d\n", s, (int) (frp-frame));
for (i = 0; i < ndef; i++) {
Cell *t = frp->args[i];
@@ -318,7 +319,7 @@ Cell *call(Node **a, int n) /* function call. very kludgy and fragile */
tempfree(y); /* don't free twice! */
}
z = frp->retval; /* return value */
- dprintf( ("%s returns %g |%s| %o\n", s, getfval(z), getsval(z), z->tval) );
+ DPRINTF("%s returns %g |%s| %o\n", s, getfval(z), getsval(z), z->tval);
frp--;
return(z);
}
@@ -346,7 +347,7 @@ Cell *arg(Node **a, int n) /* nth argument of a function */
{
n = ptoi(a[0]); /* argument number, counting from 0 */
- dprintf( ("arg(%d), frp->nargs=%d\n", n, frp->nargs) );
+ DPRINTF("arg(%d), frp->nargs=%d\n", n, frp->nargs);
if (n+1 > frp->nargs)
FATAL("argument #%d of function %s was not supplied",
n+1, frp->fcncell->nval);
@@ -471,7 +472,7 @@ makearraystring(Node *p, const char *func)
{
char *buf;
int bufsz = recsize;
- size_t blen, seplen;
+ size_t blen;
if ((buf = malloc(bufsz)) == NULL) {
FATAL("%s: out of memory", func);
@@ -479,11 +480,11 @@ makearraystring(Node *p, const char *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 seplen = strlen(getsval(subseploc));
size_t nsub = p->nnext ? seplen : 0;
size_t slen = strlen(s);
size_t tlen = blen + slen + nsub;
@@ -511,7 +512,7 @@ Cell *array(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */
x = execute(a[0]); /* Cell* for symbol table */
buf = makearraystring(a[1], __func__);
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))
xfree(x->sval);
x->tval &= ~(STR|NUM|DONTFREE);
@@ -557,7 +558,7 @@ Cell *intest(Node **a, int n) /* a[0] is index (list), a[1] is symtab */
ap = execute(a[1]); /* array name */
if (!isarr(ap)) {
- dprintf( ("making %s into an array\n", ap->nval) );
+ DPRINTF("making %s into an array\n", ap->nval);
if (freeable(ap))
xfree(ap->sval);
ap->tval &= ~(STR|NUM|DONTFREE);
@@ -686,7 +687,7 @@ Cell *relop(Node **a, int n) /* a[0 < a[1], etc. */
void tfree(Cell *a) /* free a tempcell */
{
if (freeable(a)) {
- dprintf( ("freeing %s %s %o\n", NN(a->nval), NN(a->sval), a->tval) );
+ DPRINTF("freeing %s %s %o\n", NN(a->nval), NN(a->sval), a->tval);
xfree(a->sval);
}
if (a == tmps)
@@ -773,7 +774,7 @@ Cell *substr(Node **a, int nnn) /* substr(a[0], a[1], a[2]) */
n = 0;
else if (n > k - m)
n = k - m;
- dprintf( ("substr: m=%d, n=%d, s=%s\n", m, n, s) );
+ DPRINTF("substr: m=%d, n=%d, s=%s\n", m, n, s);
y = gettemp();
temp = s[n+m-1]; /* with thanks to John Linderman */
s[n+m-1] = '\0';
@@ -1072,8 +1073,10 @@ Cell *arith(Node **a, int n) /* a[0] + a[1], etc. also -a[0] */
case POWER:
if (j >= 0 && modf(j, &v) == 0.0) /* pos integer exponent */
i = ipow(i, (int) j);
- else
+ else {
+ errno = 0;
i = errcheck(pow(i, j), "pow");
+ }
break;
default: /* can't happen */
FATAL("illegal arithmetic operator %d", n);
@@ -1166,8 +1169,10 @@ Cell *assign(Node **a, int n) /* a[0] = a[1], a[0] += a[1], etc. */
case POWEQ:
if (yf >= 0 && modf(yf, &v) == 0.0) /* pos integer exponent */
xf = ipow(xf, (int) yf);
- else
+ else {
+ errno = 0;
xf = errcheck(pow(xf, yf), "pow");
+ }
break;
default:
FATAL("illegal assignment operator %d", n);
@@ -1187,12 +1192,12 @@ Cell *cat(Node **a, int q) /* a[0] cat a[1] */
x = execute(a[0]);
n1 = strlen(getsval(x));
+ adjbuf(&s, &ssz, n1, recsize, 0, "cat1");
+ memcpy(s, x->sval, n1);
y = execute(a[1]);
n2 = strlen(getsval(y));
-
- adjbuf(&s, &ssz, n1 + n2 + 1, recsize, 0, "cat");
- memcpy(s, x->sval, n1);
+ adjbuf(&s, &ssz, n1 + n2 + 1, recsize, 0, "cat2");
memcpy(s + n1, y->sval, n2);
s[n1 + n2] = '\0';
@@ -1271,7 +1276,7 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
sep = *fs;
ap = execute(a[1]); /* array name */
freesymtab(ap);
- dprintf( ("split: s=|%s|, a=%s, sep=|%s|\n", s, NN(ap->nval), fs) );
+ DPRINTF("split: s=|%s|, a=%s, sep=|%s|\n", s, NN(ap->nval), fs);
ap->tval &= ~STR;
ap->tval |= ARR;
ap->sval = (char *) makesymtab(NSYMTAB);
@@ -1589,13 +1594,19 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis
u = strlen(getsval(x));
break;
case FLOG:
- u = errcheck(log(getfval(x)), "log"); break;
+ errno = 0;
+ u = errcheck(log(getfval(x)), "log");
+ break;
case FINT:
modf(getfval(x), &u); break;
case FEXP:
- u = errcheck(exp(getfval(x)), "exp"); break;
+ errno = 0;
+ u = errcheck(exp(getfval(x)), "exp");
+ break;
case FSQRT:
- u = errcheck(sqrt(getfval(x)), "sqrt"); break;
+ errno = 0;
+ u = errcheck(sqrt(getfval(x)), "sqrt");
+ break;
case FSIN:
u = sin(getfval(x)); break;
case FCOS:
diff --git a/tran.c b/tran.c
index 4efaa21..f0a0a09 100644
--- a/tran.c
+++ b/tran.c
@@ -234,8 +234,8 @@ Cell *setsymtab(const char *n, const char *s, Awkfloat f, unsigned t, Array *tp)
Cell *p;
if (n != NULL && (p = lookup(n, tp)) != NULL) {
- dprintf( ("setsymtab found %p: n=%s s=\"%s\" f=%g t=%o\n",
- (void*)p, NN(p->nval), NN(p->sval), p->fval, p->tval) );
+ DPRINTF("setsymtab found %p: n=%s s=\"%s\" f=%g t=%o\n",
+ (void*)p, NN(p->nval), NN(p->sval), p->fval, p->tval);
return(p);
}
p = malloc(sizeof(*p));
@@ -253,8 +253,8 @@ Cell *setsymtab(const char *n, const char *s, Awkfloat f, unsigned t, Array *tp)
h = hash(n, tp->size);
p->cnext = tp->tab[h];
tp->tab[h] = p;
- dprintf( ("setsymtab set %p: n=%s s=\"%s\" f=%g t=%o\n",
- (void*)p, p->nval, p->sval, p->fval, p->tval) );
+ DPRINTF("setsymtab set %p: n=%s s=\"%s\" f=%g t=%o\n",
+ (void*)p, p->nval, p->sval, p->fval, p->tval);
return(p);
}
@@ -313,11 +313,11 @@ Awkfloat setfval(Cell *vp, Awkfloat f) /* set float val of a Cell */
fldno = atoi(vp->nval);
if (fldno > *NF)
newfld(fldno);
- dprintf( ("setting field %d to %g\n", fldno, f) );
+ DPRINTF("setting field %d to %g\n", fldno, f);
} else if (&vp->fval == NF) {
donerec = false; /* mark $0 invalid */
setlastfld(f);
- dprintf( ("setting NF to %g\n", f) );
+ DPRINTF("setting NF to %g\n", f);
} else if (isrec(vp)) {
donefld = false; /* mark $1... invalid */
donerec = true;
@@ -333,7 +333,7 @@ Awkfloat setfval(Cell *vp, Awkfloat f) /* set float val of a Cell */
vp->tval |= NUM; /* mark number ok */
if (f == -0) /* who would have thought this possible? */
f = 0;
- dprintf( ("setfval %p: %s = %g, t=%o\n", (void*)vp, NN(vp->nval), f, vp->tval) );
+ DPRINTF("setfval %p: %s = %g, t=%o\n", (void*)vp, NN(vp->nval), f, vp->tval);
return vp->fval = f;
}
@@ -353,8 +353,8 @@ char *setsval(Cell *vp, const char *s) /* set string val of a Cell */
int fldno;
Awkfloat f;
- dprintf( ("starting setsval %p: %s = \"%s\", t=%o, r,f=%d,%d\n",
- (void*)vp, NN(vp->nval), s, vp->tval, donerec, donefld) );
+ DPRINTF("starting setsval %p: %s = \"%s\", t=%o, r,f=%d,%d\n",
+ (void*)vp, NN(vp->nval), s, vp->tval, donerec, donefld);
if ((vp->tval & (NUM | STR)) == 0)
funnyvar(vp, "assign to");
if (isfld(vp)) {
@@ -362,7 +362,7 @@ char *setsval(Cell *vp, const char *s) /* set string val of a Cell */
fldno = atoi(vp->nval);
if (fldno > *NF)
newfld(fldno);
- dprintf( ("setting field %d to %s (%p)\n", fldno, s, s) );
+ DPRINTF("setting field %d to %s (%p)\n", fldno, s, s);
} else if (isrec(vp)) {
donefld = false; /* mark $1... invalid */
donerec = true;
@@ -378,14 +378,14 @@ char *setsval(Cell *vp, const char *s) /* set string val of a Cell */
vp->tval |= STR;
vp->fmt = NULL;
setfree(vp);
- dprintf( ("setsval %p: %s = \"%s (%p) \", t=%o r,f=%d,%d\n",
- (void*)vp, NN(vp->nval), t, t, vp->tval, donerec, donefld) );
+ DPRINTF("setsval %p: %s = \"%s (%p) \", t=%o r,f=%d,%d\n",
+ (void*)vp, NN(vp->nval), t, t, vp->tval, donerec, donefld);
vp->sval = t;
if (&vp->fval == NF) {
donerec = false; /* mark $0 invalid */
f = getfval(vp);
setlastfld(f);
- dprintf( ("setting NF to %g\n", f) );
+ DPRINTF("setting NF to %g\n", f);
}
return(vp->sval);
@@ -404,8 +404,8 @@ Awkfloat getfval(Cell *vp) /* get float val of a Cell */
if (is_number(vp->sval) && !(vp->tval&CON))
vp->tval |= NUM; /* make NUM only sparingly */
}
- dprintf( ("getfval %p: %s = %g, t=%o\n",
- (void*)vp, NN(vp->nval), vp->fval, vp->tval) );
+ DPRINTF("getfval %p: %s = %g, t=%o\n",
+ (void*)vp, NN(vp->nval), vp->fval, vp->tval);
return(vp->fval);
}
@@ -492,8 +492,8 @@ static char *get_str_val(Cell *vp, char **fmt) /* get string val of a Cel
}
}
done:
- dprintf( ("getsval %p: %s = \"%s (%p)\", t=%o\n",
- (void*)vp, NN(vp->nval), vp->sval, vp->sval, vp->tval) );
+ DPRINTF("getsval %p: %s = \"%s (%p)\", t=%o\n",
+ (void*)vp, NN(vp->nval), vp->sval, vp->sval, vp->tval);
return(vp->sval);
}