1/*-
2 * This code contains changes by
3 *      Gunnar Ritter, Freiburg i. Br., Germany, 2002. All rights reserved.
4 *
5 * Conditions 1, 2, and 4 and the no-warranty notice below apply
6 * to these changes.
7 *
8 *
9 * Copyright (c) 1991
10 * 	The Regents of the University of California.  All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 *    notice, this list of conditions and the following disclaimer in the
19 *    documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 *    must display the following acknowledgement:
22 * 	This product includes software developed by the University of
23 * 	California, Berkeley and its contributors.
24 * 4. Neither the name of the University nor the names of its contributors
25 *    may be used to endorse or promote products derived from this software
26 *    without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 *
40 *
41 * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
42 *
43 * Redistribution and use in source and binary forms, with or without
44 * modification, are permitted provided that the following conditions
45 * are met:
46 *   Redistributions of source code and documentation must retain the
47 *    above copyright notice, this list of conditions and the following
48 *    disclaimer.
49 *   Redistributions in binary form must reproduce the above copyright
50 *    notice, this list of conditions and the following disclaimer in the
51 *    documentation and/or other materials provided with the distribution.
52 *   All advertising materials mentioning features or use of this software
53 *    must display the following acknowledgement:
54 *      This product includes software developed or owned by Caldera
55 *      International, Inc.
56 *   Neither the name of Caldera International, Inc. nor the names of
57 *    other contributors may be used to endorse or promote products
58 *    derived from this software without specific prior written permission.
59 *
60 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
61 * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
62 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
64 * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE
65 * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR
66 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
67 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
68 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
69 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
70 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
71 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72 *
73 *	from 4.4BSD /usr/src/old/awk/awk.def	4.6 (Berkeley) 4/27/91
74 *
75 *	Sccsid @(#)awk.def	1.19 (gritter) 12/25/06
76 */
77
78#include <stdlib.h>
79#include <inttypes.h>
80
81#define	AWKFLOAT	double
82#define	xfree(a)	{ if(a!=NULL) { yfree(a); a=NULL;} }
83#define	strfree(a)	{ if(a!=NULL && a!=EMPTY) { yfree(a);} a=EMPTY; }
84#define yfree free
85#define	isnull(x)	((x) == EMPTY || (x) == NULL)
86
87typedef	AWKFLOAT	awkfloat;
88
89extern char	*progname;
90
91extern char	**FS;
92extern char	**RS;
93extern char	**ORS;
94extern char	**OFS;
95extern char	**OFMT;
96extern awkfloat *NR;
97extern awkfloat *NF;
98extern char	**FILENAME;
99
100extern int	RECSIZE;
101
102extern char	*record;
103extern char	EMPTY[];
104extern int	dbg;
105extern long long	lineno;
106extern int	errorflag;
107extern const char	*radixchar;
108extern int	radixcharlen;
109extern int	donefld;	/* 1 if record broken into fields */
110extern int	donerec;	/* 1 if record is valid (no fld has changed */
111extern int	mb_cur_max;	/* MB_CUR_MAX acceleration */
112
113typedef struct val {	/* general value during processing */
114	char	*nval;	/* name, for variables only */
115	char	*sval;	/* string value */
116	awkfloat	fval;	/* value as number */
117	unsigned	tval;	/* type info */
118	struct val	*nextval;	/* ptr to next if chained */
119} cell;
120extern cell *symtab[];
121
122extern cell	*recloc;	/* location of input record */
123extern cell	*nrloc;		/* NR */
124extern cell	*nfloc;		/* NF */
125
126#define	STR	01	/* string value is valid */
127#define	NUM	02	/* number value is valid */
128#define FLD	04	/* FLD means don't free string space */
129#define	CON	010	/* this is a constant */
130#define	ARR	020	/* this is an array */
131
132#include <string.h>
133#include <math.h>
134#include <stdio.h>
135
136#ifdef	__GLIBC__
137#ifdef	_IO_getc_unlocked
138#undef	getc
139#define	getc(c)	_IO_getc_unlocked(c)
140#endif	/* _IO_getc_unlocked */
141#endif	/* __GLIBC__ */
142
143#define	getline	xxgetline	/* avoid glibc _GNU_SOURCE name collision */
144
145#define	DEBUG
146#ifdef	DEBUG
147#	define	dprintf	if(dbg)printf
148#else
149#	define	dprintf(x1, x2, x3, x4)
150#endif
151
152#include <wchar.h>
153
154/*
155 * Get next character from string s and store it in wc; n is set to
156 * the length of the corresponding byte sequence.
157 */
158#define	next(wc, s, n) (mb_cur_max > 1 && *(s) & 0200 ? \
159			((n) = mbtowc(&(wc), (s), mb_cur_max), \
160			 (n) = ((n) > 0 ? (n) : (n) < 0 ? (wc=WEOF, 1) : 1)) :\
161		((wc) = *(s) & 0377, (n) = 1))
162
163/* function types */
164#define	FLENGTH	1
165#define	FSQRT	2
166#define	FEXP	3
167#define	FLOG	4
168#define	FINT	5
169
170typedef struct {
171	char otype;
172	char osub;
173	cell *optr;
174} obj;
175
176#define BOTCH	1
177struct nd {
178	char ntype;
179	char subtype;
180	struct nd *nnext;
181	intptr_t nobj;
182	struct nd *narg[BOTCH];	/* C won't take a zero length array */
183};
184typedef struct nd node;
185extern node	*winner;
186extern node	*nullstat;
187
188/* otypes */
189#define OCELL	0
190#define OEXPR	1
191#define OBOOL	2
192#define OJUMP	3
193
194/* cell subtypes */
195#define CTEMP	4
196#define CNAME	3
197#define CVAR	2
198#define CFLD	1
199#define CCON	0
200
201/* bool subtypes */
202#define BTRUE	1
203#define BFALSE	2
204
205/* jump subtypes */
206#define JEXIT	1
207#define JNEXT	2
208#define	JBREAK	3
209#define	JCONT	4
210
211/* node types */
212#define NVALUE	1
213#define NSTAT	2
214#define NEXPR	3
215#define NPA2	4
216
217extern obj	(*proctab[])(node **, int);
218extern obj	true, false;
219extern int	pairstack[], paircnt;
220
221#define cantexec(n)	(n->ntype == NVALUE)
222#define notlegal(n)	(n <= FIRSTTOKEN || n >= LASTTOKEN || proctab[n-FIRSTTOKEN]== nullproc)
223#define isexpr(n)	(n->ntype == NEXPR)
224#define isjump(n)	(n.otype == OJUMP)
225#define isexit(n)	(n.otype == OJUMP && n.osub == JEXIT)
226#define	isbreak(n)	(n.otype == OJUMP && n.osub == JBREAK)
227#define	iscont(n)	(n.otype == OJUMP && n.osub == JCONT)
228#define	isnext(n)	(n.otype == OJUMP && n.osub == JNEXT)
229#define isstr(n)	(n.optr->tval & STR)
230#define istrue(n)	(n.otype == OBOOL && n.osub == BTRUE)
231#define istemp(n)	(n.otype == OCELL && n.osub == CTEMP)
232#define isfld(n)	(!donefld && n.osub==CFLD && n.otype==OCELL && n.optr->nval==EMPTY)
233#define isrec(n)	(donefld && n.osub==CFLD && n.otype==OCELL && n.optr->nval!=EMPTY)
234
235#define MAXSYM	50
236#define	HAT	0177	/* matches ^ in regular expr */
237			/* watch out for mach dep */
238/* awk.g.y */
239extern int yyparse(void);
240/* awk.lx.l */
241extern int yylex(void);
242extern void startreg(void);
243/* b.c */
244extern void overflo(void);
245extern struct fa *makedfa(const char *);
246extern int match(void *, register const char *);
247extern int member(register char, register const char *);
248/* lib.c */
249extern void growrec(void);
250extern void fldinit(void);
251extern int getrec(void);
252extern void setclvar(char *);
253extern void fldbld(void);
254extern void recbld(void);
255extern cell *fieldadr(int);
256extern void yyerror(const char *);
257extern void error(int, const char *, ...);
258extern void PUTS(const char *);
259extern int isanumber(register const char *);
260/* main.c */
261extern int yywrap(void);
262/* parse.c */
263extern node *ALLOC(int);
264extern node *exptostat(node *);
265extern node *node0(intptr_t);
266extern node *node1(intptr_t, node *);
267extern node *node2(intptr_t, node *, node *);
268extern node *node3(intptr_t, node *, node *, node *);
269extern node *node4(intptr_t, node *, node *, node *, node *);
270extern node *stat3(intptr_t, node *, node *, node *);
271extern node *op2(intptr_t, node *, node *);
272extern node *op1(intptr_t, node *);
273extern node *stat1(intptr_t, node *);
274extern node *op3(intptr_t, node *, node *, node *);
275extern node *stat2(intptr_t, node *, node *);
276extern node *stat4(intptr_t, node *, node *, node *, node *);
277extern node *valtonode(cell *, int);
278extern node *pa2stat(node *, node *, node *);
279extern node *linkum(node *, node *);
280extern node *genprint(void);
281/* run.c */
282extern void run(void);
283extern obj execute(node *);
284extern obj program(node **, int);
285extern obj getline(node **, int);
286extern obj array(node **, int);
287extern obj arrayel(node *, obj);
288extern obj matchop(node **, int);
289extern obj boolop(node **, int);
290extern obj relop(node **, int);
291extern void tempfree(obj);
292extern obj gettemp(void);
293extern obj indirect(node **, int);
294extern obj substr(node **, int);
295extern obj sindex(node **, int);
296extern char *format(const char *, node *);
297extern obj awsprintf(node **, int);
298extern obj arith(node **, int);
299extern obj incrdecr(node **, int);
300extern obj assign(node **, int);
301extern obj cat(node **, int);
302extern obj pastat(node **, int);
303extern obj dopa2(node **, int);
304extern obj aprintf(node **, int);
305extern obj split(node **, int);
306extern obj ifstat(node **, int);
307extern obj whilestat(node **, int);
308extern obj forstat(node **, int);
309extern obj instat(node **, int);
310extern obj jump(node **, int);
311extern obj fncn(node **, int);
312extern obj print(node **, int);
313extern obj nullproc(node **, int);
314extern obj nodetoobj(node *);
315extern void redirprint(const char *, int, node *);
316extern int chrlen(const char *);
317extern int chrdist(const char *, const char *);
318/* token.c */
319extern char *tokname(int);
320/* tran.c */
321extern void syminit(void);
322extern cell **makesymtab(void);
323extern void freesymtab(cell *);
324extern cell *setsymtab(const char *, char *, awkfloat, unsigned, cell **);
325extern int hash(register const unsigned char *);
326extern cell *lookup(register const char *, cell **, int);
327extern awkfloat setfval(register cell *, awkfloat);
328extern char *setsval(register cell *, const char *);
329extern awkfloat getfval(register cell *);
330extern char *getsval(register cell *);
331extern void checkval(register cell *);
332extern char *tostring(register const char *);
333