1 /*	$OpenBSD: parse.c,v 1.6 2002/12/19 21:24:28 millert Exp $	*/
2 /****************************************************************
3 Copyright (C) Lucent Technologies 1997
4 All Rights Reserved
5 
6 Permission to use, copy, modify, and distribute this software and
7 its documentation for any purpose and without fee is hereby
8 granted, provided that the above copyright notice appear in all
9 copies and that both that the copyright notice and this
10 permission notice and warranty disclaimer appear in supporting
11 documentation, and that the name Lucent Technologies or any of
12 its entities not be used in advertising or publicity pertaining
13 to distribution of the software without specific, written prior
14 permission.
15 
16 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
18 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
19 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
21 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
22 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
23 THIS SOFTWARE.
24 ****************************************************************/
25 
26 #define DEBUG
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include "awk.h"
31 #include "awkgram.h"
32 
33 __RCSID("$MirOS: src/usr.bin/awk/parse.c,v 1.2 2007/04/28 00:12:47 tg Exp $");
34 
nodealloc(int n)35 Node *nodealloc(int n)
36 {
37 	Node *x;
38 
39 	x = (Node *) malloc(sizeof(Node) + (n-1)*sizeof(Node *));
40 	if (x == NULL)
41 		FATAL("out of space in nodealloc");
42 	x->nnext = NULL;
43 	x->lineno = lineno;
44 	return(x);
45 }
46 
exptostat(Node * a)47 Node *exptostat(Node *a)
48 {
49 	a->ntype = NSTAT;
50 	return(a);
51 }
52 
node1(int a,Node * b)53 Node *node1(int a, Node *b)
54 {
55 	Node *x;
56 
57 	x = nodealloc(1);
58 	x->nobj = a;
59 	x->narg[0]=b;
60 	return(x);
61 }
62 
node2(int a,Node * b,Node * c)63 Node *node2(int a, Node *b, Node *c)
64 {
65 	Node *x;
66 
67 	x = nodealloc(2);
68 	x->nobj = a;
69 	x->narg[0] = b;
70 	x->narg[1] = c;
71 	return(x);
72 }
73 
node3(int a,Node * b,Node * c,Node * d)74 Node *node3(int a, Node *b, Node *c, Node *d)
75 {
76 	Node *x;
77 
78 	x = nodealloc(3);
79 	x->nobj = a;
80 	x->narg[0] = b;
81 	x->narg[1] = c;
82 	x->narg[2] = d;
83 	return(x);
84 }
85 
node4(int a,Node * b,Node * c,Node * d,Node * e)86 Node *node4(int a, Node *b, Node *c, Node *d, Node *e)
87 {
88 	Node *x;
89 
90 	x = nodealloc(4);
91 	x->nobj = a;
92 	x->narg[0] = b;
93 	x->narg[1] = c;
94 	x->narg[2] = d;
95 	x->narg[3] = e;
96 	return(x);
97 }
98 
stat1(int a,Node * b)99 Node *stat1(int a, Node *b)
100 {
101 	Node *x;
102 
103 	x = node1(a,b);
104 	x->ntype = NSTAT;
105 	return(x);
106 }
107 
stat2(int a,Node * b,Node * c)108 Node *stat2(int a, Node *b, Node *c)
109 {
110 	Node *x;
111 
112 	x = node2(a,b,c);
113 	x->ntype = NSTAT;
114 	return(x);
115 }
116 
stat3(int a,Node * b,Node * c,Node * d)117 Node *stat3(int a, Node *b, Node *c, Node *d)
118 {
119 	Node *x;
120 
121 	x = node3(a,b,c,d);
122 	x->ntype = NSTAT;
123 	return(x);
124 }
125 
stat4(int a,Node * b,Node * c,Node * d,Node * e)126 Node *stat4(int a, Node *b, Node *c, Node *d, Node *e)
127 {
128 	Node *x;
129 
130 	x = node4(a,b,c,d,e);
131 	x->ntype = NSTAT;
132 	return(x);
133 }
134 
op1(int a,Node * b)135 Node *op1(int a, Node *b)
136 {
137 	Node *x;
138 
139 	x = node1(a,b);
140 	x->ntype = NEXPR;
141 	return(x);
142 }
143 
op2(int a,Node * b,Node * c)144 Node *op2(int a, Node *b, Node *c)
145 {
146 	Node *x;
147 
148 	x = node2(a,b,c);
149 	x->ntype = NEXPR;
150 	return(x);
151 }
152 
op3(int a,Node * b,Node * c,Node * d)153 Node *op3(int a, Node *b, Node *c, Node *d)
154 {
155 	Node *x;
156 
157 	x = node3(a,b,c,d);
158 	x->ntype = NEXPR;
159 	return(x);
160 }
161 
op4(int a,Node * b,Node * c,Node * d,Node * e)162 Node *op4(int a, Node *b, Node *c, Node *d, Node *e)
163 {
164 	Node *x;
165 
166 	x = node4(a,b,c,d,e);
167 	x->ntype = NEXPR;
168 	return(x);
169 }
170 
celltonode(Cell * a,int b)171 Node *celltonode(Cell *a, int b)
172 {
173 	Node *x;
174 
175 	a->ctype = OCELL;
176 	a->csub = b;
177 	x = node1(0, (Node *) a);
178 	x->ntype = NVALUE;
179 	return(x);
180 }
181 
rectonode(void)182 Node *rectonode(void)	/* make $0 into a Node */
183 {
184 	extern Cell *literal0;
185 	return op1(INDIRECT, celltonode(literal0, CUNK));
186 }
187 
makearr(Node * p)188 Node *makearr(Node *p)
189 {
190 	Cell *cp;
191 
192 	if (isvalue(p)) {
193 		cp = (Cell *) (p->narg[0]);
194 		if (isfcn(cp))
195 			SYNTAX( "%s is a function, not an array", cp->nval );
196 		else if (!isarr(cp)) {
197 			xfree(cp->sval);
198 			cp->sval = (char *) makesymtab(NSYMTAB);
199 			cp->tval = ARR;
200 		}
201 	}
202 	return p;
203 }
204 
205 #define PA2NUM	50	/* max number of pat,pat patterns allowed */
206 int	paircnt;		/* number of them in use */
207 int	pairstack[PA2NUM];	/* state of each pat,pat */
208 
pa2stat(Node * a,Node * b,Node * c)209 Node *pa2stat(Node *a, Node *b, Node *c)	/* pat, pat {...} */
210 {
211 	Node *x;
212 
213 	x = node4(PASTAT2, a, b, c, itonp(paircnt));
214 	if (paircnt++ >= PA2NUM)
215 		SYNTAX( "limited to %d pat,pat statements", PA2NUM );
216 	x->ntype = NSTAT;
217 	return(x);
218 }
219 
linkum(Node * a,Node * b)220 Node *linkum(Node *a, Node *b)
221 {
222 	Node *c;
223 
224 	if (errorflag)	/* don't link things that are wrong */
225 		return a;
226 	if (a == NULL)
227 		return(b);
228 	else if (b == NULL)
229 		return(a);
230 	for (c = a; c->nnext != NULL; c = c->nnext)
231 		;
232 	c->nnext = b;
233 	return(a);
234 }
235 
defn(Cell * v,Node * vl,Node * st)236 void defn(Cell *v, Node *vl, Node *st)	/* turn on FCN bit in definition, */
237 {					/*   body of function, arglist */
238 	Node *p;
239 	int n;
240 
241 	if (isarr(v)) {
242 		SYNTAX( "`%s' is an array name and a function name", v->nval );
243 		return;
244 	}
245 	if (isarg(v->nval) != -1) {
246 		SYNTAX( "`%s' is both function name and argument name", v->nval );
247 		return;
248 	}
249 
250 	v->tval = FCN;
251 	v->sval = (char *) st;
252 	n = 0;	/* count arguments */
253 	for (p = vl; p; p = p->nnext)
254 		n++;
255 	v->fval = n;
256 	dprintf( ("defining func %s (%d args)\n", v->nval, n) );
257 }
258 
isarg(const char * s)259 int isarg(const char *s)		/* is s in argument list for current function? */
260 {			/* return -1 if not, otherwise arg # */
261 	extern Node *arglist;
262 	Node *p = arglist;
263 	int n;
264 
265 	for (n = 0; p != 0; p = p->nnext, n++)
266 		if (strcmp(((Cell *)(p->narg[0]))->nval, s) == 0)
267 			return n;
268 	return -1;
269 }
270 
ptoi(void * p)271 int ptoi(void *p)	/* convert pointer to integer */
272 {
273 	return (int) (long) p;	/* swearing that p fits, of course */
274 }
275 
itonp(int i)276 Node *itonp(int i)	/* and vice versa */
277 {
278 	return (Node *) (long) i;
279 }
280