Permalink
Browse files

from http://www.cs.princeton.edu/~bwk/btl.mirror/

  • Loading branch information...
1 parent b86116a commit 707f6afa55bb1da8d877f10ef16d63d5444ad14c christos committed Dec 29, 2012
@@ -25,6 +25,64 @@ THIS SOFTWARE.
This file lists all bug fixes, changes, etc., made since the AWK book
was sent to the printers in August, 1987.
+Dec 20, 2012:
+ fiddled makefile to get correct yacc and bison flags. pick yacc
+ (linux) or bison (mac) as necessary.
+
+ added __attribute__((__noreturn__)) to a couple of lines in
+ proto.h, to silence someone's enthusiastic checker.
+
+ fixed obscure call by value bug in split(a[1],a) reported on
+ 9fans. the management of temporary values is just a mess; i
+ took a shortcut by making an extra string copy. thanks
+ to paul patience and arnold robbins for passing it on and for
+ proposed patches.
+
+ tiny fiddle in setfval to eliminate -0 results in T.expr, which
+ has irritated me for 20+ years.
+
+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.
+ (thanks, ruslan)
+
+May 1, 2011:
+ after advice from todd miller, kevin lo, ruslan ermilov,
+ and arnold robbins, changed srand() to return the previous
+ seed (which is 1 on the first call of srand). the seed is
+ an Awkfloat internally though converted to unsigned int to
+ pass to the library srand(). thanks, everyone.
+
+ fixed a subtle (and i hope low-probability) overflow error
+ in fldbld, by adding space for one extra \0. thanks to
+ robert bassett for spotting this one and providing a fix.
+
+ removed the files related to compilation on windows. i no
+ longer have anything like a current windows environment, so
+ i can't test any of it.
+
May 23, 2010:
fixed long-standing overflow bug in run.c; many thanks to
nelson beebe for spotting it and providing the fix.
@@ -29,7 +29,7 @@ by Al Aho, Brian Kernighan, and Peter Weinberger
Changes, mostly bug fixes and occasional enhancements, are listed
in FIXES. If you distribute this code further, please please please
distribute FIXES with it. If you find errors, please report them
-to bwk@bell-labs.com. Thanks.
+to bwk@cs.princeton.edu. Thanks.
The program itself is created by
make
@@ -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; }
@@ -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--;
@@ -748,7 +748,11 @@ struct charclass {
} charclasses[] = {
{ "alnum", 5, isalnum },
{ "alpha", 5, isalpha },
+#ifndef HAS_ISBLANK
{ "blank", 5, isspace }, /* was isblank */
+#else
+ { "blank", 5, isblank },
+#endif
{ "cntrl", 5, iscntrl },
{ "digit", 5, isdigit },
{ "graph", 5, isgraph },
@@ -785,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;
@@ -411,7 +411,7 @@ int string(void)
}
*px = 0;
unput(c);
- sscanf(xbuf, "%x", &n);
+ sscanf(xbuf, "%x", (unsigned int *) &n);
*bp++ = n;
break;
}
@@ -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) );
@@ -256,6 +264,7 @@ void fldbld(void) /* create fields from current record */
{
/* this relies on having fields[] the same length as $0 */
/* the fields are all stored in this one array with \0's */
+ /* possibly with a final trailing \0 not associated with any field */
char *r, *fr, sep;
Cell *p;
int i, j, n;
@@ -268,7 +277,7 @@ void fldbld(void) /* create fields from current record */
n = strlen(r);
if (n > fieldssize) {
xfree(fields);
- if ((fields = (char *) malloc(n+1)) == NULL)
+ if ((fields = (char *) malloc(n+2)) == NULL) /* possibly 2 final \0s */
FATAL("out of space for fields in fldbld %d", n);
fieldssize = n;
}
@@ -476,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;
}
@@ -22,7 +22,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
-const char *version = "version 20100523";
+const char *version = "version 20121220";
#define DEBUG
#include <stdio.h>
@@ -38,6 +38,7 @@ extern char **environ;
extern int nfields;
int dbg = 0;
+Awkfloat srand_seed = 1;
char *cmdname; /* gets argv[0] for error messages */
extern FILE *yyin; /* lex input file */
char *lexprog; /* points to program argument if it exists */
@@ -67,6 +68,10 @@ int main(int argc, char *argv[])
exit(1);
}
signal(SIGFPE, fpecatch);
+
+ srand_seed = 1;
+ srand(srand_seed);
+
yyin = NULL;
symtab = makesymtab(NSYMTAB/NSYMTAB);
while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') {
@@ -86,13 +91,18 @@ int main(int argc, char *argv[])
safe = 1;
break;
case 'f': /* next argument is program filename */
- argc--;
- argv++;
- if (argc <= 1)
- FATAL("no program filename");
- if (npfile >= MAX_PFILE - 1)
- FATAL("too many -f options");
- pfile[npfile++] = argv[1];
+ if (argv[1][2] != 0) { /* arg is -fsomething */
+ if (npfile >= MAX_PFILE - 1)
+ FATAL("too many -f options");
+ pfile[npfile++] = &argv[1][2];
+ } else { /* arg is -f something */
+ argc--; argv++;
+ if (argc <= 1)
+ FATAL("no program filename");
+ if (npfile >= MAX_PFILE - 1)
+ FATAL("too many -f options");
+ pfile[npfile++] = argv[1];
+ }
break;
case 'F': /* set field separator */
if (argv[1][2] != 0) { /* arg is -Fsomething */
@@ -111,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]);
@@ -26,26 +26,26 @@ CFLAGS = -g
CFLAGS = -O2
CFLAGS =
-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 -g -Wall -pedantic
+CC = gcc -O4 -Wall -pedantic -fno-strict-aliasing
-YACC = bison -y
-YACC = yacc
-YFLAGS = -d
+YACC = bison -d -y
+YACC = yacc -d -S
+#YFLAGS = -d -S
+ # -S uses sprintf in yacc parser instead of sprint
OFILES = b.o main.o parse.o proctab.o tran.o lib.o run.o lex.o
SOURCE = awk.h ytab.c ytab.h proto.h awkgram.y lex.c b.c main.c \
- maketab.c parse.c lib.c run.c tran.c proctab.c missing95.c
+ maketab.c parse.c lib.c run.c tran.c proctab.c
LISTING = awk.h proto.h awkgram.y lex.c b.c main.c maketab.c parse.c \
- lib.c run.c tran.c missing95.c
+ lib.c run.c tran.c
-SHIP = README FIXES $(SOURCE) ytab[ch].bak makefile makefile.win \
- vcvars32.bat buildwin.bat awk.1
+SHIP = README FIXES $(SOURCE) ytab[ch].bak makefile \
+ awk.1
a.out: ytab.o $(OFILES)
$(CC) $(CFLAGS) ytab.o $(OFILES) $(ALLOC) -lm
Oops, something went wrong.

0 comments on commit 707f6af

Please sign in to comment.