12a55deb1SDavid E. O'Brien /**************************************************************** 22a55deb1SDavid E. O'Brien Copyright (C) Lucent Technologies 1997 32a55deb1SDavid E. O'Brien All Rights Reserved 42a55deb1SDavid E. O'Brien 52a55deb1SDavid E. O'Brien Permission to use, copy, modify, and distribute this software and 62a55deb1SDavid E. O'Brien its documentation for any purpose and without fee is hereby 72a55deb1SDavid E. O'Brien granted, provided that the above copyright notice appear in all 82a55deb1SDavid E. O'Brien copies and that both that the copyright notice and this 92a55deb1SDavid E. O'Brien permission notice and warranty disclaimer appear in supporting 102a55deb1SDavid E. O'Brien documentation, and that the name Lucent Technologies or any of 112a55deb1SDavid E. O'Brien its entities not be used in advertising or publicity pertaining 122a55deb1SDavid E. O'Brien to distribution of the software without specific, written prior 132a55deb1SDavid E. O'Brien permission. 142a55deb1SDavid E. O'Brien 152a55deb1SDavid E. O'Brien LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 162a55deb1SDavid E. O'Brien INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 172a55deb1SDavid E. O'Brien IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 182a55deb1SDavid E. O'Brien SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 192a55deb1SDavid E. O'Brien WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 202a55deb1SDavid E. O'Brien IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 212a55deb1SDavid E. O'Brien ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 222a55deb1SDavid E. O'Brien THIS SOFTWARE. 232a55deb1SDavid E. O'Brien ****************************************************************/ 242a55deb1SDavid E. O'Brien 25c263f9bfSRuslan Ermilov #include <assert.h> 26c263f9bfSRuslan Ermilov 272a55deb1SDavid E. O'Brien typedef double Awkfloat; 282a55deb1SDavid E. O'Brien 292a55deb1SDavid E. O'Brien /* unsigned char is more trouble than it's worth */ 302a55deb1SDavid E. O'Brien 312a55deb1SDavid E. O'Brien typedef unsigned char uschar; 322a55deb1SDavid E. O'Brien 332a55deb1SDavid E. O'Brien #define xfree(a) { if ((a) != NULL) { free((char *) a); a = NULL; } } 342a55deb1SDavid E. O'Brien 35813da98dSDavid E. O'Brien #define NN(p) ((p) ? (p) : "(null)") /* guaranteed non-null for dprintf 36813da98dSDavid E. O'Brien */ 372a55deb1SDavid E. O'Brien #define DEBUG 382a55deb1SDavid E. O'Brien #ifdef DEBUG 392a55deb1SDavid E. O'Brien /* uses have to be doubly parenthesized */ 402a55deb1SDavid E. O'Brien # define dprintf(x) if (dbg) printf x 412a55deb1SDavid E. O'Brien #else 422a55deb1SDavid E. O'Brien # define dprintf(x) 432a55deb1SDavid E. O'Brien #endif 442a55deb1SDavid E. O'Brien 452a55deb1SDavid E. O'Brien extern int compile_time; /* 1 if compiling, 0 if running */ 462a55deb1SDavid E. O'Brien extern int safe; /* 0 => unsafe, 1 => safe */ 472a55deb1SDavid E. O'Brien 482a55deb1SDavid E. O'Brien #define RECSIZE (8 * 1024) /* sets limit on records, fields, etc., etc. */ 492a55deb1SDavid E. O'Brien extern int recsize; /* size of current record, orig RECSIZE */ 502a55deb1SDavid E. O'Brien 512a55deb1SDavid E. O'Brien extern char **FS; 522a55deb1SDavid E. O'Brien extern char **RS; 532a55deb1SDavid E. O'Brien extern char **ORS; 542a55deb1SDavid E. O'Brien extern char **OFS; 552a55deb1SDavid E. O'Brien extern char **OFMT; 562a55deb1SDavid E. O'Brien extern Awkfloat *NR; 572a55deb1SDavid E. O'Brien extern Awkfloat *FNR; 582a55deb1SDavid E. O'Brien extern Awkfloat *NF; 592a55deb1SDavid E. O'Brien extern char **FILENAME; 602a55deb1SDavid E. O'Brien extern char **SUBSEP; 612a55deb1SDavid E. O'Brien extern Awkfloat *RSTART; 622a55deb1SDavid E. O'Brien extern Awkfloat *RLENGTH; 632a55deb1SDavid E. O'Brien 642a55deb1SDavid E. O'Brien extern char *record; /* points to $0 */ 652a55deb1SDavid E. O'Brien extern int lineno; /* line number in awk program */ 662a55deb1SDavid E. O'Brien extern int errorflag; /* 1 if error has occurred */ 672a55deb1SDavid E. O'Brien extern int donefld; /* 1 if record broken into fields */ 682a55deb1SDavid E. O'Brien extern int donerec; /* 1 if record is valid (no fld has changed */ 692a55deb1SDavid E. O'Brien extern char inputFS[]; /* FS at time of input, for field splitting */ 702a55deb1SDavid E. O'Brien 712a55deb1SDavid E. O'Brien extern int dbg; 722a55deb1SDavid E. O'Brien 732a55deb1SDavid E. O'Brien extern char *patbeg; /* beginning of pattern matched */ 742a55deb1SDavid E. O'Brien extern int patlen; /* length of pattern matched. set in b.c */ 752a55deb1SDavid E. O'Brien 762a55deb1SDavid E. O'Brien /* Cell: all information about a variable or constant */ 772a55deb1SDavid E. O'Brien 782a55deb1SDavid E. O'Brien typedef struct Cell { 792a55deb1SDavid E. O'Brien uschar ctype; /* OCELL, OBOOL, OJUMP, etc. */ 802a55deb1SDavid E. O'Brien uschar csub; /* CCON, CTEMP, CFLD, etc. */ 812a55deb1SDavid E. O'Brien char *nval; /* name, for variables only */ 822a55deb1SDavid E. O'Brien char *sval; /* string value */ 832a55deb1SDavid E. O'Brien Awkfloat fval; /* value as number */ 842a55deb1SDavid E. O'Brien int tval; /* type info: STR|NUM|ARR|FCN|FLD|CON|DONTFREE */ 852a55deb1SDavid E. O'Brien struct Cell *cnext; /* ptr to next if chained */ 862a55deb1SDavid E. O'Brien } Cell; 872a55deb1SDavid E. O'Brien 882a55deb1SDavid E. O'Brien typedef struct Array { /* symbol table array */ 892a55deb1SDavid E. O'Brien int nelem; /* elements in table right now */ 902a55deb1SDavid E. O'Brien int size; /* size of tab */ 912a55deb1SDavid E. O'Brien Cell **tab; /* hash table pointers */ 922a55deb1SDavid E. O'Brien } Array; 932a55deb1SDavid E. O'Brien 942a55deb1SDavid E. O'Brien #define NSYMTAB 50 /* initial size of a symbol table */ 952a55deb1SDavid E. O'Brien extern Array *symtab; 962a55deb1SDavid E. O'Brien 972a55deb1SDavid E. O'Brien extern Cell *nrloc; /* NR */ 982a55deb1SDavid E. O'Brien extern Cell *fnrloc; /* FNR */ 992a55deb1SDavid E. O'Brien extern Cell *nfloc; /* NF */ 1002a55deb1SDavid E. O'Brien extern Cell *rstartloc; /* RSTART */ 1012a55deb1SDavid E. O'Brien extern Cell *rlengthloc; /* RLENGTH */ 1022a55deb1SDavid E. O'Brien 1032a55deb1SDavid E. O'Brien /* Cell.tval values: */ 1042a55deb1SDavid E. O'Brien #define NUM 01 /* number value is valid */ 1052a55deb1SDavid E. O'Brien #define STR 02 /* string value is valid */ 1062a55deb1SDavid E. O'Brien #define DONTFREE 04 /* string space is not freeable */ 1072a55deb1SDavid E. O'Brien #define CON 010 /* this is a constant */ 1082a55deb1SDavid E. O'Brien #define ARR 020 /* this is an array */ 1092a55deb1SDavid E. O'Brien #define FCN 040 /* this is a function name */ 1102a55deb1SDavid E. O'Brien #define FLD 0100 /* this is a field $1, $2, ... */ 1112a55deb1SDavid E. O'Brien #define REC 0200 /* this is $0 */ 1122a55deb1SDavid E. O'Brien 1132a55deb1SDavid E. O'Brien 1142a55deb1SDavid E. O'Brien /* function types */ 1152a55deb1SDavid E. O'Brien #define FLENGTH 1 1162a55deb1SDavid E. O'Brien #define FSQRT 2 1172a55deb1SDavid E. O'Brien #define FEXP 3 1182a55deb1SDavid E. O'Brien #define FLOG 4 1192a55deb1SDavid E. O'Brien #define FINT 5 1202a55deb1SDavid E. O'Brien #define FSYSTEM 6 1212a55deb1SDavid E. O'Brien #define FRAND 7 1222a55deb1SDavid E. O'Brien #define FSRAND 8 1232a55deb1SDavid E. O'Brien #define FSIN 9 1242a55deb1SDavid E. O'Brien #define FCOS 10 1252a55deb1SDavid E. O'Brien #define FATAN 11 1262a55deb1SDavid E. O'Brien #define FTOUPPER 12 1272a55deb1SDavid E. O'Brien #define FTOLOWER 13 1282a55deb1SDavid E. O'Brien #define FFLUSH 14 1292a55deb1SDavid E. O'Brien 1302a55deb1SDavid E. O'Brien /* Node: parse tree is made of nodes, with Cell's at bottom */ 1312a55deb1SDavid E. O'Brien 1322a55deb1SDavid E. O'Brien typedef struct Node { 1332a55deb1SDavid E. O'Brien int ntype; 1342a55deb1SDavid E. O'Brien struct Node *nnext; 1352a55deb1SDavid E. O'Brien int lineno; 1362a55deb1SDavid E. O'Brien int nobj; 1372a55deb1SDavid E. O'Brien struct Node *narg[1]; /* variable: actual size set by calling malloc */ 1382a55deb1SDavid E. O'Brien } Node; 1392a55deb1SDavid E. O'Brien 1402a55deb1SDavid E. O'Brien #define NIL ((Node *) 0) 1412a55deb1SDavid E. O'Brien 1422a55deb1SDavid E. O'Brien extern Node *winner; 1432a55deb1SDavid E. O'Brien extern Node *nullstat; 1442a55deb1SDavid E. O'Brien extern Node *nullnode; 1452a55deb1SDavid E. O'Brien 1462a55deb1SDavid E. O'Brien /* ctypes */ 1472a55deb1SDavid E. O'Brien #define OCELL 1 1482a55deb1SDavid E. O'Brien #define OBOOL 2 1492a55deb1SDavid E. O'Brien #define OJUMP 3 1502a55deb1SDavid E. O'Brien 1512a55deb1SDavid E. O'Brien /* Cell subtypes: csub */ 1522a55deb1SDavid E. O'Brien #define CFREE 7 1532a55deb1SDavid E. O'Brien #define CCOPY 6 1542a55deb1SDavid E. O'Brien #define CCON 5 1552a55deb1SDavid E. O'Brien #define CTEMP 4 1562a55deb1SDavid E. O'Brien #define CNAME 3 1572a55deb1SDavid E. O'Brien #define CVAR 2 1582a55deb1SDavid E. O'Brien #define CFLD 1 1592a55deb1SDavid E. O'Brien #define CUNK 0 1602a55deb1SDavid E. O'Brien 1612a55deb1SDavid E. O'Brien /* bool subtypes */ 1622a55deb1SDavid E. O'Brien #define BTRUE 11 1632a55deb1SDavid E. O'Brien #define BFALSE 12 1642a55deb1SDavid E. O'Brien 1652a55deb1SDavid E. O'Brien /* jump subtypes */ 1662a55deb1SDavid E. O'Brien #define JEXIT 21 1672a55deb1SDavid E. O'Brien #define JNEXT 22 1682a55deb1SDavid E. O'Brien #define JBREAK 23 1692a55deb1SDavid E. O'Brien #define JCONT 24 1702a55deb1SDavid E. O'Brien #define JRET 25 1712a55deb1SDavid E. O'Brien #define JNEXTFILE 26 1722a55deb1SDavid E. O'Brien 1732a55deb1SDavid E. O'Brien /* node types */ 1742a55deb1SDavid E. O'Brien #define NVALUE 1 1752a55deb1SDavid E. O'Brien #define NSTAT 2 1762a55deb1SDavid E. O'Brien #define NEXPR 3 1772a55deb1SDavid E. O'Brien 1782a55deb1SDavid E. O'Brien 1792a55deb1SDavid E. O'Brien extern int pairstack[], paircnt; 1802a55deb1SDavid E. O'Brien 1812a55deb1SDavid E. O'Brien #define notlegal(n) (n <= FIRSTTOKEN || n >= LASTTOKEN || proctab[n-FIRSTTOKEN] == nullproc) 1822a55deb1SDavid E. O'Brien #define isvalue(n) ((n)->ntype == NVALUE) 1832a55deb1SDavid E. O'Brien #define isexpr(n) ((n)->ntype == NEXPR) 1842a55deb1SDavid E. O'Brien #define isjump(n) ((n)->ctype == OJUMP) 1852a55deb1SDavid E. O'Brien #define isexit(n) ((n)->csub == JEXIT) 1862a55deb1SDavid E. O'Brien #define isbreak(n) ((n)->csub == JBREAK) 1872a55deb1SDavid E. O'Brien #define iscont(n) ((n)->csub == JCONT) 1882a55deb1SDavid E. O'Brien #define isnext(n) ((n)->csub == JNEXT || (n)->csub == JNEXTFILE) 1892a55deb1SDavid E. O'Brien #define isret(n) ((n)->csub == JRET) 1902a55deb1SDavid E. O'Brien #define isrec(n) ((n)->tval & REC) 1912a55deb1SDavid E. O'Brien #define isfld(n) ((n)->tval & FLD) 1922a55deb1SDavid E. O'Brien #define isstr(n) ((n)->tval & STR) 1932a55deb1SDavid E. O'Brien #define isnum(n) ((n)->tval & NUM) 1942a55deb1SDavid E. O'Brien #define isarr(n) ((n)->tval & ARR) 1952a55deb1SDavid E. O'Brien #define isfcn(n) ((n)->tval & FCN) 1962a55deb1SDavid E. O'Brien #define istrue(n) ((n)->csub == BTRUE) 1972a55deb1SDavid E. O'Brien #define istemp(n) ((n)->csub == CTEMP) 1982a55deb1SDavid E. O'Brien #define isargument(n) ((n)->nobj == ARG) 1992a55deb1SDavid E. O'Brien /* #define freeable(p) (!((p)->tval & DONTFREE)) */ 2002a55deb1SDavid E. O'Brien #define freeable(p) ( ((p)->tval & (STR|DONTFREE)) == STR ) 2012a55deb1SDavid E. O'Brien 2022a55deb1SDavid E. O'Brien /* structures used by regular expression matching machinery, mostly b.c: */ 2032a55deb1SDavid E. O'Brien 204c263f9bfSRuslan Ermilov #define NCHARS (256+3) /* 256 handles 8-bit chars; 128 does 7-bit */ 2052a55deb1SDavid E. O'Brien /* watch out in match(), etc. */ 2062a55deb1SDavid E. O'Brien #define NSTATES 32 2072a55deb1SDavid E. O'Brien 2082a55deb1SDavid E. O'Brien typedef struct rrow { 2092a55deb1SDavid E. O'Brien long ltype; /* long avoids pointer warnings on 64-bit */ 2102a55deb1SDavid E. O'Brien union { 2112a55deb1SDavid E. O'Brien int i; 2122a55deb1SDavid E. O'Brien Node *np; 2132a55deb1SDavid E. O'Brien uschar *up; 2142a55deb1SDavid E. O'Brien } lval; /* because Al stores a pointer in it! */ 2152a55deb1SDavid E. O'Brien int *lfollow; 2162a55deb1SDavid E. O'Brien } rrow; 2172a55deb1SDavid E. O'Brien 2182a55deb1SDavid E. O'Brien typedef struct fa { 2192a55deb1SDavid E. O'Brien uschar gototab[NSTATES][NCHARS]; 2202a55deb1SDavid E. O'Brien uschar out[NSTATES]; 2212a55deb1SDavid E. O'Brien uschar *restr; 2222a55deb1SDavid E. O'Brien int *posns[NSTATES]; 2232a55deb1SDavid E. O'Brien int anchor; 2242a55deb1SDavid E. O'Brien int use; 2252a55deb1SDavid E. O'Brien int initstat; 2262a55deb1SDavid E. O'Brien int curstat; 2272a55deb1SDavid E. O'Brien int accept; 2282a55deb1SDavid E. O'Brien int reset; 2292a55deb1SDavid E. O'Brien struct rrow re[1]; /* variable: actual size set by calling malloc */ 2302a55deb1SDavid E. O'Brien } fa; 2312a55deb1SDavid E. O'Brien 2322a55deb1SDavid E. O'Brien 2332a55deb1SDavid E. O'Brien #include "proto.h" 234