1*74a4d8c2SCharles.Forsyth /**************************************************************** 2*74a4d8c2SCharles.Forsyth Copyright (C) Lucent Technologies 1997 3*74a4d8c2SCharles.Forsyth All Rights Reserved 4*74a4d8c2SCharles.Forsyth 5*74a4d8c2SCharles.Forsyth Permission to use, copy, modify, and distribute this software and 6*74a4d8c2SCharles.Forsyth its documentation for any purpose and without fee is hereby 7*74a4d8c2SCharles.Forsyth granted, provided that the above copyright notice appear in all 8*74a4d8c2SCharles.Forsyth copies and that both that the copyright notice and this 9*74a4d8c2SCharles.Forsyth permission notice and warranty disclaimer appear in supporting 10*74a4d8c2SCharles.Forsyth documentation, and that the name Lucent Technologies or any of 11*74a4d8c2SCharles.Forsyth its entities not be used in advertising or publicity pertaining 12*74a4d8c2SCharles.Forsyth to distribution of the software without specific, written prior 13*74a4d8c2SCharles.Forsyth permission. 14*74a4d8c2SCharles.Forsyth 15*74a4d8c2SCharles.Forsyth LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16*74a4d8c2SCharles.Forsyth INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 17*74a4d8c2SCharles.Forsyth IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 18*74a4d8c2SCharles.Forsyth SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19*74a4d8c2SCharles.Forsyth WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 20*74a4d8c2SCharles.Forsyth IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 21*74a4d8c2SCharles.Forsyth ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 22*74a4d8c2SCharles.Forsyth THIS SOFTWARE. 23*74a4d8c2SCharles.Forsyth ****************************************************************/ 24*74a4d8c2SCharles.Forsyth 25*74a4d8c2SCharles.Forsyth typedef double Awkfloat; 26*74a4d8c2SCharles.Forsyth 27*74a4d8c2SCharles.Forsyth /* unsigned char is more trouble than it's worth */ 28*74a4d8c2SCharles.Forsyth 29*74a4d8c2SCharles.Forsyth typedef unsigned char uschar; 30*74a4d8c2SCharles.Forsyth 31*74a4d8c2SCharles.Forsyth #define xfree(a) { if ((a) != NULL) { free((char *) a); a = NULL; } } 32*74a4d8c2SCharles.Forsyth 33*74a4d8c2SCharles.Forsyth #define DEBUG 34*74a4d8c2SCharles.Forsyth #ifdef DEBUG 35*74a4d8c2SCharles.Forsyth /* uses have to be doubly parenthesized */ 36*74a4d8c2SCharles.Forsyth # define dprintf(x) if (dbg) printf x 37*74a4d8c2SCharles.Forsyth #else 38*74a4d8c2SCharles.Forsyth # define dprintf(x) 39*74a4d8c2SCharles.Forsyth #endif 40*74a4d8c2SCharles.Forsyth 41*74a4d8c2SCharles.Forsyth extern char errbuf[]; 42*74a4d8c2SCharles.Forsyth 43*74a4d8c2SCharles.Forsyth extern int compile_time; /* 1 if compiling, 0 if running */ 44*74a4d8c2SCharles.Forsyth extern int safe; /* 0 => unsafe, 1 => safe */ 45*74a4d8c2SCharles.Forsyth 46*74a4d8c2SCharles.Forsyth #define RECSIZE (8 * 1024) /* sets limit on records, fields, etc., etc. */ 47*74a4d8c2SCharles.Forsyth extern int recsize; /* size of current record, orig RECSIZE */ 48*74a4d8c2SCharles.Forsyth 49*74a4d8c2SCharles.Forsyth extern char **FS; 50*74a4d8c2SCharles.Forsyth extern char **RS; 51*74a4d8c2SCharles.Forsyth extern char **ORS; 52*74a4d8c2SCharles.Forsyth extern char **OFS; 53*74a4d8c2SCharles.Forsyth extern char **OFMT; 54*74a4d8c2SCharles.Forsyth extern Awkfloat *NR; 55*74a4d8c2SCharles.Forsyth extern Awkfloat *FNR; 56*74a4d8c2SCharles.Forsyth extern Awkfloat *NF; 57*74a4d8c2SCharles.Forsyth extern char **FILENAME; 58*74a4d8c2SCharles.Forsyth extern char **SUBSEP; 59*74a4d8c2SCharles.Forsyth extern Awkfloat *RSTART; 60*74a4d8c2SCharles.Forsyth extern Awkfloat *RLENGTH; 61*74a4d8c2SCharles.Forsyth 62*74a4d8c2SCharles.Forsyth extern char *record; /* points to $0 */ 63*74a4d8c2SCharles.Forsyth extern int lineno; /* line number in awk program */ 64*74a4d8c2SCharles.Forsyth extern int errorflag; /* 1 if error has occurred */ 65*74a4d8c2SCharles.Forsyth extern int donefld; /* 1 if record broken into fields */ 66*74a4d8c2SCharles.Forsyth extern int donerec; /* 1 if record is valid (no fld has changed */ 67*74a4d8c2SCharles.Forsyth extern char inputFS[]; /* FS at time of input, for field splitting */ 68*74a4d8c2SCharles.Forsyth 69*74a4d8c2SCharles.Forsyth extern int dbg; 70*74a4d8c2SCharles.Forsyth 71*74a4d8c2SCharles.Forsyth extern char *patbeg; /* beginning of pattern matched */ 72*74a4d8c2SCharles.Forsyth extern int patlen; /* length of pattern matched. set in b.c */ 73*74a4d8c2SCharles.Forsyth 74*74a4d8c2SCharles.Forsyth /* Cell: all information about a variable or constant */ 75*74a4d8c2SCharles.Forsyth 76*74a4d8c2SCharles.Forsyth typedef struct Cell { 77*74a4d8c2SCharles.Forsyth uschar ctype; /* OCELL, OBOOL, OJUMP, etc. */ 78*74a4d8c2SCharles.Forsyth uschar csub; /* CCON, CTEMP, CFLD, etc. */ 79*74a4d8c2SCharles.Forsyth char *nval; /* name, for variables only */ 80*74a4d8c2SCharles.Forsyth char *sval; /* string value */ 81*74a4d8c2SCharles.Forsyth Awkfloat fval; /* value as number */ 82*74a4d8c2SCharles.Forsyth int tval; /* type info: STR|NUM|ARR|FCN|FLD|CON|DONTFREE */ 83*74a4d8c2SCharles.Forsyth struct Cell *cnext; /* ptr to next if chained */ 84*74a4d8c2SCharles.Forsyth } Cell; 85*74a4d8c2SCharles.Forsyth 86*74a4d8c2SCharles.Forsyth typedef struct Array { /* symbol table array */ 87*74a4d8c2SCharles.Forsyth int nelem; /* elements in table right now */ 88*74a4d8c2SCharles.Forsyth int size; /* size of tab */ 89*74a4d8c2SCharles.Forsyth Cell **tab; /* hash table pointers */ 90*74a4d8c2SCharles.Forsyth } Array; 91*74a4d8c2SCharles.Forsyth 92*74a4d8c2SCharles.Forsyth #define NSYMTAB 50 /* initial size of a symbol table */ 93*74a4d8c2SCharles.Forsyth extern Array *symtab; 94*74a4d8c2SCharles.Forsyth 95*74a4d8c2SCharles.Forsyth extern Cell *nrloc; /* NR */ 96*74a4d8c2SCharles.Forsyth extern Cell *fnrloc; /* FNR */ 97*74a4d8c2SCharles.Forsyth extern Cell *nfloc; /* NF */ 98*74a4d8c2SCharles.Forsyth extern Cell *rstartloc; /* RSTART */ 99*74a4d8c2SCharles.Forsyth extern Cell *rlengthloc; /* RLENGTH */ 100*74a4d8c2SCharles.Forsyth 101*74a4d8c2SCharles.Forsyth /* Cell.tval values: */ 102*74a4d8c2SCharles.Forsyth #define NUM 01 /* number value is valid */ 103*74a4d8c2SCharles.Forsyth #define STR 02 /* string value is valid */ 104*74a4d8c2SCharles.Forsyth #define DONTFREE 04 /* string space is not freeable */ 105*74a4d8c2SCharles.Forsyth #define CON 010 /* this is a constant */ 106*74a4d8c2SCharles.Forsyth #define ARR 020 /* this is an array */ 107*74a4d8c2SCharles.Forsyth #define FCN 040 /* this is a function name */ 108*74a4d8c2SCharles.Forsyth #define FLD 0100 /* this is a field $1, $2, ... */ 109*74a4d8c2SCharles.Forsyth #define REC 0200 /* this is $0 */ 110*74a4d8c2SCharles.Forsyth 111*74a4d8c2SCharles.Forsyth 112*74a4d8c2SCharles.Forsyth /* function types */ 113*74a4d8c2SCharles.Forsyth #define FLENGTH 1 114*74a4d8c2SCharles.Forsyth #define FSQRT 2 115*74a4d8c2SCharles.Forsyth #define FEXP 3 116*74a4d8c2SCharles.Forsyth #define FLOG 4 117*74a4d8c2SCharles.Forsyth #define FINT 5 118*74a4d8c2SCharles.Forsyth #define FSYSTEM 6 119*74a4d8c2SCharles.Forsyth #define FRAND 7 120*74a4d8c2SCharles.Forsyth #define FSRAND 8 121*74a4d8c2SCharles.Forsyth #define FSIN 9 122*74a4d8c2SCharles.Forsyth #define FCOS 10 123*74a4d8c2SCharles.Forsyth #define FATAN 11 124*74a4d8c2SCharles.Forsyth #define FTOUPPER 12 125*74a4d8c2SCharles.Forsyth #define FTOLOWER 13 126*74a4d8c2SCharles.Forsyth #define FFLUSH 14 127*74a4d8c2SCharles.Forsyth 128*74a4d8c2SCharles.Forsyth /* Node: parse tree is made of nodes, with Cell's at bottom */ 129*74a4d8c2SCharles.Forsyth 130*74a4d8c2SCharles.Forsyth typedef struct Node { 131*74a4d8c2SCharles.Forsyth int ntype; 132*74a4d8c2SCharles.Forsyth struct Node *nnext; 133*74a4d8c2SCharles.Forsyth int lineno; 134*74a4d8c2SCharles.Forsyth int nobj; 135*74a4d8c2SCharles.Forsyth struct Node *narg[1]; /* variable: actual size set by calling malloc */ 136*74a4d8c2SCharles.Forsyth } Node; 137*74a4d8c2SCharles.Forsyth 138*74a4d8c2SCharles.Forsyth #define NIL ((Node *) 0) 139*74a4d8c2SCharles.Forsyth 140*74a4d8c2SCharles.Forsyth extern Node *winner; 141*74a4d8c2SCharles.Forsyth extern Node *nullstat; 142*74a4d8c2SCharles.Forsyth extern Node *nullnode; 143*74a4d8c2SCharles.Forsyth 144*74a4d8c2SCharles.Forsyth /* ctypes */ 145*74a4d8c2SCharles.Forsyth #define OCELL 1 146*74a4d8c2SCharles.Forsyth #define OBOOL 2 147*74a4d8c2SCharles.Forsyth #define OJUMP 3 148*74a4d8c2SCharles.Forsyth 149*74a4d8c2SCharles.Forsyth /* Cell subtypes: csub */ 150*74a4d8c2SCharles.Forsyth #define CFREE 7 151*74a4d8c2SCharles.Forsyth #define CCOPY 6 152*74a4d8c2SCharles.Forsyth #define CCON 5 153*74a4d8c2SCharles.Forsyth #define CTEMP 4 154*74a4d8c2SCharles.Forsyth #define CNAME 3 155*74a4d8c2SCharles.Forsyth #define CVAR 2 156*74a4d8c2SCharles.Forsyth #define CFLD 1 157*74a4d8c2SCharles.Forsyth #define CUNK 0 158*74a4d8c2SCharles.Forsyth 159*74a4d8c2SCharles.Forsyth /* bool subtypes */ 160*74a4d8c2SCharles.Forsyth #define BTRUE 11 161*74a4d8c2SCharles.Forsyth #define BFALSE 12 162*74a4d8c2SCharles.Forsyth 163*74a4d8c2SCharles.Forsyth /* jump subtypes */ 164*74a4d8c2SCharles.Forsyth #define JEXIT 21 165*74a4d8c2SCharles.Forsyth #define JNEXT 22 166*74a4d8c2SCharles.Forsyth #define JBREAK 23 167*74a4d8c2SCharles.Forsyth #define JCONT 24 168*74a4d8c2SCharles.Forsyth #define JRET 25 169*74a4d8c2SCharles.Forsyth #define JNEXTFILE 26 170*74a4d8c2SCharles.Forsyth 171*74a4d8c2SCharles.Forsyth /* node types */ 172*74a4d8c2SCharles.Forsyth #define NVALUE 1 173*74a4d8c2SCharles.Forsyth #define NSTAT 2 174*74a4d8c2SCharles.Forsyth #define NEXPR 3 175*74a4d8c2SCharles.Forsyth 176*74a4d8c2SCharles.Forsyth 177*74a4d8c2SCharles.Forsyth extern int pairstack[], paircnt; 178*74a4d8c2SCharles.Forsyth 179*74a4d8c2SCharles.Forsyth #define notlegal(n) (n <= FIRSTTOKEN || n >= LASTTOKEN || proctab[n-FIRSTTOKEN] == nullproc) 180*74a4d8c2SCharles.Forsyth #define isvalue(n) ((n)->ntype == NVALUE) 181*74a4d8c2SCharles.Forsyth #define isexpr(n) ((n)->ntype == NEXPR) 182*74a4d8c2SCharles.Forsyth #define isjump(n) ((n)->ctype == OJUMP) 183*74a4d8c2SCharles.Forsyth #define isexit(n) ((n)->csub == JEXIT) 184*74a4d8c2SCharles.Forsyth #define isbreak(n) ((n)->csub == JBREAK) 185*74a4d8c2SCharles.Forsyth #define iscont(n) ((n)->csub == JCONT) 186*74a4d8c2SCharles.Forsyth #define isnext(n) ((n)->csub == JNEXT || (n)->csub == JNEXTFILE) 187*74a4d8c2SCharles.Forsyth #define isret(n) ((n)->csub == JRET) 188*74a4d8c2SCharles.Forsyth #define isrec(n) ((n)->tval & REC) 189*74a4d8c2SCharles.Forsyth #define isfld(n) ((n)->tval & FLD) 190*74a4d8c2SCharles.Forsyth #define isstr(n) ((n)->tval & STR) 191*74a4d8c2SCharles.Forsyth #define isnum(n) ((n)->tval & NUM) 192*74a4d8c2SCharles.Forsyth #define isarr(n) ((n)->tval & ARR) 193*74a4d8c2SCharles.Forsyth #define isfcn(n) ((n)->tval & FCN) 194*74a4d8c2SCharles.Forsyth #define istrue(n) ((n)->csub == BTRUE) 195*74a4d8c2SCharles.Forsyth #define istemp(n) ((n)->csub == CTEMP) 196*74a4d8c2SCharles.Forsyth #define isargument(n) ((n)->nobj == ARG) 197*74a4d8c2SCharles.Forsyth /* #define freeable(p) (!((p)->tval & DONTFREE)) */ 198*74a4d8c2SCharles.Forsyth #define freeable(p) ( ((p)->tval & (STR|DONTFREE)) == STR ) 199*74a4d8c2SCharles.Forsyth 200*74a4d8c2SCharles.Forsyth /* structures used by regular expression matching machinery, mostly b.c: */ 201*74a4d8c2SCharles.Forsyth 202*74a4d8c2SCharles.Forsyth #define NCHARS (256+1) /* 256 handles 8-bit chars; 128 does 7-bit */ 203*74a4d8c2SCharles.Forsyth /* watch out in match(), etc. */ 204*74a4d8c2SCharles.Forsyth #define NSTATES 32 205*74a4d8c2SCharles.Forsyth 206*74a4d8c2SCharles.Forsyth typedef struct rrow { 207*74a4d8c2SCharles.Forsyth long ltype; /* long avoids pointer warnings on 64-bit */ 208*74a4d8c2SCharles.Forsyth union { 209*74a4d8c2SCharles.Forsyth int i; 210*74a4d8c2SCharles.Forsyth Node *np; 211*74a4d8c2SCharles.Forsyth uschar *up; 212*74a4d8c2SCharles.Forsyth } lval; /* because Al stores a pointer in it! */ 213*74a4d8c2SCharles.Forsyth int *lfollow; 214*74a4d8c2SCharles.Forsyth } rrow; 215*74a4d8c2SCharles.Forsyth 216*74a4d8c2SCharles.Forsyth typedef struct fa { 217*74a4d8c2SCharles.Forsyth uschar gototab[NSTATES][NCHARS]; 218*74a4d8c2SCharles.Forsyth uschar out[NSTATES]; 219*74a4d8c2SCharles.Forsyth uschar *restr; 220*74a4d8c2SCharles.Forsyth int *posns[NSTATES]; 221*74a4d8c2SCharles.Forsyth int anchor; 222*74a4d8c2SCharles.Forsyth int use; 223*74a4d8c2SCharles.Forsyth int initstat; 224*74a4d8c2SCharles.Forsyth int curstat; 225*74a4d8c2SCharles.Forsyth int accept; 226*74a4d8c2SCharles.Forsyth int reset; 227*74a4d8c2SCharles.Forsyth struct rrow re[1]; /* variable: actual size set by calling malloc */ 228*74a4d8c2SCharles.Forsyth } fa; 229*74a4d8c2SCharles.Forsyth 230*74a4d8c2SCharles.Forsyth 231*74a4d8c2SCharles.Forsyth #include "proto.h" 232