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