diff options
-rw-r--r-- | usr.bin/awk/FIXES | 77 | ||||
-rw-r--r-- | usr.bin/awk/OpenBSD-PATCHES | 6 | ||||
-rw-r--r-- | usr.bin/awk/README | 37 | ||||
-rw-r--r-- | usr.bin/awk/awk.h | 4 | ||||
-rw-r--r-- | usr.bin/awk/b.c | 73 | ||||
-rw-r--r-- | usr.bin/awk/lex.c | 28 | ||||
-rw-r--r-- | usr.bin/awk/lib.c | 20 | ||||
-rw-r--r-- | usr.bin/awk/main.c | 22 | ||||
-rw-r--r-- | usr.bin/awk/maketab.c | 10 | ||||
-rw-r--r-- | usr.bin/awk/parse.c | 4 | ||||
-rw-r--r-- | usr.bin/awk/proto.h | 65 | ||||
-rw-r--r-- | usr.bin/awk/run.c | 82 | ||||
-rw-r--r-- | usr.bin/awk/tran.c | 53 |
13 files changed, 324 insertions, 157 deletions
diff --git a/usr.bin/awk/FIXES b/usr.bin/awk/FIXES index 878cf8b302e..ee0f79f0660 100644 --- a/usr.bin/awk/FIXES +++ b/usr.bin/awk/FIXES @@ -1,4 +1,4 @@ -/* $OpenBSD: FIXES,v 1.10 2001/09/08 00:12:40 millert Exp $ */ +/* $OpenBSD: FIXES,v 1.11 2002/12/19 21:24:28 millert Exp $ */ /**************************************************************** Copyright (C) Lucent Technologies 1997 All Rights Reserved @@ -26,6 +26,81 @@ THIS SOFTWARE. This file lists all bug fixes, changes, etc., made since the AWK book was sent to the printers in August, 1987. +Dec 13, 2002: + for the moment, the internationalization changes of nov 29 are + rolled back -- programs like x = 1.2 don't work in some locales, + because the parser is expecting x = 1,2. until i understand this + better, this will have to wait. + +Nov 29, 2002: + modified b.c (with tiny changes in main and run) to support + locales, using strcoll and iswhatever tests for posix character + classes. thanks to ruslan ermilov (ru@freebsd.org) for code. + the function isblank doesn't seem to have propagated to any + header file near me, so it's there explicitly. not properly + tested on non-ascii character sets by me. + +Jun 28, 2002: + modified run/format() and tran/getsval() to do a slightly better + job on using OFMT for output from print and CONVFMT for other + number->string conversions, as promised by posix and done by + gawk and mawk. there are still places where it doesn't work + right if CONVFMT is changed; by then the STR attribute of the + variable has been irrevocably set. thanks to arnold robbins for + code and examples. + + fixed subtle bug in format that could get core dump. thanks to + Jaromir Dolecek <jdolecek@NetBSD.org> for finding and fixing. + minor cleanup in run.c / format() at the same time. + + added some tests for null pointers to debugging printf's, which + were never intended for external consumption. thanks to dave + kerns (dkerns@lucent.com) for pointing this out. + + GNU compatibility: an empty regexp matches anything (thanks to + dag-erling smorgrav, des@ofug.org). subject to reversion if + this does more harm than good. + + pervasive small changes to make things more const-correct, as + reported by gcc's -Wwrite-strings. as it says in the gcc manual, + this may be more nuisance than useful. provoked by a suggestion + and code from arnaud desitter, arnaud@nimbus.geog.ox.ac.uk + + minor documentation changes to note that this now compiles out + of the box on Mac OS X. + +Feb 10, 2002: + changed types in posix chars structure to quiet solaris cc. + +Jan 1, 2002: + fflush() or fflush("") flushes all files and pipes. + + length(arrayname) returns number of elements; thanks to + arnold robbins for suggestion. + + added a makefile.win to make it easier to build on windows. + based on dan allen's buildwin.bat. + +Nov 16, 2001: + added support for posix character class names like [:digit:], + which are not exactly shorter than [0-9] and perhaps no more + portable. thanks to dag-erling smorgrav for code. + +Feb 16, 2001: + removed -m option; no longer needed, and it was actually + broken (noted thanks to volker kiefel). + +Feb 10, 2001: + fixed an appalling bug in gettok: any sequence of digits, +,-, E, e, + and period was accepted as a valid number if it started with a period. + this would never have happened with the lex version. + + other 1-character botches, now fixed, include a bare $ and a + bare " at the end of the input. + +Feb 7, 2001: + more (const char *) casts in b.c and tran.c to silence warnings. + Nov 15, 2000: fixed a bug introduced in august 1997 that caused expressions like $f[1] to be syntax errors. thanks to arnold robbins for diff --git a/usr.bin/awk/OpenBSD-PATCHES b/usr.bin/awk/OpenBSD-PATCHES index 7349b5d801d..aba9d589554 100644 --- a/usr.bin/awk/OpenBSD-PATCHES +++ b/usr.bin/awk/OpenBSD-PATCHES @@ -1,4 +1,4 @@ -/* $OpenBSD: OpenBSD-PATCHES,v 1.4 1999/04/20 17:31:28 millert Exp $ */ +/* $OpenBSD: OpenBSD-PATCHES,v 1.5 2002/12/19 21:24:28 millert Exp $ */ I merged the April 16, 1999 version of the "one true awk" from Brian Kernighan's web page http://cm.bell-labs.com/who/bwk/ @@ -15,7 +15,7 @@ Start of historical section: -------------------------------------------------------------- These are the changes made from Research Awk to allow it to -build on OpenBSD with flex. Below is the inof that came +build on OpenBSD with flex. Below is the info that came with the original set of diffs (from 4.4BSD). ytab.* was changed to awkgram.* for make's benefit. @@ -38,7 +38,7 @@ Let me know if you find more problems. --- /home/millert/tmp/awk/awk.1 Sun Jan 19 18:06:25 1997 +++ awk.1 Sun Jan 19 17:51:39 1997 @@ -1,3 +1,4 @@ -+.\" $OpenBSD: OpenBSD-PATCHES,v 1.4 1999/04/20 17:31:28 millert Exp $ ++.\" $OpenBSD: OpenBSD-PATCHES,v 1.5 2002/12/19 21:24:28 millert Exp $ .de EX .nf .ft CW diff --git a/usr.bin/awk/README b/usr.bin/awk/README index 39ad4d77920..308fddfee50 100644 --- a/usr.bin/awk/README +++ b/usr.bin/awk/README @@ -1,4 +1,4 @@ -/* $OpenBSD: README,v 1.4 2001/09/08 00:12:40 millert Exp $ */ +/* $OpenBSD: README,v 1.5 2002/12/19 21:24:28 millert Exp $ */ /**************************************************************** Copyright (C) Lucent Technologies 1997 All Rights Reserved @@ -41,18 +41,18 @@ which should produce a sequence of messages roughly like this: conflicts: 43 shift/reduce, 85 reduce/reduce mv y.tab.c ytab.c mv y.tab.h ytab.h - cc -O -c ytab.c - cc -O -c b.c - cc -O -c main.c - cc -O -c parse.c - cc -O maketab.c -o maketab + cc -c ytab.c + cc -c b.c + cc -c main.c + cc -c parse.c + cc maketab.c -o maketab ./maketab >proctab.c - cc -O -c proctab.c - cc -O -c tran.c - cc -O -c lib.c - cc -O -c run.c - cc -O -c lex.c - cc -O ytab.o b.o main.o parse.o proctab.o tran.o lib.o run.o lex.o -lm + cc -c proctab.c + cc -c tran.c + cc -c lib.c + cc -c run.c + cc -c lex.c + cc ytab.o b.o main.o parse.o proctab.o tran.o lib.o run.o lex.o -lm This produces an executable a.out; you will eventually want to move this to some place like /usr/bin/awk. @@ -69,16 +69,21 @@ compilers on a variety of systems, but new systems or compilers may raise some new complaint; reports of difficulties are welcome. -This also compiles with Visual C++ on Windows 95 and Windows NT, +This also compiles with Visual C++ on all flavors of Windows, *if* you provide versions of popen and pclose. The file missing95.c contains versions that can be used to get started with, though the underlying support has mysterious properties, the symptom of which can be truncated pipe output. Beware. +The file makefile.win gives hints on how to proceed. -This is also said to compile on Macintosh systems, using the +This compiles without change on Macintosh OS X using gcc and +the standard developer tools. + +This is also said to compile on Macintosh OS 9 systems, using the file "buildmac" provided by Dan Allen (danallen@microsoft.com), -to whom many thanks. Dan also provided buildwin.bat, a simple -script for compiling on NT if you prefer. +to whom many thanks. The version of malloc that comes with some systems is sometimes astonishly slow. If awk seems slow, you might try fixing that. +More generally, turning on optimization can significantly improve +awk's speed, perhaps by 1/3 for highest levels. diff --git a/usr.bin/awk/awk.h b/usr.bin/awk/awk.h index 9762944b892..e29804c8c83 100644 --- a/usr.bin/awk/awk.h +++ b/usr.bin/awk/awk.h @@ -1,4 +1,4 @@ -/* $OpenBSD: awk.h,v 1.9 2001/09/08 00:12:40 millert Exp $ */ +/* $OpenBSD: awk.h,v 1.10 2002/12/19 21:24:28 millert Exp $ */ /**************************************************************** Copyright (C) Lucent Technologies 1997 All Rights Reserved @@ -31,6 +31,8 @@ typedef unsigned char uschar; #define xfree(a) { if ((a) != NULL) { free((char *) a); a = NULL; } } +#define NN(p) ((p) ? (p) : "(null)") /* guaranteed non-null for dprintf +*/ #define DEBUG #ifdef DEBUG /* uses have to be doubly parenthesized */ diff --git a/usr.bin/awk/b.c b/usr.bin/awk/b.c index 288d022cffe..c6039e6740b 100644 --- a/usr.bin/awk/b.c +++ b/usr.bin/awk/b.c @@ -1,4 +1,4 @@ -/* $OpenBSD: b.c,v 1.10 2001/09/08 00:12:40 millert Exp $ */ +/* $OpenBSD: b.c,v 1.11 2002/12/19 21:24:28 millert Exp $ */ /**************************************************************** Copyright (C) Lucent Technologies 1997 All Rights Reserved @@ -76,7 +76,7 @@ int patlen; fa *fatab[NFA]; int nfatab = 0; /* entries in fatab */ -fa *makedfa(char *s, int anchor) /* returns dfa for reg expr s */ +fa *makedfa(const char *s, int anchor) /* returns dfa for reg expr s */ { int i, use, nuse; fa *pfa; @@ -94,7 +94,7 @@ fa *makedfa(char *s, int anchor) /* returns dfa for reg expr s */ return mkdfa(s, anchor); for (i = 0; i < nfatab; i++) /* is it there already? */ if (fatab[i]->anchor == anchor - && strcmp(fatab[i]->restr, s) == 0) { + && strcmp((const char *) fatab[i]->restr, s) == 0) { fatab[i]->use = now++; return fatab[i]; } @@ -118,7 +118,7 @@ fa *makedfa(char *s, int anchor) /* returns dfa for reg expr s */ return pfa; } -fa *mkdfa(char *s, int anchor) /* does the real work of making a dfa */ +fa *mkdfa(const char *s, int anchor) /* does the real work of making a dfa */ /* anchor = 1 for anchored matches, else 0 */ { Node *p, *p1; @@ -283,7 +283,7 @@ int quoted(char **pp) /* pick up next thing after a \\ */ return c; } -char *cclenter(char *argp) /* add a character class */ +char *cclenter(const char *argp) /* add a character class */ { int i, c, c2; uschar *p = (uschar *) argp; @@ -329,7 +329,7 @@ char *cclenter(char *argp) /* add a character class */ return (char *) tostring((char *) buf); } -void overflo(char *s) +void overflo(const char *s) { FATAL("regular expression too big: %.30s...", s); } @@ -447,7 +447,7 @@ void follow(Node *v) /* collects leaves that can follow v into setvec */ } } -int member(int c, char *sarg) /* is c in s? */ +int member(int c, const char *sarg) /* is c in s? */ { uschar *s = (uschar *) sarg; @@ -457,7 +457,7 @@ int member(int c, char *sarg) /* is c in s? */ return(0); } -int match(fa *f, char *p0) /* shortest match ? */ +int match(fa *f, const char *p0) /* shortest match ? */ { int s, ns; uschar *p = (uschar *) p0; @@ -476,7 +476,7 @@ int match(fa *f, char *p0) /* shortest match ? */ return(0); } -int pmatch(fa *f, char *p0) /* longest match, for sub */ +int pmatch(fa *f, const char *p0) /* longest match, for sub */ { int s, ns; uschar *p = (uschar *) p0; @@ -529,7 +529,7 @@ int pmatch(fa *f, char *p0) /* longest match, for sub */ return (0); } -int nematch(fa *f, char *p0) /* non-empty match, for sub */ +int nematch(fa *f, const char *p0) /* non-empty match, for sub */ { int s, ns; uschar *p = (uschar *) p0; @@ -581,15 +581,17 @@ int nematch(fa *f, char *p0) /* non-empty match, for sub */ return (0); } -Node *reparse(char *p) /* parses regular expression pointed to by p */ +Node *reparse(const char *p) /* parses regular expression pointed to by p */ { /* uses relex() to scan regular expression */ Node *np; dprintf( ("reparse <%s>\n", p) ); lastre = prestr = (uschar *) p; /* prestr points to string to be parsed */ rtok = relex(); + /* GNU compatibility: an empty regexp matches anything */ if (rtok == '\0') - FATAL("empty regular expression"); + /* FATAL("empty regular expression"); previous */ + return(op2(ALL, NIL, NIL)); np = regexp(); if (rtok != '\0') FATAL("syntax error in regular expression %s at %s", lastre, prestr); @@ -684,6 +686,37 @@ Node *unary(Node *np) } } +/* + * Character class definitions conformant to the POSIX locale as + * defined in IEEE P1003.1 draft 7 of June 2001, assuming the source + * and operating character sets are both ASCII (ISO646) or supersets + * thereof. + * + * Note that to avoid overflowing the temporary buffer used in + * relex(), the expanded character class (prior to range expansion) + * must be less than twice the size of their full name. + */ +struct charclass { + const char *cc_name; + int cc_namelen; + const char *cc_expand; +} charclasses[] = { + { "alnum", 5, "0-9A-Za-z" }, + { "alpha", 5, "A-Za-z" }, + { "blank", 5, " \t" }, + { "cntrl", 5, "\000-\037\177" }, + { "digit", 5, "0-9" }, + { "graph", 5, "\041-\176" }, + { "lower", 5, "a-z" }, + { "print", 5, " \041-\176" }, + { "punct", 5, "\041-\057\072-\100\133-\140\173-\176" }, + { "space", 5, " \f\n\r\t\v" }, + { "upper", 5, "A-Z" }, + { "xdigit", 6, "0-9A-Fa-f" }, + { NULL, 0, NULL }, +}; + + int relex(void) /* lexical analyzer for reparse */ { int c, n; @@ -691,6 +724,8 @@ int relex(void) /* lexical analyzer for reparse */ static uschar *buf = 0; static int bufsz = 100; uschar *bp; + struct charclass *cc; + const uschar *p; switch (c = *prestr++) { case '|': return OR; @@ -720,7 +755,7 @@ int relex(void) /* lexical analyzer for reparse */ } else cflag = 0; - n = 2 * strlen(prestr)+1; + n = 2 * strlen((const char *) prestr)+1; if (!adjbuf((char **) &buf, &bufsz, n, n, (char **) &bp, 0)) FATAL("out of space for reg expr %.10s...", lastre); for (; ; ) { @@ -731,6 +766,18 @@ int relex(void) /* lexical analyzer for reparse */ *bp++ = c; /* } else if (c == '\n') { */ /* FATAL("newline in character class %.20s...", lastre); */ + } else if (c == '[' && *prestr == ':') { + /* POSIX char class names, Dag-Erling Smorgrav, des@ofug.org */ + for (cc = charclasses; cc->cc_name; cc++) + if (strncmp((const char *) prestr + 1, (const char *) cc->cc_name, cc->cc_namelen) == 0) + break; + if (cc->cc_name != NULL && prestr[1 + cc->cc_namelen] == ':' && + prestr[2 + cc->cc_namelen] == ']') { + prestr += cc->cc_namelen + 3; + for (p = (const uschar *) cc->cc_expand; *p; p++) + *bp++ = *p; + } else + *bp++ = c; } else if (c == '\0') { FATAL("nonterminated character class %.20s", lastre); } else if (bp == buf) { /* 1st char is special */ diff --git a/usr.bin/awk/lex.c b/usr.bin/awk/lex.c index 809e190af8f..96d61ebdfc0 100644 --- a/usr.bin/awk/lex.c +++ b/usr.bin/awk/lex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lex.c,v 1.5 2001/09/08 00:12:40 millert Exp $ */ +/* $OpenBSD: lex.c,v 1.6 2002/12/19 21:24:28 millert Exp $ */ /**************************************************************** Copyright (C) Lucent Technologies 1997 All Rights Reserved @@ -39,7 +39,7 @@ int brackcnt = 0; int parencnt = 0; typedef struct Keyword { - char *word; + const char *word; int sub; int type; } Keyword; @@ -106,7 +106,7 @@ int peek(void) int gettok(char **pbuf, int *psz) /* get next input token */ { - int c; + int c, retc; char *buf = *pbuf; int sz = *psz; char *bp = buf; @@ -134,6 +134,7 @@ int gettok(char **pbuf, int *psz) /* get next input token */ } } *bp = 0; + retc = 'a'; /* alphanumeric */ } else { /* it's a number */ char *rem; /* read input until can't be a number */ @@ -152,11 +153,17 @@ int gettok(char **pbuf, int *psz) /* get next input token */ *bp = 0; strtod(buf, &rem); /* parse the number */ unputstr(rem); /* put rest back for later */ - rem[0] = 0; + if (rem == buf) { /* it wasn't a valid number at all */ + buf[1] = 0; /* so return one character as token */ + retc = buf[0]; /* character is its own type */ + } else { /* some prefix was a number */ + rem[0] = 0; /* so truncate where failure started */ + retc = '0'; /* number */ + } } *pbuf = buf; *psz = sz; - return buf[0]; + return retc; } int word(char *); @@ -187,7 +194,7 @@ int yylex(void) return 0; if (isalpha(c) || c == '_') return word(buf); - if (isdigit(c) || c == '.') { + if (isdigit(c)) { yylval.cp = setsymtab(buf, tostring(buf), atof(buf), CON|NUM, symtab); /* should this also have STR set? */ RET(NUMBER); @@ -312,6 +319,9 @@ int yylex(void) } yylval.cp = setsymtab(buf, "", 0.0, STR|NUM, symtab); RET(IVAR); + } else if (c == 0) { /* */ + SYNTAX( "unexpected end of input after $" ); + RET(';'); } else { unputstr(buf); RET(INDIRECT); @@ -367,6 +377,8 @@ int string(void) case 0: SYNTAX( "non-terminated string %.10s...", buf ); lineno++; + if (c == 0) /* hopeless */ + FATAL( "giving up" ); break; case '\\': c = input(); @@ -488,7 +500,7 @@ int word(char *w) } } -void startreg(void) /* next call to yyles will return a regular expression */ +void startreg(void) /* next call to yylex will return a regular expression */ { reg = 1; } @@ -563,7 +575,7 @@ void unput(int c) /* put lexical character back on input */ ep = ebuf + sizeof(ebuf) - 1; } -void unputstr(char *s) /* put a string back on input */ +void unputstr(const char *s) /* put a string back on input */ { int i; diff --git a/usr.bin/awk/lib.c b/usr.bin/awk/lib.c index 2e2ec08b547..27c6175232c 100644 --- a/usr.bin/awk/lib.c +++ b/usr.bin/awk/lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lib.c,v 1.10 2002/07/04 02:38:58 deraadt Exp $ */ +/* $OpenBSD: lib.c,v 1.11 2002/12/19 21:24:28 millert Exp $ */ /**************************************************************** Copyright (C) Lucent Technologies 1997 All Rights Reserved @@ -394,7 +394,7 @@ void growfldtab(int n) /* make new fields up to at least $n */ nfields = nf; } -int refldbld(char *rec, char *fs) /* build fields from reg expr in FS */ +int refldbld(const char *rec, const char *fs) /* build fields from reg expr in FS */ { /* this relies on having fields[] the same length as $0 */ /* the fields are all stored in this one array with \0's */ @@ -479,12 +479,12 @@ void recbld(void) /* create $0 from $1..$NF if necessary */ int errorflag = 0; -void yyerror(char *s) +void yyerror(const char *s) { SYNTAX(s); } -void SYNTAX(char *fmt, ...) +void SYNTAX(const char *fmt, ...) { extern char *cmdname, *curfname; static int been_here = 0; @@ -569,7 +569,7 @@ void bcheck2(int n, int c1, int c2) fprintf(stderr, "\t%d extra %c's\n", -n, c2); } -void FATAL(char *fmt, ...) +void FATAL(const char *fmt, ...) { extern char *cmdname; va_list varg; @@ -585,7 +585,7 @@ void FATAL(char *fmt, ...) exit(2); } -void WARNING(char *fmt, ...) +void WARNING(const char *fmt, ...) { extern char *cmdname; va_list varg; @@ -667,7 +667,7 @@ void bclass(int c) } } -double errcheck(double x, char *s) +double errcheck(double x, const char *s) { if (errno == EDOM) { @@ -682,9 +682,9 @@ double errcheck(double x, char *s) return x; } -int isclvar(char *s) /* is s of form var=something ? */ +int isclvar(const char *s) /* is s of form var=something ? */ { - char *os = s; + const char *os = s; if (!isalpha((uschar) *s) && *s != '_') return 0; @@ -699,7 +699,7 @@ int isclvar(char *s) /* is s of form var=something ? */ /* wrong: violates 4.10.1.4 of ansi C standard */ #include <math.h> -int is_number(char *s) +int is_number(const char *s) { double r; char *ep; diff --git a/usr.bin/awk/main.c b/usr.bin/awk/main.c index 8215d56a282..40ed2624efc 100644 --- a/usr.bin/awk/main.c +++ b/usr.bin/awk/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.11 2001/09/08 00:12:40 millert Exp $ */ +/* $OpenBSD: main.c,v 1.12 2002/12/19 21:24:28 millert Exp $ */ /**************************************************************** Copyright (C) Lucent Technologies 1997 All Rights Reserved @@ -23,7 +23,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ****************************************************************/ -char *version = "version 20001115"; +const char *version = "version 20021213"; #define DEBUG #include <stdio.h> @@ -57,8 +57,7 @@ int safe = 0; /* 1 => "safe" mode */ int main(int argc, char *argv[]) { - char *fs = NULL, *marg; - int temp; + const char *fs = NULL; setlocale(LC_ALL, ""); @@ -113,19 +112,8 @@ int main(int argc, char *argv[]) setclvar(argv[1]); break; case 'm': /* more memory: -mr=record, -mf=fields */ - /* no longer needed */ - marg = argv[1]; - if (argv[1][3]) - temp = atoi(&argv[1][3]); - else { - argv++; argc--; - temp = atoi(&argv[1][0]); - } - switch (marg[2]) { - case 'r': recsize = temp; break; - case 'f': nfields = temp; break; - default: FATAL("unknown option %s\n", marg); - } + /* no longer supported */ + WARNING("obsolete option %s ignored", argv[1]); break; case 'd': dbg = atoi(&argv[1][2]); diff --git a/usr.bin/awk/maketab.c b/usr.bin/awk/maketab.c index 84e3db99566..5213164e886 100644 --- a/usr.bin/awk/maketab.c +++ b/usr.bin/awk/maketab.c @@ -1,4 +1,4 @@ -/* $OpenBSD: maketab.c,v 1.5 2002/07/04 02:38:58 deraadt Exp $ */ +/* $OpenBSD: maketab.c,v 1.6 2002/12/19 21:24:28 millert Exp $ */ /**************************************************************** Copyright (C) Lucent Technologies 1997 All Rights Reserved @@ -37,8 +37,8 @@ THIS SOFTWARE. struct xx { int token; - char *name; - char *pname; + const char *name; + const char *pname; } proc[] = { { PROGRAM, "program", NULL }, { BOR, "boolop", " || " }, @@ -108,12 +108,12 @@ struct xx }; #define SIZE (LASTTOKEN - FIRSTTOKEN + 1) -char *table[SIZE]; +const char *table[SIZE]; char *names[SIZE]; int main(int argc, char *argv[]) { - struct xx *p; + const struct xx *p; int i, n, tok; char c; FILE *fp; diff --git a/usr.bin/awk/parse.c b/usr.bin/awk/parse.c index 698bb4cda1d..c10aa44cc79 100644 --- a/usr.bin/awk/parse.c +++ b/usr.bin/awk/parse.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.c,v 1.5 2001/09/08 00:12:40 millert Exp $ */ +/* $OpenBSD: parse.c,v 1.6 2002/12/19 21:24:28 millert Exp $ */ /**************************************************************** Copyright (C) Lucent Technologies 1997 All Rights Reserved @@ -254,7 +254,7 @@ void defn(Cell *v, Node *vl, Node *st) /* turn on FCN bit in definition, */ dprintf( ("defining func %s (%d args)\n", v->nval, n) ); } -int isarg(char *s) /* is s in argument list for current function? */ +int isarg(const char *s) /* is s in argument list for current function? */ { /* return -1 if not, otherwise arg # */ extern Node *arglist; Node *p = arglist; diff --git a/usr.bin/awk/proto.h b/usr.bin/awk/proto.h index 9538c3c754d..934200d300a 100644 --- a/usr.bin/awk/proto.h +++ b/usr.bin/awk/proto.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proto.h,v 1.6 1999/12/08 23:09:46 millert Exp $ */ +/* $OpenBSD: proto.h,v 1.7 2002/12/19 21:24:28 millert Exp $ */ /**************************************************************** Copyright (C) Lucent Technologies 1997 All Rights Reserved @@ -34,28 +34,28 @@ extern int yylex(void); extern void startreg(void); extern int input(void); extern void unput(int); -extern void unputstr(char *); +extern void unputstr(const char *); extern int yylook(void); extern int yyback(int *, int); extern int yyinput(void); -extern fa *makedfa(char *, int); -extern fa *mkdfa(char *, int); +extern fa *makedfa(const char *, int); +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 char *cclenter(char *); -extern void overflo(char *); +extern char *cclenter(const char *); +extern void overflo(const char *); extern void cfoll(fa *, Node *); extern int first(Node *); extern void follow(Node *); -extern int member(int, char *); -extern int match(fa *, char *); -extern int pmatch(fa *, char *); -extern int nematch(fa *, char *); -extern Node *reparse(char *); +extern int member(int, const char *); +extern int match(fa *, const char *); +extern int pmatch(fa *, const char *); +extern int nematch(fa *, const char *); +extern Node *reparse(const char *); extern Node *regexp(void); extern Node *primary(void); extern Node *concat(Node *); @@ -88,7 +88,7 @@ extern Node *makearr(Node *); extern Node *pa2stat(Node *, Node *, Node *); extern Node *linkum(Node *, Node *); extern void defn(Cell *, Node *, Node *); -extern int isarg(char *); +extern int isarg(const char *); extern char *tokname(int); extern Cell *(*proctab[])(Node **, int); extern int ptoi(void *); @@ -99,18 +99,19 @@ extern void arginit(int, char **); extern void envinit(char **); extern Array *makesymtab(int); extern void freesymtab(Cell *); -extern void freeelem(Cell *, char *); -extern Cell *setsymtab(char *, char *, double, unsigned int, Array *); -extern int hash(char *, int); +extern void freeelem(Cell *, const char *); +extern Cell *setsymtab(const char *, const char *, double, unsigned int, Array *); +extern int hash(const char *, int); extern void rehash(Array *); -extern Cell *lookup(char *, Array *); +extern Cell *lookup(const char *, Array *); extern double setfval(Cell *, double); -extern void funnyvar(Cell *, char *); -extern char *setsval(Cell *, char *); +extern void funnyvar(Cell *, const char *); +extern char *setsval(Cell *, const char *); extern double getfval(Cell *); extern char *getsval(Cell *); -extern char *tostring(char *); -extern char *qstring(char *, int); +extern char *getpssval(Cell *); /* for print */ +extern char *tostring(const char *); +extern char *qstring(const char *, int); extern void recinit(unsigned int); extern void initgetrec(void); @@ -124,24 +125,24 @@ extern void setclvar(char *); extern void fldbld(void); extern void cleanfld(int, int); extern void newfld(int); -extern int refldbld(char *, char *); +extern int refldbld(const char *, const char *); extern void recbld(void); extern Cell *fieldadr(int); -extern void yyerror(char *); +extern void yyerror(const char *); extern void fpecatch(int); extern void bracecheck(void); extern void bcheck2(int, int, int); -extern void SYNTAX(char *, ...); -extern void FATAL(char *, ...); -extern void WARNING(char *, ...); +extern void SYNTAX(const char *, ...); +extern void FATAL(const char *, ...); +extern void WARNING(const char *, ...); extern void error(void); extern void eprint(void); extern void bclass(int); -extern double errcheck(double, char *); -extern int isclvar(char *); -extern int is_number(char *); +extern double errcheck(double, const char *); +extern int isclvar(const char *); +extern int is_number(const char *); -extern int adjbuf(char **pb, int *sz, int min, int q, char **pbp, char *what); +extern int adjbuf(char **pb, int *sz, int min, int q, char **pbp, const char *what); extern void run(Node *); extern Cell *execute(Node *); extern Cell *program(Node **, int); @@ -163,7 +164,7 @@ extern Cell *field(Node **, int); extern Cell *indirect(Node **, int); extern Cell *substr(Node **, int); extern Cell *sindex(Node **, int); -extern int format(char **, int *, char *, Node *); +extern int format(char **, int *, const char *, Node *); extern Cell *awksprintf(Node **, int); extern Cell *awkprintf(Node **, int); extern Cell *arith(Node **, int); @@ -184,8 +185,8 @@ extern Cell *bltin(Node **, int); extern Cell *printstat(Node **, int); extern Cell *nullproc(Node **, int); extern FILE *redirect(int, Node *); -extern FILE *openfile(int, char *); -extern char *filename(FILE *); +extern FILE *openfile(int, const char *); +extern const char *filename(FILE *); extern Cell *closefile(Node **, int); extern void closeall(void); extern Cell *sub(Node **, int); diff --git a/usr.bin/awk/run.c b/usr.bin/awk/run.c index 76f25d45035..4e582664e78 100644 --- a/usr.bin/awk/run.c +++ b/usr.bin/awk/run.c @@ -1,4 +1,4 @@ -/* $OpenBSD: run.c,v 1.17 2001/09/08 00:12:40 millert Exp $ */ +/* $OpenBSD: run.c,v 1.18 2002/12/19 21:24:28 millert Exp $ */ /**************************************************************** Copyright (C) Lucent Technologies 1997 All Rights Reserved @@ -91,7 +91,7 @@ Node *curnode = NULL; /* the node being executed, for debugging */ /* buffer memory management */ int adjbuf(char **pbuf, int *psiz, int minlen, int quantum, char **pbptr, - char *whatrtn) + const char *whatrtn) /* pbuf: address of pointer to buffer being managed * psiz: address of buffer size variable * minlen: minimum length of buffer needed @@ -248,7 +248,7 @@ Cell *call(Node **a, int n) /* function call. very kludgy and fragile */ y = execute(x); oargs[i] = y; dprintf( ("args[%d]: %s %f <%s>, t=%o\n", - i, y->nval, y->fval, isarr(y) ? "(array)" : y->sval, y->tval) ); + i, NN(y->nval), y->fval, isarr(y) ? "(array)" : NN(y->sval), y->tval) ); if (isfcn(y)) FATAL("can't use function %s as argument in %s", y->nval, s); if (isarr(y)) @@ -464,7 +464,7 @@ Cell *array(Node **a, int n) /* a[0] is symtab, a[1] is list of subscripts */ tempfree(y); } if (!isarr(x)) { - dprintf( ("making %s into an array\n", x->nval) ); + dprintf( ("making %s into an array\n", NN(x->nval)) ); if (freeable(x)) xfree(x->sval); x->tval &= ~(STR|NUM|DONTFREE); @@ -565,7 +565,7 @@ Cell *matchop(Node **a, int n) /* ~ and match() */ char *s, *t; int i; fa *pfa; - int (*mf)(fa *, char *) = match, mode = 0; + int (*mf)(fa *, const char *) = match, mode = 0; if (n == MATCHFCN) { mf = pmatch; @@ -670,7 +670,7 @@ Cell *relop(Node **a, int n) /* a[0 < a[1], etc. */ void tfree(Cell *a) /* free a tempcell */ { if (freeable(a)) { - dprintf( ("freeing %s %s %o\n", a->nval, a->sval, a->tval) ); + dprintf( ("freeing %s %s %o\n", NN(a->nval), NN(a->sval), a->tval) ); xfree(a->sval); } if (a == tmps) @@ -791,10 +791,11 @@ Cell *sindex(Node **a, int nnn) /* index(a[0], a[1]) */ #define MAXNUMSIZE 50 -int format(char **pbuf, int *pbufsize, char *s, Node *a) /* printf-like conversions */ +int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like conversions */ { char *fmt; - char *p, *t, *os; + char *p, *t; + const char *os; Cell *x; int flag = 0, n; int fmtwd; /* format width */ @@ -845,27 +846,27 @@ int format(char **pbuf, int *pbufsize, char *s, Node *a) /* printf-like conversi switch (*s) { case 'f': case 'e': case 'g': case 'E': case 'G': - flag = 1; + flag = 'f'; break; case 'd': case 'i': - flag = 2; + flag = 'd'; if(*(s-1) == 'l') break; *(t-1) = 'l'; *t = 'd'; *++t = '\0'; break; case 'o': case 'x': case 'X': case 'u': - flag = *(s-1) == 'l' ? 2 : 3; + flag = *(s-1) == 'l' ? 'd' : 'u'; break; case 's': - flag = 4; + flag = 's'; break; case 'c': - flag = 5; + flag = 'c'; break; default: WARNING("weird printf conversion %s", fmt); - flag = 0; + flag = '?'; break; } if (a == NULL) @@ -877,7 +878,7 @@ int format(char **pbuf, int *pbufsize, char *s, Node *a) /* printf-like conversi n = fmtwd; adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format"); switch (flag) { - case 0: sprintf(p, "%s", fmt); /* unknown, so dump it too */ + case '?': sprintf(p, "%s", fmt); /* unknown, so dump it too */ t = getsval(x); n = strlen(t); if (fmtwd > n) @@ -886,10 +887,10 @@ int format(char **pbuf, int *pbufsize, char *s, Node *a) /* printf-like conversi p += strlen(p); sprintf(p, "%s", t); break; - case 1: sprintf(p, fmt, getfval(x)); break; - case 2: sprintf(p, fmt, (long) getfval(x)); break; - case 3: sprintf(p, fmt, (int) getfval(x)); break; - case 4: + case 'f': sprintf(p, fmt, getfval(x)); break; + case 'd': sprintf(p, fmt, (long) getfval(x)); break; + case 'u': sprintf(p, fmt, (int) getfval(x)); break; + case 's': t = getsval(x); n = strlen(t); if (fmtwd > n) @@ -898,15 +899,19 @@ int format(char **pbuf, int *pbufsize, char *s, Node *a) /* printf-like conversi FATAL("huge string/format (%d chars) in printf %.30s... ran format() out of memory", n, t); sprintf(p, fmt, t); break; - case 5: + case 'c': if (isnum(x)) { if (getfval(x)) sprintf(p, fmt, (int) getfval(x)); - else - *p++ = '\0'; + else { + *p++ = '\0'; /* explicit null byte */ + *p = '\0'; /* next output will start here */ + } } else sprintf(p, fmt, getsval(x)[0]); break; + default: + FATAL("can't happen: bad conversion %c in format()", flag); } tempfree(x); p += strlen(p); @@ -1211,7 +1216,7 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */ sep = *fs; ap = execute(a[1]); /* array name */ freesymtab(ap); - dprintf( ("split: s=|%s|, a=%s, sep=|%s|\n", s, ap->nval, fs) ); + dprintf( ("split: s=|%s|, a=%s, sep=|%s|\n", s, NN(ap->nval), fs) ); ap->tval &= ~STR; ap->tval |= ARR; ap->sval = (char *) makesymtab(NSYMTAB); @@ -1449,13 +1454,18 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis char *p, *buf; Node *nextarg; FILE *fp; + void flush_all(void); t = ptoi(a[0]); x = execute(a[1]); nextarg = a[1]->nnext; switch (t) { case FLENGTH: - u = strlen(getsval(x)); break; + if (isarr(x)) + u = ((Array *) x->sval)->nelem; /* GROT. should be function*/ + else + u = strlen(getsval(x)); + break; case FLOG: u = errcheck(log(getfval(x)), "log"); break; case FINT: @@ -1512,7 +1522,10 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis free(buf); return x; case FFLUSH: - if ((fp = openfile(FFLUSH, getsval(x))) == NULL) + if (isrec(x) || strlen(getsval(x)) == 0) { + flush_all(); /* fflush() or fflush("") -> all */ + u = 0; + } else if ((fp = openfile(FFLUSH, getsval(x))) == NULL) u = EOF; else u = fflush(fp); @@ -1544,7 +1557,7 @@ Cell *printstat(Node **a, int n) /* print a[0] */ fp = redirect(ptoi(a[1]), a[2]); for (x = a[0]; x != NULL; x = x->nnext) { y = execute(x); - fputs(getsval(y), fp); + fputs(getpssval(y), fp); tempfree(y); if (x->nnext == NULL) fputs(*ORS, fp); @@ -1583,7 +1596,7 @@ FILE *redirect(int a, Node *b) /* set up all i/o redirections */ struct files { FILE *fp; - char *fname; + const char *fname; int mode; /* '|', 'a', 'w' => LE/LT, GT */ } files[FOPEN_MAX] ={ { NULL, "/dev/stdin", LT }, /* watch out: don't free this! */ @@ -1598,9 +1611,9 @@ void stdinit(void) /* in case stdin, etc., are not constants */ files[2].fp = stderr; } -FILE *openfile(int a, char *us) +FILE *openfile(int a, const char *us) { - char *s = us; + const char *s = us; int i, m; FILE *fp = 0; @@ -1644,7 +1657,7 @@ FILE *openfile(int a, char *us) return fp; } -char *filename(FILE *fp) +const char *filename(FILE *fp) { int i; @@ -1703,6 +1716,15 @@ void closeall(void) } } +void flush_all(void) +{ + int i; + + for (i = 0; i < FOPEN_MAX; i++) + if (files[i].fp) + fflush(files[i].fp); +} + void backsub(char **pb_ptr, char **sptr_ptr); Cell *sub(Node **a, int nnn) /* substitute command */ diff --git a/usr.bin/awk/tran.c b/usr.bin/awk/tran.c index 9c910f52572..71dd01356ff 100644 --- a/usr.bin/awk/tran.c +++ b/usr.bin/awk/tran.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tran.c,v 1.7 2001/09/08 00:12:40 millert Exp $ */ +/* $OpenBSD: tran.c,v 1.8 2002/12/19 21:24:28 millert Exp $ */ /**************************************************************** Copyright (C) Lucent Technologies 1997 All Rights Reserved @@ -171,14 +171,17 @@ void freesymtab(Cell *ap) /* free a symbol table */ xfree(cp->sval); temp = cp->cnext; /* avoids freeing then using */ free(cp); + tp->nelem--; } tp->tab[i] = 0; } + if (tp->nelem != 0) + WARNING("can't happen: inconsistent element count freeing %s", ap->nval); free(tp->tab); free(tp); } -void freeelem(Cell *ap, char *s) /* free elem s from ap (i.e., ap["s"] */ +void freeelem(Cell *ap, const char *s) /* free elem s from ap (i.e., ap["s"] */ { Array *tp; Cell *p, *prev = NULL; @@ -201,14 +204,14 @@ void freeelem(Cell *ap, char *s) /* free elem s from ap (i.e., ap["s"] */ } } -Cell *setsymtab(char *n, char *s, Awkfloat f, unsigned t, Array *tp) +Cell *setsymtab(const char *n, const char *s, Awkfloat f, unsigned t, Array *tp) { int h; Cell *p; if (n != NULL && (p = lookup(n, tp)) != NULL) { dprintf( ("setsymtab found %p: n=%s s=\"%s\" f=%g t=%o\n", - p, p->nval, p->sval, p->fval, p->tval) ); + p, NN(p->nval), NN(p->sval), p->fval, p->tval) ); return(p); } p = (Cell *) malloc(sizeof(Cell)); @@ -231,7 +234,7 @@ Cell *setsymtab(char *n, char *s, Awkfloat f, unsigned t, Array *tp) return(p); } -int hash(char *s, int n) /* form hash value for string s */ +int hash(const char *s, int n) /* form hash value for string s */ { unsigned hashval; @@ -262,7 +265,7 @@ void rehash(Array *tp) /* rehash items in small table into big one */ tp->size = nsz; } -Cell *lookup(char *s, Array *tp) /* look for s in tp */ +Cell *lookup(const char *s, Array *tp) /* look for s in tp */ { Cell *p; int h; @@ -294,11 +297,11 @@ 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, vp->nval, f, vp->tval) ); + dprintf( ("setfval %p: %s = %g, t=%o\n", vp, NN(vp->nval), f, vp->tval) ); return vp->fval = f; } -void funnyvar(Cell *vp, char *rw) +void funnyvar(Cell *vp, const char *rw) { if (isarr(vp)) FATAL("can't %s %s; it's an array name.", rw, vp->nval); @@ -308,12 +311,12 @@ void funnyvar(Cell *vp, char *rw) vp, vp->nval, vp->sval, vp->fval, vp->tval); } -char *setsval(Cell *vp, char *s) /* set string val of a Cell */ +char *setsval(Cell *vp, const char *s) /* set string val of a Cell */ { char *t; int fldno; - dprintf( ("starting setsval %p: %s = \"%s\", t=%o\n", vp, vp->nval, s, vp->tval) ); + dprintf( ("starting setsval %p: %s = \"%s\", t=%o\n", vp, NN(vp->nval), s, vp->tval) ); if ((vp->tval & (NUM | STR)) == 0) funnyvar(vp, "assign to"); if (isfld(vp)) { @@ -332,7 +335,7 @@ char *setsval(Cell *vp, char *s) /* set string val of a Cell */ if (freeable(vp)) xfree(vp->sval); vp->tval &= ~DONTFREE; - dprintf( ("setsval %p: %s = \"%s (%p)\", t=%o\n", vp, vp->nval, t,t, vp->tval) ); + dprintf( ("setsval %p: %s = \"%s (%p)\", t=%o\n", vp, NN(vp->nval), t,t, vp->tval) ); return(vp->sval = t); } @@ -349,11 +352,12 @@ 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, vp->nval, vp->fval, vp->tval) ); + dprintf( ("getfval %p: %s = %g, t=%o\n", vp, NN(vp->nval), vp->fval, vp->tval) ); return(vp->fval); } -char *getsval(Cell *vp) /* get string val of a Cell */ + static char *get_str_val(Cell *vp, char **fmt) /* get string val of a Cell */ + { char s[100]; /* BUG: unchecked */ double dtemp; @@ -370,16 +374,27 @@ char *getsval(Cell *vp) /* get string val of a Cell */ if (modf(vp->fval, &dtemp) == 0) /* it's integral */ sprintf(s, "%.30g", vp->fval); else - sprintf(s, *CONVFMT, vp->fval); + sprintf(s, *fmt, vp->fval); vp->sval = tostring(s); vp->tval &= ~DONTFREE; vp->tval |= STR; } - dprintf( ("getsval %p: %s = \"%s (%p)\", t=%o\n", vp, vp->nval, vp->sval, vp->sval, vp->tval) ); + dprintf( ("getsval %p: %s = \"%s (%p)\", t=%o\n", vp, NN(vp->nval), vp->sval, vp->sval, vp->tval) ); return(vp->sval); } -char *tostring(char *s) /* make a copy of string s */ +char *getsval(Cell *vp) /* get string val of a Cell */ +{ + return get_str_val(vp, CONVFMT); +} + +char *getpssval(Cell *vp) /* get string val of a Cell for print */ +{ + return get_str_val(vp, OFMT); +} + + +char *tostring(const char *s) /* make a copy of string s */ { char *p; @@ -390,14 +405,14 @@ char *tostring(char *s) /* make a copy of string s */ return(p); } -char *qstring(char *is, int delim) /* collect string up to next delim */ +char *qstring(const char *is, int delim) /* collect string up to next delim */ { - char *os = is; + const char *os = is; int c, n; uschar *s = (uschar *) is; uschar *buf, *bp; - if ((buf = (uschar *) malloc(strlen(s)+3)) == NULL) + if ((buf = (uschar *) malloc(strlen(is)+3)) == NULL) FATAL( "out of space in qstring(%s)", s); for (bp = buf; (c = *s) != delim; s++) { if (c == '\n') |