diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/Makefile.lint | 1 | ||||
-rw-r--r-- | usr/src/cmd/awk/Makefile | 7 | ||||
-rw-r--r-- | usr/src/cmd/awk/awk.g.y | 33 | ||||
-rw-r--r-- | usr/src/cmd/awk/awk.h | 263 | ||||
-rw-r--r-- | usr/src/cmd/awk/awk.lx.l | 66 | ||||
-rw-r--r-- | usr/src/cmd/awk/b.c | 506 | ||||
-rw-r--r-- | usr/src/cmd/awk/lib.c | 543 | ||||
-rw-r--r-- | usr/src/cmd/awk/main.c | 77 | ||||
-rw-r--r-- | usr/src/cmd/awk/maketab.c | 16 | ||||
-rw-r--r-- | usr/src/cmd/awk/parse.c | 183 | ||||
-rw-r--r-- | usr/src/cmd/awk/run.c | 1226 | ||||
-rw-r--r-- | usr/src/cmd/awk/tran.c | 385 |
12 files changed, 1988 insertions, 1318 deletions
diff --git a/usr/src/Makefile.lint b/usr/src/Makefile.lint index 856156650c..1274119719 100644 --- a/usr/src/Makefile.lint +++ b/usr/src/Makefile.lint @@ -45,6 +45,7 @@ COMMON_SUBDIRS = \ cmd/auditstat \ cmd/auths \ cmd/autopush \ + cmd/awk \ cmd/banner \ cmd/bart \ cmd/basename \ diff --git a/usr/src/cmd/awk/Makefile b/usr/src/cmd/awk/Makefile index fc834193aa..a437a67e97 100644 --- a/usr/src/cmd/awk/Makefile +++ b/usr/src/cmd/awk/Makefile @@ -22,8 +22,8 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright (c) 1989,1996,2001 by Sun Microsystems, Inc. -# All rights reserved. +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. # # cmd/awk/Makefile # @@ -49,6 +49,7 @@ XGETFLAGS += -a -x awk.xcl CPPFLAGS += -D_FILE_OFFSET_BITS=64 YFLAGS += -d LDLIBS += -lm +LINTFLAGS += -u CLEANFILES= maketab proctab.c awk.g.c awk.lx.c y.tab.h .KEEP_STATE: @@ -79,7 +80,7 @@ install: all $(ROOTPROG) $(ROOTLINK) clean: $(RM) $(OBJS) $(CLEANFILES) -lint: lint_SRCS +lint: awk.g.c lint_SRCS awk.g.c + y.tab.h: awk.g.y diff --git a/usr/src/cmd/awk/awk.g.y b/usr/src/cmd/awk/awk.g.y index b6f6f475de..21bc8b6dc8 100644 --- a/usr/src/cmd/awk/awk.g.y +++ b/usr/src/cmd/awk/awk.g.y @@ -21,17 +21,21 @@ * CDDL HEADER END */ %} +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ - %{ #ident "%Z%%M% %I% %E% SMI" /* SVr4.0 2.10 */ %} %{ #include "awk.h" -yywrap() { return(1); } +int yywrap(void) { return(1); } #ifndef DEBUG # define PUTS(x) #endif @@ -39,8 +43,10 @@ Node *beginloc = 0, *endloc = 0; int infunc = 0; /* = 1 if in arglist or body of func */ uchar *curfname = 0; Node *arglist = 0; /* list of args for current function */ -uchar *strnode(); -Node *notnull(); +static void setfname(Cell *); +static int constnode(Node *); +static uchar *strnode(Node *); +static Node *notnull(); %} %union { @@ -232,7 +238,7 @@ pattern: | pattern and pattern %prec AND { $$ = op2(AND, notnull($1), notnull($3)); } | NOT pattern - { $$ = op1(NOT, op2(NE,$2,valtonode(lookup("$zero&null",symtab),CCON))); } + { $$ = op1(NOT, op2(NE,$2,valtonode(lookup((uchar *)"$zero&null",symtab),CCON))); } | pattern EQ pattern { $$ = op2($2, $1, $3); } | pattern GE pattern { $$ = op2($2, $1, $3); } | pattern GT pattern { $$ = op2($2, $1, $3); } @@ -428,8 +434,8 @@ while: %% -setfname(p) - Cell *p; +static void +setfname(Cell *p) { if (isarr(p)) ERROR "%s is an array, not a function", p->nval SYNTAX; @@ -438,20 +444,21 @@ setfname(p) curfname = p->nval; } -constnode(p) - Node *p; + +static int +constnode(Node *p) { return p->ntype == NVALUE && ((Cell *) (p->narg[0]))->csub == CCON; } -uchar *strnode(p) - Node *p; +static uchar * +strnode(Node *p) { return ((Cell *)(p->narg[0]))->sval; } -Node *notnull(n) - Node *n; +static Node * +notnull(Node *n) { switch (n->nobj) { case LE: case LT: case EQ: case NE: case GT: case GE: diff --git a/usr/src/cmd/awk/awk.h b/usr/src/cmd/awk/awk.h index 3bc85fbcc5..808c3282b8 100644 --- a/usr/src/cmd/awk/awk.h +++ b/usr/src/cmd/awk/awk.h @@ -19,17 +19,26 @@ * * CDDL HEADER END */ -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ /* - * Copyright (c) 1996, 2001 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ -#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 2.13 */ +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ + +#ifndef AWK_H +#define AWK_H + +#pragma ident "%Z%%M% %I% %E% SMI" #include <sys/types.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <libintl.h> #include <limits.h> typedef double Awkfloat; @@ -40,27 +49,31 @@ typedef unsigned char uchar; #define DEBUG #ifdef DEBUG /* uses have to be doubly parenthesized */ -# define dprintf(x) if (dbg) printf x +#define dprintf(x) if (dbg) (void) printf x #else -# define dprintf(x) +#define dprintf(x) #endif extern char errbuf[200]; -#define ERROR sprintf(errbuf, +extern void error(int, char *); +#define ERROR (void) snprintf(errbuf, sizeof (errbuf), +/*CSTYLED*/ #define FATAL ), error(1, errbuf) +/*CSTYLED*/ #define WARNING ), error(0, errbuf) +/*CSTYLED*/ #define SYNTAX ), yyerror(errbuf) +/*CSTYLED*/ +#define CONT ) extern int compile_time; /* 1 if compiling, 0 if running */ -/* The standards (SUSV2) requires that Record size be atleast LINE_MAX. - * LINE_MAX is standard variable defined in limits.h. - * Though nawk is not standards compliant, we let RECSIZE - * grow with LINE_MAX instead of magic number 1024. - */ -#define RECSIZE (3 * LINE_MAX) /* sets limit on records, fields, etc., etc. */ +#define FLD_INCR 64 +#define LINE_INCR 256 -#define MAXFLD 500 +/* ensure that there is extra 1 byte in the buffer */ +#define expand_buf(p, n, r) \ + if (*(n) == 0 || (r) >= (*(n) - 1)) r_expand_buf(p, n, r) extern uchar **FS; extern uchar **RS; @@ -76,14 +89,11 @@ extern Awkfloat *RSTART; extern Awkfloat *RLENGTH; extern uchar *record; -extern int dbg; -extern off_t lineno; +extern size_t record_size; extern int errorflag; extern int donefld; /* 1 if record broken into fields */ extern int donerec; /* 1 if record is valid (no fld has changed */ -extern uchar cbuf[RECSIZE]; /* miscellaneous character collection */ - extern uchar *patbeg; /* beginning of pattern matched */ extern int patlen; /* length. set in b.c */ @@ -95,7 +105,8 @@ typedef struct Cell { uchar *nval; /* name, for variables only */ uchar *sval; /* string value */ Awkfloat fval; /* value as number */ - unsigned tval; /* type info: STR|NUM|ARR|FCN|FLD|CON|DONTFREE */ + unsigned tval; + /* type info: STR|NUM|ARR|FCN|FLD|CON|DONTFREE */ struct Cell *cnext; /* ptr to next if chained */ } Cell; @@ -106,8 +117,9 @@ typedef struct { /* symbol table array */ } Array; #define NSYMTAB 50 /* initial size of a symbol table */ -extern Array *symtab, *makesymtab(); -extern Cell *setsymtab(), *lookup(); +extern Array *symtab, *makesymtab(int); +extern Cell *setsymtab(uchar *, uchar *, Awkfloat, unsigned int, Array *); +extern Cell *lookup(uchar *, Array *); extern Cell *recloc; /* location of input record */ extern Cell *nrloc; /* NR */ @@ -119,20 +131,23 @@ extern Cell *rlengthloc; /* RLENGTH */ /* Cell.tval values: */ #define NUM 01 /* number value is valid */ #define STR 02 /* string value is valid */ -#define DONTFREE 04 /* string space is not freeable */ +#define DONTFREE 04 /* string space is not freeable */ #define CON 010 /* this is a constant */ #define ARR 020 /* this is an array */ #define FCN 040 /* this is a function name */ -#define FLD 0100 /* this is a field $1, $2, ... */ +#define FLD 0100 /* this is a field $1, $2, ... */ #define REC 0200 /* this is $0 */ -#define freeable(p) (!((p)->tval & DONTFREE)) +#define freeable(p) (!((p)->tval & DONTFREE)) -Awkfloat setfval(), getfval(); -uchar *setsval(), *getsval(); -uchar *tostring(), *tokname(), *qstring(); +extern Awkfloat setfval(Cell *, Awkfloat), getfval(Cell *), r_getfval(Cell *); +extern uchar *setsval(Cell *, uchar *), *getsval(Cell *), *r_getsval(Cell *); +extern uchar *tostring(uchar *), *tokname(int), *qstring(uchar *, int); -double log(), sqrt(), exp(), atof(); +#define getfval(p) \ + (((p)->tval & (ARR|FLD|REC|NUM)) == NUM ? (p)->fval : r_getfval(p)) +#define getsval(p) \ + (((p)->tval & (ARR|FLD|REC|STR)) == STR ? (p)->sval : r_getsval(p)) /* function types */ #define FLENGTH 1 @@ -156,74 +171,81 @@ typedef struct Node { struct Node *nnext; off_t lineno; int nobj; - struct Node *narg[1]; /* variable: actual size set by calling malloc */ + struct Node *narg[1]; + /* variable: actual size set by calling malloc */ } Node; -#define NIL ((Node *) 0) +#define NIL ((Node *)0) extern Node *winner; extern Node *nullstat; extern Node *nullnode; /* ctypes */ -#define OCELL 1 -#define OBOOL 2 -#define OJUMP 3 +#define OCELL 1 +#define OBOOL 2 +#define OJUMP 3 /* Cell subtypes: csub */ #define CFREE 7 -#define CCOPY 6 -#define CCON 5 -#define CTEMP 4 -#define CNAME 3 -#define CVAR 2 -#define CFLD 1 +#define CCOPY 6 +#define CCON 5 +#define CTEMP 4 +#define CNAME 3 +#define CVAR 2 +#define CFLD 1 /* bool subtypes */ -#define BTRUE 11 -#define BFALSE 12 +#define BTRUE 11 +#define BFALSE 12 /* jump subtypes */ -#define JEXIT 21 -#define JNEXT 22 +#define JEXIT 21 +#define JNEXT 22 #define JBREAK 23 #define JCONT 24 #define JRET 25 /* node types */ -#define NVALUE 1 -#define NSTAT 2 -#define NEXPR 3 +#define NVALUE 1 +#define NSTAT 2 +#define NEXPR 3 #define NFIELD 4 -extern Cell *(*proctab[])(); -extern Cell *nullproc(); +extern Cell *(*proctab[])(Node **, int); +extern Cell *nullproc(Node **, int); extern int pairstack[], paircnt; -extern Cell *fieldadr(); - -extern Node *stat1(), *stat2(), *stat3(), *stat4(), *pa2stat(); -extern Node *op1(), *op2(), *op3(), *op4(); -extern Node *linkum(), *valtonode(), *rectonode(), *exptostat(); -extern Node *makearr(); - -#define notlegal(n) (n <= FIRSTTOKEN || n >= LASTTOKEN || proctab[n-FIRSTTOKEN] == nullproc) -#define isvalue(n) ((n)->ntype == NVALUE) -#define isexpr(n) ((n)->ntype == NEXPR) -#define isjump(n) ((n)->ctype == OJUMP) -#define isexit(n) ((n)->csub == JEXIT) + +extern Node *stat1(int, Node *), *stat2(int, Node *, Node *); +extern Node *stat3(int, Node *, Node *, Node *); +extern Node *stat4(int, Node *, Node *, Node *, Node *); +extern Node *pa2stat(Node *, Node *, Node *); +extern Node *op1(int, Node *), *op2(int, Node *, Node *); +extern Node *op3(int, Node *, Node *, Node *); +extern Node *op4(int, Node *, Node *, Node *, Node *); +extern Node *linkum(Node *, Node *), *valtonode(Cell *, int); +extern Node *rectonode(void), *exptostat(Node *); +extern Node *makearr(Node *); + +#define notlegal(n) \ + (n <= FIRSTTOKEN || n >= LASTTOKEN || proctab[n-FIRSTTOKEN] == nullproc) +#define isvalue(n) ((n)->ntype == NVALUE) +#define isexpr(n) ((n)->ntype == NEXPR) +#define isjump(n) ((n)->ctype == OJUMP) +#define isexit(n) ((n)->csub == JEXIT) #define isbreak(n) ((n)->csub == JBREAK) #define iscont(n) ((n)->csub == JCONT) #define isnext(n) ((n)->csub == JNEXT) #define isret(n) ((n)->csub == JRET) -#define isstr(n) ((n)->tval & STR) -#define isnum(n) ((n)->tval & NUM) -#define isarr(n) ((n)->tval & ARR) -#define isfunc(n) ((n)->tval & FCN) -#define istrue(n) ((n)->csub == BTRUE) -#define istemp(n) ((n)->csub == CTEMP) +#define isstr(n) ((n)->tval & STR) +#define isnum(n) ((n)->tval & NUM) +#define isarr(n) ((n)->tval & ARR) +#define isfunc(n) ((n)->tval & FCN) +#define istrue(n) ((n)->csub == BTRUE) +#define istemp(n) ((n)->csub == CTEMP) -#define NCHARS (256+1) -#define NSTATES 32 +#define NCHARS (256+1) +#define NSTATES 32 typedef struct rrow { int ltype; @@ -245,4 +267,105 @@ typedef struct fa { struct rrow re[1]; } fa; -extern fa *makedfa(); +/* b.c */ +extern fa *makedfa(uchar *, int); +extern int nematch(fa *, uchar *); +extern int match(fa *, uchar *); +extern int pmatch(fa *, uchar *); + +/* lib.c */ +extern int isclvar(uchar *); +extern int is_number(uchar *); +extern void setclvar(uchar *); +extern int readrec(uchar **, size_t *, FILE *); +extern void bracecheck(void); +extern void syminit(void); +extern void yyerror(char *); +extern void fldbld(void); +extern void recbld(void); +extern int getrec(uchar **, size_t *); +extern Cell *fieldadr(int); +extern void newfld(int); +extern Cell *getfld(int); +extern int fldidx(Cell *); +extern double errcheck(double, char *); +extern void fpecatch(int); +extern void init_buf(uchar **, size_t *, size_t); +extern void adjust_buf(uchar **, size_t); +extern void r_expand_buf(uchar **, size_t *, size_t); + +extern int donefld; +extern int donerec; +extern uchar *recdata; +extern uchar *record; +extern size_t record_size; + +/* main.c */ +extern int dbg; +extern uchar *cmdname; +extern uchar *lexprog; +extern int compile_time; +extern char radixpoint; + +/* tran.c */ +extern void syminit(void); +extern void arginit(int, uchar **); +extern void envinit(uchar **); +extern void freesymtab(Cell *); +extern void freeelem(Cell *, uchar *); +extern void funnyvar(Cell *, char *); +extern int hash(uchar *, int); +extern Awkfloat *ARGC; + +/* run.c */ +extern void run(Node *); + +extern int paircnt; +extern Node *winner; + +#ifndef input +extern int input(void); +#endif +extern int yyparse(void); +extern FILE *yyin; +extern off_t lineno; + +/* proc */ +extern Cell *nullproc(Node **, int); +extern Cell *program(Node **, int); +extern Cell *boolop(Node **, int); +extern Cell *relop(Node **, int); +extern Cell *array(Node **, int); +extern Cell *indirect(Node **, int); +extern Cell *substr(Node **, int); +extern Cell *sub(Node **, int); +extern Cell *gsub(Node **, int); +extern Cell *sindex(Node **, int); +extern Cell *asprintf(Node **, int); +extern Cell *arith(Node **, int); +extern Cell *incrdecr(Node **, int); +extern Cell *cat(Node **, int); +extern Cell *pastat(Node **, int); +extern Cell *dopa2(Node **, int); +extern Cell *matchop(Node **, int); +extern Cell *intest(Node **, int); +extern Cell *aprintf(Node **, int); +extern Cell *print(Node **, int); +extern Cell *closefile(Node **, int); +extern Cell *delete(Node **, int); +extern Cell *split(Node **, int); +extern Cell *assign(Node **, int); +extern Cell *condexpr(Node **, int); +extern Cell *ifstat(Node **, int); +extern Cell *whilestat(Node **, int); +extern Cell *forstat(Node **, int); +extern Cell *dostat(Node **, int); +extern Cell *instat(Node **, int); +extern Cell *jump(Node **, int); +extern Cell *bltin(Node **, int); +extern Cell *call(Node **, int); +extern Cell *arg(Node **, int); +extern Cell *getnf(Node **, int); +extern Cell *getline(Node **, int); + +#endif /* AWK_H */ diff --git a/usr/src/cmd/awk/awk.lx.l b/usr/src/cmd/awk/awk.lx.l index 6f83c363d8..a7e8185832 100644 --- a/usr/src/cmd/awk/awk.lx.l +++ b/usr/src/cmd/awk/awk.lx.l @@ -1,15 +1,4 @@ %{ -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -%} -%{ -/* All Rights Reserved */ -%} - -%{ -/* */ -%} - -%{ /* * CDDL HEADER START * @@ -31,15 +20,18 @@ * * CDDL HEADER END */ -/* Copyright (c) 1996, 2001 by Sun Microsystems, Inc. */ -/* All rights reserved. */ -%} -%{ -/* */ + +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ %} %{ -#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 2.9 */ +#pragma ident "%Z%%M% %I% %E% SMI" %} %Start A str sc reg comment @@ -53,6 +45,9 @@ #undef input /* defeat lex */ #undef unput +static void unput(int); +static void unputstr(char *); + extern YYSTYPE yylval; extern int infunc; @@ -67,15 +62,23 @@ int parencnt = 0; # define RET(x) return(x) #endif +/* + * The standards (SUSV2) requires that Record size be atleast LINE_MAX. + * LINE_MAX is a standard variable defined in limits.h. + * Though nawk is not standards compliant, we let RECSIZE + * grow with LINE_MAX instead of the magic number 1024. + */ +#define CBUFLEN (3 * LINE_MAX) + #define CADD cbuf[clen++] = yytext[0]; \ - if (clen >= RECSIZE-1) { \ + if (clen >= CBUFLEN-1) { \ ERROR "string/reg expr %.10s... too long", cbuf SYNTAX; \ BEGIN A; \ } -uchar cbuf[RECSIZE]; -uchar *s; -int clen, cflag; +static uchar cbuf[CBUFLEN]; +static uchar *s; +static int clen, cflag; %} A [a-zA-Z_] @@ -138,15 +141,16 @@ WS [ \t] unputstr(yytext+1); return(INDIRECT); } else { - yylval.cp = setsymtab(yytext+1,"",0.0,STR|NUM,symtab); + yylval.cp = setsymtab((uchar *)yytext+1, + (uchar *)"",0.0,STR|NUM,symtab); RET(IVAR); } } <A>"$" { RET(INDIRECT); } -<A>NF { yylval.cp = setsymtab(yytext, "", 0.0, NUM, symtab); RET(VARNF); } +<A>NF { yylval.cp = setsymtab((uchar *)yytext, (uchar *)"", 0.0, NUM, symtab); RET(VARNF); } <A>({D}+("."?){D}*|"."{D}+)((e|E)("+"|-)?{D}+)? { - yylval.cp = setsymtab(yytext, tostring(yytext), atof(yytext), CON|NUM, symtab); + yylval.cp = setsymtab((uchar *)yytext, tostring((uchar *)yytext), atof(yytext), CON|NUM, symtab); RET(NUMBER); } <A>while { RET(WHILE); } @@ -191,7 +195,8 @@ WS [ \t] yylval.i = n; RET(ARG); } else { - yylval.cp = setsymtab(yytext,"",0.0,STR|NUM,symtab); + yylval.cp = setsymtab((uchar *)yytext, + (uchar *)"",0.0,STR|NUM,symtab); if (c == '(') { RET(CALL); } else { @@ -243,6 +248,7 @@ WS [ \t] %% +void startreg() { BEGIN reg; @@ -257,7 +263,8 @@ startreg() uchar ebuf[300]; uchar *ep = ebuf; -input() +int +input(void) { register int c; extern uchar *lexprog; @@ -277,7 +284,8 @@ input() return *ep++ = c; } -unput(c) +static void +unput(int c) { yytchar = c; if (yytchar == '\n') @@ -288,8 +296,8 @@ unput(c) } -unputstr(s) - char *s; +static void +unputstr(char *s) { int i; diff --git a/usr/src/cmd/awk/b.c b/usr/src/cmd/awk/b.c index 785cd92254..e1bed57ab1 100644 --- a/usr/src/cmd/awk/b.c +++ b/usr/src/cmd/awk/b.c @@ -19,48 +19,46 @@ * * CDDL HEADER END */ -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 2.11 */ +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ + +#pragma ident "%Z%%M% %I% %E% SMI" #define DEBUG #include "awk.h" -#include <ctype.h> -#include <stdio.h> #include "y.tab.h" #define HAT (NCHARS-1) /* matches ^ in regular expr */ /* NCHARS is 2**n */ +#define MAXLIN (3 * LINE_MAX) -#define type(v) (v)->nobj -#define left(v) (v)->narg[0] -#define right(v) (v)->narg[1] -#define parent(v) (v)->nnext - -#define LEAF case CCL: case NCCL: case CHAR: case DOT: case FINAL: case ALL: -#define UNARY case STAR: case PLUS: case QUEST: +#define type(v) (v)->nobj +#define left(v) (v)->narg[0] +#define right(v) (v)->narg[1] +#define parent(v) (v)->nnext -/* encoding in tree Nodes: - leaf (CCL, NCCL, CHAR, DOT, FINAL, ALL): - left is index, right contains value or pointer to value - unary (STAR, PLUS, QUEST): left is child, right is null - binary (CAT, OR): left and right are children - parent contains pointer to parent -*/ +#define LEAF case CCL: case NCCL: case CHAR: case DOT: case FINAL: case ALL: +#define UNARY case STAR: case PLUS: case QUEST: +/* + * encoding in tree Nodes: + * leaf (CCL, NCCL, CHAR, DOT, FINAL, ALL): + * left is index, right contains value or pointer to value + * unary (STAR, PLUS, QUEST): left is child, right is null + * binary (CAT, OR): left and right are children + * parent contains pointer to parent + */ -uchar chars[RECSIZE]; -int setvec[RECSIZE]; -int tmpset[RECSIZE]; -Node *point[RECSIZE]; +int setvec[MAXLIN]; +int tmpset[MAXLIN]; +Node *point[MAXLIN]; int rtok; /* next token in current re */ int rlxval; @@ -77,28 +75,40 @@ int patlen; #define NFA 20 /* cache this many dynamic fa's */ fa *fatab[NFA]; int nfatab = 0; /* entries in fatab */ -fa *mkdfa(); -fa *makedfa(s, anchor) /* returns dfa for reg expr s */ - uchar *s; - int anchor; +static fa *mkdfa(uchar *, int); +static int makeinit(fa *, int); +static void penter(Node *); +static void freetr(Node *); +static void overflo(char *); +static void cfoll(fa *, Node *); +static void follow(Node *); +static Node *reparse(uchar *); +static int relex(void); +static void freefa(fa *); +static int cgoto(fa *, int, int); + +fa * +makedfa(uchar *s, int anchor) /* returns dfa for reg expr s */ { int i, use, nuse; fa *pfa; if (compile_time) /* a constant for sure */ - 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) { + return (mkdfa(s, anchor)); + for (i = 0; i < nfatab; i++) { /* is it there already? */ + if (fatab[i]->anchor == anchor && + strcmp((char *)fatab[i]->restr, (char *)s) == 0) { fatab[i]->use++; - return fatab[i]; + return (fatab[i]); + } } pfa = mkdfa(s, anchor); if (nfatab < NFA) { /* room for another */ fatab[nfatab] = pfa; fatab[nfatab]->use = 1; nfatab++; - return pfa; + return (pfa); } use = fatab[0]->use; /* replace least-recently used */ nuse = 0; @@ -110,14 +120,14 @@ fa *makedfa(s, anchor) /* returns dfa for reg expr s */ freefa(fatab[nuse]); fatab[nuse] = pfa; pfa->use = 1; - return pfa; + return (pfa); } -fa *mkdfa(s, anchor) /* does the real work of making a dfa */ - uchar *s; - int anchor; /* anchor = 1 for anchored matches, else 0 */ +fa * +mkdfa(uchar *s, int anchor) /* does the real work of making a dfa */ + /* anchor = 1 for anchored matches, else 0 */ { - Node *p, *p1, *reparse(); + Node *p, *p1; fa *f; p = reparse(s); @@ -128,25 +138,27 @@ fa *mkdfa(s, anchor) /* does the real work of making a dfa */ poscnt = 0; penter(p1); /* enter parent pointers and leaf indices */ - if ((f = (fa *) calloc(1, sizeof(fa) + poscnt*sizeof(rrow))) == NULL) + if ((f = (fa *)calloc(1, sizeof (fa) + poscnt * sizeof (rrow))) == NULL) overflo("no room for fa"); - f->accept = poscnt-1; /* penter has computed number of positions in re */ + /* penter has computed number of positions in re */ + f->accept = poscnt-1; cfoll(f, p1); /* set up follow sets */ freetr(p1); - if ((f->posns[0] = (int *) calloc(1, *(f->re[0].lfollow)*sizeof(int))) == NULL) + if ((f->posns[0] = + (int *)calloc(1, *(f->re[0].lfollow) * sizeof (int))) == NULL) { overflo("out of space in makedfa"); - if ((f->posns[1] = (int *) calloc(1, sizeof(int))) == NULL) + } + if ((f->posns[1] = (int *)calloc(1, sizeof (int))) == NULL) overflo("out of space in makedfa"); *f->posns[1] = 0; f->initstat = makeinit(f, anchor); f->anchor = anchor; f->restr = tostring(s); - return f; + return (f); } -int makeinit(f, anchor) - fa *f; - int anchor; +static int +makeinit(fa *f, int anchor) { register int i, k; @@ -154,20 +166,20 @@ int makeinit(f, anchor) f->out[2] = 0; f->reset = 0; k = *(f->re[0].lfollow); - xfree(f->posns[2]); - if ((f->posns[2] = (int *) calloc(1, (k+1)*sizeof(int))) == NULL) + xfree(f->posns[2]); + if ((f->posns[2] = (int *)calloc(1, (k+1) * sizeof (int))) == NULL) overflo("out of space in makeinit"); - for (i=0; i<=k; i++) { + for (i = 0; i <= k; i++) { (f->posns[2])[i] = (f->re[0].lfollow)[i]; } if ((f->posns[2])[1] == f->accept) f->out[2] = 1; - for (i=0; i<NCHARS; i++) + for (i = 0; i < NCHARS; i++) f->gototab[2][i] = 0; f->curstat = cgoto(f, 2, HAT); if (anchor) { *f->posns[2] = k-1; /* leave out position 0 */ - for (i=0; i<k; i++) { + for (i = 0; i < k; i++) { (f->posns[0])[i] = (f->posns[2])[i]; } @@ -175,13 +187,13 @@ int makeinit(f, anchor) if (f->curstat != 2) --(*f->posns[f->curstat]); } - return f->curstat; + return (f->curstat); } -penter(p) /* set up parent pointers and leaf indices */ - Node *p; +void +penter(Node *p) /* set up parent pointers and leaf indices */ { - switch(type(p)) { + switch (type(p)) { LEAF left(p) = (Node *) poscnt; point[poscnt++] = p; @@ -203,8 +215,8 @@ penter(p) /* set up parent pointers and leaf indices */ } } -freetr(p) /* free parse tree */ - Node *p; +static void +freetr(Node *p) /* free parse tree */ { switch (type(p)) { LEAF @@ -226,12 +238,14 @@ freetr(p) /* free parse tree */ } } -uchar *cclenter(p) - register uchar *p; +uchar * +cclenter(uchar *p) { register int i, c; - uchar *op; + uchar *op, *chars, *ret; + size_t bsize; + init_buf(&chars, &bsize, LINE_INCR); op = p; i = 0; while ((c = *p++) != 0) { @@ -261,101 +275,112 @@ uchar *cclenter(p) } else if (c == '-' && i > 0 && chars[i-1] != 0) { if (*p != 0) { c = chars[i-1]; - while ((uchar) c < *p) { /* fails if *p is \\ */ - if (i >= RECSIZE-1) - overflo("character class too big"); + while ((uchar)c < *p) { /* fails if *p is \\ */ + expand_buf(&chars, &bsize, i); chars[i++] = ++c; } p++; continue; } } - if (i >= RECSIZE-1) - overflo("character class too big"); + expand_buf(&chars, &bsize, i); chars[i++] = c; } chars[i++] = '\0'; - dprintf( ("cclenter: in = |%s|, out = |%s|\n", op, chars) ); + dprintf(("cclenter: in = |%s|, out = |%s|\n", op, chars)); xfree(op); - return(tostring(chars)); + ret = tostring(chars); + free(chars); + return (ret); } -overflo(s) - uchar *s; +static void +overflo(char *s) { - ERROR "regular expression too big: %s", gettext((char *) s) FATAL; + ERROR "regular expression too big: %s", gettext((char *)s) FATAL; } -cfoll(f, v) /* enter follow set of each leaf of vertex v into lfollow[leaf] */ - fa *f; - register Node *v; +/* enter follow set of each leaf of vertex v into lfollow[leaf] */ +static void +cfoll(fa *f, Node *v) { register int i; register int *p; - switch(type(v)) { + switch (type(v)) { LEAF - f->re[(int) left(v)].ltype = type(v); - f->re[(int) left(v)].lval = (int) right(v); - for (i=0; i<=f->accept; i++) + f->re[(int)left(v)].ltype = type(v); + f->re[(int)left(v)].lval = (int)right(v); + for (i = 0; i <= f->accept; i++) setvec[i] = 0; setcnt = 0; follow(v); /* computes setvec and setcnt */ - if ((p = (int *) calloc(1, (setcnt+1)*sizeof(int))) == NULL) + if ((p = (int *)calloc(1, (setcnt+1) * sizeof (int))) == NULL) overflo("follow set overflow"); - f->re[(int) left(v)].lfollow = p; + f->re[(int)left(v)].lfollow = p; *p = setcnt; - for (i = f->accept; i >= 0; i--) - if (setvec[i] == 1) *++p = i; + for (i = f->accept; i >= 0; i--) { + if (setvec[i] == 1) + *++p = i; + } break; UNARY - cfoll(f,left(v)); + cfoll(f, left(v)); break; case CAT: case OR: - cfoll(f,left(v)); - cfoll(f,right(v)); + cfoll(f, left(v)); + cfoll(f, right(v)); break; default: ERROR "unknown type %d in cfoll", type(v) FATAL; } } -first(p) /* collects initially active leaves of p into setvec */ - register Node *p; /* returns 0 or 1 depending on whether p matches empty string */ +/* + * collects initially active leaves of p into setvec + * returns 0 or 1 depending on whether p matches empty string + */ +static int +first(Node *p) { register int b; - switch(type(p)) { + switch (type(p)) { LEAF - if (setvec[(int) left(p)] != 1) { - setvec[(int) left(p)] = 1; + if (setvec[(int)left(p)] != 1) { + setvec[(int)left(p)] = 1; setcnt++; } - if (type(p) == CCL && (*(uchar *) right(p)) == '\0') - return(0); /* empty CCL */ - else return(1); + if (type(p) == CCL && (*(uchar *)right(p)) == '\0') + return (0); /* empty CCL */ + else + return (1); case PLUS: - if (first(left(p)) == 0) return(0); - return(1); + if (first(left(p)) == 0) + return (0); + return (1); case STAR: case QUEST: - first(left(p)); - return(0); + (void) first(left(p)); + return (0); case CAT: - if (first(left(p)) == 0 && first(right(p)) == 0) return(0); - return(1); + if (first(left(p)) == 0 && first(right(p)) == 0) + return (0); + return (1); case OR: b = first(right(p)); - if (first(left(p)) == 0 || b == 0) return(0); - return(1); + if (first(left(p)) == 0 || b == 0) + return (0); + return (1); } ERROR "unknown type %d in first", type(p) FATAL; - return(-1); + return (-1); } -follow(v) - Node *v; /* collects leaves that can follow v into setvec */ +/* collects leaves that can follow v into setvec */ +static void +follow(Node *v) { Node *p; @@ -365,7 +390,7 @@ follow(v) switch (type(p)) { case STAR: case PLUS: - first(v); + (void) first(v); follow(p); return; @@ -380,8 +405,7 @@ follow(v) follow(p); return; } - } - else /* v is right child */ + } else /* v is right child */ follow(p); return; default: @@ -390,49 +414,47 @@ follow(v) } } -member(c, s) /* is c in s? */ - register uchar c, *s; +static int +member(uchar c, uchar *s) /* is c in s? */ { while (*s) if (c == *s++) - return(1); - return(0); + return (1); + return (0); } -match(f, p) - register fa *f; - register uchar *p; +int +match(fa *f, uchar *p) { register int s, ns; - s = f->reset?makeinit(f,0):f->initstat; + s = f->reset ? makeinit(f, 0) : f->initstat; if (f->out[s]) - return(1); + return (1); do { - if (ns=f->gototab[s][*p]) - s=ns; + if ((ns = f->gototab[s][*p]) != 0) + s = ns; else - s=cgoto(f,s,*p); + s = cgoto(f, s, *p); if (f->out[s]) - return(1); + return (1); } while (*p++ != 0); - return(0); + return (0); } -pmatch(f, p) - register fa *f; - register uchar *p; +int +pmatch(fa *f, uchar *p) { register int s, ns; register uchar *q; int i, k; - if (f->reset) { - f->initstat = s = makeinit(f,1); - } else { - s = f->initstat; - } + if (f->reset) { + f->initstat = s = makeinit(f, 1); + } else { + s = f->initstat; + } patbeg = p; patlen = -1; do { @@ -440,53 +462,54 @@ pmatch(f, p) do { if (f->out[s]) /* final state */ patlen = q-p; - if (ns=f->gototab[s][*q]) - s=ns; + if ((ns = f->gototab[s][*q]) != 0) + s = ns; else - s=cgoto(f,s,*q); - if (s==1) /* no transition */ + s = cgoto(f, s, *q); + if (s == 1) { /* no transition */ if (patlen >= 0) { patbeg = p; - return(1); - } - else + return (1); + } else goto nextin; /* no match */ + } } while (*q++ != 0); if (f->out[s]) - patlen = q-p-1; /* don't count $ */ + patlen = q - p - 1; /* don't count $ */ if (patlen >= 0) { patbeg = p; - return(1); + return (1); } nextin: s = 2; if (f->reset) { - for (i=2; i<=f->curstat; i++) + for (i = 2; i <= f->curstat; i++) xfree(f->posns[i]); - k = *f->posns[0]; - if ((f->posns[2] = (int *) calloc(1, (k+1)*sizeof(int))) == NULL) + k = *f->posns[0]; + if ((f->posns[2] = + (int *)calloc(1, (k + 1) * sizeof (int))) == NULL) { overflo("out of space in pmatch"); - for (i=0; i<=k; i++) + } + for (i = 0; i <= k; i++) (f->posns[2])[i] = (f->posns[0])[i]; f->initstat = f->curstat = 2; f->out[2] = f->out[0]; - for (i=0; i<NCHARS; i++) + for (i = 0; i < NCHARS; i++) f->gototab[2][i] = 0; } } while (*p++ != 0); return (0); } -nematch(f, p) - register fa *f; - register uchar *p; +int +nematch(fa *f, uchar *p) { register int s, ns; register uchar *q; int i, k; if (f->reset) { - f->initstat = s = makeinit(f,1); + f->initstat = s = makeinit(f, 1); } else { s = f->initstat; } @@ -496,78 +519,86 @@ nematch(f, p) do { if (f->out[s]) /* final state */ patlen = q-p; - if (ns=f->gototab[s][*q]) - s=ns; + if ((ns = f->gototab[s][*q]) != 0) + s = ns; else - s=cgoto(f,s,*q); - if (s==1) /* no transition */ + s = cgoto(f, s, *q); + if (s == 1) { /* no transition */ if (patlen > 0) { patbeg = p; - return(1); - } - else + return (1); + } else goto nnextin; /* no nonempty match */ + } } while (*q++ != 0); if (f->out[s]) - patlen = q-p-1; /* don't count $ */ - if (patlen > 0 ) { + patlen = q - p - 1; /* don't count $ */ + if (patlen > 0) { patbeg = p; - return(1); + return (1); } nnextin: s = 2; if (f->reset) { - for (i=2; i<=f->curstat; i++) + for (i = 2; i <= f->curstat; i++) xfree(f->posns[i]); - k = *f->posns[0]; - if ((f->posns[2] = (int *) calloc(1, (k+1)*sizeof(int))) == NULL) + k = *f->posns[0]; + if ((f->posns[2] = + (int *)calloc(1, (k + 1) * sizeof (int))) == NULL) { overflo("out of state space"); - for (i=0; i<=k; i++) + } + for (i = 0; i <= k; i++) (f->posns[2])[i] = (f->posns[0])[i]; f->initstat = f->curstat = 2; f->out[2] = f->out[0]; - for (i=0; i<NCHARS; i++) + for (i = 0; i < NCHARS; i++) f->gototab[2][i] = 0; } - p++; + p++; } return (0); } -Node *regexp(), *primary(), *concat(), *alt(), *unary(); +static Node *regexp(void), *primary(void), *concat(Node *); +static Node *alt(Node *), *unary(Node *); -Node *reparse(p) - uchar *p; +static Node * +reparse(uchar *p) { /* parses regular expression pointed to by p */ /* uses relex() to scan regular expression */ Node *np; - dprintf( ("reparse <%s>\n", p) ); + dprintf(("reparse <%s>\n", p)); lastre = prestr = p; /* prestr points to string to be parsed */ rtok = relex(); if (rtok == '\0') ERROR "empty regular expression" FATAL; np = regexp(); - if (rtok == '\0') - return(np); - else - ERROR "syntax error in regular expression %s at %s", lastre, prestr FATAL; + if (rtok == '\0') { + return (np); + } else { + ERROR "syntax error in regular expression %s at %s", + lastre, prestr FATAL; + } /*NOTREACHED*/ + return (NULL); } -Node *regexp() +static Node * +regexp(void) { return (alt(concat(primary()))); } -Node *primary() +static Node * +primary(void) { Node *np; switch (rtok) { case CHAR: - np = op2(CHAR, NIL, (Node *) rlxval); + np = op2(CHAR, NIL, (Node *)rlxval); rtok = relex(); return (unary(np)); case ALL: @@ -577,16 +608,18 @@ Node *primary() rtok = relex(); return (unary(op2(DOT, NIL, NIL))); case CCL: - np = op2(CCL, NIL, (Node*) cclenter(rlxstr)); + /*LINTED align*/ + np = op2(CCL, NIL, (Node *)cclenter(rlxstr)); rtok = relex(); return (unary(np)); case NCCL: - np = op2(NCCL, NIL, (Node *) cclenter(rlxstr)); + /*LINTED align*/ + np = op2(NCCL, NIL, (Node *)cclenter(rlxstr)); rtok = relex(); return (unary(np)); case '^': rtok = relex(); - return (unary(op2(CHAR, NIL, (Node *) HAT))); + return (unary(op2(CHAR, NIL, (Node *)HAT))); case '$': rtok = relex(); return (unary(op2(CHAR, NIL, NIL))); @@ -594,23 +627,28 @@ Node *primary() rtok = relex(); if (rtok == ')') { /* special pleading for () */ rtok = relex(); - return unary(op2(CCL, NIL, (Node *) tostring(""))); + return (unary(op2(CCL, NIL, + /*LINTED align*/ + (Node *)tostring((uchar *)"")))); } np = regexp(); if (rtok == ')') { rtok = relex(); return (unary(np)); + } else { + ERROR "syntax error in regular expression %s at %s", + lastre, prestr FATAL; } - else - ERROR "syntax error in regular expression %s at %s", lastre, prestr FATAL; default: - ERROR "illegal primary in regular expression %s at %s", lastre, prestr FATAL; + ERROR "illegal primary in regular expression %s at %s", + lastre, prestr FATAL; } /*NOTREACHED*/ + return (NULL); } -Node *concat(np) - Node *np; +static Node * +concat(Node *np) { switch (rtok) { case CHAR: case DOT: case ALL: case CCL: case NCCL: case '$': case '(': @@ -620,8 +658,8 @@ Node *concat(np) } } -Node *alt(np) - Node *np; +static Node * +alt(Node *np) { if (rtok == OR) { rtok = relex(); @@ -630,8 +668,8 @@ Node *alt(np) return (np); } -Node *unary(np) - Node *np; +static Node * +unary(Node *np) { switch (rtok) { case STAR: @@ -648,10 +686,11 @@ Node *unary(np) } } -relex() /* lexical analyzer for reparse */ +static int +relex(void) /* lexical analyzer for reparse */ { register int c; - uchar cbuf[RECSIZE]; + uchar *cbuf; int clen, cflag; switch (c = *prestr++) { @@ -665,7 +704,7 @@ relex() /* lexical analyzer for reparse */ case '$': case '(': case ')': - return c; + return (c); case '\\': if ((c = *prestr++) == 't') c = '\t'; @@ -689,68 +728,77 @@ relex() /* lexical analyzer for reparse */ c = n; } /* else it's now in c */ rlxval = c; - return CHAR; + return (CHAR); default: rlxval = c; - return CHAR; - case '[': + return (CHAR); + case '[': clen = 0; if (*prestr == '^') { cflag = 1; prestr++; - } - else + } else cflag = 0; + init_buf(&cbuf, NULL, strlen((char *)prestr) * 2 + 1); for (;;) { if ((c = *prestr++) == '\\') { cbuf[clen++] = '\\'; - if ((c = *prestr++) == '\0') - ERROR "nonterminated character class %s", lastre FATAL; + if ((c = *prestr++) == '\0') { + ERROR + "nonterminated character class %s", lastre FATAL; + } cbuf[clen++] = c; } else if (c == ']') { cbuf[clen] = 0; rlxstr = tostring(cbuf); + free(cbuf); if (cflag == 0) - return CCL; + return (CCL); else - return NCCL; + return (NCCL); } else if (c == '\n') { - ERROR "newline in character class %s...", lastre FATAL; + ERROR "newline in character class %s...", + lastre FATAL; } else if (c == '\0') { - ERROR "nonterminated character class %s", lastre FATAL; + ERROR "nonterminated character class %s", + lastre FATAL; } else cbuf[clen++] = c; } + /*NOTREACHED*/ } + return (0); } -int cgoto(f, s, c) - fa *f; - int s, c; +static int +cgoto(fa *f, int s, int c) { register int i, j, k; register int *p, *q; - for (i=0; i<=f->accept; i++) + for (i = 0; i <= f->accept; i++) setvec[i] = 0; setcnt = 0; /* compute positions of gototab[s,c] into setvec */ p = f->posns[s]; - for (i=1; i<=*p; i++) { + for (i = 1; i <= *p; i++) { if ((k = f->re[p[i]].ltype) != FINAL) { - if (k == CHAR && c == f->re[p[i]].lval - || k == DOT && c != 0 && c != HAT - || k == ALL && c != 0 - || k == CCL && member(c, (uchar *) f->re[p[i]].lval) - || k == NCCL && !member(c, (uchar *) f->re[p[i]].lval) && c != 0 && c != HAT) { - q = f->re[p[i]].lfollow; - for (j=1; j<=*q; j++) { - if (setvec[q[j]] == 0) { - setcnt++; - setvec[q[j]] = 1; - } + if (k == CHAR && c == f->re[p[i]].lval || + k == DOT && c != 0 && c != HAT || + k == ALL && c != 0 || + k == CCL && + member(c, (uchar *)f->re[p[i]].lval) || + k == NCCL && + !member(c, (uchar *)f->re[p[i]].lval) && + c != 0 && c != HAT) { + q = f->re[p[i]].lfollow; + for (j = 1; j <= *q; j++) { + if (setvec[q[j]] == 0) { + setcnt++; + setvec[q[j]] = 1; } } + } } } /* determine if setvec is a previous state */ @@ -761,7 +809,7 @@ int cgoto(f, s, c) tmpset[j++] = i; } /* tmpset == previous state? */ - for (i=1; i<= f->curstat; i++) { + for (i = 1; i <= f->curstat; i++) { p = f->posns[i]; if ((k = tmpset[0]) != p[0]) goto different; @@ -770,7 +818,7 @@ int cgoto(f, s, c) goto different; /* setvec is state i */ f->gototab[s][c] = i; - return i; + return (i); different:; } @@ -778,15 +826,14 @@ int cgoto(f, s, c) if (f->curstat >= NSTATES-1) { f->curstat = 2; f->reset = 1; - for (i=2; i<NSTATES; i++) + for (i = 2; i < NSTATES; i++) xfree(f->posns[i]); - } - else + } else ++(f->curstat); - for (i=0; i<NCHARS; i++) + for (i = 0; i < NCHARS; i++) f->gototab[f->curstat][i] = 0; xfree(f->posns[f->curstat]); - if ((p = (int *) calloc(1, (setcnt+1)*sizeof(int))) == NULL) + if ((p = (int *)calloc(1, (setcnt + 1) * sizeof (int))) == NULL) overflo("out of space in cgoto"); f->posns[f->curstat] = p; @@ -797,21 +844,20 @@ int cgoto(f, s, c) f->out[f->curstat] = 1; else f->out[f->curstat] = 0; - return f->curstat; + return (f->curstat); } - -freefa(f) - struct fa *f; +static void +freefa(fa *f) { register int i; if (f == NULL) return; - for (i=0; i<=f->curstat; i++) + for (i = 0; i <= f->curstat; i++) xfree(f->posns[i]); - for (i=0; i<=f->accept; i++) + for (i = 0; i <= f->accept; i++) xfree(f->re[i].lfollow); xfree(f->restr); xfree(f); diff --git a/usr/src/cmd/awk/lib.c b/usr/src/cmd/awk/lib.c index 0291838a8f..588700e870 100644 --- a/usr/src/cmd/awk/lib.c +++ b/usr/src/cmd/awk/lib.c @@ -19,49 +19,52 @@ * * CDDL HEADER END */ -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - /* - * Copyright (c) 1996-2001 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 2.13 */ +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ + +#pragma ident "%Z%%M% %I% %E% SMI" -#include <stdio.h> -#include <ctype.h> #include <errno.h> -#include <libintl.h> #include "awk.h" #include "y.tab.h" -#define getfval(p) \ - (((p)->tval & (ARR|FLD|REC|NUM)) == NUM ? (p)->fval : r_getfval(p)) -#define getsval(p) \ - (((p)->tval & (ARR|FLD|REC|STR)) == STR ? (p)->sval : r_getsval(p)) - -extern Awkfloat r_getfval(); -extern uchar *r_getsval(); - -FILE *infile = NULL; -uchar *file = (uchar*) ""; -uchar recdata[RECSIZE]; -uchar *record = recdata; -uchar fields[RECSIZE]; +uchar *recdata; +uchar *record; +size_t record_size; int donefld; /* 1 = implies rec broken into fields */ int donerec; /* 1 = record is valid (no flds have changed) */ -Cell fldtab[MAXFLD]; /* room for fields */ +static struct fldtab_chunk { + struct fldtab_chunk *next; + Cell fields[FLD_INCR]; +} *fldtab_head, *fldtab_tail; -int maxfld = 0; /* last used field */ -int argno = 1; /* current input argument number */ -extern Awkfloat *ARGC; -extern uchar *getargv(); +static size_t fldtab_maxidx; -initgetrec() +static FILE *infile = NULL; +static uchar *file = (uchar*) ""; +static uchar *fields; +static size_t fields_size = LINE_INCR; + +static int maxfld = 0; /* last used field */ +static int argno = 1; /* current input argument number */ + +static uchar *getargv(int); +static void cleanfld(int, int); +static int refldbld(uchar *, uchar *); +static void bcheck2(int, int, int); +static void eprint(void); +static void bclass(int); + +static void +initgetrec(void) { int i; uchar *p; @@ -76,21 +79,22 @@ initgetrec() /* *FILENAME = file = (uchar*) "-"; */ } -getrec(buf) - uchar *buf; +int +getrec(uchar **bufp, size_t *bufsizep) { int c; static int firsttime = 1; + uchar_t *buf, *nbuf; + size_t len; if (firsttime) { firsttime = 0; initgetrec(); } dprintf(("RS=<%s>, FS=<%s>, ARGC=%f, FILENAME=%s\n", - *RS, *FS, *ARGC, *FILENAME)); + *RS, *FS, *ARGC, *FILENAME)); donefld = 0; donerec = 1; - buf[0] = 0; while (argno < *ARGC || infile == stdin) { dprintf(("argno=%d, file=|%s|\n", argno, file)); if (infile == NULL) { /* have to open a new file */ @@ -110,92 +114,96 @@ getrec(buf) infile = stdin; else if ((infile = fopen((char *)file, "r")) == NULL) ERROR "can't open file %s", file FATAL; - setfval(fnrloc, 0.0); + (void) setfval(fnrloc, 0.0); } - c = readrec(buf, RECSIZE, infile); + c = readrec(&nbuf, &len, infile); + expand_buf(bufp, bufsizep, len); + buf = *bufp; + (void) memcpy(buf, nbuf, len); + buf[len] = '\0'; + free(nbuf); + if (c != 0 || buf[0] != '\0') { /* normal record */ if (buf == record) { if (!(recloc->tval & DONTFREE)) xfree(recloc->sval); recloc->sval = record; recloc->tval = REC | STR | DONTFREE; - if (isnumber(recloc->sval)) { - recloc->fval = atof(recloc->sval); + if (is_number(recloc->sval)) { + recloc->fval = + atof((const char *)recloc->sval); recloc->tval |= NUM; } } - setfval(nrloc, nrloc->fval+1); - setfval(fnrloc, fnrloc->fval+1); + (void) setfval(nrloc, nrloc->fval+1); + (void) setfval(fnrloc, fnrloc->fval+1); return (1); } /* EOF arrived on this file; set up next */ if (infile != stdin) - fclose(infile); + (void) fclose(infile); infile = NULL; argno++; } return (0); /* true end of file */ } -readrec(buf, bufsize, inf) /* read one record into buf */ - uchar *buf; - int bufsize; - FILE *inf; +int +readrec(uchar **bufp, size_t *sizep, FILE *inf) /* read one record into buf */ { register int sep, c; - register uchar *rr; + uchar *buf; int count; + size_t bufsize; + init_buf(&buf, &bufsize, LINE_INCR); if ((sep = **RS) == 0) { sep = '\n'; /* skip leading \n's */ while ((c = getc(inf)) == '\n' && c != EOF) ; if (c != EOF) - ungetc(c, inf); + (void) ungetc(c, inf); } - for (rr = buf, count = 0; ; ) { + count = 0; + for (;;) { while ((c = getc(inf)) != sep && c != EOF) { - count++; - if (count > bufsize) - ERROR "input record `%.20s...' too long", - buf FATAL; - *rr++ = c; + expand_buf(&buf, &bufsize, count); + buf[count++] = c; } if (**RS == sep || c == EOF) break; if ((c = getc(inf)) == '\n' || c == EOF) /* 2 in a row */ break; - count += 2; - if (count > bufsize) - ERROR "input record `%.20s...' too long", buf FATAL; - *rr++ = '\n'; - *rr++ = c; + expand_buf(&buf, &bufsize, count + 1); + buf[count++] = '\n'; + buf[count++] = c; } - *rr = 0; + buf[count] = '\0'; dprintf(("readrec saw <%s>, returns %d\n", - buf, c == EOF && rr == buf ? 0 : 1)); - return (c == EOF && rr == buf ? 0 : 1); + buf, c == EOF && count == 0 ? 0 : 1)); + *bufp = buf; + *sizep = count; + return (c == EOF && count == 0 ? 0 : 1); } /* get ARGV[n] */ -uchar * -getargv(n) - int n; +static uchar * +getargv(int n) { Cell *x; - uchar *s, temp[10]; + uchar *s, temp[11]; extern Array *ARGVtab; - sprintf((char *)temp, "%d", n); - x = setsymtab(temp, "", 0.0, STR, ARGVtab); + (void) sprintf((char *)temp, "%d", n); + x = setsymtab(temp, (uchar *)"", 0.0, STR, ARGVtab); s = getsval(x); dprintf(("getargv(%d) returns |%s|\n", n, s)); return (s); } -setclvar(s) /* set var=value from s */ -uchar *s; +void +setclvar(uchar *s) /* set var=value from s */ { uchar *p; Cell *q; @@ -205,29 +213,43 @@ uchar *s; *p++ = 0; p = qstring(p, '\0'); q = setsymtab(s, p, 0.0, STR, symtab); - setsval(q, p); - if (isnumber(q->sval)) { - q->fval = atof(q->sval); + (void) setsval(q, p); + if (is_number(q->sval)) { + q->fval = atof((const char *)q->sval); q->tval |= NUM; } dprintf(("command line set %s to |%s|\n", s, p)); + free(p); } - -fldbld() +void +fldbld(void) { register uchar *r, *fr, sep; Cell *p; int i; + size_t len; if (donefld) return; if (!(recloc->tval & STR)) - getsval(recloc); + (void) getsval(recloc); r = recloc->sval; /* was record! */ + + /* make sure fields is always allocated */ + adjust_buf(&fields, fields_size); + + /* + * make sure fields has enough size. We don't expand the buffer + * in the middle of the loop, since p->sval has already pointed + * the address in the fields. + */ + len = strlen((char *)r) + 1; + expand_buf(&fields, &fields_size, len); fr = fields; + i = 0; /* number of fields accumulated here */ - if (strlen(*FS) > 1) { /* it's a regular expression */ + if (strlen((char *)*FS) > 1) { /* it's a regular expression */ i = refldbld(r, *FS); } else if ((sep = **FS) == ' ') { for (i = 0; ; ) { @@ -236,28 +258,27 @@ fldbld() if (*r == 0) break; i++; - if (i >= MAXFLD) - break; - if (!(fldtab[i].tval & DONTFREE)) - xfree(fldtab[i].sval); - fldtab[i].sval = fr; - fldtab[i].tval = FLD | STR | DONTFREE; + p = getfld(i); + if (!(p->tval & DONTFREE)) + xfree(p->sval); + p->sval = fr; + p->tval = FLD | STR | DONTFREE; do *fr++ = *r++; while (*r != ' ' && *r != '\t' && *r != '\n' && - *r != '\0'); + *r != '\0') + ; *fr++ = 0; } *fr = 0; } else if (*r != 0) { /* if 0, it's a null field */ for (;;) { i++; - if (i >= MAXFLD) - break; - if (!(fldtab[i].tval & DONTFREE)) - xfree(fldtab[i].sval); - fldtab[i].sval = fr; - fldtab[i].tval = FLD | STR | DONTFREE; + p = getfld(i); + if (!(p->tval & DONTFREE)) + xfree(p->sval); + p->sval = fr; + p->tval = FLD | STR | DONTFREE; /* \n always a separator */ while (*r != sep && *r != '\n' && *r != '\0') *fr++ = *r++; @@ -267,30 +288,36 @@ fldbld() } *fr = 0; } - if (i >= MAXFLD) - ERROR "record `%.20s...' has too many fields", record FATAL; /* clean out junk from previous record */ cleanfld(i, maxfld); maxfld = i; donefld = 1; - for (p = fldtab+1; p <= fldtab+maxfld; p++) { - if (isnumber(p->sval)) { - p->fval = atof(p->sval); + for (i = 1; i <= maxfld; i++) { + p = getfld(i); + if (is_number(p->sval)) { + p->fval = atof((const char *)p->sval); p->tval |= NUM; } } - setfval(nfloc, (Awkfloat) maxfld); - if (dbg) - for (p = fldtab; p <= fldtab+maxfld; p++) - printf("field %d: |%s|\n", p-fldtab, p->sval); + + (void) setfval(nfloc, (Awkfloat) maxfld); + if (dbg) { + for (i = 0; i <= maxfld; i++) { + p = getfld(i); + (void) printf("field %d: |%s|\n", i, p->sval); + } + } } -cleanfld(n1, n2) /* clean out fields n1..n2 inclusive */ +static void +cleanfld(int n1, int n2) /* clean out fields n1..n2 inclusive */ { static uchar *nullstat = (uchar *) ""; - register Cell *p, *q; + register Cell *p; + int i; - for (p = &fldtab[n2], q = &fldtab[n1]; p > q; p--) { + for (i = n2; i > n1; i--) { + p = getfld(i); if (!(p->tval & DONTFREE)) xfree(p->sval); p->tval = FLD | STR | DONTFREE; @@ -298,46 +325,134 @@ cleanfld(n1, n2) /* clean out fields n1..n2 inclusive */ } } -newfld(n) /* add field n (after end) */ +void +newfld(int n) /* add field n (after end) */ { - if (n >= MAXFLD) - ERROR "creating too many fields", record FATAL; + if (n < 0) + ERROR "accessing invalid field", record FATAL; + (void) getfld(n); cleanfld(maxfld, n); maxfld = n; - setfval(nfloc, (Awkfloat) n); + (void) setfval(nfloc, (Awkfloat) n); } -refldbld(rec, fs) /* build fields from reg expr in FS */ - uchar *rec, *fs; +/* + * allocate field table. We don't reallocate the table since there + * might be somewhere recording the address of the table. + */ +static void +morefld(void) +{ + int i; + struct fldtab_chunk *fldcp; + Cell *newfld; + + if ((fldcp = calloc(sizeof (struct fldtab_chunk), 1)) == NULL) + ERROR "out of space in morefld" FATAL; + + newfld = &fldcp->fields[0]; + for (i = 0; i < FLD_INCR; i++) { + newfld[i].ctype = OCELL; + newfld[i].csub = CFLD; + newfld[i].nval = NULL; + newfld[i].sval = (uchar *)""; + newfld[i].fval = 0.0; + newfld[i].tval = FLD|STR|DONTFREE; + newfld[i].cnext = NULL; + } + /* + * link this field chunk + */ + if (fldtab_head == NULL) + fldtab_head = fldcp; + else + fldtab_tail->next = fldcp; + fldtab_tail = fldcp; + fldcp->next = NULL; + + fldtab_maxidx += FLD_INCR; +} + +Cell * +getfld(int idx) +{ + struct fldtab_chunk *fldcp; + int cbase; + + if (idx < 0) + ERROR "trying to access field %d", idx FATAL; + while (idx >= fldtab_maxidx) + morefld(); + cbase = 0; + for (fldcp = fldtab_head; fldcp != NULL; fldcp = fldcp->next) { + if (idx < (cbase + FLD_INCR)) + return (&fldcp->fields[idx - cbase]); + cbase += FLD_INCR; + } + /* should never happen */ + ERROR "trying to access invalid field %d", idx FATAL; + return (NULL); +} + +int +fldidx(Cell *vp) +{ + struct fldtab_chunk *fldcp; + Cell *tbl; + int cbase; + + cbase = 0; + for (fldcp = fldtab_head; fldcp != NULL; fldcp = fldcp->next) { + tbl = &fldcp->fields[0]; + if (vp >= tbl && vp < (tbl + FLD_INCR)) + return (cbase + (vp - tbl)); + cbase += FLD_INCR; + } + /* should never happen */ + ERROR "trying to access unknown field" FATAL; + return (0); +} + +static int +refldbld(uchar *rec, uchar *fs) /* build fields from reg expr in FS */ { - fa *makedfa(); uchar *fr; int i, tempstat; fa *pfa; + Cell *p; + size_t len; + /* make sure fields is allocated */ + adjust_buf(&fields, fields_size); fr = fields; *fr = '\0'; if (*rec == '\0') return (0); + + len = strlen((char *)rec) + 1; + expand_buf(&fields, &fields_size, len); + fr = fields; + pfa = makedfa(fs, 1); dprintf(("into refldbld, rec = <%s>, pat = <%s>\n", rec, fs)); tempstat = pfa->initstat; - for (i = 1; i < MAXFLD; i++) { - if (!(fldtab[i].tval & DONTFREE)) - xfree(fldtab[i].sval); - fldtab[i].tval = FLD | STR | DONTFREE; - fldtab[i].sval = fr; + for (i = 1; ; i++) { + p = getfld(i); + if (!(p->tval & DONTFREE)) + xfree(p->sval); + p->tval = FLD | STR | DONTFREE; + p->sval = fr; dprintf(("refldbld: i=%d\n", i)); if (nematch(pfa, rec)) { pfa->initstat = 2; dprintf(("match %s (%d chars)\n", patbeg, patlen)); - strncpy(fr, rec, patbeg-rec); + (void) strncpy((char *)fr, (char *)rec, patbeg-rec); fr += patbeg - rec + 1; *(fr-1) = '\0'; rec = patbeg + patlen; } else { dprintf(("no match %s\n", rec)); - strcpy(fr, rec); + (void) strcpy((char *)fr, (char *)rec); pfa->initstat = tempstat; break; } @@ -345,70 +460,84 @@ refldbld(rec, fs) /* build fields from reg expr in FS */ return (i); } -recbld() +void +recbld(void) { int i; - register uchar *r, *p; - static uchar rec[RECSIZE]; + register uchar *p; + size_t cnt, len, olen; + static uchar *rec; + size_t osize, nsize; if (donerec == 1) return; - r = rec; + /* sync up rec size */ + adjust_buf(&rec, record_size); + cnt = 0; + olen = strlen((char *)*OFS); for (i = 1; i <= *NF; i++) { - p = getsval(&fldtab[i]); - while ((r < rec + RECSIZE) && (*r = *p++)) - r++; - if (i < *NF) - for (p = *OFS; (r < rec + RECSIZE) && (*r = *p++); ) - r++; + p = getsval(getfld(i)); + len = strlen((char *)p); + osize = record_size; + nsize = cnt + len + olen; + expand_buf(&rec, &record_size, nsize); + if (osize != record_size) + adjust_buf(&recdata, record_size); + (void) memcpy(&rec[cnt], p, len); + cnt += len; + if (i < *NF) { + (void) memcpy(&rec[cnt], *OFS, olen); + cnt += olen; + } } - if (r >= rec + RECSIZE) - ERROR "built giant record `%.20s...'", record FATAL; - *r = '\0'; - dprintf(("in recbld FS=%o, recloc=%o\n", **FS, recloc)); + rec[cnt] = '\0'; + dprintf(("in recbld FS=%o, recloc=%p\n", **FS, (void *)recloc)); recloc->tval = REC | STR | DONTFREE; recloc->sval = record = rec; - dprintf(("in recbld FS=%o, recloc=%o\n", **FS, recloc)); + dprintf(("in recbld FS=%o, recloc=%p\n", **FS, (void *)recloc)); dprintf(("recbld = |%s|\n", record)); donerec = 1; } Cell * -fieldadr(n) +fieldadr(int n) { - if (n < 0 || n >= MAXFLD) + if (n < 0) ERROR "trying to access field %d", n FATAL; - return (&fldtab[n]); + return (getfld(n)); } int errorflag = 0; char errbuf[200]; -yyerror(s) - uchar *s; +void +yyerror(char *s) { extern uchar *cmdname, *curfname; static int been_here = 0; if (been_here++ > 2) return; - fprintf(stderr, "%s: %s", cmdname, s); - fprintf(stderr, gettext(" at source line %lld"), lineno); + (void) fprintf(stderr, "%s: %s", cmdname, s); + (void) fprintf(stderr, gettext(" at source line %lld"), lineno); if (curfname != NULL) - fprintf(stderr, gettext(" in function %s"), curfname); - fprintf(stderr, "\n"); + (void) fprintf(stderr, gettext(" in function %s"), curfname); + (void) fprintf(stderr, "\n"); errorflag = 2; eprint(); } -fpecatch() +/*ARGSUSED*/ +void +fpecatch(int sig) { ERROR "floating point exception" FATAL; } extern int bracecnt, brackcnt, parencnt; -bracecheck() +void +bracecheck(void) { int c; static int beenhere = 0; @@ -422,40 +551,44 @@ bracecheck() bcheck2(parencnt, '(', ')'); } -bcheck2(n, c1, c2) +/*ARGSUSED*/ +static void +bcheck2(int n, int c1, int c2) { if (n == 1) - fprintf(stderr, gettext("\tmissing %c\n"), c2); + (void) fprintf(stderr, gettext("\tmissing %c\n"), c2); else if (n > 1) - fprintf(stderr, gettext("\t%d missing %c's\n"), n, c2); + (void) fprintf(stderr, gettext("\t%d missing %c's\n"), n, c2); else if (n == -1) - fprintf(stderr, gettext("\textra %c\n"), c2); + (void) fprintf(stderr, gettext("\textra %c\n"), c2); else if (n < -1) - fprintf(stderr, gettext("\t%d extra %c's\n"), -n, c2); + (void) fprintf(stderr, gettext("\t%d extra %c's\n"), -n, c2); } -error(f, s) - int f; - char *s; +void +error(int f, char *s) { extern Node *curnode; extern uchar *cmdname; - fflush(stdout); - fprintf(stderr, "%s: ", cmdname); - fprintf(stderr, "%s", s); - fprintf(stderr, "\n"); + (void) fflush(stdout); + (void) fprintf(stderr, "%s: ", cmdname); + (void) fprintf(stderr, "%s", s); + (void) fprintf(stderr, "\n"); if (compile_time != 2 && NR && *NR > 0) { - fprintf(stderr, gettext(" input record number %g"), *FNR); - if (strcmp(*FILENAME, "-") != 0) - fprintf(stderr, gettext(", file %s"), *FILENAME); - fprintf(stderr, "\n"); + (void) fprintf(stderr, + gettext(" input record number %g"), *FNR); + if (strcmp((char *)*FILENAME, "-") != 0) + (void) fprintf(stderr, gettext(", file %s"), *FILENAME); + (void) fprintf(stderr, "\n"); } if (compile_time != 2 && curnode) - fprintf(stderr, gettext(" source line number %lld\n"), + (void) fprintf(stderr, gettext(" source line number %lld\n"), curnode->lineno); - else if (compile_time != 2 && lineno) - fprintf(stderr, gettext(" source line number %lld\n"), lineno); + else if (compile_time != 2 && lineno) { + (void) fprintf(stderr, + gettext(" source line number %lld\n"), lineno); + } eprint(); if (f) { if (dbg) @@ -464,7 +597,8 @@ error(f, s) } } -eprint() /* try to print context around error */ +static void +eprint(void) /* try to print context around error */ { uchar *p, *q; int c; @@ -480,28 +614,28 @@ eprint() /* try to print context around error */ ; while (*p == '\n') p++; - fprintf(stderr, gettext(" context is\n\t")); - for (q = ep-1; q >= p && *q != ' ' && *q != '\t' && *q != '\n'; - q--) + (void) fprintf(stderr, gettext(" context is\n\t")); + for (q = ep-1; q >= p && *q != ' ' && *q != '\t' && *q != '\n'; q--) ; for (; p < q; p++) if (*p) - putc(*p, stderr); - fprintf(stderr, " >>> "); + (void) putc(*p, stderr); + (void) fprintf(stderr, " >>> "); for (; p < ep; p++) if (*p) - putc(*p, stderr); - fprintf(stderr, " <<< "); + (void) putc(*p, stderr); + (void) fprintf(stderr, " <<< "); if (*ep) while ((c = input()) != '\n' && c != '\0' && c != EOF) { - putc(c, stderr); + (void) putc(c, stderr); bclass(c); } - putc('\n', stderr); + (void) putc('\n', stderr); ep = ebuf; } -bclass(c) +static void +bclass(int c) { switch (c) { case '{': bracecnt++; break; @@ -514,9 +648,7 @@ bclass(c) } double -errcheck(x, s) - double x; - uchar *s; +errcheck(double x, char *s) { extern int errno; @@ -532,25 +664,27 @@ errcheck(x, s) return (x); } -PUTS(s) uchar *s; { +void +PUTS(uchar *s) +{ dprintf(("%s\n", s)); } -isclvar(s) /* is s of form var=something? */ - char *s; +int +isclvar(uchar *s) /* is s of form var=something? */ { - char *os = s; + uchar *os = s; for (; *s; s++) if (!(isalnum(*s) || *s == '_')) break; - return (*s == '=' && s > os && *(s+1) != '='); + return (*s == '=' && s > os && *(s + 1) != '='); } #define MAXEXPON 38 /* maximum exponent for fp number */ -isnumber(s) -register uchar *s; +int +is_number(uchar *s) { register int d1, d2; int point; @@ -596,11 +730,12 @@ register uchar *s; do { s++; } while (isdigit(*s)); - if (s - es > 2) + if (s - es > 2) { return (0); - else if (s - es == 2 && - (int)(10 * (*es-'0') + *(es+1)-'0') >= MAXEXPON) + } else if (s - es == 2 && + (int)(10 * (*es-'0') + *(es+1)-'0') >= MAXEXPON) { return (0); + } } while (*s == ' ' || *s == '\t' || *s == '\n') s++; @@ -609,3 +744,47 @@ register uchar *s; else return (0); } + +void +init_buf(uchar **optr, size_t *sizep, size_t amt) +{ + uchar *nptr = NULL; + + if ((nptr = malloc(amt)) == NULL) + ERROR "out of space in init_buf" FATAL; + /* initial buffer should have NULL terminated */ + *nptr = '\0'; + if (sizep != NULL) + *sizep = amt; + *optr = nptr; +} + +void +r_expand_buf(uchar **optr, size_t *sizep, size_t req) +{ + uchar *nptr; + size_t amt, size = *sizep; + + if (size != 0 && req < (size - 1)) + return; + amt = req + 1 - size; + amt = (amt / LINE_INCR + 1) * LINE_INCR; + + if ((nptr = realloc(*optr, size + amt)) == NULL) + ERROR "out of space in expand_buf" FATAL; + /* initial buffer should have NULL terminated */ + if (size == 0) + *nptr = '\0'; + *sizep += amt; + *optr = nptr; +} + +void +adjust_buf(uchar **optr, size_t size) +{ + uchar *nptr; + + if ((nptr = realloc(*optr, size)) == NULL) + ERROR "out of space in adjust_buf" FATAL; + *optr = nptr; +} diff --git a/usr/src/cmd/awk/main.c b/usr/src/cmd/awk/main.c index edb422e346..ace889cdc2 100644 --- a/usr/src/cmd/awk/main.c +++ b/usr/src/cmd/awk/main.c @@ -19,15 +19,16 @@ * * CDDL HEADER END */ + /* - * Copyright (c) 1999 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ + /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ - -#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 2.12 */ +#pragma ident "%Z%%M% %I% %E% SMI" #include <stdio.h> #include <ctype.h> @@ -45,24 +46,20 @@ char *version = "version Oct 11, 1989"; int dbg = 0; uchar *cmdname; /* gets argv[0] for error messages */ -extern FILE *yyin; /* lex input file */ uchar *lexprog; /* points to program argument if it exists */ -extern int errorflag; /* non-zero if any syntax errors; set by yyerror */ int compile_time = 2; /* for error printing: */ /* 2 = cmdline, 1 = compile, 0 = running */ - -uchar *pfile[20]; /* program filenames from -f's */ -int npfile = 0; /* number of filenames */ -int curpfile = 0; /* current filename */ char radixpoint = '.'; -main(argc, argv, envp) - int argc; - uchar *argv[], *envp[]; +static uchar **pfile = NULL; /* program filenames from -f's */ +static int npfile = 0; /* number of filenames */ +static int curpfile = 0; /* current filename */ + +int +main(int argc, char *argv[], char *envp[]) { uchar *fs = NULL; char *nl_radix; - extern void fpecatch(); /* * At this point, numbers are still scanned as in * the POSIX locale. @@ -74,14 +71,14 @@ main(argc, argv, envp) #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ #endif (void) textdomain(TEXT_DOMAIN); - cmdname = argv[0]; + cmdname = (uchar *)argv[0]; if (argc == 1) { - fprintf(stderr, gettext( - "Usage: %s [-f programfile | 'program'] [-Ffieldsep] " - "[-v var=value] [files]\n"), cmdname); + (void) fprintf(stderr, gettext( + "Usage: %s [-f programfile | 'program'] [-Ffieldsep] " + "[-v var=value] [files]\n"), cmdname); exit(1); } - signal(SIGFPE, fpecatch); + (void) signal(SIGFPE, fpecatch); yyin = NULL; syminit(); while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') { @@ -97,7 +94,10 @@ main(argc, argv, envp) argv++; if (argc <= 1) ERROR "no program filename" FATAL; - pfile[npfile++] = argv[1]; + pfile = realloc(pfile, sizeof (uchar *) * (npfile + 1)); + if (pfile == NULL) + ERROR "out of space in main" FATAL; + pfile[npfile++] = (uchar *)argv[1]; break; case 'F': /* set field separator */ if (argv[1][2] != 0) { /* arg is -Fsomething */ @@ -105,16 +105,16 @@ main(argc, argv, envp) if (argv[1][2] == 't' && argv[1][3] == 0) fs = (uchar *) "\t"; else if (argv[1][2] != 0) - fs = &argv[1][2]; + fs = (uchar *)&argv[1][2]; } else { /* arg is -F something */ argc--; argv++; if (argc > 1) { /* wart: t=>\t */ if (argv[1][0] == 't' && - argv[1][1] == 0) + argv[1][1] == 0) fs = (uchar *) "\t"; else if (argv[1][0] != 0) - fs = &argv[1][0]; + fs = (uchar *)&argv[1][0]; } } if (fs == NULL || *fs == '\0') @@ -122,14 +122,14 @@ main(argc, argv, envp) 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]); + isclvar((uchar *)(++argv)[1])) + setclvar((uchar *)argv[1]); break; case 'd': dbg = atoi(&argv[1][2]); if (dbg == 0) dbg = 1; - printf("awk %s\n", version); + (void) printf("awk %s\n", version); break; default: ERROR "unknown option %s ignored", argv[1] WARNING; @@ -143,18 +143,18 @@ main(argc, argv, envp) if (argc <= 1) ERROR "no program given" FATAL; dprintf(("program = |%s|\n", argv[1])); - lexprog = argv[1]; + lexprog = (uchar *)argv[1]; argc--; argv++; } compile_time = 1; - argv[0] = cmdname; /* put prog name at front of arglist */ + argv[0] = (char *)cmdname; /* put prog name at front of arglist */ dprintf(("argc=%d, argv[0]=%s\n", argc, argv[0])); - arginit(argc, argv); - envinit(envp); + arginit(argc, (uchar **)argv); + envinit((uchar **)envp); yyparse(); if (fs) - *FS = tostring(qstring(fs, '\0')); + *FS = qstring(fs, '\0'); dprintf(("errorflag=%d\n", errorflag)); /* * done parsing, so now activate the LC_NUMERIC @@ -169,10 +169,11 @@ main(argc, argv, envp) run(winner); } else bracecheck(); - exit(errorflag); + return (errorflag); } -pgetc() /* get program character */ +int +pgetc(void) /* get program character */ { int c; @@ -180,14 +181,16 @@ pgetc() /* get program character */ if (yyin == NULL) { if (curpfile >= npfile) return (EOF); - yyin = (strcmp((char *) pfile[curpfile], "-") == 0) ? - stdin : fopen((char *) pfile[curpfile], "r"); - if (yyin == NULL) + yyin = (strcmp((char *)pfile[curpfile], "-") == 0) ? + stdin : fopen((char *)pfile[curpfile], "r"); + if (yyin == NULL) { ERROR "can't open file %s", - pfile[curpfile] FATAL; + pfile[curpfile] FATAL; + } } if ((c = getc(yyin)) != EOF) return (c); + (void) fclose(yyin); yyin = NULL; curpfile++; } diff --git a/usr/src/cmd/awk/maketab.c b/usr/src/cmd/awk/maketab.c index 314b8a22a2..7b34e4edfe 100644 --- a/usr/src/cmd/awk/maketab.c +++ b/usr/src/cmd/awk/maketab.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -123,12 +123,6 @@ main() printf("#include \"awk.h\"\n"); printf("#include \"y.tab.h\"\n\n"); - printf("Cell *nullproc();\n"); - for (i = SIZE; --i >= 0; ) - names[i] = ""; - for (p = proc; p->token != 0; p++) - if (p == proc || strcmp(p->name, (p-1)->name)) - printf("extern Cell *%s();\n", p->name); if ((fp = fopen("y.tab.h", "r")) == NULL) { fprintf(stderr, gettext("maketab can't open y.tab.h!\n")); @@ -163,12 +157,12 @@ main() printf("\t%s,\t/* %s */\n", table[i], names[i]); printf("};\n\n"); - printf("uchar *tokname(n)\n"); /* print a tokname() function */ + printf("uchar *\ntokname(int n)\n"); /* print a tokname() function */ printf("{\n"); - printf(" static uchar buf[100];\n\n"); + printf(" static char buf[100];\n\n"); printf(" if (n < FIRSTTOKEN || n > LASTTOKEN) {\n"); - printf(" sprintf(buf, \"token %%d\", n);\n"); - printf(" return buf;\n"); + printf(" (void) sprintf(buf, \"token %%d\", n);\n"); + printf(" return ((uchar *)buf);\n"); printf(" }\n"); printf(" return printname[n-257];\n"); printf("}\n"); diff --git a/usr/src/cmd/awk/parse.c b/usr/src/cmd/awk/parse.c index db9f1ac692..909977f10f 100644 --- a/usr/src/cmd/awk/parse.c +++ b/usr/src/cmd/awk/parse.c @@ -19,65 +19,79 @@ * * CDDL HEADER END */ + +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ +#pragma ident "%Z%%M% %I% %E% SMI" -#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 2.8 */ - -#define DEBUG -#include <stdio.h> +#define DEBUG #include "awk.h" #include "y.tab.h" -Node *nodealloc(n) +Node * +nodealloc(int n) { register Node *x; - x = (Node *) malloc(sizeof(Node) + (n-1)*sizeof(Node *)); + + x = (Node *)malloc(sizeof (Node) + (n - 1) * sizeof (Node *)); if (x == NULL) ERROR "out of space in nodealloc" FATAL; x->nnext = NULL; x->lineno = lineno; - return(x); + return (x); } -Node *exptostat(a) Node *a; +Node * +exptostat(Node *a) { a->ntype = NSTAT; - return(a); + return (a); } -Node *node1(a,b) Node *b; +Node * +node1(int a, Node *b) { register Node *x; + x = nodealloc(1); x->nobj = a; - x->narg[0]=b; - return(x); + x->narg[0] = b; + return (x); } -Node *node2(a,b,c) Node *b, *c; +Node * +node2(int a, Node *b, Node *c) { register Node *x; + x = nodealloc(2); x->nobj = a; x->narg[0] = b; x->narg[1] = c; - return(x); + return (x); } -Node *node3(a,b,c,d) Node *b, *c, *d; +Node * +node3(int a, Node *b, Node *c, Node *d) { register Node *x; + x = nodealloc(3); x->nobj = a; x->narg[0] = b; x->narg[1] = c; x->narg[2] = d; - return(x); + return (x); } -Node *node4(a,b,c,d,e) Node *b, *c, *d, *e; +Node * +node4(int a, Node *b, Node *c, Node *d, Node *e) { register Node *x; x = nodealloc(4); @@ -86,159 +100,186 @@ Node *node4(a,b,c,d,e) Node *b, *c, *d, *e; x->narg[1] = c; x->narg[2] = d; x->narg[3] = e; - return(x); + return (x); } -Node *stat3(a,b,c,d) Node *b, *c, *d; +Node * +stat3(int a, Node *b, Node *c, Node *d) { register Node *x; - x = node3(a,b,c,d); + + x = node3(a, b, c, d); x->ntype = NSTAT; - return(x); + return (x); } -Node *op2(a,b,c) Node *b, *c; +Node * +op2(int a, Node *b, Node *c) { register Node *x; - x = node2(a,b,c); + + x = node2(a, b, c); x->ntype = NEXPR; - return(x); + return (x); } -Node *op1(a,b) Node *b; +Node * +op1(int a, Node *b) { register Node *x; - x = node1(a,b); + + x = node1(a, b); x->ntype = NEXPR; - return(x); + return (x); } -Node *stat1(a,b) Node *b; +Node * +stat1(int a, Node *b) { register Node *x; - x = node1(a,b); + + x = node1(a, b); x->ntype = NSTAT; - return(x); + return (x); } -Node *op3(a,b,c,d) Node *b, *c, *d; +Node * +op3(int a, Node *b, Node *c, Node *d) { register Node *x; - x = node3(a,b,c,d); + + x = node3(a, b, c, d); x->ntype = NEXPR; - return(x); + return (x); } -Node *op4(a,b,c,d,e) Node *b, *c, *d, *e; +Node * +op4(int a, Node *b, Node *c, Node *d, Node *e) { register Node *x; - x = node4(a,b,c,d,e); + + x = node4(a, b, c, d, e); x->ntype = NEXPR; - return(x); + return (x); } -Node *stat2(a,b,c) Node *b, *c; +Node * +stat2(int a, Node *b, Node *c) { register Node *x; - x = node2(a,b,c); + + x = node2(a, b, c); x->ntype = NSTAT; - return(x); + return (x); } -Node *stat4(a,b,c,d,e) Node *b, *c, *d, *e; +Node * +stat4(int a, Node *b, Node *c, Node *d, Node *e) { register Node *x; - x = node4(a,b,c,d,e); + + x = node4(a, b, c, d, e); x->ntype = NSTAT; - return(x); + return (x); } -Node *valtonode(a, b) Cell *a; +Node * +valtonode(Cell *a, int b) { register Node *x; a->ctype = OCELL; a->csub = b; - x = node1(0, (Node *) a); + x = node1(0, (Node *)a); x->ntype = NVALUE; - return(x); + return (x); } -Node *rectonode() +Node * +rectonode(void) { /* return valtonode(lookup("$0", symtab), CFLD); */ - return valtonode(recloc, CFLD); + return (valtonode(recloc, CFLD)); } -Node *makearr(p) Node *p; +Node * +makearr(Node *p) { Cell *cp; if (isvalue(p)) { - cp = (Cell *) (p->narg[0]); + cp = (Cell *)(p->narg[0]); if (isfunc(cp)) ERROR "%s is a function, not an array", cp->nval SYNTAX; else if (!isarr(cp)) { xfree(cp->sval); - cp->sval = (uchar *) makesymtab(NSYMTAB); + cp->sval = (uchar *)makesymtab(NSYMTAB); cp->tval = ARR; } } - return p; + return (p); } -Node *pa2stat(a,b,c) Node *a, *b, *c; +Node * +pa2stat(Node *a, Node *b, Node *c) { register Node *x; - x = node4(PASTAT2, a, b, c, (Node *) paircnt); + + x = node4(PASTAT2, a, b, c, (Node *)paircnt); paircnt++; x->ntype = NSTAT; - return(x); + return (x); } -Node *linkum(a,b) Node *a, *b; +Node * +linkum(Node *a, Node *b) { register Node *c; if (errorflag) /* don't link things that are wrong */ - return a; - if (a == NULL) return(b); - else if (b == NULL) return(a); + return (a); + if (a == NULL) + return (b); + else if (b == NULL) + return (a); for (c = a; c->nnext != NULL; c = c->nnext) ; c->nnext = b; - return(a); + return (a); } -defn(v, vl, st) /* turn on FCN bit in definition */ - Cell *v; - Node *st, *vl; /* body of function, arglist */ +void +defn(Cell *v, Node *vl, Node *st) /* turn on FCN bit in definition */ { Node *p; int n; if (isarr(v)) { - ERROR "`%s' is an array name and a function name", v->nval SYNTAX; + ERROR "`%s' is an array name and a function name", + v->nval SYNTAX; return; } v->tval = FCN; - v->sval = (uchar *) st; + v->sval = (uchar *)st; n = 0; /* count arguments */ for (p = vl; p; p = p->nnext) n++; v->fval = n; - dprintf( ("defining func %s (%d args)\n", v->nval, n) ); + dprintf(("defining func %s (%d args)\n", v->nval, n)); } -isarg(s) /* is s in argument list for current function? */ - uchar *s; +int +isarg(uchar *s) /* is s in argument list for current function? */ { extern Node *arglist; Node *p = arglist; int n; - for (n = 0; p != 0; p = p->nnext, n++) - if (strcmp(((Cell *)(p->narg[0]))->nval, s) == 0) - return n; - return -1; + for (n = 0; p != 0; p = p->nnext, n++) { + if (strcmp((char *)((Cell *)(p->narg[0]))->nval, + (char *)s) == 0) { + return (n); + } + } + return (-1); } diff --git a/usr/src/cmd/awk/run.c b/usr/src/cmd/awk/run.c index 8891e00b38..99ba446e38 100644 --- a/usr/src/cmd/awk/run.c +++ b/usr/src/cmd/awk/run.c @@ -19,23 +19,22 @@ * * CDDL HEADER END */ -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 2.13 */ +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ + +#pragma ident "%Z%%M% %I% %E% SMI" -#define tempfree(x,s) if (istemp(x)) tfree(x,s); else +#define tempfree(x, s) if (istemp(x)) tfree(x, s) -/* #define execute(p) (isvalue(p) ? (Cell *)((p)->narg[0]) : r_execute(p)) */ #define execute(p) r_execute(p) -#define DEBUG +#define DEBUG #include "awk.h" #include <math.h> #include "y.tab.h" @@ -49,53 +48,55 @@ #endif -jmp_buf env; +static jmp_buf env; -#define getfval(p) (((p)->tval & (ARR|FLD|REC|NUM)) == NUM ? (p)->fval : r_getfval(p)) -#define getsval(p) (((p)->tval & (ARR|FLD|REC|STR)) == STR ? (p)->sval : r_getsval(p)) - -extern Awkfloat r_getfval(); -extern uchar *r_getsval(); -extern Cell *r_execute(), *fieldel(), *dopa2(), *gettemp(), *copycell(); -extern FILE *openfile(), *redirect(); -extern double errcheck(); +static Cell *r_execute(Node *); +static Cell *gettemp(char *), *copycell(Cell *); +static FILE *openfile(int, uchar *), *redirect(int, Node *); int paircnt; Node *winner = NULL; -Cell *tmps; -static Cell truecell ={ OBOOL, BTRUE, 0, 0, 1.0, NUM }; +static Cell *tmps; + +static Cell truecell = { OBOOL, BTRUE, 0, 0, 1.0, NUM }; Cell *true = &truecell; -static Cell falsecell ={ OBOOL, BFALSE, 0, 0, 0.0, NUM }; +static Cell falsecell = { OBOOL, BFALSE, 0, 0, 0.0, NUM }; Cell *false = &falsecell; -static Cell breakcell ={ OJUMP, JBREAK, 0, 0, 0.0, NUM }; +static Cell breakcell = { OJUMP, JBREAK, 0, 0, 0.0, NUM }; Cell *jbreak = &breakcell; -static Cell contcell ={ OJUMP, JCONT, 0, 0, 0.0, NUM }; +static Cell contcell = { OJUMP, JCONT, 0, 0, 0.0, NUM }; Cell *jcont = &contcell; -static Cell nextcell ={ OJUMP, JNEXT, 0, 0, 0.0, NUM }; +static Cell nextcell = { OJUMP, JNEXT, 0, 0, 0.0, NUM }; Cell *jnext = &nextcell; -static Cell exitcell ={ OJUMP, JEXIT, 0, 0, 0.0, NUM }; +static Cell exitcell = { OJUMP, JEXIT, 0, 0, 0.0, NUM }; Cell *jexit = &exitcell; -static Cell retcell ={ OJUMP, JRET, 0, 0, 0.0, NUM }; +static Cell retcell = { OJUMP, JRET, 0, 0, 0.0, NUM }; Cell *jret = &retcell; -static Cell tempcell ={ OCELL, CTEMP, 0, 0, 0.0, NUM }; +static Cell tempcell = { OCELL, CTEMP, 0, 0, 0.0, NUM }; Node *curnode = NULL; /* the node being executed, for debugging */ -run(a) Node *a; +static void tfree(Cell *, char *); +static void closeall(void); +static double ipow(double, int); + +void +run(Node *a) { - execute(a); + (void) execute(a); closeall(); } -Cell *r_execute(u) Node *u; +static Cell * +r_execute(Node *u) { register Cell *(*proc)(); register Cell *x; register Node *a; if (u == NULL) - return(true); + return (true); for (a = u; ; a = a->nnext) { curnode = a; if (isvalue(a)) { @@ -104,9 +105,10 @@ Cell *r_execute(u) Node *u; fldbld(); else if ((x->tval & REC) && !donerec) recbld(); - return(x); + return (x); } - if (notlegal(a->nobj)) /* probably a Cell* but too risky to print */ + /* probably a Cell* but too risky to print */ + if (notlegal(a->nobj)) ERROR "illegal statement" FATAL; proc = proctab[a->nobj-FIRSTTOKEN]; x = (*proc)(a->narg, a->nobj); @@ -115,18 +117,19 @@ Cell *r_execute(u) Node *u; else if ((x->tval & REC) && !donerec) recbld(); if (isexpr(a)) - return(x); + return (x); /* a statement, goto next statement */ if (isjump(x)) - return(x); + return (x); if (a->nnext == (Node *)NULL) - return(x); + return (x); tempfree(x, "execute"); } } - -Cell *program(a, n) register Node **a; +/*ARGSUSED*/ +Cell * +program(Node **a, int n) { register Cell *x; @@ -135,20 +138,22 @@ Cell *program(a, n) register Node **a; if (a[0]) { /* BEGIN */ x = execute(a[0]); if (isexit(x)) - return(true); - if (isjump(x)) - ERROR "illegal break, continue or next from BEGIN" FATAL; + return (true); + if (isjump(x)) { + ERROR "illegal break, continue or next from BEGIN" + FATAL; + } tempfree(x, ""); } - loop: +loop: if (a[1] || a[2]) - while (getrec(record) > 0) { + while (getrec(&record, &record_size) > 0) { x = execute(a[1]); if (isexit(x)) break; tempfree(x, ""); } - ex: +ex: if (setjmp(env) != 0) goto ex1; if (a[2]) { /* END */ @@ -159,8 +164,8 @@ Cell *program(a, n) register Node **a; ERROR "illegal break or next from END" FATAL; tempfree(x, ""); } - ex1: - return(true); +ex1: + return (true); } struct Frame { @@ -172,13 +177,16 @@ struct Frame { #define NARGS 30 -struct Frame *frame = NULL; /* base of stack frames; dynamically allocated */ +struct Frame *frame = NULL; /* base of stack frames; dynamically allocated */ int nframe = 0; /* number of frames allocated */ struct Frame *fp = NULL; /* frame pointer. bottom level unused */ -Cell *call(a, n) Node **a; +/*ARGSUSED*/ +Cell * +call(Node **a, int n) { - static Cell newcopycell = { OCELL, CCOPY, 0, (uchar *) "", 0.0, NUM|STR|DONTFREE }; + static Cell newcopycell = + { OCELL, CCOPY, 0, (uchar *) "", 0.0, NUM|STR|DONTFREE }; int i, ncall, ndef, freed = 0; Node *x; Cell *args[NARGS], *oargs[NARGS], *y, *z, *fcn; @@ -189,34 +197,45 @@ Cell *call(a, n) Node **a; if (!isfunc(fcn)) ERROR "calling undefined function %s", s FATAL; if (frame == NULL) { - fp = frame = (struct Frame *) calloc(nframe += 100, sizeof(struct Frame)); - if (frame == NULL) - ERROR "out of space for stack frames calling %s", s FATAL; + fp = frame = (struct Frame *)calloc(nframe += 100, + sizeof (struct Frame)); + if (frame == NULL) { + ERROR "out of space for stack frames calling %s", + s FATAL; + } } - for (ncall = 0, x = a[1]; x != NULL; x = x->nnext) /* args in call */ + for (ncall = 0, x = a[1]; x != NULL; x = x->nnext) /* args in call */ ncall++; - ndef = (int) fcn->fval; /* args in defn */ - dprintf( ("calling %s, %d args (%d in defn), fp=%d\n", s, ncall, ndef, fp-frame) ); - if (ncall > ndef) + ndef = (int)fcn->fval; /* args in defn */ + dprintf(("calling %s, %d args (%d in defn), fp=%d\n", + s, ncall, ndef, fp-frame)); + if (ncall > ndef) { ERROR "function %s called with %d args, uses only %d", - s, ncall, ndef WARNING; - if (ncall + ndef > NARGS) - ERROR "function %s has %d arguments, limit %d", s, ncall+ndef, NARGS FATAL; - for (i = 0, x = a[1]; x != NULL; i++, x = x->nnext) { /* get call args */ - dprintf( ("evaluate args[%d], fp=%d:\n", i, fp-frame) ); + s, ncall, ndef WARNING; + } + if (ncall + ndef > NARGS) { + ERROR "function %s has %d arguments, limit %d", + s, ncall+ndef, NARGS FATAL; + } + for (i = 0, x = a[1]; x != NULL; i++, x = x->nnext) { + /* get call args */ + dprintf(("evaluate args[%d], fp=%d:\n", i, fp-frame)); y = execute(x); oargs[i] = y; - dprintf( ("args[%d]: %s %f <%s>, t=%o\n", - i, y->nval, y->fval, isarr(y) ? "(array)" : (char*) y->sval, y->tval) ); - if (isfunc(y)) - ERROR "can't use function %s as argument in %s", y->nval, s FATAL; + dprintf(("args[%d]: %s %f <%s>, t=%o\n", + i, y->nval, y->fval, + isarr(y) ? "(array)" : (char *)y->sval, y->tval)); + if (isfunc(y)) { + ERROR "can't use function %s as argument in %s", + y->nval, s FATAL; + } if (isarr(y)) args[i] = y; /* arrays by ref */ else args[i] = copycell(y); tempfree(y, "callargs"); } - for ( ; i < ndef; i++) { /* add null args for ones not provided */ + for (; i < ndef; i++) { /* add null args for ones not provided */ args[i] = gettemp("nullargs"); *args[i] = newcopycell; } @@ -224,7 +243,7 @@ Cell *call(a, n) Node **a; if (fp >= frame + nframe) { int dfp = fp - frame; /* old index */ frame = (struct Frame *) - realloc(frame, (nframe += 100) * sizeof(struct Frame)); + realloc(frame, (nframe += 100) * sizeof (struct Frame)); if (frame == NULL) ERROR "out of space for stack frames in %s", s FATAL; fp = frame + dfp; @@ -234,9 +253,10 @@ Cell *call(a, n) Node **a; fp->nargs = ndef; /* number defined with (excess are locals) */ fp->retval = gettemp("retval"); - dprintf( ("start exec of %s, fp=%d\n", s, fp-frame) ); + dprintf(("start exec of %s, fp=%d\n", s, fp-frame)); + /*LINTED align*/ y = execute((Node *)(fcn->sval)); /* execute body */ - dprintf( ("finished exec of %s, fp=%d\n", s, fp-frame) ); + dprintf(("finished exec of %s, fp=%d\n", s, fp-frame)); for (i = 0; i < ndef; i++) { Cell *t = fp->args[i]; @@ -260,16 +280,18 @@ Cell *call(a, n) Node **a; } tempfree(fcn, "call.fcn"); if (isexit(y) || isnext(y)) - return y; - if (!freed) tempfree(y, "fcn ret"); /* should not free twice! */ + return (y); + if (!freed) + tempfree(y, "fcn ret"); /* this can free twice! */ z = fp->retval; /* return value */ - dprintf( ("%s returns %g |%s| %o\n", s, getfval(z), getsval(z), z->tval) ); + dprintf(("%s returns %g |%s| %o\n", + s, getfval(z), getsval(z), z->tval)); fp--; - return(z); + return (z); } -Cell *copycell(x) /* make a copy of a cell in a temp */ - Cell *x; +static Cell * +copycell(Cell *x) /* make a copy of a cell in a temp */ { Cell *y; @@ -278,24 +300,28 @@ Cell *copycell(x) /* make a copy of a cell in a temp */ y->nval = x->nval; y->sval = x->sval ? tostring(x->sval) : NULL; y->fval = x->fval; - y->tval = x->tval & ~(CON|FLD|REC|DONTFREE); /* copy is not constant or field */ - /* is DONTFREE right? */ - return y; + /* copy is not constant or field is DONTFREE right? */ + y->tval = x->tval & ~(CON|FLD|REC|DONTFREE); + return (y); } -Cell *arg(a) Node **a; +/*ARGSUSED*/ +Cell * +arg(Node **a, int nnn) { int n; - n = (int) a[0]; /* argument number, counting from 0 */ - dprintf( ("arg(%d), fp->nargs=%d\n", n, fp->nargs) ); - if (n+1 > fp->nargs) + n = (int)a[0]; /* argument number, counting from 0 */ + dprintf(("arg(%d), fp->nargs=%d\n", n, fp->nargs)); + if (n+1 > fp->nargs) { ERROR "argument #%d of function %s was not supplied", - n+1, fp->fcncell->nval FATAL; - return fp->args[n]; + n+1, fp->fcncell->nval FATAL; + } + return (fp->args[n]); } -Cell *jump(a, n) Node **a; +Cell * +jump(Node **a, int n) { register Cell *y; @@ -307,171 +333,225 @@ Cell *jump(a, n) Node **a; tempfree(y, ""); } longjmp(env, 1); + /*NOTREACHED*/ case RETURN: if (a[0] != NULL) { y = execute(a[0]); if ((y->tval & (STR|NUM)) == (STR|NUM)) { - setsval(fp->retval, getsval(y)); + (void) setsval(fp->retval, getsval(y)); fp->retval->fval = getfval(y); fp->retval->tval |= NUM; - } - else if (y->tval & STR) - setsval(fp->retval, getsval(y)); + } else if (y->tval & STR) + (void) setsval(fp->retval, getsval(y)); else if (y->tval & NUM) - setfval(fp->retval, getfval(y)); + (void) setfval(fp->retval, getfval(y)); tempfree(y, ""); } - return(jret); + return (jret); case NEXT: - return(jnext); + return (jnext); case BREAK: - return(jbreak); + return (jbreak); case CONTINUE: - return(jcont); + return (jcont); default: /* can't happen */ ERROR "illegal jump type %d", n FATAL; } + /*NOTREACHED*/ + return (NULL); } -Cell *getline(a, n) Node **a; int n; +Cell * +getline(Node **a, int n) { /* a[0] is variable, a[1] is operator, a[2] is filename */ register Cell *r, *x; - uchar buf[RECSIZE]; + uchar *buf; FILE *fp; + size_t len; - fflush(stdout); /* in case someone is waiting for a prompt */ + (void) fflush(stdout); /* in case someone is waiting for a prompt */ r = gettemp(""); if (a[1] != NULL) { /* getline < file */ x = execute(a[2]); /* filename */ - if ((int) a[1] == '|') /* input pipe */ - a[1] = (Node *) LE; /* arbitrary flag */ - fp = openfile((int) a[1], getsval(x)); + if ((int)a[1] == '|') /* input pipe */ + a[1] = (Node *)LE; /* arbitrary flag */ + fp = openfile((int)a[1], getsval(x)); tempfree(x, ""); + buf = NULL; if (fp == NULL) n = -1; else - n = readrec(buf, sizeof(buf), fp); - if (n <= 0) { - ; - } else if (a[0] != NULL) { /* getline var <file */ - setsval(execute(a[0]), buf); - } else { /* getline <file */ - if (!(recloc->tval & DONTFREE)) - xfree(recloc->sval); - strcpy(record, buf); - recloc->sval = record; - recloc->tval = REC | STR | DONTFREE; - donerec = 1; donefld = 0; + n = readrec(&buf, &len, fp); + if (n > 0) { + if (a[0] != NULL) { /* getline var <file */ + (void) setsval(execute(a[0]), buf); + } else { /* getline <file */ + if (!(recloc->tval & DONTFREE)) + xfree(recloc->sval); + expand_buf(&record, &record_size, len); + (void) memcpy(record, buf, len); + record[len] = '\0'; + recloc->sval = record; + recloc->tval = REC | STR | DONTFREE; + donerec = 1; donefld = 0; + } } + if (buf != NULL) + free(buf); } else { /* bare getline; use current input */ if (a[0] == NULL) /* getline */ - n = getrec(record); + n = getrec(&record, &record_size); else { /* getline var */ - n = getrec(buf); - setsval(execute(a[0]), buf); + init_buf(&buf, &len, LINE_INCR); + n = getrec(&buf, &len); + (void) setsval(execute(a[0]), buf); + free(buf); } } - setfval(r, (Awkfloat) n); - return r; + (void) setfval(r, (Awkfloat)n); + return (r); } -Cell *getnf(a,n) register Node **a; +/*ARGSUSED*/ +Cell * +getnf(Node **a, int n) { if (donefld == 0) fldbld(); - return (Cell *) a[0]; + return ((Cell *)a[0]); } -Cell *array(a,n) register Node **a; +/*ARGSUSED*/ +Cell * +array(Node **a, int n) { register Cell *x, *y, *z; register uchar *s; register Node *np; - uchar buf[RECSIZE]; + uchar *buf; + size_t bsize, tlen, len, slen; x = execute(a[0]); /* Cell* for symbol table */ - buf[0] = 0; + init_buf(&buf, &bsize, LINE_INCR); + buf[0] = '\0'; + tlen = 0; + slen = strlen((char *)*SUBSEP); for (np = a[1]; np; np = np->nnext) { y = execute(np); /* subscript */ s = getsval(y); - strcat(buf, s); - if (np->nnext) - strcat(buf, *SUBSEP); + len = strlen((char *)s); + expand_buf(&buf, &bsize, tlen + len + slen); + (void) memcpy(&buf[tlen], s, len); + tlen += len; + if (np->nnext) { + (void) memcpy(&buf[tlen], *SUBSEP, slen); + tlen += slen; + } + buf[tlen] = '\0'; tempfree(y, ""); } if (!isarr(x)) { - dprintf( ("making %s into an array\n", x->nval) ); + dprintf(("making %s into an array\n", x->nval)); if (freeable(x)) xfree(x->sval); x->tval &= ~(STR|NUM|DONTFREE); x->tval |= ARR; x->sval = (uchar *) makesymtab(NSYMTAB); } - z = setsymtab(buf, "", 0.0, STR|NUM, (Array *) x->sval); + /*LINTED align*/ + z = setsymtab(buf, (uchar *)"", 0.0, STR|NUM, (Array *)x->sval); z->ctype = OCELL; z->csub = CVAR; tempfree(x, ""); - return(z); + free(buf); + return (z); } -Cell *delete(a, n) Node **a; +/*ARGSUSED*/ +Cell * +delete(Node **a, int n) { Cell *x, *y; Node *np; - uchar buf[RECSIZE], *s; + uchar *buf, *s; + size_t bsize, tlen, slen, len; x = execute(a[0]); /* Cell* for symbol table */ if (!isarr(x)) - return true; - buf[0] = 0; + return (true); + init_buf(&buf, &bsize, LINE_INCR); + buf[0] = '\0'; + tlen = 0; + slen = strlen((char *)*SUBSEP); for (np = a[1]; np; np = np->nnext) { y = execute(np); /* subscript */ s = getsval(y); - strcat(buf, s); - if (np->nnext) - strcat(buf, *SUBSEP); + len = strlen((char *)s); + expand_buf(&buf, &bsize, tlen + len + slen); + (void) memcpy(&buf[tlen], s, len); + tlen += len; + if (np->nnext) { + (void) memcpy(&buf[tlen], *SUBSEP, slen); + tlen += slen; + } + buf[tlen] = '\0'; tempfree(y, ""); } freeelem(x, buf); tempfree(x, ""); - return true; + free(buf); + return (true); } -Cell *intest(a, n) Node **a; +/*ARGSUSED*/ +Cell * +intest(Node **a, int n) { register Cell *x, *ap, *k; Node *p; - char buf[RECSIZE]; + uchar *buf; uchar *s; + size_t bsize, tlen, slen, len; ap = execute(a[1]); /* array name */ if (!isarr(ap)) ERROR "%s is not an array", ap->nval FATAL; + init_buf(&buf, &bsize, LINE_INCR); buf[0] = 0; + tlen = 0; + slen = strlen((char *)*SUBSEP); for (p = a[0]; p; p = p->nnext) { x = execute(p); /* expr */ s = getsval(x); - strcat(buf, s); + len = strlen((char *)s); + expand_buf(&buf, &bsize, tlen + len + slen); + (void) memcpy(&buf[tlen], s, len); + tlen += len; tempfree(x, ""); - if (p->nnext) - strcat(buf, *SUBSEP); + if (p->nnext) { + (void) memcpy(&buf[tlen], *SUBSEP, slen); + tlen += slen; + } + buf[tlen] = '\0'; } - k = lookup(buf, (Array *) ap->sval); + /*LINTED align*/ + k = lookup(buf, (Array *)ap->sval); tempfree(ap, ""); + free(buf); if (k == NULL) - return(false); + return (false); else - return(true); + return (true); } -Cell *matchop(a,n) Node **a; +Cell * +matchop(Node **a, int n) { register Cell *x, *y; register uchar *s, *t; register int i; - extern int match(), pmatch(); fa *pfa; int (*mf)() = match, mode = 0; @@ -495,20 +575,21 @@ Cell *matchop(a,n) Node **a; int start = patbeg - s + 1; if (patlen < 0) start = 0; - setfval(rstartloc, (Awkfloat) start); - setfval(rlengthloc, (Awkfloat) patlen); + (void) setfval(rstartloc, (Awkfloat)start); + (void) setfval(rlengthloc, (Awkfloat)patlen); x = gettemp(""); x->tval = NUM; x->fval = start; - return x; + return (x); } else if (n == MATCH && i == 1 || n == NOTMATCH && i == 0) - return(true); + return (true); else - return(false); + return (false); } -Cell *boolop(a,n) Node **a; +Cell * +boolop(Node **a, int n) { register Cell *x, *y; register int i; @@ -518,29 +599,30 @@ Cell *boolop(a,n) Node **a; tempfree(x, ""); switch (n) { case BOR: - if (i) return(true); + if (i) + return (true); y = execute(a[1]); i = istrue(y); tempfree(y, ""); - if (i) return(true); - else return(false); + return (i ? true : false); case AND: - if ( !i ) return(false); + if (!i) + return (false); y = execute(a[1]); i = istrue(y); tempfree(y, ""); - if (i) return(true); - else return(false); + return (i ? true : false); case NOT: - if (i) return(false); - else return(true); + return (i ? false : true); default: /* can't happen */ ERROR "unknown boolean operator %d", n FATAL; } /*NOTREACHED*/ + return (NULL); } -Cell *relop(a,n) Node **a; +Cell * +relop(Node **a, int n) { register int i; register Cell *x, *y; @@ -550,34 +632,33 @@ Cell *relop(a,n) Node **a; y = execute(a[1]); if (x->tval&NUM && y->tval&NUM) { j = x->fval - y->fval; - i = j<0? -1: (j>0? 1: 0); + i = j < 0 ? -1: (j > 0 ? 1: 0); } else { - i = strcmp(getsval(x), getsval(y)); + i = strcmp((char *)getsval(x), (char *)getsval(y)); } tempfree(x, ""); tempfree(y, ""); switch (n) { - case LT: if (i<0) return(true); - else return(false); - case LE: if (i<=0) return(true); - else return(false); - case NE: if (i!=0) return(true); - else return(false); - case EQ: if (i == 0) return(true); - else return(false); - case GE: if (i>=0) return(true); - else return(false); - case GT: if (i>0) return(true); - else return(false); + case LT: return (i < 0 ? true : false); + case LE: return (i <= 0 ? true : false); + case NE: return (i != 0 ? true : false); + case EQ: return (i == 0 ? true : false); + case GE: return (i >= 0 ? true : false); + case GT: return (i > 0 ? true : false); default: /* can't happen */ ERROR "unknown relational operator %d", n FATAL; } /*NOTREACHED*/ + return (false); } -tfree(a, s) register Cell *a; char *s; +static void +tfree(Cell *a, char *s) { - if (dbg>1) printf("## tfree %.8s %06o %s\n", s, a, a->sval ? a->sval : (uchar *)""); + if (dbg > 1) { + (void) printf("## tfree %.8s %06lo %s\n", + s, (ulong_t)a, a->sval ? a->sval : (uchar *)""); + } if (freeable(a)) xfree(a->sval); if (a == tmps) @@ -586,44 +667,50 @@ tfree(a, s) register Cell *a; char *s; tmps = a; } -Cell *gettemp(s) char *s; -{ int i; +static Cell * +gettemp(char *s) +{ + int i; register Cell *x; if (!tmps) { - tmps = (Cell *) calloc(100, sizeof(Cell)); + tmps = (Cell *)calloc(100, sizeof (Cell)); if (!tmps) ERROR "no space for temporaries" FATAL; - for(i = 1; i < 100; i++) + for (i = 1; i < 100; i++) tmps[i-1].cnext = &tmps[i]; tmps[i-1].cnext = 0; } x = tmps; tmps = x->cnext; *x = tempcell; - if (dbg>1) printf("## gtemp %.8s %06o\n", s, x); - return(x); + if (dbg > 1) + (void) printf("## gtemp %.8s %06lo\n", s, (ulong_t)x); + return (x); } -Cell *indirect(a,n) Node **a; +/*ARGSUSED*/ +Cell * +indirect(Node **a, int n) { register Cell *x; register int m; register uchar *s; - Cell *fieldadr(); x = execute(a[0]); m = getfval(x); - if (m == 0 && !isnumber(s = getsval(x))) /* suspicion! */ + if (m == 0 && !is_number(s = getsval(x))) /* suspicion! */ ERROR "illegal field $(%s)", s FATAL; tempfree(x, ""); x = fieldadr(m); x->ctype = OCELL; x->csub = CFLD; - return(x); + return (x); } -Cell *substr(a, nnn) Node **a; +/*ARGSUSED*/ +Cell * +substr(Node **a, int nnn) { register int k, m, n; register uchar *s; @@ -635,15 +722,15 @@ Cell *substr(a, nnn) Node **a; if (a[2] != 0) z = execute(a[2]); s = getsval(x); - k = strlen(s) + 1; + k = strlen((char *)s) + 1; if (k <= 1) { tempfree(x, ""); tempfree(y, ""); if (a[2] != 0) tempfree(z, ""); x = gettemp(""); - setsval(x, ""); - return(x); + (void) setsval(x, (uchar *)""); + return (x); } m = getfval(y); if (m <= 0) @@ -660,17 +747,19 @@ Cell *substr(a, nnn) Node **a; n = 0; else if (n > k - m) n = k - m; - dprintf( ("substr: m=%d, n=%d, s=%s\n", m, n, s) ); + dprintf(("substr: m=%d, n=%d, s=%s\n", m, n, s)); y = gettemp(""); - temp = s[n+m-1]; /* with thanks to John Linderman */ - s[n+m-1] = '\0'; - setsval(y, s + m - 1); - s[n+m-1] = temp; + temp = s[n + m - 1]; /* with thanks to John Linderman */ + s[n + m - 1] = '\0'; + (void) setsval(y, s + m - 1); + s[n + m - 1] = temp; tempfree(x, ""); - return(y); + return (y); } -Cell *sindex(a, nnn) Node **a; +/*ARGSUSED*/ +Cell * +sindex(Node **a, int nnn) { register Cell *x, *y, *z; register uchar *s1, *s2, *p1, *p2, *q; @@ -683,7 +772,7 @@ Cell *sindex(a, nnn) Node **a; z = gettemp(""); for (p1 = s1; *p1 != '\0'; p1++) { - for (q=p1, p2=s2; *p2 != '\0' && *q == *p2; q++, p2++) + for (q = p1, p2 = s2; *p2 != '\0' && *q == *p2; q++, p2++) ; if (*p2 == '\0') { v = (Awkfloat) (p1 - s1 + 1); /* origin 1 */ @@ -692,59 +781,72 @@ Cell *sindex(a, nnn) Node **a; } tempfree(x, ""); tempfree(y, ""); - setfval(z, v); - return(z); + (void) setfval(z, v); + return (z); } -format(buf, bufsize, s, a) uchar *buf, *s; int bufsize; Node *a; +void +format(uchar **bufp, uchar *s, Node *a) { - uchar fmt[RECSIZE]; - register uchar *p, *t, *os; + uchar *fmt; + register uchar *os; register Cell *x; - int flag = 0; + int flag = 0, len; + uchar_t *buf; + size_t bufsize, fmtsize, cnt, tcnt, ret; + init_buf(&buf, &bufsize, LINE_INCR); + init_buf(&fmt, &fmtsize, LINE_INCR); os = s; - p = buf; + cnt = 0; while (*s) { - if (p - buf >= bufsize) - return -1; if (*s != '%') { - *p++ = *s++; + expand_buf(&buf, &bufsize, cnt); + buf[cnt++] = *s++; continue; } if (*(s+1) == '%') { - *p++ = '%'; + expand_buf(&buf, &bufsize, cnt); + buf[cnt++] = '%'; s += 2; continue; } - for (t=fmt; (*t++ = *s) != '\0'; s++) { + for (tcnt = 0; ; s++) { + expand_buf(&fmt, &fmtsize, tcnt); + fmt[tcnt++] = *s; + if (*s == '\0') + break; if (isalpha(*s) && *s != 'l' && *s != 'h' && *s != 'L') break; /* the ansi panoply */ if (*s == '*') { if (a == NULL) { - ERROR + ERROR "not enough args in printf(%s) or sprintf(%s)", os, os FATAL; } x = execute(a); a = a->nnext; - sprintf((char *)t-1, "%d", (int) getfval(x)); - t = fmt + strlen(fmt); + tcnt--; + expand_buf(&fmt, &fmtsize, tcnt + 12); + ret = sprintf((char *)&fmt[tcnt], "%d", + (int)getfval(x)); + tcnt += ret; tempfree(x, ""); } } - *t = '\0'; - if (t >= fmt + sizeof(fmt)) - ERROR "format item %.20s... too long", os FATAL; + fmt[tcnt] = '\0'; + switch (*s) { case 'f': case 'e': case 'g': case 'E': case 'G': flag = 1; break; case 'd': case 'i': flag = 2; - if(*(s-1) == 'l') break; - *(t-1) = 'l'; - *t = 'd'; - *++t = '\0'; + if (*(s-1) == 'l') + break; + fmt[tcnt - 1] = 'l'; + expand_buf(&fmt, &fmtsize, tcnt); + fmt[tcnt++] = 'd'; + fmt[tcnt] = '\0'; break; case 'o': case 'x': case 'X': case 'u': flag = *(s-1) == 'l' ? 2 : 3; @@ -760,8 +862,11 @@ format(buf, bufsize, s, a) uchar *buf, *s; int bufsize; Node *a; break; } if (flag == 0) { - sprintf((char *)p, "%s", fmt); - p += strlen(p); + len = strlen((char *)fmt); + expand_buf(&buf, &bufsize, cnt + len); + (void) memcpy(&buf[cnt], fmt, len); + cnt += len; + buf[cnt] = '\0'; continue; } if (a == NULL) { @@ -770,68 +875,108 @@ format(buf, bufsize, s, a) uchar *buf, *s; int bufsize; Node *a; } x = execute(a); a = a->nnext; - switch (flag) { - case 1: sprintf((char *)p, (char *)fmt, getfval(x)); break; - case 2: sprintf((char *)p, (char *)fmt, (long) getfval(x)); break; - case 3: sprintf((char *)p, (char *)fmt, (int) getfval(x)); break; - case 4: sprintf((char *)p, (char *)fmt, getsval(x)); break; - case 5: isnum(x) ? sprintf((char *)p, (char *)fmt, (int) getfval(x)) - : sprintf((char *)p, (char *)fmt, getsval(x)[0]); - break; + for (;;) { + /* make sure we have at least 1 byte space */ + expand_buf(&buf, &bufsize, cnt + 1); + len = bufsize - cnt; + switch (flag) { + case 1: + /*LINTED*/ + ret = snprintf((char *)&buf[cnt], len, + (char *)fmt, getfval(x)); + break; + case 2: + /*LINTED*/ + ret = snprintf((char *)&buf[cnt], len, + (char *)fmt, (long)getfval(x)); + break; + case 3: + /*LINTED*/ + ret = snprintf((char *)&buf[cnt], len, + (char *)fmt, (int)getfval(x)); + break; + case 4: + /*LINTED*/ + ret = snprintf((char *)&buf[cnt], len, + (char *)fmt, getsval(x)); + break; + case 5: + if (isnum(x)) { + /*LINTED*/ + ret = snprintf((char *)&buf[cnt], len, + (char *)fmt, (int)getfval(x)); + } else { + /*LINTED*/ + ret = snprintf((char *)&buf[cnt], len, + (char *)fmt, getsval(x)[0]); + } + break; + default: + ret = 0; + } + if (ret < len) + break; + expand_buf(&buf, &bufsize, cnt + ret); } tempfree(x, ""); - p += strlen(p); + cnt += ret; s++; } - *p = '\0'; - for ( ; a; a = a->nnext) /* evaluate any remaining args */ - execute(a); - return 0; + buf[cnt] = '\0'; + for (; a; a = a->nnext) /* evaluate any remaining args */ + (void) execute(a); + *bufp = tostring(buf); + free(buf); + free(fmt); } -Cell *asprintf(a,n) Node **a; +/*ARGSUSED*/ +Cell * +asprintf(Node **a, int n) { register Cell *x; register Node *y; - uchar buf[3*RECSIZE]; + uchar *buf; y = a[0]->nnext; x = execute(a[0]); - if (format(buf, sizeof buf, getsval(x), y) == -1) - ERROR "sprintf string %.40s... too long", buf FATAL; + format(&buf, getsval(x), y); tempfree(x, ""); x = gettemp(""); - x->sval = tostring(buf); + x->sval = buf; x->tval = STR; - return(x); + return (x); } -Cell *aprintf(a,n) Node **a; +/*ARGSUSED*/ +Cell * +aprintf(Node **a, int n) { FILE *fp; register Cell *x; register Node *y; - uchar buf[3*RECSIZE]; + uchar *buf; y = a[0]->nnext; x = execute(a[0]); - if (format(buf, sizeof buf, getsval(x), y) == -1) - ERROR "printf string %.40s... too long", buf FATAL; + format(&buf, getsval(x), y); tempfree(x, ""); if (a[1] == NULL) - fputs((char *)buf, stdout); + (void) fputs((char *)buf, stdout); else { fp = redirect((int)a[1], a[2]); - fputs((char *)buf, fp); - fflush(fp); + (void) fputs((char *)buf, fp); + (void) fflush(fp); } - return(true); + free(buf); + return (true); } -Cell *arith(a,n) Node **a; +Cell * +arith(Node **a, int n) { Awkfloat i, j; - double v, ipow(); + double v; register Cell *x, *y, *z; x = execute(a[0]); @@ -861,41 +1006,41 @@ Cell *arith(a,n) Node **a; case MOD: if (j == 0) ERROR "division by zero in mod" FATAL; - modf(i/j, &v); + (void) modf(i/j, &v); i = i - j * v; break; case UMINUS: i = -i; break; case POWER: - if (j >= 0 && modf(j, &v) == 0.0) /* pos integer exponent */ - i = ipow(i, (int) j); + if (j >= 0 && modf(j, &v) == 0.0) /* pos integer exponent */ + i = ipow(i, (int)j); else i = errcheck(pow(i, j), "pow"); break; default: /* can't happen */ ERROR "illegal arithmetic operator %d", n FATAL; } - setfval(z, i); - return(z); + (void) setfval(z, i); + return (z); } -double ipow(x, n) - double x; - int n; +static double +ipow(double x, int n) { double v; if (n <= 0) - return 1; + return (1.0); v = ipow(x, n/2); if (n % 2 == 0) - return v * v; + return (v * v); else - return x * v * v; + return (x * v * v); } -Cell *incrdecr(a, n) Node **a; +Cell * +incrdecr(Node **a, int n) { register Cell *x, *z; register int k; @@ -905,38 +1050,38 @@ Cell *incrdecr(a, n) Node **a; xf = getfval(x); k = (n == PREINCR || n == POSTINCR) ? 1 : -1; if (n == PREINCR || n == PREDECR) { - setfval(x, xf + k); - return(x); + (void) setfval(x, xf + k); + return (x); } z = gettemp(""); - setfval(z, xf); - setfval(x, xf + k); + (void) setfval(z, xf); + (void) setfval(x, xf + k); tempfree(x, ""); - return(z); + return (z); } -Cell *assign(a,n) Node **a; +Cell * +assign(Node **a, int n) { register Cell *x, *y; Awkfloat xf, yf; - double v, ipow(); + double v; y = execute(a[1]); x = execute(a[0]); /* order reversed from before... */ if (n == ASSIGN) { /* ordinary assignment */ if ((y->tval & (STR|NUM)) == (STR|NUM)) { - setsval(x, getsval(y)); + (void) setsval(x, getsval(y)); x->fval = getfval(y); x->tval |= NUM; - } - else if (y->tval & STR) - setsval(x, getsval(y)); + } else if (y->tval & STR) + (void) setsval(x, getsval(y)); else if (y->tval & NUM) - setfval(x, getfval(y)); + (void) setfval(x, getfval(y)); else funnyvar(y, "read value of"); tempfree(y, ""); - return(x); + return (x); } xf = getfval(x); yf = getfval(y); @@ -958,12 +1103,12 @@ Cell *assign(a,n) Node **a; case MODEQ: if (yf == 0) ERROR "division by zero in %%=" FATAL; - modf(xf/yf, &v); + (void) modf(xf/yf, &v); xf = xf - yf * v; break; case POWEQ: - if (yf >= 0 && modf(yf, &v) == 0.0) /* pos integer exponent */ - xf = ipow(xf, (int) yf); + if (yf >= 0 && modf(yf, &v) == 0.0) /* pos integer exponent */ + xf = ipow(xf, (int)yf); else xf = errcheck(pow(xf, yf), "pow"); break; @@ -972,11 +1117,13 @@ Cell *assign(a,n) Node **a; break; } tempfree(y, ""); - setfval(x, xf); - return(x); + (void) setfval(x, xf); + return (x); } -Cell *cat(a,q) Node **a; +/*ARGSUSED*/ +Cell * +cat(Node **a, int q) { register Cell *x, *y, *z; register int n1, n2; @@ -984,25 +1131,28 @@ Cell *cat(a,q) Node **a; x = execute(a[0]); y = execute(a[1]); - getsval(x); - getsval(y); - n1 = strlen(x->sval); - n2 = strlen(y->sval); - s = (uchar *) malloc(n1 + n2 + 1); - if (s == NULL) + (void) getsval(x); + (void) getsval(y); + n1 = strlen((char *)x->sval); + n2 = strlen((char *)y->sval); + s = (uchar *)malloc(n1 + n2 + 1); + if (s == NULL) { ERROR "out of space concatenating %.15s and %.15s", - x->sval, y->sval FATAL; - strcpy(s, x->sval); - strcpy(s+n1, y->sval); + x->sval, y->sval FATAL; + } + (void) strcpy((char *)s, (char *)x->sval); + (void) strcpy((char *)s + n1, (char *)y->sval); tempfree(y, ""); z = gettemp(""); z->sval = s; z->tval = STR; tempfree(x, ""); - return(z); + return (z); } -Cell *pastat(a,n) Node **a; +/*ARGSUSED*/ +Cell * +pastat(Node **a, int n) { register Cell *x; @@ -1015,10 +1165,12 @@ Cell *pastat(a,n) Node **a; x = execute(a[1]); } } - return x; + return (x); } -Cell *dopa2(a,n) Node **a; +/*ARGSUSED*/ +Cell * +dopa2(Node **a, int n) { Cell *x; int pair; @@ -1033,7 +1185,7 @@ Cell *dopa2(a,n) Node **a; (void) memset(pairstack, 0, sizeof (int) * paircnt); } - pair = (int) a[3]; + pair = (int)a[3]; if (pairstack[pair] == 0) { x = execute(a[0]); if (istrue(x)) @@ -1046,76 +1198,91 @@ Cell *dopa2(a,n) Node **a; pairstack[pair] = 0; tempfree(x, ""); x = execute(a[2]); - return(x); + return (x); } - return(false); + return (false); } -Cell *split(a,nnn) Node **a; +/*ARGSUSED*/ +Cell * +split(Node **a, int nnn) { Cell *x, *y, *ap; register uchar *s; register int sep; - uchar *t, temp, num[5], *fs; + uchar *t, temp, num[11], *fs; int n, tempstat; y = execute(a[0]); /* source string */ s = getsval(y); if (a[2] == 0) /* fs string */ fs = *FS; - else if ((int) a[3] == STRING) { /* split(str,arr,"string") */ + else if ((int)a[3] == STRING) { /* split(str,arr,"string") */ x = execute(a[2]); fs = getsval(x); - } else if ((int) a[3] == REGEXPR) - fs = (uchar*) "(regexpr)"; /* split(str,arr,/regexpr/) */ + } else if ((int)a[3] == REGEXPR) + fs = (uchar *)"(regexpr)"; /* split(str,arr,/regexpr/) */ else ERROR "illegal type of split()" FATAL; 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, ap->nval, fs)); ap->tval &= ~STR; ap->tval |= ARR; - ap->sval = (uchar *) makesymtab(NSYMTAB); + ap->sval = (uchar *)makesymtab(NSYMTAB); n = 0; - if (*s != '\0' && strlen(fs) > 1 || (int) a[3] == REGEXPR) { /* reg expr */ + if (*s != '\0' && strlen((char *)fs) > 1 || (int)a[3] == REGEXPR) { + /* reg expr */ fa *pfa; - if ((int) a[3] == REGEXPR) { /* it's ready already */ - pfa = (fa *) a[2]; + if ((int)a[3] == REGEXPR) { /* it's ready already */ + pfa = (fa *)a[2]; } else { pfa = makedfa(fs, 1); } - if (nematch(pfa,s)) { + if (nematch(pfa, s)) { tempstat = pfa->initstat; pfa->initstat = 2; do { n++; - sprintf((char *)num, "%d", n); + (void) sprintf((char *)num, "%d", n); temp = *patbeg; *patbeg = '\0'; - if (isnumber(s)) - setsymtab(num, s, atof((char *)s), STR|NUM, (Array *) ap->sval); - else - setsymtab(num, s, 0.0, STR, (Array *) ap->sval); + if (is_number(s)) { + (void) setsymtab(num, s, + atof((char *)s), + /*LINTED align*/ + STR|NUM, (Array *)ap->sval); + } else { + (void) setsymtab(num, s, 0.0, + /*LINTED align*/ + STR, (Array *)ap->sval); + } *patbeg = temp; s = patbeg + patlen; if (*(patbeg+patlen-1) == 0 || *s == 0) { n++; - sprintf((char *)num, "%d", n); - setsymtab(num, "", 0.0, STR, (Array *) ap->sval); + (void) sprintf((char *)num, "%d", n); + (void) setsymtab(num, (uchar *)"", 0.0, + /*LINTED align*/ + STR, (Array *)ap->sval); pfa->initstat = tempstat; goto spdone; } - } while (nematch(pfa,s)); + } while (nematch(pfa, s)); } n++; - sprintf((char *)num, "%d", n); - if (isnumber(s)) - setsymtab(num, s, atof((char *)s), STR|NUM, (Array *) ap->sval); - else - setsymtab(num, s, 0.0, STR, (Array *) ap->sval); - spdone: + (void) sprintf((char *)num, "%d", n); + if (is_number(s)) { + (void) setsymtab(num, s, atof((char *)s), + /*LINTED align*/ + STR|NUM, (Array *)ap->sval); + } else { + /*LINTED align*/ + (void) setsymtab(num, s, 0.0, STR, (Array *)ap->sval); + } +spdone: pfa = NULL; } else if (sep == ' ') { for (n = 0; ; ) { @@ -1127,14 +1294,21 @@ Cell *split(a,nnn) Node **a; t = s; do s++; - while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0'); + while (*s != ' ' && *s != '\t' && + *s != '\n' && *s != '\0') + ; temp = *s; *s = '\0'; - sprintf((char *)num, "%d", n); - if (isnumber(t)) - setsymtab(num, t, atof((char *)t), STR|NUM, (Array *) ap->sval); - else - setsymtab(num, t, 0.0, STR, (Array *) ap->sval); + (void) sprintf((char *)num, "%d", n); + if (is_number(t)) { + (void) setsymtab(num, t, atof((char *)t), + /*LINTED align*/ + STR|NUM, (Array *)ap->sval); + } else { + (void) setsymtab(num, t, 0.0, + /*LINTED align*/ + STR, (Array *)ap->sval); + } *s = temp; if (*s != 0) s++; @@ -1147,11 +1321,16 @@ Cell *split(a,nnn) Node **a; s++; temp = *s; *s = '\0'; - sprintf((char *)num, "%d", n); - if (isnumber(t)) - setsymtab(num, t, atof((char *)t), STR|NUM, (Array *) ap->sval); - else - setsymtab(num, t, 0.0, STR, (Array *) ap->sval); + (void) sprintf((char *)num, "%d", n); + if (is_number(t)) { + (void) setsymtab(num, t, atof((char *)t), + /*LINTED align*/ + STR|NUM, (Array *)ap->sval); + } else { + (void) setsymtab(num, t, 0.0, + /*LINTED align*/ + STR, (Array *)ap->sval); + } *s = temp; if (*s++ == 0) break; @@ -1159,15 +1338,17 @@ Cell *split(a,nnn) Node **a; } tempfree(ap, ""); tempfree(y, ""); - if (a[2] != 0 && (int) a[3] == STRING) + if (a[2] != 0 && (int)a[3] == STRING) tempfree(x, ""); x = gettemp(""); x->tval = NUM; x->fval = n; - return(x); + return (x); } -Cell *condexpr(a,n) Node **a; +/*ARGSUSED*/ +Cell * +condexpr(Node **a, int n) { register Cell *x; @@ -1179,10 +1360,12 @@ Cell *condexpr(a,n) Node **a; tempfree(x, ""); x = execute(a[2]); } - return(x); + return (x); } -Cell *ifstat(a,n) Node **a; +/*ARGSUSED*/ +Cell * +ifstat(Node **a, int n) { register Cell *x; @@ -1194,71 +1377,81 @@ Cell *ifstat(a,n) Node **a; tempfree(x, ""); x = execute(a[2]); } - return(x); + return (x); } -Cell *whilestat(a,n) Node **a; +/*ARGSUSED*/ +Cell * +whilestat(Node **a, int n) { register Cell *x; for (;;) { x = execute(a[0]); if (!istrue(x)) - return(x); + return (x); tempfree(x, ""); x = execute(a[1]); if (isbreak(x)) { x = true; - return(x); + return (x); } if (isnext(x) || isexit(x) || isret(x)) - return(x); + return (x); tempfree(x, ""); } } -Cell *dostat(a,n) Node **a; +/*ARGSUSED*/ +Cell * +dostat(Node **a, int n) { register Cell *x; for (;;) { x = execute(a[0]); if (isbreak(x)) - return true; + return (true); if (isnext(x) || isexit(x) || isret(x)) - return(x); + return (x); tempfree(x, ""); x = execute(a[1]); if (!istrue(x)) - return(x); + return (x); tempfree(x, ""); } } -Cell *forstat(a,n) Node **a; +/*ARGSUSED*/ +Cell * +forstat(Node **a, int n) { register Cell *x; x = execute(a[0]); tempfree(x, ""); for (;;) { - if (a[1]!=0) { + if (a[1] != 0) { x = execute(a[1]); - if (!istrue(x)) return(x); - else tempfree(x, ""); + if (!istrue(x)) + return (x); + else + tempfree(x, ""); } x = execute(a[3]); if (isbreak(x)) /* turn off break */ - return true; + return (true); if (isnext(x) || isexit(x) || isret(x)) - return(x); + return (x); tempfree(x, ""); x = execute(a[2]); tempfree(x, ""); } } -Cell *instat(a, n) Node **a; +/*ARGSUSED*/ +Cell * +instat(Node **a, int n) { register Cell *x, *vp, *arrayp, *cp, *ncp; Array *tp; @@ -1268,45 +1461,48 @@ Cell *instat(a, n) Node **a; arrayp = execute(a[1]); if (!isarr(arrayp)) ERROR "%s is not an array", arrayp->nval FATAL; - tp = (Array *) arrayp->sval; + /*LINTED align*/ + tp = (Array *)arrayp->sval; tempfree(arrayp, ""); - for (i = 0; i < tp->size; i++) { /* this routine knows too much */ + for (i = 0; i < tp->size; i++) { /* this routine knows too much */ for (cp = tp->tab[i]; cp != NULL; cp = ncp) { - setsval(vp, cp->nval); + (void) setsval(vp, cp->nval); ncp = cp->cnext; x = execute(a[2]); if (isbreak(x)) { tempfree(vp, ""); - return true; + return (true); } if (isnext(x) || isexit(x) || isret(x)) { tempfree(vp, ""); - return(x); + return (x); } tempfree(x, ""); } } - return true; + return (true); } -Cell *bltin(a,n) Node **a; +/*ARGSUSED*/ +Cell * +bltin(Node **a, int n) { register Cell *x, *y; Awkfloat u; register int t; - uchar *p, buf[RECSIZE]; + uchar *p, *buf; Node *nextarg; - t = (int) a[0]; + t = (int)a[0]; x = execute(a[1]); nextarg = a[1]->nnext; switch (t) { case FLENGTH: - u = (Awkfloat) strlen(getsval(x)); break; + u = (Awkfloat)strlen((char *)getsval(x)); break; case FLOG: u = errcheck(log(getfval(x)), "log"); break; case FINT: - modf(getfval(x), &u); break; + (void) modf(getfval(x), &u); break; case FEXP: u = errcheck(exp(getfval(x)), "exp"); break; case FSQRT: @@ -1317,7 +1513,8 @@ Cell *bltin(a,n) Node **a; u = cos(getfval(x)); break; case FATAN: if (nextarg == 0) { - ERROR "atan2 requires two arguments; returning 1.0" WARNING; + ERROR "atan2 requires two arguments; returning 1.0" + WARNING; u = 1.0; } else { y = execute(a[1]->nnext); @@ -1327,22 +1524,24 @@ Cell *bltin(a,n) Node **a; } break; case FSYSTEM: - fflush(stdout); /* in case something is buffered already */ - u = (Awkfloat) system((char *)getsval(x)) / 256; /* 256 is unix-dep */ + /* in case something is buffered already */ + (void) fflush(stdout); + /* 256 is unix-dep */ + u = (Awkfloat)system((char *)getsval(x)) / 256; break; case FRAND: - u = (Awkfloat) (rand() % 32767) / 32767.0; + u = (Awkfloat)(rand() % 32767) / 32767.0; break; case FSRAND: if (x->tval & REC) /* no argument provided */ u = time((time_t *)0); else u = getfval(x); - srand((int) u); u = (int) u; + srand((int)u); u = (int)u; break; case FTOUPPER: case FTOLOWER: - strcpy(buf, getsval(x)); + buf = tostring(getsval(x)); if (t == FTOUPPER) { for (p = buf; *p; p++) if (islower(*p)) @@ -1354,24 +1553,27 @@ Cell *bltin(a,n) Node **a; } tempfree(x, ""); x = gettemp(""); - setsval(x, buf); - return x; + (void) setsval(x, buf); + free(buf); + return (x); default: /* can't happen */ ERROR "illegal function type %d", t FATAL; break; } tempfree(x, ""); x = gettemp(""); - setfval(x, u); + (void) setfval(x, u); if (nextarg != 0) { ERROR "warning: function has too many arguments" WARNING; - for ( ; nextarg; nextarg = nextarg->nnext) - execute(nextarg); + for (; nextarg; nextarg = nextarg->nnext) + (void) execute(nextarg); } - return(x); + return (x); } -Cell *print(a,n) Node **a; +/*ARGSUSED*/ +Cell * +print(Node **a, int n) { register Node *x; register Cell *y; @@ -1383,30 +1585,33 @@ Cell *print(a,n) Node **a; fp = redirect((int)a[1], a[2]); for (x = a[0]; x != NULL; x = x->nnext) { y = execute(x); - fputs((char *)getsval(y), fp); + (void) fputs((char *)getsval(y), fp); tempfree(y, ""); if (x->nnext == NULL) - fputs((char *)*ORS, fp); + (void) fputs((char *)*ORS, fp); else - fputs((char *)*OFS, fp); + (void) fputs((char *)*OFS, fp); } if (a[1] != 0) - fflush(fp); - return(true); + (void) fflush(fp); + return (true); } -Cell *nullproc() { return 0; } - - -struct +/*ARGSUSED*/ +Cell * +nullproc(Node **a, int n) { + return (0); +} + +struct { FILE *fp; uchar *fname; int mode; /* '|', 'a', 'w' */ } files[FOPEN_MAX]; -FILE *redirect(a, b) - Node *b; +static FILE * +redirect(int a, Node *b) { FILE *fp; Cell *x; @@ -1418,28 +1623,33 @@ FILE *redirect(a, b) if (fp == NULL) ERROR "can't open file %s", fname FATAL; tempfree(x, ""); - return fp; + return (fp); } -FILE *openfile(a, s) - uchar *s; +static FILE * +openfile(int a, uchar *s) { register int i, m; register FILE *fp; - extern FILE *popen(); if (*s == '\0') ERROR "null file name in print or getline" FATAL; - for (i=0; i < FOPEN_MAX; 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; - for (i=0; i < FOPEN_MAX; i++) + for (i = 0; i < FOPEN_MAX; i++) { + if (files[i].fname && + strcmp((char *)s, (char *)files[i].fname) == 0) { + if (a == files[i].mode || + a == APPEND && files[i].mode == GT) { + return (files[i].fp); + } + } + } + for (i = 0; i < FOPEN_MAX; i++) { if (files[i].fp == 0) break; + } if (i >= FOPEN_MAX) ERROR "%s makes too many open files", s FATAL; - fflush(stdout); /* force a semblance of order */ + (void) fflush(stdout); /* force a semblance of order */ m = a; if (a == GT) { fp = fopen((char *)s, "w"); @@ -1451,7 +1661,8 @@ FILE *openfile(a, s) } else if (a == LE) { /* input pipe */ fp = popen((char *)s, "r"); } else if (a == LT) { /* getline <file */ - fp = strcmp((char *)s, "-") == 0 ? stdin : fopen((char *)s, "r"); /* "-" is stdin */ + fp = strcmp((char *)s, "-") == 0 ? + stdin : fopen((char *)s, "r"); /* "-" is stdin */ } else /* can't happen */ ERROR "illegal redirection" FATAL; if (fp != NULL) { @@ -1459,62 +1670,80 @@ FILE *openfile(a, s) files[i].fp = fp; files[i].mode = m; } - return fp; + return (fp); } -Cell *closefile(a) Node **a; +/*ARGSUSED*/ +Cell * +closefile(Node **a, int n) { register Cell *x; int i, stat; x = execute(a[0]); - getsval(x); - for (i = 0; i < FOPEN_MAX; i++) - if (files[i].fname && strcmp(x->sval, files[i].fname) == 0) { - if (ferror(files[i].fp)) - ERROR "i/o error occurred on %s", files[i].fname WARNING; + (void) getsval(x); + for (i = 0; i < FOPEN_MAX; i++) { + if (files[i].fname && + strcmp((char *)x->sval, (char *)files[i].fname) == 0) { + if (ferror(files[i].fp)) { + ERROR "i/o error occurred on %s", + files[i].fname WARNING; + } if (files[i].mode == '|' || files[i].mode == LE) stat = pclose(files[i].fp); else stat = fclose(files[i].fp); - if (stat == EOF) - ERROR "i/o error occurred closing %s", files[i].fname WARNING; + if (stat == EOF) { + ERROR "i/o error occurred closing %s", + files[i].fname WARNING; + } xfree(files[i].fname); - files[i].fname = NULL; /* watch out for ref thru this */ + /* watch out for ref thru this */ + files[i].fname = NULL; files[i].fp = NULL; } + } tempfree(x, "close"); - return(true); + return (true); } -closeall() +static void +closeall(void) { int i, stat; - for (i = 0; i < FOPEN_MAX; i++) + for (i = 0; i < FOPEN_MAX; i++) { if (files[i].fp) { - if (ferror(files[i].fp)) - ERROR "i/o error occurred on %s", files[i].fname WARNING; + if (ferror(files[i].fp)) { + ERROR "i/o error occurred on %s", + files[i].fname WARNING; + } if (files[i].mode == '|' || files[i].mode == LE) stat = pclose(files[i].fp); else stat = fclose(files[i].fp); - if (stat == EOF) - ERROR "i/o error occurred while closing %s", files[i].fname WARNING; + if (stat == EOF) { + ERROR "i/o error occurred while closing %s", + files[i].fname WARNING; + } } + } } -Cell *sub(a, nnn) Node **a; +/*ARGSUSED*/ +Cell * +sub(Node **a, int nnn) { - register uchar *sptr, *pb, *q; + register uchar *sptr; register Cell *x, *y, *result; - uchar buf[RECSIZE], *t; + uchar *buf, *t; fa *pfa; + size_t bsize, cnt, len; x = execute(a[3]); /* target string */ t = getsval(x); if (a[0] == 0) - pfa = (fa *) a[1]; /* regular expression */ + pfa = (fa *)a[1]; /* regular expression */ else { y = execute(a[1]); pfa = makedfa(getsval(y), 1); @@ -1523,45 +1752,57 @@ Cell *sub(a, nnn) Node **a; y = execute(a[2]); /* replacement string */ result = false; if (pmatch(pfa, t)) { - pb = buf; + init_buf(&buf, &bsize, LINE_INCR); + cnt = 0; sptr = t; - while (sptr < patbeg) - *pb++ = *sptr++; + len = patbeg - sptr; + if (len > 0) { + expand_buf(&buf, &bsize, cnt + len); + (void) memcpy(buf, sptr, len); + cnt += len; + } sptr = getsval(y); - while (*sptr != 0 && pb < buf + RECSIZE - 1) + while (*sptr != 0) { + expand_buf(&buf, &bsize, cnt); if (*sptr == '\\' && *(sptr+1) == '&') { sptr++; /* skip \, */ - *pb++ = *sptr++; /* add & */ + buf[cnt++] = *sptr++; /* add & */ } else if (*sptr == '&') { + expand_buf(&buf, &bsize, cnt + patlen); sptr++; - for (q = patbeg; q < patbeg+patlen; ) - *pb++ = *q++; - } else - *pb++ = *sptr++; - *pb = '\0'; - if (pb >= buf + RECSIZE) - ERROR "sub() result %.20s too big", buf FATAL; + (void) memcpy(&buf[cnt], patbeg, patlen); + cnt += patlen; + } else { + buf[cnt++] = *sptr++; + } + } sptr = patbeg + patlen; - if ((patlen == 0 && *patbeg) || (patlen && *(sptr-1))) - while (*pb++ = *sptr++) - ; - if (pb >= buf + RECSIZE) - ERROR "sub() result %.20s too big", buf FATAL; - setsval(x, buf); - result = true;; + if ((patlen == 0 && *patbeg) || (patlen && *(sptr-1))) { + len = strlen((char *)sptr); + expand_buf(&buf, &bsize, cnt + len); + (void) memcpy(&buf[cnt], sptr, len); + cnt += len; + } + buf[cnt] = '\0'; + (void) setsval(x, buf); + free(buf); + result = true; } tempfree(x, ""); tempfree(y, ""); - return result; + return (result); } -Cell *gsub(a, nnn) Node **a; +/*ARGSUSED*/ +Cell * +gsub(Node **a, int nnn) { register Cell *x, *y; - register uchar *rptr, *sptr, *t, *pb; - uchar buf[RECSIZE]; + register uchar *rptr, *sptr, *t; + uchar *buf; register fa *pfa; int mflag, tempstat, num; + size_t bsize, cnt, len; mflag = 0; /* if mflag == 0, can replace empty string */ num = 0; @@ -1578,75 +1819,80 @@ Cell *gsub(a, nnn) Node **a; if (pmatch(pfa, t)) { tempstat = pfa->initstat; pfa->initstat = 2; - pb = buf; + init_buf(&buf, &bsize, LINE_INCR); rptr = getsval(y); + cnt = 0; do { - /* - uchar *p; - int i; - printf("target string: %s, *patbeg = %o, patlen = %d\n", - t, *patbeg, patlen); - printf(" match found: "); - p=patbeg; - for (i=0; i<patlen; i++) - printf("%c", *p++); - printf("\n"); - */ - if (patlen == 0 && *patbeg != 0) { /* matched empty string */ + if (patlen == 0 && *patbeg != 0) { + /* matched empty string */ if (mflag == 0) { /* can replace empty */ num++; sptr = rptr; - while (*sptr != 0 && pb < buf + RECSIZE-1) - if (*sptr == '\\' && *(sptr+1) == '&') { + while (*sptr != 0) { + expand_buf(&buf, &bsize, cnt); + if (*sptr == '\\' && + *(sptr+1) == '&') { sptr++; - *pb++ = *sptr++; + buf[cnt++] = *sptr++; } else if (*sptr == '&') { - uchar *q; + expand_buf(&buf, + &bsize, + cnt + patlen); sptr++; - for (q = patbeg; q < patbeg+patlen; ) - *pb++ = *q++; - } else - *pb++ = *sptr++; + (void) memcpy(&buf[cnt], + patbeg, patlen); + cnt += patlen; + } else { + buf[cnt++] = *sptr++; + } + } } if (*t == 0) /* at end */ goto done; - *pb++ = *t++; - if (pb >= buf + RECSIZE) - ERROR "gsub() result %.20s too big", buf FATAL; + expand_buf(&buf, &bsize, cnt); + buf[cnt++] = *t++; mflag = 0; - } - else { /* matched nonempty string */ + } else { /* matched nonempty string */ num++; sptr = t; - while (sptr < patbeg && pb < buf + RECSIZE-1) - *pb++ = *sptr++; + len = patbeg - sptr; + if (len > 0) { + expand_buf(&buf, &bsize, cnt + len); + (void) memcpy(&buf[cnt], sptr, len); + cnt += len; + } sptr = rptr; - while (*sptr != 0 && pb < buf + RECSIZE-1) + while (*sptr != 0) { + expand_buf(&buf, &bsize, cnt); if (*sptr == '\\' && *(sptr+1) == '&') { sptr++; - *pb++ = *sptr++; + buf[cnt++] = *sptr++; } else if (*sptr == '&') { - uchar *q; + expand_buf(&buf, &bsize, + cnt + patlen); sptr++; - for (q = patbeg; q < patbeg+patlen; ) - *pb++ = *q++; - } else - *pb++ = *sptr++; + (void) memcpy(&buf[cnt], + patbeg, patlen); + cnt += patlen; + } else { + buf[cnt++] = *sptr++; + } + } t = patbeg + patlen; if ((*(t-1) == 0) || (*t == 0)) goto done; - if (pb >= buf + RECSIZE) - ERROR "gsub() result %.20s too big", buf FATAL; mflag = 1; } - } while (pmatch(pfa,t)); + } while (pmatch(pfa, t)); sptr = t; - while (*pb++ = *sptr++) - ; - done: if (pb >= buf + RECSIZE) - ERROR "gsub() result %.20s too big", buf FATAL; - *pb = '\0'; - setsval(x, buf); + len = strlen((char *)sptr); + expand_buf(&buf, &bsize, len + cnt); + (void) memcpy(&buf[cnt], sptr, len); + cnt += len; + done: + buf[cnt] = '\0'; + (void) setsval(x, buf); + free(buf); pfa->initstat = tempstat; } tempfree(x, ""); @@ -1654,5 +1900,5 @@ Cell *gsub(a, nnn) Node **a; x = gettemp(""); x->tval = NUM; x->fval = num; - return(x); + return (x); } diff --git a/usr/src/cmd/awk/tran.c b/usr/src/cmd/awk/tran.c index 8ea858ef80..0541e62b67 100644 --- a/usr/src/cmd/awk/tran.c +++ b/usr/src/cmd/awk/tran.c @@ -19,20 +19,20 @@ * * CDDL HEADER END */ -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 2.13 */ +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ +#pragma ident "%Z%%M% %I% %E% SMI" #define DEBUG #include <stdio.h> +#include <stdlib.h> #include <ctype.h> #include <string.h> #include "awk.h" @@ -47,7 +47,7 @@ uchar **FS; /* initial field sep */ uchar **RS; /* initial record sep */ uchar **OFS; /* output field sep */ uchar **ORS; /* output record sep */ -uchar **OFMT; /* output format for numbers*/ +uchar **OFMT; /* output format for numbers */ Awkfloat *NF; /* number of fields in current record */ Awkfloat *NR; /* number of current record */ Awkfloat *FNR; /* number of current record in current file */ @@ -70,125 +70,134 @@ Cell *symtabloc; /* SYMTAB */ Cell *nullloc; Node *nullnode; /* zero&null, converted into a node for comparisons */ -extern Node *valtonode(); -extern Cell fldtab[]; -extern uchar recdata[]; +static void rehash(Array *); -syminit() +void +syminit(void) { - int i; + Cell *p; + + init_buf(&recdata, &record_size, LINE_INCR); + record = recdata; + + p = getfld(0); + /* initialize $0 */ + p->nval = (uchar*) "$0"; + p->sval = recdata; + p->tval = REC|STR|DONTFREE; - fldtab[0].ctype = OCELL; - fldtab[0].csub = CFLD; - fldtab[0].nval = (uchar*) "$0"; - fldtab[0].sval = recdata; - fldtab[0].fval = 0.0; - fldtab[0].tval = REC|STR|DONTFREE; - - for (i = 1; i < MAXFLD; i++) { - fldtab[i].ctype = OCELL; - fldtab[i].csub = CFLD; - fldtab[i].nval = NULL; - fldtab[i].sval = (uchar*) ""; - fldtab[i].fval = 0.0; - fldtab[i].tval = FLD|STR|DONTFREE; - } symtab = makesymtab(NSYMTAB); - setsymtab("0", "0", 0.0, NUM|STR|CON|DONTFREE, symtab); + (void) setsymtab((uchar *)"0", (uchar *)"0", 0.0, + NUM|STR|CON|DONTFREE, symtab); /* this is used for if(x)... tests: */ - nullloc = setsymtab("$zero&null", "", 0.0, NUM|STR|CON|DONTFREE, symtab); + nullloc = setsymtab((uchar *)"$zero&null", (uchar *)"", 0.0, + NUM|STR|CON|DONTFREE, symtab); nullnode = valtonode(nullloc, CCON); - /* recloc = setsymtab("$0", record, 0.0, REC|STR|DONTFREE, symtab); */ - recloc = &fldtab[0]; - FS = &setsymtab("FS", " ", 0.0, STR|DONTFREE, symtab)->sval; - RS = &setsymtab("RS", "\n", 0.0, STR|DONTFREE, symtab)->sval; - OFS = &setsymtab("OFS", " ", 0.0, STR|DONTFREE, symtab)->sval; - ORS = &setsymtab("ORS", "\n", 0.0, STR|DONTFREE, symtab)->sval; - OFMT = &setsymtab("OFMT", "%.6g", 0.0, STR|DONTFREE, symtab)->sval; - FILENAME = &setsymtab("FILENAME", "-", 0.0, STR|DONTFREE, symtab)->sval; - nfloc = setsymtab("NF", "", 0.0, NUM, symtab); + recloc = getfld(0); + FS = &setsymtab((uchar *)"FS", (uchar *)" ", 0.0, + STR|DONTFREE, symtab)->sval; + RS = &setsymtab((uchar *)"RS", (uchar *)"\n", 0.0, + STR|DONTFREE, symtab)->sval; + OFS = &setsymtab((uchar *)"OFS", (uchar *)" ", 0.0, + STR|DONTFREE, symtab)->sval; + ORS = &setsymtab((uchar *)"ORS", (uchar *)"\n", 0.0, + STR|DONTFREE, symtab)->sval; + OFMT = &setsymtab((uchar *)"OFMT", (uchar *)"%.6g", 0.0, + STR|DONTFREE, symtab)->sval; + FILENAME = &setsymtab((uchar *)"FILENAME", (uchar *)"-", 0.0, + STR|DONTFREE, symtab)->sval; + nfloc = setsymtab((uchar *)"NF", (uchar *)"", 0.0, NUM, symtab); NF = &nfloc->fval; - nrloc = setsymtab("NR", "", 0.0, NUM, symtab); + nrloc = setsymtab((uchar *)"NR", (uchar *)"", 0.0, NUM, symtab); NR = &nrloc->fval; - fnrloc = setsymtab("FNR", "", 0.0, NUM, symtab); + fnrloc = setsymtab((uchar *)"FNR", (uchar *)"", 0.0, NUM, symtab); FNR = &fnrloc->fval; - SUBSEP = &setsymtab("SUBSEP", "\034", 0.0, STR|DONTFREE, symtab)->sval; - rstartloc = setsymtab("RSTART", "", 0.0, NUM, symtab); + SUBSEP = &setsymtab((uchar *)"SUBSEP", (uchar *)"\034", 0.0, + STR|DONTFREE, symtab)->sval; + rstartloc = setsymtab((uchar *)"RSTART", (uchar *)"", 0.0, + NUM, symtab); RSTART = &rstartloc->fval; - rlengthloc = setsymtab("RLENGTH", "", 0.0, NUM, symtab); + rlengthloc = setsymtab((uchar *)"RLENGTH", (uchar *)"", 0.0, + NUM, symtab); RLENGTH = &rlengthloc->fval; - symtabloc = setsymtab("SYMTAB", "", 0.0, ARR, symtab); - symtabloc->sval = (uchar *) symtab; + symtabloc = setsymtab((uchar *)"SYMTAB", (uchar *)"", 0.0, ARR, symtab); + symtabloc->sval = (uchar *)symtab; } -arginit(ac, av) - int ac; - uchar *av[]; +void +arginit(int ac, uchar *av[]) { Cell *cp; - Array *makesymtab(); int i; - uchar temp[5]; + uchar temp[11]; - for (i = 1; i < ac; i++) /* first make FILENAME first real argument */ + /* first make FILENAME first real argument */ + for (i = 1; i < ac; i++) { if (!isclvar(av[i])) { - setsval(lookup("FILENAME", symtab), av[i]); + (void) setsval(lookup((uchar *)"FILENAME", symtab), + av[i]); break; } - ARGC = &setsymtab("ARGC", "", (Awkfloat) ac, NUM, symtab)->fval; - cp = setsymtab("ARGV", "", 0.0, ARR, symtab); + } + ARGC = &setsymtab((uchar *)"ARGC", (uchar *)"", (Awkfloat)ac, + NUM, symtab)->fval; + cp = setsymtab((uchar *)"ARGV", (uchar *)"", 0.0, ARR, symtab); ARGVtab = makesymtab(NSYMTAB); /* could be (int) ARGC as well */ cp->sval = (uchar *) ARGVtab; for (i = 0; i < ac; i++) { - sprintf((char *)temp, "%d", i); - if (isnumber(*av)) - setsymtab(temp, *av, atof(*av), STR|NUM, ARGVtab); - else - setsymtab(temp, *av, 0.0, STR, ARGVtab); + (void) sprintf((char *)temp, "%d", i); + if (is_number(*av)) { + (void) setsymtab(temp, *av, atof((const char *)*av), + STR|NUM, ARGVtab); + } else { + (void) setsymtab(temp, *av, 0.0, STR, ARGVtab); + } av++; } } -envinit(envp) - uchar *envp[]; +void +envinit(uchar *envp[]) { Cell *cp; - Array *makesymtab(); uchar *p; - cp = setsymtab("ENVIRON", "", 0.0, ARR, symtab); + cp = setsymtab((uchar *)"ENVIRON", (uchar *)"", 0.0, ARR, symtab); ENVtab = makesymtab(NSYMTAB); cp->sval = (uchar *) ENVtab; - for ( ; *envp; envp++) { - if ((p = (uchar *) strchr((char *) *envp, '=')) == NULL) /* index() on bsd */ + for (; *envp; envp++) { + if ((p = (uchar *)strchr((char *)*envp, '=')) == NULL) continue; *p++ = 0; /* split into two strings at = */ - if (isnumber(p)) - setsymtab(*envp, p, atof(p), STR|NUM, ENVtab); - else - setsymtab(*envp, p, 0.0, STR, ENVtab); - p[-1] = '='; /* restore in case env is passed down to a shell */ + if (is_number(p)) { + (void) setsymtab(*envp, p, atof((const char *)p), + STR|NUM, ENVtab); + } else { + (void) setsymtab(*envp, p, 0.0, STR, ENVtab); + } + /* restore in case env is passed down to a shell */ + p[-1] = '='; } } -Array *makesymtab(n) - int n; +Array * +makesymtab(int n) { Array *ap; Cell **tp; - ap = (Array *) malloc(sizeof(Array)); - tp = (Cell **) calloc(n, sizeof(Cell *)); + ap = (Array *)malloc(sizeof (Array)); + tp = (Cell **)calloc(n, sizeof (Cell *)); if (ap == NULL || tp == NULL) ERROR "out of space in makesymtab" FATAL; ap->nelem = 0; ap->size = n; ap->tab = tp; - return(ap); + return (ap); } -freesymtab(ap) /* free symbol table */ - Cell *ap; +void +freesymtab(Cell *ap) /* free symbol table */ { Cell *cp, *next; Array *tp; @@ -196,7 +205,8 @@ freesymtab(ap) /* free symbol table */ if (!isarr(ap)) return; - tp = (Array *) ap->sval; + /*LINTED align*/ + tp = (Array *)ap->sval; if (tp == NULL) return; for (i = 0; i < tp->size; i++) { @@ -212,18 +222,18 @@ freesymtab(ap) /* free symbol table */ free(tp); } -freeelem(ap, s) /* free elem s from ap (i.e., ap["s"] */ - Cell *ap; - uchar *s; +void +freeelem(Cell *ap, uchar *s) /* free elem s from ap (i.e., ap["s"] */ { Array *tp; Cell *p, *prev = NULL; int h; - - tp = (Array *) ap->sval; + + /*LINTED align*/ + tp = (Array *)ap->sval; h = hash(s, tp->size); for (p = tp->tab[h]; p != NULL; prev = p, p = p->cnext) - if (strcmp((char *) s, (char *) p->nval) == 0) { + if (strcmp((char *)s, (char *)p->nval) == 0) { if (prev == NULL) /* 1st one */ tp->tab[h] = p->cnext; else /* middle somewhere */ @@ -237,26 +247,23 @@ freeelem(ap, s) /* free elem s from ap (i.e., ap["s"] */ } } -Cell *setsymtab(n, s, f, t, tp) - uchar *n, *s; - Awkfloat f; - unsigned t; - Array *tp; +Cell * +setsymtab(uchar *n, uchar *s, Awkfloat f, unsigned int t, Array *tp) { register int h; register Cell *p; - Cell *lookup(); if (n != NULL && (p = lookup(n, tp)) != NULL) { - dprintf( ("setsymtab found %o: n=%s", p, p->nval) ); - dprintf( (" s=\"%s\" f=%g t=%o\n", p->sval, p->fval, p->tval) ); - return(p); + dprintf(("setsymtab found %p: n=%s", (void *)p, p->nval)); + dprintf((" s=\"%s\" f=%g t=%p\n", + p->sval, p->fval, (void *)p->tval)); + return (p); } - p = (Cell *) malloc(sizeof(Cell)); + p = (Cell *)malloc(sizeof (Cell)); if (p == NULL) ERROR "symbol table overflow at %s", n FATAL; p->nval = tostring(n); - p->sval = s ? tostring(s) : tostring(""); + p->sval = s ? tostring(s) : tostring((uchar *)""); p->fval = f; p->tval = t; p->csub = 0; @@ -267,30 +274,29 @@ Cell *setsymtab(n, s, f, t, tp) h = hash(n, tp->size); p->cnext = tp->tab[h]; tp->tab[h] = p; - dprintf( ("setsymtab set %o: n=%s", p, p->nval) ); - dprintf( (" s=\"%s\" f=%g t=%o\n", p->sval, p->fval, p->tval) ); - return(p); + dprintf(("setsymtab set %p: n=%s", (void *)p, p->nval)); + dprintf((" s=\"%s\" f=%g t=%p\n", p->sval, p->fval, (void *)p->tval)); + return (p); } -hash(s, n) /* form hash value for string s */ - register uchar *s; - int n; +int +hash(uchar *s, int n) /* form hash value for string s */ { register unsigned hashval; for (hashval = 0; *s != '\0'; s++) hashval = (*s + 31 * hashval); - return hashval % n; + return (hashval % n); } -rehash(tp) /* rehash items in small table into big one */ - Array *tp; +static void +rehash(Array *tp) /* rehash items in small table into big one */ { int i, nh, nsz; Cell *cp, *op, **np; nsz = GROWTAB * tp->size; - np = (Cell **) calloc(nsz, sizeof(Cell *)); + np = (Cell **)calloc(nsz, sizeof (Cell *)); if (np == NULL) ERROR "out of space in rehash" FATAL; for (i = 0; i < tp->size; i++) { @@ -306,66 +312,69 @@ rehash(tp) /* rehash items in small table into big one */ tp->size = nsz; } -Cell *lookup(s, tp) /* look for s in tp */ - register uchar *s; - Array *tp; +Cell * +lookup(uchar *s, Array *tp) /* look for s in tp */ { - register Cell *p, *prev = NULL; + register Cell *p; int h; h = hash(s, tp->size); - for (p = tp->tab[h]; p != NULL; prev = p, p = p->cnext) - if (strcmp((char *) s, (char *) p->nval) == 0) - return(p); /* found it */ - return(NULL); /* not found */ + for (p = tp->tab[h]; p != NULL; p = p->cnext) { + if (strcmp((char *)s, (char *)p->nval) == 0) + return (p); /* found it */ + } + return (NULL); /* not found */ } -Awkfloat setfval(vp, f) - register Cell *vp; - Awkfloat f; +Awkfloat +setfval(Cell *vp, Awkfloat f) { - if ((vp->tval & (NUM | STR)) == 0) + int i; + + if ((vp->tval & (NUM | STR)) == 0) funnyvar(vp, "assign to"); if (vp->tval & FLD) { donerec = 0; /* mark $0 invalid */ - if (vp-fldtab > *NF) - newfld(vp-fldtab); - dprintf( ("setting field %d to %g\n", vp-fldtab, f) ); + i = fldidx(vp); + if (i > *NF) + newfld(i); + dprintf(("setting field %d to %g\n", i, f)); } else if (vp->tval & REC) { donefld = 0; /* mark $1... invalid */ donerec = 1; } vp->tval &= ~STR; /* mark string invalid */ vp->tval |= NUM; /* mark number ok */ - dprintf( ("setfval %p: %s = %g, t=%o\n", vp, - vp->nval ? vp->nval : (unsigned char *)"NULL", - f, vp->tval) ); - return vp->fval = f; + dprintf(("setfval %p: %s = %g, t=%p\n", (void *)vp, + vp->nval ? vp->nval : (unsigned char *)"NULL", + f, (void *)vp->tval)); + return (vp->fval = f); } -funnyvar(vp, rw) - Cell *vp; - char *rw; +void +funnyvar(Cell *vp, char *rw) { if (vp->tval & ARR) ERROR "can't %s %s; it's an array name.", rw, vp->nval FATAL; if (vp->tval & FCN) ERROR "can't %s %s; it's a function.", rw, vp->nval FATAL; ERROR "funny variable %o: n=%s s=\"%s\" f=%g t=%o", - vp, vp->nval, vp->sval, vp->fval, vp->tval); + vp, vp->nval, vp->sval, vp->fval, vp->tval CONT; } -uchar *setsval(vp, s) -register Cell *vp; -uchar *s; +uchar * +setsval(Cell *vp, uchar *s) { + int i; + if ((vp->tval & (NUM | STR)) == 0) funnyvar(vp, "assign to"); if (vp->tval & FLD) { donerec = 0; /* mark $0 invalid */ - if (vp-fldtab > *NF) - newfld(vp-fldtab); - dprintf( ("setting field %d to %s\n", vp-fldtab, s) ); + i = fldidx(vp); + if (i > *NF) + newfld(i); + dprintf(("setting field %d to %s\n", i, s)); } else if (vp->tval & REC) { donefld = 0; /* mark $1... invalid */ donerec = 1; @@ -375,16 +384,17 @@ uchar *s; if (freeable(vp)) xfree(vp->sval); vp->tval &= ~DONTFREE; - dprintf( ("setsval %o: %s = \"%s\", t=%o\n", vp, vp->nval, s, vp->tval) ); - return(vp->sval = tostring(s)); + dprintf(("setsval %p: %s = \"%s\", t=%p\n", + (void *)vp, + vp->nval ? (char *)vp->nval : "", + s, + (void *)(vp->tval ? (char *)vp->tval : ""))); + return (vp->sval = tostring(s)); } -Awkfloat r_getfval(vp) -register Cell *vp; +Awkfloat +r_getfval(Cell *vp) { - /* if (vp->tval & ARR) - ERROR "illegal reference to array %s", vp->nval FATAL; - return 0.0; */ if ((vp->tval & (NUM | STR)) == 0) funnyvar(vp, "read value of"); if ((vp->tval & FLD) && donefld == 0) @@ -392,22 +402,20 @@ register Cell *vp; else if ((vp->tval & REC) && donerec == 0) recbld(); if (!isnum(vp)) { /* not a number */ - vp->fval = atof(vp->sval); /* best guess */ - if (isnumber(vp->sval) && !(vp->tval&CON)) + vp->fval = atof((const char *)vp->sval); /* best guess */ + if (is_number(vp->sval) && !(vp->tval&CON)) vp->tval |= NUM; /* make NUM only sparingly */ } - dprintf( ("getfval %o: %s = %g, t=%o\n", vp, vp->nval, vp->fval, vp->tval) ); - return(vp->fval); + dprintf(("getfval %p: %s = %g, t=%p\n", + (void *)vp, vp->nval, vp->fval, (void *)vp->tval)); + return (vp->fval); } -uchar *r_getsval(vp) -register Cell *vp; +uchar * +r_getsval(Cell *vp) { - uchar s[100]; + uchar s[256]; - /* if (vp->tval & ARR) - ERROR "illegal reference to array %s", vp->nval FATAL; - return ""; */ if ((vp->tval & (NUM | STR)) == 0) funnyvar(vp, "read value of"); if ((vp->tval & FLD) && donefld == 0) @@ -417,55 +425,65 @@ register Cell *vp; if ((vp->tval & STR) == 0) { if (!(vp->tval&DONTFREE)) xfree(vp->sval); - if ((long long)vp->fval == vp->fval) - sprintf((char *)s, "%.20g", vp->fval); - else - sprintf((char *)s, (char *)*OFMT, vp->fval); + if ((long long)vp->fval == vp->fval) { + (void) snprintf((char *)s, sizeof (s), + "%.20g", vp->fval); + } else { + /*LINTED*/ + (void) snprintf((char *)s, sizeof (s), + (char *)*OFMT, vp->fval); + } vp->sval = tostring(s); vp->tval &= ~DONTFREE; vp->tval |= STR; } - dprintf( ("getsval %p: %s = \"%s\", t=%o\n", vp, vp->nval, vp->sval, vp->tval) ); - return(vp->sval); + dprintf(("getsval %p: %s = \"%s\", t=%p\n", + (void *)vp, + vp->nval ? (char *)vp->nval : "", + vp->sval ? (char *)vp->sval : "", + (void *)vp->tval)); + return (vp->sval); } -uchar *tostring(s) -register uchar *s; +uchar * +tostring(uchar *s) { register uchar *p; - p = (uchar *) malloc(strlen((char *) s)+1); + p = (uchar *)malloc(strlen((char *)s)+1); if (p == NULL) ERROR "out of space in tostring on %s", s FATAL; - strcpy((char *) p, (char *) s); - return(p); + (void) strcpy((char *)p, (char *)s); + return (p); } -uchar *qstring(s, delim) /* collect string up to delim */ - uchar *s; - int delim; +uchar * +qstring(uchar *s, int delim) /* collect string up to delim */ { - uchar *q; + uchar *cbuf, *ret; int c, n; + size_t cbufsz, cnt; + + init_buf(&cbuf, &cbufsz, LINE_INCR); - for (q = cbuf; (c = *s) != delim; s++) { - if (q >= cbuf + RECSIZE - 1) - ERROR "string %.10s... too long", cbuf SYNTAX; - else if (c == '\n') + for (cnt = 0; (c = *s) != delim; s++) { + if (c == '\n') { ERROR "newline in string %.10s...", cbuf SYNTAX; - else if (c != '\\') - *q++ = c; - else /* \something */ + } else if (c != '\\') { + expand_buf(&cbuf, &cbufsz, cnt); + cbuf[cnt++] = c; + } else { /* \something */ + expand_buf(&cbuf, &cbufsz, cnt); switch (c = *++s) { - case '\\': *q++ = '\\'; break; - case 'n': *q++ = '\n'; break; - case 't': *q++ = '\t'; break; - case 'b': *q++ = '\b'; break; - case 'f': *q++ = '\f'; break; - case 'r': *q++ = '\r'; break; + case '\\': cbuf[cnt++] = '\\'; break; + case 'n': cbuf[cnt++] = '\n'; break; + case 't': cbuf[cnt++] = '\t'; break; + case 'b': cbuf[cnt++] = '\b'; break; + case 'f': cbuf[cnt++] = '\f'; break; + case 'r': cbuf[cnt++] = '\r'; break; default: if (!isdigit(c)) { - *q++ = c; + cbuf[cnt++] = c; break; } n = c - '0'; @@ -474,10 +492,13 @@ uchar *qstring(s, delim) /* collect string up to delim */ if (isdigit(s[1])) n = 8 * n + *++s - '0'; } - *q++ = n; + cbuf[cnt++] = n; break; } + } } - *q = '\0'; - return cbuf; + cbuf[cnt] = '\0'; + ret = tostring(cbuf); + free(cbuf); + return (ret); } |