Import awk-20110810.
authorSascha Wildner <saw@online.de>
Fri, 12 Aug 2011 21:07:23 +0000 (23:07 +0200)
committerSascha Wildner <saw@online.de>
Fri, 12 Aug 2011 21:07:23 +0000 (23:07 +0200)
* /pat/, \n /pat/ {...} is now legal, though bad style to use.
* added checks to new -v code that permits -vnospace
* removed fixed limit on number of open files
* 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)
* split(s, a, //) now behaves the same as split(s, a, "")
* another fix to avoid core dump with delete(ARGV)

contrib/awk/FIXES
contrib/awk/awkgram.y
contrib/awk/b.c
contrib/awk/lex.c
contrib/awk/lib.c
contrib/awk/main.c
contrib/awk/proto.h
contrib/awk/run.c
contrib/awk/tran.c

index e6edc53..a708027 100644 (file)
@@ -25,6 +25,28 @@ THIS SOFTWARE.
 This file lists all bug fixes, changes, etc., made since the AWK book
 was sent to the printers in August, 1987.
 
+Aug 10, 2011:
+       another fix to avoid core dump with delete(ARGV); again, many thanks
+       to ruslan ermilov.
+
+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.
index 91b6257..5b5c461 100644 (file)
@@ -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; }
index 97dc32a..4f78a60 100644 (file)
@@ -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;
index 49d7c5c..d09f550 100644 (file)
@@ -411,7 +411,7 @@ int string(void)
                                }
                                *px = 0;
                                unput(c);
-                               sscanf(xbuf, "%x", &n);
+                               sscanf(xbuf, "%x", (unsigned int *) &n);
                                *bp++ = n;
                                break;
                            }
index d7eee31..5eeb53d 100644 (file)
@@ -89,8 +89,13 @@ void initgetrec(void)
        char *p;
 
        for (i = 1; i < *ARGC; i++) {
-               if (!isclvar(p = getargv(i))) { /* find 1st real filename */
-                       setsval(lookup("FILENAME", symtab), getargv(i));
+               p = getargv(i); /* find 1st real filename */
+               if (p == NULL || *p == '\0') {  /* deleted or zapped */
+                       argno++;
+                       continue;
+               }
+               if (!isclvar(p)) {
+                       setsval(lookup("FILENAME", symtab), p);
                        return;
                }
                setclvar(p);    /* a commandline assignment before filename */
@@ -124,7 +129,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 +192,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 +233,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 +485,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;
 }
index 9eff3d7..3c4dbf5 100644 (file)
@@ -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 20110810";
 
 #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]);
index 0a68b3a..e4de112 100644 (file)
@@ -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 *);
index e96379b..553081f 100644 (file)
@@ -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);
 }
index c19ce94..e9d7750 100644 (file)
@@ -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);
 }