From 93e5dd87a1fc9782b877d41efa6222f55a0e4167 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Thu, 16 Apr 2020 20:56:49 +0300 Subject: Fix noreturn for old compilers. --- FIXES | 4 ++++ awk.h | 4 ++++ main.c | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/FIXES b/FIXES index e96cf33..509f4ac 100644 --- a/FIXES +++ b/FIXES @@ -25,6 +25,10 @@ THIS SOFTWARE. This file lists all bug fixes, changes, etc., made since the AWK book was sent to the printers in August, 1987. +April 16, 2020: + Handle old compilers that don't support C11 (for noreturn). + Thanks to Arnold Robbins. + April 5, 2020: Use and noreturn instead of GCC attributes. Thanks to GitHub user awkfan77. Closes PR #77. diff --git a/awk.h b/awk.h index 4e01325..36a4286 100644 --- a/awk.h +++ b/awk.h @@ -25,7 +25,11 @@ THIS SOFTWARE. #include #include #include +#if __STDC__ <= 199901L +#define noreturn +#else #include +#endif typedef double Awkfloat; diff --git a/main.c b/main.c index ce0a412..6b1ed56 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 20200416"; #define DEBUG #include -- cgit v1.2.3 From 1107437dceb036a21745779d911539cc273bb094 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Fri, 15 May 2020 15:12:15 +0300 Subject: Fix test for use of noreturn. --- FIXES | 4 ++++ awk.h | 2 +- main.c | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/FIXES b/FIXES index 509f4ac..baa7ae5 100644 --- a/FIXES +++ b/FIXES @@ -25,6 +25,10 @@ THIS SOFTWARE. This file lists all bug fixes, changes, etc., made since the AWK book was sent to the printers in August, 1987. +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. diff --git a/awk.h b/awk.h index 36a4286..5a55301 100644 --- a/awk.h +++ b/awk.h @@ -25,7 +25,7 @@ THIS SOFTWARE. #include #include #include -#if __STDC__ <= 199901L +#if __STDC_VERSION__ <= 199901L #define noreturn #else #include diff --git a/main.c b/main.c index 6b1ed56..3b903f8 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 20200416"; +const char *version = "version 20200515"; #define DEBUG #include -- cgit v1.2.3 From 754cf93645ad3a0061bbd434618a667ac6110121 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Fri, 5 Jun 2020 12:25:15 +0300 Subject: In fldbld(), check that inputFS is set. --- FIXES | 5 +++++ lib.c | 2 ++ main.c | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/FIXES b/FIXES index baa7ae5..f002f0c 100644 --- a/FIXES +++ b/FIXES @@ -25,6 +25,11 @@ THIS SOFTWARE. This file lists all bug fixes, changes, etc., made since the AWK book was sent to the printers in August, 1987. +June 5, 2020: + In fldbld(), make sure that inputFS is set before trying to + use it. Thanks to Steffen Nurpmeso + 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. diff --git a/lib.c b/lib.c index 9665244..a98ffee 100644 --- a/lib.c +++ b/lib.c @@ -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 */ diff --git a/main.c b/main.c index 3b903f8..7b19557 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 20200515"; +const char *version = "version 20200605"; #define DEBUG #include -- cgit v1.2.3 From b2de1c4ee74c1283bae52cd6a94a56308430f79e Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Fri, 12 Jun 2020 05:16:12 -0600 Subject: Clear errno before using errcheck() to avoid spurious errors. (#80) The errcheck() function treats an errno of ERANGE or EDOM as something to report, so make sure errno is set to zero before invoking a function to check so that a previous such errno value won't result in a false positive. This could happen simply due to input line fields that looked enough like floating-point input to trigger ERANGE. Reported by Jordan Geoghegan, fix from Philip Guenther. --- run.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/run.c b/run.c index 26e8c4f..41f1bbe 100644 --- a/run.c +++ b/run.c @@ -25,6 +25,7 @@ THIS SOFTWARE. #define DEBUG #include #include +#include #include #include #include @@ -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); @@ -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: -- cgit v1.2.3 From cef51801109a3032c66aa76503a92ce66724725a Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Fri, 12 Jun 2020 14:30:03 +0300 Subject: Fix Issue 78 and apply PR 80. --- FIXES | 9 +++++++++ lib.c | 6 +++++- main.c | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/FIXES b/FIXES index f002f0c..4cbcca2 100644 --- a/FIXES +++ b/FIXES @@ -25,6 +25,15 @@ THIS SOFTWARE. This file lists all bug fixes, changes, etc., made since the AWK book was sent to the printers in August, 1987. +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 diff --git a/lib.c b/lib.c index a98ffee..27ef30f 100644 --- a/lib.c +++ b/lib.c @@ -758,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 int is_number(const char *s) @@ -768,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 7b19557..269f0a8 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 20200605"; +const char *version = "version 20200612"; #define DEBUG #include -- cgit v1.2.3 From 292d39f7b7b15e56a10f4712467d4680c8fedb2e Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Thu, 25 Jun 2020 12:32:34 -0600 Subject: Rename dprintf to DPRINTF and use C99 cpp variadic arguments. (#82) POSIX specifies a dprintf function that operates on an fd instead of a stdio stream. Using upper case for macros is more idiomatic too. We no longer need to use an extra set of parentheses for debugging printf statements. --- awk.h | 7 +++---- b.c | 4 ++-- lib.c | 28 ++++++++++++++-------------- main.c | 6 +++--- parse.c | 2 +- run.c | 28 ++++++++++++++-------------- tran.c | 34 +++++++++++++++++----------------- 7 files changed, 54 insertions(+), 55 deletions(-) diff --git a/awk.h b/awk.h index 5a55301..cc30249 100644 --- a/awk.h +++ b/awk.h @@ -44,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..9d67bb2 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 */ diff --git a/lib.c b/lib.c index 27ef30f..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); } @@ -504,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) @@ -513,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; @@ -556,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; } diff --git a/main.c b/main.c index 269f0a8..24117ac 100644 --- a/main.c +++ b/main.c @@ -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 41f1bbe..4adacb3 100644 --- a/run.c +++ b/run.c @@ -119,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); @@ -247,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)) @@ -284,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]; @@ -319,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); } @@ -347,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); @@ -512,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); @@ -558,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); @@ -687,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) @@ -774,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'; @@ -1276,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); 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); } -- cgit v1.2.3 From e5a89e63feb665c476df819f5ce5f247d0068124 Mon Sep 17 00:00:00 2001 From: awkfan77 Date: Thu, 25 Jun 2020 19:33:52 +0100 Subject: Fix onetrueawk#83 (#84) --- b.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/b.c b/b.c index 545fb7d..7174eda 100644 --- a/b.c +++ b/b.c @@ -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++; } -- cgit v1.2.3 From f232de85f6787967552cd3efe79fc0b4f152d090 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Thu, 25 Jun 2020 21:36:24 +0300 Subject: Update FIXES and date in main.c. --- FIXES | 4 ++++ main.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/FIXES b/FIXES index 4cbcca2..03bb867 100644 --- a/FIXES +++ b/FIXES @@ -25,6 +25,10 @@ THIS SOFTWARE. This file lists all bug fixes, changes, etc., made since the AWK book was sent to the printers in August, 1987. +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 diff --git a/main.c b/main.c index 24117ac..37572cc 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 20200612"; +const char *version = "version 20200625"; #define DEBUG #include -- cgit v1.2.3 From cc19af1308fadaad9ff1611155c666cd48cfe32b Mon Sep 17 00:00:00 2001 From: Tim van der Molen <58601421+tbvdm@users.noreply.github.com> Date: Thu, 2 Jul 2020 20:21:10 +0200 Subject: Fix concatenation regression (#85) The optimization in commit 1d6ddfd9c0ed7119c0601474cded3a385068e886 reintroduced the regression that was fixed in commit e26237434fb769d9c1ea239101eb5b24be588eea. Co-authored-by: Tim van der Molen --- run.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/run.c b/run.c index 4adacb3..9aff663 100644 --- a/run.c +++ b/run.c @@ -1192,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'; -- cgit v1.2.3 From ee5b49bb3307e70054299a00d6c3308996049ce2 Mon Sep 17 00:00:00 2001 From: Tim van der Molen <58601421+tbvdm@users.noreply.github.com> Date: Thu, 2 Jul 2020 20:22:15 +0200 Subject: Fix regression with changed SUBSEP in subscript (#86) Commit 0d8778bbbb415810bfd126694a38b6bf4b71e79c reintroduced a regression that was fixed in commit 97a4b7ed215ae6446d13fe0eab15b5b3ae4da7da. The length of SUBSEP needs to be rechecked after calling execute(), in case SUBSEP itself has been changed. Co-authored-by: Tim van der Molen --- run.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/run.c b/run.c index 9aff663..98787f1 100644 --- a/run.c +++ b/run.c @@ -472,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); @@ -480,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; -- cgit v1.2.3 From b2554a9e3d57042b9a6713888c1a65de25b3ed63 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Thu, 2 Jul 2020 21:35:06 +0300 Subject: Add regression script for bugs-fixed directory. --- FIXES | 4 ++++ REGRESS | 4 ++++ bugs-fixed/REGRESS | 28 ++++++++++++++++++++++++++++ bugs-fixed/fs-overflow.ok | 1 + bugs-fixed/missing-precision.ok | 2 +- bugs-fixed/negative-nf.ok | 2 +- main.c | 2 +- 7 files changed, 40 insertions(+), 3 deletions(-) create mode 100755 bugs-fixed/REGRESS create mode 100644 bugs-fixed/fs-overflow.ok diff --git a/FIXES b/FIXES index 03bb867..9516a36 100644 --- a/FIXES +++ b/FIXES @@ -25,6 +25,10 @@ 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. 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/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/main.c b/main.c index 37572cc..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 20200625"; +const char *version = "version 20200702"; #define DEBUG #include -- cgit v1.2.3 From 2a4146ec3027d12e375209e03ed1c5a9ab230da4 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Thu, 2 Jul 2020 21:39:56 +0300 Subject: Add a note about low-level maintenance. --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) 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 -- cgit v1.2.3