Vendor import of bwk's 7-Aug-2011 release.
This commit is contained in:
parent
e2f76e526c
commit
9cb3faa660
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/one-true-awk/dist/; revision=224729 svn path=/vendor/one-true-awk/20110807/; revision=224730; tag=vendor/one-true-awk/20110807
18
FIXES
18
FIXES
@ -25,6 +25,24 @@ THIS SOFTWARE.
|
||||
This file lists all bug fixes, changes, etc., made since the AWK book
|
||||
was sent to the printers in August, 1987.
|
||||
|
||||
Aug 7, 2011:
|
||||
split(s, a, //) now behaves the same as split(s, a, "")
|
||||
|
||||
Jun 12, 2011:
|
||||
/pat/, \n /pat/ {...} is now legal, though bad style to use.
|
||||
|
||||
added checks to new -v code that permits -vnospace; thanks to
|
||||
ruslan ermilov for spotting this and providing the patch.
|
||||
|
||||
removed fixed limit on number of open files; thanks to aleksey
|
||||
cheusov and christos zoulos.
|
||||
|
||||
fixed day 1 bug that resurrected deleted elements of ARGV when
|
||||
used as filenames (in lib.c).
|
||||
|
||||
minor type fiddles to make gcc -Wall -pedantic happier (but not
|
||||
totally so); turned on -fno-strict-aliasing in makefile.
|
||||
|
||||
May 6, 2011:
|
||||
added #ifdef for isblank.
|
||||
now allows -ffoo as well as -f foo arguments.
|
||||
|
@ -174,8 +174,8 @@ pa_pat:
|
||||
pa_stat:
|
||||
pa_pat { $$ = stat2(PASTAT, $1, stat2(PRINT, rectonode(), NIL)); }
|
||||
| pa_pat lbrace stmtlist '}' { $$ = stat2(PASTAT, $1, $3); }
|
||||
| pa_pat ',' pa_pat { $$ = pa2stat($1, $3, stat2(PRINT, rectonode(), NIL)); }
|
||||
| pa_pat ',' pa_pat lbrace stmtlist '}' { $$ = pa2stat($1, $3, $5); }
|
||||
| pa_pat ',' opt_nl pa_pat { $$ = pa2stat($1, $4, stat2(PRINT, rectonode(), NIL)); }
|
||||
| pa_pat ',' opt_nl pa_pat lbrace stmtlist '}' { $$ = pa2stat($1, $4, $6); }
|
||||
| lbrace stmtlist '}' { $$ = stat2(PASTAT, NIL, $2); }
|
||||
| XBEGIN lbrace stmtlist '}'
|
||||
{ beginloc = linkum(beginloc, $3); $$ = 0; }
|
||||
|
14
b.c
14
b.c
@ -231,7 +231,7 @@ void freetr(Node *p) /* free parse tree */
|
||||
/* in the parsing of regular expressions, metacharacters like . have */
|
||||
/* to be seen literally; \056 is not a metacharacter. */
|
||||
|
||||
int hexstr(char **pp) /* find and eval hex string at pp, return new p */
|
||||
int hexstr(uschar **pp) /* find and eval hex string at pp, return new p */
|
||||
{ /* only pick up one 8-bit byte (2 chars) */
|
||||
uschar *p;
|
||||
int n = 0;
|
||||
@ -245,16 +245,16 @@ int hexstr(char **pp) /* find and eval hex string at pp, return new p */
|
||||
else if (*p >= 'A' && *p <= 'F')
|
||||
n = 16 * n + *p - 'A' + 10;
|
||||
}
|
||||
*pp = (char *) p;
|
||||
*pp = (uschar *) p;
|
||||
return n;
|
||||
}
|
||||
|
||||
#define isoctdigit(c) ((c) >= '0' && (c) <= '7') /* multiple use of arg */
|
||||
|
||||
int quoted(char **pp) /* pick up next thing after a \\ */
|
||||
int quoted(uschar **pp) /* pick up next thing after a \\ */
|
||||
/* and increment *pp */
|
||||
{
|
||||
char *p = *pp;
|
||||
uschar *p = *pp;
|
||||
int c;
|
||||
|
||||
if ((c = *p++) == 't')
|
||||
@ -299,13 +299,13 @@ char *cclenter(const char *argp) /* add a character class */
|
||||
bp = buf;
|
||||
for (i = 0; (c = *p++) != 0; ) {
|
||||
if (c == '\\') {
|
||||
c = quoted((char **) &p);
|
||||
c = quoted(&p);
|
||||
} else if (c == '-' && i > 0 && bp[-1] != 0) {
|
||||
if (*p != 0) {
|
||||
c = bp[-1];
|
||||
c2 = *p++;
|
||||
if (c2 == '\\')
|
||||
c2 = quoted((char **) &p);
|
||||
c2 = quoted(&p);
|
||||
if (c > c2) { /* empty; ignore */
|
||||
bp--;
|
||||
i--;
|
||||
@ -789,7 +789,7 @@ int relex(void) /* lexical analyzer for reparse */
|
||||
case ')':
|
||||
return c;
|
||||
case '\\':
|
||||
rlxval = quoted((char **) &prestr);
|
||||
rlxval = quoted(&prestr);
|
||||
return CHAR;
|
||||
default:
|
||||
rlxval = c;
|
||||
|
2
lex.c
2
lex.c
@ -411,7 +411,7 @@ int string(void)
|
||||
}
|
||||
*px = 0;
|
||||
unput(c);
|
||||
sscanf(xbuf, "%x", &n);
|
||||
sscanf(xbuf, "%x", (unsigned int *) &n);
|
||||
*bp++ = n;
|
||||
break;
|
||||
}
|
||||
|
9
lib.c
9
lib.c
@ -124,7 +124,7 @@ int getrec(char **pbuf, int *pbufsize, int isrecord) /* get next input record */
|
||||
dprintf( ("argno=%d, file=|%s|\n", argno, file) );
|
||||
if (infile == NULL) { /* have to open a new file */
|
||||
file = getargv(argno);
|
||||
if (*file == '\0') { /* it's been zapped */
|
||||
if (file == NULL || *file == '\0') { /* deleted or zapped */
|
||||
argno++;
|
||||
continue;
|
||||
}
|
||||
@ -187,6 +187,7 @@ int readrec(char **pbuf, int *pbufsize, FILE *inf) /* read one record into buf *
|
||||
|
||||
if (strlen(*FS) >= 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) {
|
||||
sep = '\n';
|
||||
@ -227,6 +228,8 @@ char *getargv(int n) /* get ARGV[n] */
|
||||
extern Array *ARGVtab;
|
||||
|
||||
sprintf(temp, "%d", n);
|
||||
if (lookup(temp, ARGVtab) == NULL)
|
||||
return NULL;
|
||||
x = setsymtab(temp, "", 0.0, STR, ARGVtab);
|
||||
s = getsval(x);
|
||||
dprintf( ("getargv(%d) returns |%s|\n", n, s) );
|
||||
@ -477,14 +480,14 @@ 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, 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, fldtab[0]) );
|
||||
dprintf( ("in recbld inputFS=%s, fldtab[0]=%p\n", inputFS, (void*)fldtab[0]) );
|
||||
dprintf( ("recbld = |%s|\n", record) );
|
||||
donerec = 1;
|
||||
}
|
||||
|
20
main.c
20
main.c
@ -22,7 +22,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
****************************************************************/
|
||||
|
||||
const char *version = "version 20110506";
|
||||
const char *version = "version 20110807";
|
||||
|
||||
#define DEBUG
|
||||
#include <stdio.h>
|
||||
@ -121,10 +121,20 @@ int main(int argc, char *argv[])
|
||||
WARNING("field separator FS is empty");
|
||||
break;
|
||||
case 'v': /* -v a=1 to be done NOW. one -v for each */
|
||||
if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
|
||||
setclvar(argv[1]);
|
||||
else if (argv[1][2] != '\0')
|
||||
setclvar(&argv[1][2]);
|
||||
if (argv[1][2] != 0) { /* arg is -vsomething */
|
||||
if (isclvar(&argv[1][2]))
|
||||
setclvar(&argv[1][2]);
|
||||
else
|
||||
FATAL("invalid -v option argument: %s", &argv[1][2]);
|
||||
} else { /* arg is -v something */
|
||||
argc--; argv++;
|
||||
if (argc <= 1)
|
||||
FATAL("no variable name");
|
||||
if (isclvar(argv[1]))
|
||||
setclvar(argv[1]);
|
||||
else
|
||||
FATAL("invalid -v option argument: %s", argv[1]);
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
dbg = atoi(&argv[1][2]);
|
||||
|
2
makefile
2
makefile
@ -30,7 +30,7 @@ CC = gcc -Wall -g
|
||||
CC = cc
|
||||
CC = gcc -Wall -g -Wwrite-strings
|
||||
CC = gcc -fprofile-arcs -ftest-coverage # then gcov f1.c; cat f1.c.gcov
|
||||
CC = gcc -O4
|
||||
CC = gcc -O4 -Wall -pedantic -fno-strict-aliasing
|
||||
|
||||
YACC = bison -y
|
||||
YACC = yacc
|
||||
|
4
proto.h
4
proto.h
@ -43,8 +43,8 @@ extern fa *mkdfa(const char *, int);
|
||||
extern int makeinit(fa *, int);
|
||||
extern void penter(Node *);
|
||||
extern void freetr(Node *);
|
||||
extern int hexstr(char **);
|
||||
extern int quoted(char **);
|
||||
extern int hexstr(uschar **);
|
||||
extern int quoted(uschar **);
|
||||
extern char *cclenter(const char *);
|
||||
extern void overflo(const char *);
|
||||
extern void cfoll(fa *, Node *);
|
||||
|
52
run.c
52
run.c
@ -1236,6 +1236,12 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
|
||||
ap->sval = (char *) makesymtab(NSYMTAB);
|
||||
|
||||
n = 0;
|
||||
if (arg3type == REGEXPR && strlen((char*)((fa*)a[2])->restr) == 0) {
|
||||
/* split(s, a, //); have to arrange that it looks like empty sep */
|
||||
arg3type = 0;
|
||||
fs = "";
|
||||
sep = 0;
|
||||
}
|
||||
if (*s != '\0' && (strlen(fs) > 1 || arg3type == REGEXPR)) { /* reg expr */
|
||||
fa *pfa;
|
||||
if (arg3type == REGEXPR) { /* it's ready already */
|
||||
@ -1618,17 +1624,25 @@ struct files {
|
||||
FILE *fp;
|
||||
const char *fname;
|
||||
int mode; /* '|', 'a', 'w' => LE/LT, GT */
|
||||
} files[FOPEN_MAX] ={
|
||||
{ NULL, "/dev/stdin", LT }, /* watch out: don't free this! */
|
||||
{ NULL, "/dev/stdout", GT },
|
||||
{ NULL, "/dev/stderr", GT }
|
||||
};
|
||||
} *files;
|
||||
|
||||
int nfiles;
|
||||
|
||||
void stdinit(void) /* in case stdin, etc., are not constants */
|
||||
{
|
||||
files[0].fp = stdin;
|
||||
files[1].fp = stdout;
|
||||
files[2].fp = stderr;
|
||||
nfiles = FOPEN_MAX;
|
||||
files = calloc(nfiles, sizeof(*files));
|
||||
if (files == NULL)
|
||||
FATAL("can't allocate file memory for %u files", nfiles);
|
||||
files[0].fp = stdin;
|
||||
files[0].fname = "/dev/stdin";
|
||||
files[0].mode = LT;
|
||||
files[1].fp = stdout;
|
||||
files[1].fname = "/dev/stdout";
|
||||
files[1].mode = GT;
|
||||
files[2].fp = stderr;
|
||||
files[2].fname = "/dev/stderr";
|
||||
files[2].mode = GT;
|
||||
}
|
||||
|
||||
FILE *openfile(int a, const char *us)
|
||||
@ -1639,7 +1653,7 @@ FILE *openfile(int a, const char *us)
|
||||
|
||||
if (*s == '\0')
|
||||
FATAL("null file name in print or getline");
|
||||
for (i=0; i < FOPEN_MAX; i++)
|
||||
for (i=0; i < nfiles; i++)
|
||||
if (files[i].fname && strcmp(s, files[i].fname) == 0) {
|
||||
if (a == files[i].mode || (a==APPEND && files[i].mode==GT))
|
||||
return files[i].fp;
|
||||
@ -1649,11 +1663,19 @@ FILE *openfile(int a, const char *us)
|
||||
if (a == FFLUSH) /* didn't find it, so don't create it! */
|
||||
return NULL;
|
||||
|
||||
for (i=0; i < FOPEN_MAX; i++)
|
||||
for (i=0; i < nfiles; i++)
|
||||
if (files[i].fp == 0)
|
||||
break;
|
||||
if (i >= FOPEN_MAX)
|
||||
FATAL("%s makes too many open files", s);
|
||||
if (i >= nfiles) {
|
||||
struct files *nf;
|
||||
int nnf = nfiles + FOPEN_MAX;
|
||||
nf = realloc(files, nnf * sizeof(*nf));
|
||||
if (nf == NULL)
|
||||
FATAL("cannot grow files for %s and %d files", s, nnf);
|
||||
memset(&nf[nfiles], 0, FOPEN_MAX * sizeof(*nf));
|
||||
nfiles = nnf;
|
||||
files = nf;
|
||||
}
|
||||
fflush(stdout); /* force a semblance of order */
|
||||
m = a;
|
||||
if (a == GT) {
|
||||
@ -1681,7 +1703,7 @@ const char *filename(FILE *fp)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < FOPEN_MAX; i++)
|
||||
for (i = 0; i < nfiles; i++)
|
||||
if (fp == files[i].fp)
|
||||
return files[i].fname;
|
||||
return "???";
|
||||
@ -1696,7 +1718,7 @@ Cell *closefile(Node **a, int n)
|
||||
x = execute(a[0]);
|
||||
getsval(x);
|
||||
stat = -1;
|
||||
for (i = 0; i < FOPEN_MAX; i++) {
|
||||
for (i = 0; i < nfiles; i++) {
|
||||
if (files[i].fname && strcmp(x->sval, files[i].fname) == 0) {
|
||||
if (ferror(files[i].fp))
|
||||
WARNING( "i/o error occurred on %s", files[i].fname );
|
||||
@ -1740,7 +1762,7 @@ void flush_all(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < FOPEN_MAX; i++)
|
||||
for (i = 0; i < nfiles; i++)
|
||||
if (files[i].fp)
|
||||
fflush(files[i].fp);
|
||||
}
|
||||
|
16
tran.c
16
tran.c
@ -212,7 +212,7 @@ Cell *setsymtab(const char *n, const char *s, Awkfloat f, unsigned t, Array *tp)
|
||||
|
||||
if (n != NULL && (p = lookup(n, tp)) != NULL) {
|
||||
dprintf( ("setsymtab found %p: n=%s s=\"%s\" f=%g t=%o\n",
|
||||
p, NN(p->nval), NN(p->sval), p->fval, p->tval) );
|
||||
(void*)p, NN(p->nval), NN(p->sval), p->fval, p->tval) );
|
||||
return(p);
|
||||
}
|
||||
p = (Cell *) malloc(sizeof(Cell));
|
||||
@ -231,7 +231,7 @@ Cell *setsymtab(const char *n, const char *s, Awkfloat f, unsigned t, Array *tp)
|
||||
p->cnext = tp->tab[h];
|
||||
tp->tab[h] = p;
|
||||
dprintf( ("setsymtab set %p: n=%s s=\"%s\" f=%g t=%o\n",
|
||||
p, p->nval, p->sval, p->fval, p->tval) );
|
||||
(void*)p, p->nval, p->sval, p->fval, p->tval) );
|
||||
return(p);
|
||||
}
|
||||
|
||||
@ -298,7 +298,7 @@ Awkfloat setfval(Cell *vp, Awkfloat f) /* set float val of a Cell */
|
||||
xfree(vp->sval); /* free any previous string */
|
||||
vp->tval &= ~STR; /* mark string invalid */
|
||||
vp->tval |= NUM; /* mark number ok */
|
||||
dprintf( ("setfval %p: %s = %g, t=%o\n", 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;
|
||||
}
|
||||
|
||||
@ -318,7 +318,7 @@ char *setsval(Cell *vp, const char *s) /* set string val of a Cell */
|
||||
int fldno;
|
||||
|
||||
dprintf( ("starting setsval %p: %s = \"%s\", t=%o, r,f=%d,%d\n",
|
||||
vp, NN(vp->nval), s, vp->tval, donerec, donefld) );
|
||||
(void*)vp, NN(vp->nval), s, vp->tval, donerec, donefld) );
|
||||
if ((vp->tval & (NUM | STR)) == 0)
|
||||
funnyvar(vp, "assign to");
|
||||
if (isfld(vp)) {
|
||||
@ -338,7 +338,7 @@ char *setsval(Cell *vp, const char *s) /* set string val of a Cell */
|
||||
vp->tval |= STR;
|
||||
vp->tval &= ~DONTFREE;
|
||||
dprintf( ("setsval %p: %s = \"%s (%p) \", t=%o r,f=%d,%d\n",
|
||||
vp, NN(vp->nval), t,t, vp->tval, donerec, donefld) );
|
||||
(void*)vp, NN(vp->nval), t,t, vp->tval, donerec, donefld) );
|
||||
return(vp->sval = t);
|
||||
}
|
||||
|
||||
@ -355,7 +355,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", 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);
|
||||
}
|
||||
|
||||
@ -381,7 +382,8 @@ static char *get_str_val(Cell *vp, char **fmt) /* get string val of a Cel
|
||||
vp->tval &= ~DONTFREE;
|
||||
vp->tval |= STR;
|
||||
}
|
||||
dprintf( ("getsval %p: %s = \"%s (%p)\", t=%o\n", 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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user