Faster awk. [rsc] --rw-rw-r-- M 632921 glenda sys 16722 Feb 9 10:43 sys/src/cmd/awk/lib.c /n/sourcesdump/2006/0209/plan9/sys/src/cmd/awk/lib.c:673,678 - /n/sourcesdump/2006/0210/plan9/sys/src/cmd/awk/lib.c:673,704 { double r; char *ep; + + /* + * fast could-it-be-a-number check before calling strtod, + * which takes a surprisingly long time to reject non-numbers. + */ + switch (*s) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + case '-': + case '+': + case '.': + case 'n': /* nans */ + case 'N': + case 'i': /* infs */ + case 'I': + break; + default: + return 0; /* can't be a number */ + } + errno = 0; r = strtod(s, &ep); if (ep == s || r == HUGE_VAL || errno == ERANGE) [rsc] --rw-rw-r-- M 632921 glenda sys 42772 Feb 9 10:43 sys/src/cmd/awk/run.c /n/sourcesdump/2006/0209/plan9/sys/src/cmd/awk/run.c:133,138 - /n/sourcesdump/2006/0210/plan9/sys/src/cmd/awk/run.c:133,139 Cell *execute(Node *u) /* execute a node of the parse tree */ { + int nobj; Cell *(*proc)(Node **, int); Cell *x; Node *a; /n/sourcesdump/2006/0209/plan9/sys/src/cmd/awk/run.c:149,158 - /n/sourcesdump/2006/0210/plan9/sys/src/cmd/awk/run.c:150,160 recbld(); return(x); } - if (notlegal(a->nobj)) /* probably a Cell* but too risky to print */ + nobj = a->nobj; + if (notlegal(nobj)) /* probably a Cell* but too risky to print */ FATAL("illegal statement"); - proc = proctab[a->nobj-FIRSTTOKEN]; - x = (*proc)(a->narg, a->nobj); + proc = proctab[nobj-FIRSTTOKEN]; + x = (*proc)(a->narg, nobj); if (isfld(x) && !donefld) fldbld(); else if (isrec(x) && !donerec) /n/sourcesdump/2006/0209/plan9/sys/src/cmd/awk/run.c:1540,1545 - /n/sourcesdump/2006/0210/plan9/sys/src/cmd/awk/run.c:1542,1548 Cell *printstat(Node **a, int n) /* print a[0] */ { + int r; Node *x; Cell *y; FILE *fp; /n/sourcesdump/2006/0209/plan9/sys/src/cmd/awk/run.c:1553,1566 - /n/sourcesdump/2006/0210/plan9/sys/src/cmd/awk/run.c:1556,1570 fputs(getsval(y), fp); tempfree(y); if (x->nnext == NULL) - fputs(*ORS, fp); + r = fputs(*ORS, fp); else - fputs(*OFS, fp); + r = fputs(*OFS, fp); + if (r == EOF) + FATAL("write error on %s", filename(fp)); } if (a[1] != 0) - fflush(fp); - if (ferror(fp)) - FATAL("write error on %s", filename(fp)); + if (fflush(fp) == EOF) + FATAL("write error on %s", filename(fp)); return(True); }