diff options
| author | Ruslan Ermilov <ru@FreeBSD.org> | 2011-12-08 10:42:38 +0000 |
|---|---|---|
| committer | Ruslan Ermilov <ru@FreeBSD.org> | 2011-12-08 10:42:38 +0000 |
| commit | 838ab47dcac9bd7d04471f78b0f7bb81f3b68654 (patch) | |
| tree | 83a502f25649edf23b2a3c85dc177fe11e47170f /contrib | |
| parent | 1248ebfa52a8ac9c9d7e4a574bd621ab9e668121 (diff) | |
Notes
Diffstat (limited to 'contrib')
| -rw-r--r-- | contrib/one-true-awk/FIXES | 53 | ||||
| -rw-r--r-- | contrib/one-true-awk/README | 2 | ||||
| -rw-r--r-- | contrib/one-true-awk/awkgram.y | 4 | ||||
| -rw-r--r-- | contrib/one-true-awk/b.c | 20 | ||||
| -rw-r--r-- | contrib/one-true-awk/lex.c | 2 | ||||
| -rw-r--r-- | contrib/one-true-awk/lib.c | 21 | ||||
| -rw-r--r-- | contrib/one-true-awk/main.c | 21 | ||||
| -rw-r--r-- | contrib/one-true-awk/makefile | 15 | ||||
| -rw-r--r-- | contrib/one-true-awk/proctab.c | 207 | ||||
| -rw-r--r-- | contrib/one-true-awk/proto.h | 4 | ||||
| -rw-r--r-- | contrib/one-true-awk/run.c | 64 | ||||
| -rw-r--r-- | contrib/one-true-awk/tran.c | 16 |
12 files changed, 164 insertions, 265 deletions
diff --git a/contrib/one-true-awk/FIXES b/contrib/one-true-awk/FIXES index bda79768606a..a708027461ce 100644 --- a/contrib/one-true-awk/FIXES +++ b/contrib/one-true-awk/FIXES @@ -25,6 +25,59 @@ 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. + (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. + + fixed bug that didn't parse -vd=1 properly; thanks to santiago + vila for spotting it. + +Feb 8, 2010: + i give up. replaced isblank with isspace in b.c; there are + no consistent header files. + Nov 26, 2009: fixed a long-standing issue with when FS takes effect. a change to FS is now noticed immediately for subsequent splits. diff --git a/contrib/one-true-awk/README b/contrib/one-true-awk/README index 21255a1ca020..24aaf9092d58 100644 --- a/contrib/one-true-awk/README +++ b/contrib/one-true-awk/README @@ -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 diff --git a/contrib/one-true-awk/awkgram.y b/contrib/one-true-awk/awkgram.y index 91b62571b8a9..5b5c461b3eed 100644 --- a/contrib/one-true-awk/awkgram.y +++ b/contrib/one-true-awk/awkgram.y @@ -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; } diff --git a/contrib/one-true-awk/b.c b/contrib/one-true-awk/b.c index baefe6f71e27..447993521975 100644 --- a/contrib/one-true-awk/b.c +++ b/contrib/one-true-awk/b.c @@ -234,7 +234,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; @@ -248,16 +248,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') @@ -314,13 +314,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 (collate_range_cmp(c, c2) > 0) { bp--; i--; @@ -752,7 +752,7 @@ Node *unary(Node *np) /* #define HAS_ISBLANK */ #ifndef HAS_ISBLANK -int (isblank)(int c) +int (xisblank)(int c) { return c==' ' || c=='\t'; } @@ -766,7 +766,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 }, @@ -803,7 +807,7 @@ int relex(void) /* lexical analyzer for reparse */ case ')': return c; case '\\': - rlxval = quoted((char **) &prestr); + rlxval = quoted(&prestr); return CHAR; default: rlxval = c; diff --git a/contrib/one-true-awk/lex.c b/contrib/one-true-awk/lex.c index 49d7c5ca74e8..d09f5507e3d2 100644 --- a/contrib/one-true-awk/lex.c +++ b/contrib/one-true-awk/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; } diff --git a/contrib/one-true-awk/lib.c b/contrib/one-true-awk/lib.c index 017b37670d07..5eeb53d4679d 100644 --- a/contrib/one-true-awk/lib.c +++ b/contrib/one-true-awk/lib.c @@ -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; } diff --git a/contrib/one-true-awk/main.c b/contrib/one-true-awk/main.c index d78a8511e79b..8cc70573afd7 100644 --- a/contrib/one-true-awk/main.c +++ b/contrib/one-true-awk/main.c @@ -25,7 +25,7 @@ THIS SOFTWARE. #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -const char *version = "version 20091126 (FreeBSD)"; +const char *version = "version 20110810 (FreeBSD)"; #define DEBUG #include <stdio.h> @@ -41,6 +41,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 */ @@ -71,6 +72,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') { @@ -90,7 +95,7 @@ int main(int argc, char *argv[]) safe = 1; break; case 'f': /* next argument is program filename */ - if (argv[1][2] != 0) { /* arg is -fsomething */ + if (argv[1][2] != 0) { /* arg is -fsomething */ if (npfile >= MAX_PFILE - 1) FATAL("too many -f options"); pfile[npfile++] = &argv[1][2]; @@ -120,13 +125,19 @@ 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) { /* arg is -vsomething */ - if (argv[1][2] != 0) + 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 && isclvar(argv[1])) + 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': diff --git a/contrib/one-true-awk/makefile b/contrib/one-true-awk/makefile index 9d3985be2d4c..52c7424b34c1 100644 --- a/contrib/one-true-awk/makefile +++ b/contrib/one-true-awk/makefile @@ -26,12 +26,11 @@ CFLAGS = -g CFLAGS = -O2 CFLAGS = -CC = gcc -Wall -g -Wwrite-strings -CC = gcc -fprofile-arcs -ftest-coverage # then gcov f1.c; cat f1.c.gcov CC = gcc -Wall -g CC = cc -CC = gcc -O4 - +CC = gcc -Wall -g -Wwrite-strings +CC = gcc -fprofile-arcs -ftest-coverage # then gcov f1.c; cat f1.c.gcov +CC = gcc -O4 -Wall -pedantic -fno-strict-aliasing YACC = bison -y YACC = yacc @@ -40,13 +39,13 @@ YFLAGS = -d 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 diff --git a/contrib/one-true-awk/proctab.c b/contrib/one-true-awk/proctab.c deleted file mode 100644 index e4eddfda92d1..000000000000 --- a/contrib/one-true-awk/proctab.c +++ /dev/null @@ -1,207 +0,0 @@ -#include <stdio.h> -#include "awk.h" -#include "ytab.h" - -static char *printname[93] = { - (char *) "FIRSTTOKEN", /* 258 */ - (char *) "PROGRAM", /* 259 */ - (char *) "PASTAT", /* 260 */ - (char *) "PASTAT2", /* 261 */ - (char *) "XBEGIN", /* 262 */ - (char *) "XEND", /* 263 */ - (char *) "NL", /* 264 */ - (char *) "ARRAY", /* 265 */ - (char *) "MATCH", /* 266 */ - (char *) "NOTMATCH", /* 267 */ - (char *) "MATCHOP", /* 268 */ - (char *) "FINAL", /* 269 */ - (char *) "DOT", /* 270 */ - (char *) "ALL", /* 271 */ - (char *) "CCL", /* 272 */ - (char *) "NCCL", /* 273 */ - (char *) "CHAR", /* 274 */ - (char *) "OR", /* 275 */ - (char *) "STAR", /* 276 */ - (char *) "QUEST", /* 277 */ - (char *) "PLUS", /* 278 */ - (char *) "EMPTYRE", /* 279 */ - (char *) "AND", /* 280 */ - (char *) "BOR", /* 281 */ - (char *) "APPEND", /* 282 */ - (char *) "EQ", /* 283 */ - (char *) "GE", /* 284 */ - (char *) "GT", /* 285 */ - (char *) "LE", /* 286 */ - (char *) "LT", /* 287 */ - (char *) "NE", /* 288 */ - (char *) "IN", /* 289 */ - (char *) "ARG", /* 290 */ - (char *) "BLTIN", /* 291 */ - (char *) "BREAK", /* 292 */ - (char *) "CLOSE", /* 293 */ - (char *) "CONTINUE", /* 294 */ - (char *) "DELETE", /* 295 */ - (char *) "DO", /* 296 */ - (char *) "EXIT", /* 297 */ - (char *) "FOR", /* 298 */ - (char *) "FUNC", /* 299 */ - (char *) "SUB", /* 300 */ - (char *) "GSUB", /* 301 */ - (char *) "IF", /* 302 */ - (char *) "INDEX", /* 303 */ - (char *) "LSUBSTR", /* 304 */ - (char *) "MATCHFCN", /* 305 */ - (char *) "NEXT", /* 306 */ - (char *) "NEXTFILE", /* 307 */ - (char *) "ADD", /* 308 */ - (char *) "MINUS", /* 309 */ - (char *) "MULT", /* 310 */ - (char *) "DIVIDE", /* 311 */ - (char *) "MOD", /* 312 */ - (char *) "ASSIGN", /* 313 */ - (char *) "ASGNOP", /* 314 */ - (char *) "ADDEQ", /* 315 */ - (char *) "SUBEQ", /* 316 */ - (char *) "MULTEQ", /* 317 */ - (char *) "DIVEQ", /* 318 */ - (char *) "MODEQ", /* 319 */ - (char *) "POWEQ", /* 320 */ - (char *) "PRINT", /* 321 */ - (char *) "PRINTF", /* 322 */ - (char *) "SPRINTF", /* 323 */ - (char *) "ELSE", /* 324 */ - (char *) "INTEST", /* 325 */ - (char *) "CONDEXPR", /* 326 */ - (char *) "POSTINCR", /* 327 */ - (char *) "PREINCR", /* 328 */ - (char *) "POSTDECR", /* 329 */ - (char *) "PREDECR", /* 330 */ - (char *) "VAR", /* 331 */ - (char *) "IVAR", /* 332 */ - (char *) "VARNF", /* 333 */ - (char *) "CALL", /* 334 */ - (char *) "NUMBER", /* 335 */ - (char *) "STRING", /* 336 */ - (char *) "REGEXPR", /* 337 */ - (char *) "GETLINE", /* 338 */ - (char *) "SUBSTR", /* 339 */ - (char *) "SPLIT", /* 340 */ - (char *) "RETURN", /* 341 */ - (char *) "WHILE", /* 342 */ - (char *) "CAT", /* 343 */ - (char *) "UMINUS", /* 344 */ - (char *) "NOT", /* 345 */ - (char *) "POWER", /* 346 */ - (char *) "INCR", /* 347 */ - (char *) "DECR", /* 348 */ - (char *) "INDIRECT", /* 349 */ - (char *) "LASTTOKEN", /* 350 */ -}; - - -Cell *(*proctab[93])(Node **, int) = { - nullproc, /* FIRSTTOKEN */ - program, /* PROGRAM */ - pastat, /* PASTAT */ - dopa2, /* PASTAT2 */ - nullproc, /* XBEGIN */ - nullproc, /* XEND */ - nullproc, /* NL */ - array, /* ARRAY */ - matchop, /* MATCH */ - matchop, /* NOTMATCH */ - nullproc, /* MATCHOP */ - nullproc, /* FINAL */ - nullproc, /* DOT */ - nullproc, /* ALL */ - nullproc, /* CCL */ - nullproc, /* NCCL */ - nullproc, /* CHAR */ - nullproc, /* OR */ - nullproc, /* STAR */ - nullproc, /* QUEST */ - nullproc, /* PLUS */ - nullproc, /* EMPTYRE */ - boolop, /* AND */ - boolop, /* BOR */ - nullproc, /* APPEND */ - relop, /* EQ */ - relop, /* GE */ - relop, /* GT */ - relop, /* LE */ - relop, /* LT */ - relop, /* NE */ - instat, /* IN */ - arg, /* ARG */ - bltin, /* BLTIN */ - jump, /* BREAK */ - closefile, /* CLOSE */ - jump, /* CONTINUE */ - awkdelete, /* DELETE */ - dostat, /* DO */ - jump, /* EXIT */ - forstat, /* FOR */ - nullproc, /* FUNC */ - sub, /* SUB */ - gsub, /* GSUB */ - ifstat, /* IF */ - sindex, /* INDEX */ - nullproc, /* LSUBSTR */ - matchop, /* MATCHFCN */ - jump, /* NEXT */ - jump, /* NEXTFILE */ - arith, /* ADD */ - arith, /* MINUS */ - arith, /* MULT */ - arith, /* DIVIDE */ - arith, /* MOD */ - assign, /* ASSIGN */ - nullproc, /* ASGNOP */ - assign, /* ADDEQ */ - assign, /* SUBEQ */ - assign, /* MULTEQ */ - assign, /* DIVEQ */ - assign, /* MODEQ */ - assign, /* POWEQ */ - printstat, /* PRINT */ - awkprintf, /* PRINTF */ - awksprintf, /* SPRINTF */ - nullproc, /* ELSE */ - intest, /* INTEST */ - condexpr, /* CONDEXPR */ - incrdecr, /* POSTINCR */ - incrdecr, /* PREINCR */ - incrdecr, /* POSTDECR */ - incrdecr, /* PREDECR */ - nullproc, /* VAR */ - nullproc, /* IVAR */ - getnf, /* VARNF */ - call, /* CALL */ - nullproc, /* NUMBER */ - nullproc, /* STRING */ - nullproc, /* REGEXPR */ - awkgetline, /* GETLINE */ - substr, /* SUBSTR */ - split, /* SPLIT */ - jump, /* RETURN */ - whilestat, /* WHILE */ - cat, /* CAT */ - arith, /* UMINUS */ - boolop, /* NOT */ - arith, /* POWER */ - nullproc, /* INCR */ - nullproc, /* DECR */ - indirect, /* INDIRECT */ - nullproc, /* LASTTOKEN */ -}; - -char *tokname(int n) -{ - static char buf[100]; - - if (n < FIRSTTOKEN || n > LASTTOKEN) { - sprintf(buf, "token %d", n); - return buf; - } - return printname[n-FIRSTTOKEN]; -} diff --git a/contrib/one-true-awk/proto.h b/contrib/one-true-awk/proto.h index 0a68b3a813f8..e4de112723f4 100644 --- a/contrib/one-true-awk/proto.h +++ b/contrib/one-true-awk/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 *); diff --git a/contrib/one-true-awk/run.c b/contrib/one-true-awk/run.c index 20c08b10525a..942f25013a74 100644 --- a/contrib/one-true-awk/run.c +++ b/contrib/one-true-awk/run.c @@ -69,6 +69,7 @@ void tempfree(Cell *p) { jmp_buf env; extern int pairstack[]; +extern Awkfloat srand_seed; Node *winner = NULL; /* root of parse tree */ Cell *tmps; /* free temporary cells for execution */ @@ -1238,6 +1239,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 */ @@ -1469,6 +1476,7 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis Cell *x, *y; Awkfloat u; int t; + Awkfloat tmp; char *p, *buf; Node *nextarg; FILE *fp; @@ -1520,7 +1528,10 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis u = time((time_t *)0); else u = getfval(x); + tmp = u; srand((unsigned int) u); + u = srand_seed; + srand_seed = tmp; break; case FTOUPPER: case FTOLOWER: @@ -1616,17 +1627,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) @@ -1637,7 +1656,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; @@ -1647,11 +1666,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) { @@ -1679,7 +1706,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 "???"; @@ -1694,7 +1721,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 ); @@ -1738,7 +1765,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); } @@ -1890,9 +1917,10 @@ Cell *gsub(Node **a, int nnn) /* global substitute */ adjbuf(&buf, &bufsz, 1+strlen(sptr)+pb-buf, 0, &pb, "gsub"); while ((*pb++ = *sptr++) != 0) ; - done: if (pb > buf + bufsz) - FATAL("gsub result2 %.30s too big; can't happen", buf); - *pb = '\0'; + done: if (pb < buf + bufsz) + *pb = '\0'; + else if (*(pb-1) != '\0') + FATAL("gsub result2 %.30s truncated; can't happen", buf); setsval(x, buf); /* BUG: should be able to avoid copy + free */ pfa->initstat = tempstat; } diff --git a/contrib/one-true-awk/tran.c b/contrib/one-true-awk/tran.c index c19ce94302a2..e9d77506a34d 100644 --- a/contrib/one-true-awk/tran.c +++ b/contrib/one-true-awk/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); } |
