185587Sobrien/**************************************************************** 285587SobrienCopyright (C) Lucent Technologies 1997 385587SobrienAll Rights Reserved 485587Sobrien 585587SobrienPermission to use, copy, modify, and distribute this software and 685587Sobrienits documentation for any purpose and without fee is hereby 785587Sobriengranted, provided that the above copyright notice appear in all 885587Sobriencopies and that both that the copyright notice and this 985587Sobrienpermission notice and warranty disclaimer appear in supporting 1085587Sobriendocumentation, and that the name Lucent Technologies or any of 1185587Sobrienits entities not be used in advertising or publicity pertaining 1285587Sobriento distribution of the software without specific, written prior 1385587Sobrienpermission. 1485587Sobrien 1585587SobrienLUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1685587SobrienINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 1785587SobrienIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 1885587SobrienSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1985587SobrienWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 2085587SobrienIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 2185587SobrienARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 2285587SobrienTHIS SOFTWARE. 2385587Sobrien****************************************************************/ 2485587Sobrien 25146299Sru#include <assert.h> 26146299Sru 2785587Sobrientypedef double Awkfloat; 2885587Sobrien 2985587Sobrien/* unsigned char is more trouble than it's worth */ 3085587Sobrien 3185587Sobrientypedef unsigned char uschar; 3285587Sobrien 33170331Srafan#define xfree(a) { if ((a) != NULL) { free((void *) (a)); (a) = NULL; } } 3485587Sobrien 35107806Sobrien#define NN(p) ((p) ? (p) : "(null)") /* guaranteed non-null for dprintf 36107806Sobrien*/ 3785587Sobrien#define DEBUG 3885587Sobrien#ifdef DEBUG 3985587Sobrien /* uses have to be doubly parenthesized */ 4085587Sobrien# define dprintf(x) if (dbg) printf x 4185587Sobrien#else 4285587Sobrien# define dprintf(x) 4385587Sobrien#endif 4485587Sobrien 4585587Sobrienextern int compile_time; /* 1 if compiling, 0 if running */ 4685587Sobrienextern int safe; /* 0 => unsafe, 1 => safe */ 4785587Sobrien 4885587Sobrien#define RECSIZE (8 * 1024) /* sets limit on records, fields, etc., etc. */ 4985587Sobrienextern int recsize; /* size of current record, orig RECSIZE */ 5085587Sobrien 5185587Sobrienextern char **FS; 5285587Sobrienextern char **RS; 5385587Sobrienextern char **ORS; 5485587Sobrienextern char **OFS; 5585587Sobrienextern char **OFMT; 5685587Sobrienextern Awkfloat *NR; 5785587Sobrienextern Awkfloat *FNR; 5885587Sobrienextern Awkfloat *NF; 5985587Sobrienextern char **FILENAME; 6085587Sobrienextern char **SUBSEP; 6185587Sobrienextern Awkfloat *RSTART; 6285587Sobrienextern Awkfloat *RLENGTH; 6385587Sobrien 6485587Sobrienextern char *record; /* points to $0 */ 6585587Sobrienextern int lineno; /* line number in awk program */ 6685587Sobrienextern int errorflag; /* 1 if error has occurred */ 6785587Sobrienextern int donefld; /* 1 if record broken into fields */ 6885587Sobrienextern int donerec; /* 1 if record is valid (no fld has changed */ 6985587Sobrienextern char inputFS[]; /* FS at time of input, for field splitting */ 7085587Sobrien 7185587Sobrienextern int dbg; 7285587Sobrien 7385587Sobrienextern char *patbeg; /* beginning of pattern matched */ 7485587Sobrienextern int patlen; /* length of pattern matched. set in b.c */ 7585587Sobrien 7685587Sobrien/* Cell: all information about a variable or constant */ 7785587Sobrien 7885587Sobrientypedef struct Cell { 7985587Sobrien uschar ctype; /* OCELL, OBOOL, OJUMP, etc. */ 8085587Sobrien uschar csub; /* CCON, CTEMP, CFLD, etc. */ 8185587Sobrien char *nval; /* name, for variables only */ 8285587Sobrien char *sval; /* string value */ 8385587Sobrien Awkfloat fval; /* value as number */ 8485587Sobrien int tval; /* type info: STR|NUM|ARR|FCN|FLD|CON|DONTFREE */ 8585587Sobrien struct Cell *cnext; /* ptr to next if chained */ 8685587Sobrien} Cell; 8785587Sobrien 8885587Sobrientypedef struct Array { /* symbol table array */ 8985587Sobrien int nelem; /* elements in table right now */ 9085587Sobrien int size; /* size of tab */ 9185587Sobrien Cell **tab; /* hash table pointers */ 9285587Sobrien} Array; 9385587Sobrien 9485587Sobrien#define NSYMTAB 50 /* initial size of a symbol table */ 9585587Sobrienextern Array *symtab; 9685587Sobrien 9785587Sobrienextern Cell *nrloc; /* NR */ 9885587Sobrienextern Cell *fnrloc; /* FNR */ 9985587Sobrienextern Cell *nfloc; /* NF */ 10085587Sobrienextern Cell *rstartloc; /* RSTART */ 10185587Sobrienextern Cell *rlengthloc; /* RLENGTH */ 10285587Sobrien 10385587Sobrien/* Cell.tval values: */ 10485587Sobrien#define NUM 01 /* number value is valid */ 10585587Sobrien#define STR 02 /* string value is valid */ 10685587Sobrien#define DONTFREE 04 /* string space is not freeable */ 10785587Sobrien#define CON 010 /* this is a constant */ 10885587Sobrien#define ARR 020 /* this is an array */ 10985587Sobrien#define FCN 040 /* this is a function name */ 11085587Sobrien#define FLD 0100 /* this is a field $1, $2, ... */ 11185587Sobrien#define REC 0200 /* this is $0 */ 11285587Sobrien 11385587Sobrien 11485587Sobrien/* function types */ 11585587Sobrien#define FLENGTH 1 11685587Sobrien#define FSQRT 2 11785587Sobrien#define FEXP 3 11885587Sobrien#define FLOG 4 11985587Sobrien#define FINT 5 12085587Sobrien#define FSYSTEM 6 12185587Sobrien#define FRAND 7 12285587Sobrien#define FSRAND 8 12385587Sobrien#define FSIN 9 12485587Sobrien#define FCOS 10 12585587Sobrien#define FATAN 11 12685587Sobrien#define FTOUPPER 12 12785587Sobrien#define FTOLOWER 13 12885587Sobrien#define FFLUSH 14 12985587Sobrien 13085587Sobrien/* Node: parse tree is made of nodes, with Cell's at bottom */ 13185587Sobrien 13285587Sobrientypedef struct Node { 13385587Sobrien int ntype; 13485587Sobrien struct Node *nnext; 13585587Sobrien int lineno; 13685587Sobrien int nobj; 13785587Sobrien struct Node *narg[1]; /* variable: actual size set by calling malloc */ 13885587Sobrien} Node; 13985587Sobrien 14085587Sobrien#define NIL ((Node *) 0) 14185587Sobrien 14285587Sobrienextern Node *winner; 14385587Sobrienextern Node *nullstat; 14485587Sobrienextern Node *nullnode; 14585587Sobrien 14685587Sobrien/* ctypes */ 14785587Sobrien#define OCELL 1 14885587Sobrien#define OBOOL 2 14985587Sobrien#define OJUMP 3 15085587Sobrien 15185587Sobrien/* Cell subtypes: csub */ 15285587Sobrien#define CFREE 7 15385587Sobrien#define CCOPY 6 15485587Sobrien#define CCON 5 15585587Sobrien#define CTEMP 4 15685587Sobrien#define CNAME 3 15785587Sobrien#define CVAR 2 15885587Sobrien#define CFLD 1 15985587Sobrien#define CUNK 0 16085587Sobrien 16185587Sobrien/* bool subtypes */ 16285587Sobrien#define BTRUE 11 16385587Sobrien#define BFALSE 12 16485587Sobrien 16585587Sobrien/* jump subtypes */ 16685587Sobrien#define JEXIT 21 16785587Sobrien#define JNEXT 22 16885587Sobrien#define JBREAK 23 16985587Sobrien#define JCONT 24 17085587Sobrien#define JRET 25 17185587Sobrien#define JNEXTFILE 26 17285587Sobrien 17385587Sobrien/* node types */ 17485587Sobrien#define NVALUE 1 17585587Sobrien#define NSTAT 2 17685587Sobrien#define NEXPR 3 17785587Sobrien 17885587Sobrien 17985587Sobrienextern int pairstack[], paircnt; 18085587Sobrien 18185587Sobrien#define notlegal(n) (n <= FIRSTTOKEN || n >= LASTTOKEN || proctab[n-FIRSTTOKEN] == nullproc) 18285587Sobrien#define isvalue(n) ((n)->ntype == NVALUE) 18385587Sobrien#define isexpr(n) ((n)->ntype == NEXPR) 18485587Sobrien#define isjump(n) ((n)->ctype == OJUMP) 18585587Sobrien#define isexit(n) ((n)->csub == JEXIT) 18685587Sobrien#define isbreak(n) ((n)->csub == JBREAK) 18785587Sobrien#define iscont(n) ((n)->csub == JCONT) 18885587Sobrien#define isnext(n) ((n)->csub == JNEXT || (n)->csub == JNEXTFILE) 18985587Sobrien#define isret(n) ((n)->csub == JRET) 19085587Sobrien#define isrec(n) ((n)->tval & REC) 19185587Sobrien#define isfld(n) ((n)->tval & FLD) 19285587Sobrien#define isstr(n) ((n)->tval & STR) 19385587Sobrien#define isnum(n) ((n)->tval & NUM) 19485587Sobrien#define isarr(n) ((n)->tval & ARR) 19585587Sobrien#define isfcn(n) ((n)->tval & FCN) 19685587Sobrien#define istrue(n) ((n)->csub == BTRUE) 19785587Sobrien#define istemp(n) ((n)->csub == CTEMP) 19885587Sobrien#define isargument(n) ((n)->nobj == ARG) 19985587Sobrien/* #define freeable(p) (!((p)->tval & DONTFREE)) */ 20085587Sobrien#define freeable(p) ( ((p)->tval & (STR|DONTFREE)) == STR ) 20185587Sobrien 20285587Sobrien/* structures used by regular expression matching machinery, mostly b.c: */ 20385587Sobrien 204146299Sru#define NCHARS (256+3) /* 256 handles 8-bit chars; 128 does 7-bit */ 20585587Sobrien /* watch out in match(), etc. */ 20685587Sobrien#define NSTATES 32 20785587Sobrien 20885587Sobrientypedef struct rrow { 20985587Sobrien long ltype; /* long avoids pointer warnings on 64-bit */ 21085587Sobrien union { 21185587Sobrien int i; 21285587Sobrien Node *np; 21385587Sobrien uschar *up; 21485587Sobrien } lval; /* because Al stores a pointer in it! */ 21585587Sobrien int *lfollow; 21685587Sobrien} rrow; 21785587Sobrien 21885587Sobrientypedef struct fa { 21985587Sobrien uschar gototab[NSTATES][NCHARS]; 22085587Sobrien uschar out[NSTATES]; 22185587Sobrien uschar *restr; 22285587Sobrien int *posns[NSTATES]; 22385587Sobrien int anchor; 22485587Sobrien int use; 22585587Sobrien int initstat; 22685587Sobrien int curstat; 22785587Sobrien int accept; 22885587Sobrien int reset; 22985587Sobrien struct rrow re[1]; /* variable: actual size set by calling malloc */ 23085587Sobrien} fa; 23185587Sobrien 23285587Sobrien 23385587Sobrien#include "proto.h" 234