xref: /openbsd/usr.bin/awk/parse.c (revision c4ead62f)
1 /*	$OpenBSD: parse.c,v 1.14 2023/09/10 14:59:00 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.tab.h"
32 
nodealloc(size_t n)33 Node *nodealloc(size_t n)
34 {
35 	Node *x;
36 
37 	x = (Node *) malloc(sizeof(*x) + (n-1) * sizeof(x));
38 	if (x == NULL)
39 		FATAL("out of space in nodealloc");
40 	x->nnext = NULL;
41 	x->lineno = lineno;
42 	return(x);
43 }
44 
exptostat(Node * a)45 Node *exptostat(Node *a)
46 {
47 	a->ntype = NSTAT;
48 	return(a);
49 }
50 
node1(int a,Node * b)51 Node *node1(int a, Node *b)
52 {
53 	Node *x;
54 
55 	x = nodealloc(1);
56 	x->nobj = a;
57 	x->narg[0]=b;
58 	return(x);
59 }
60 
node2(int a,Node * b,Node * c)61 Node *node2(int a, Node *b, Node *c)
62 {
63 	Node *x;
64 
65 	x = nodealloc(2);
66 	x->nobj = a;
67 	x->narg[0] = b;
68 	x->narg[1] = c;
69 	return(x);
70 }
71 
node3(int a,Node * b,Node * c,Node * d)72 Node *node3(int a, Node *b, Node *c, Node *d)
73 {
74 	Node *x;
75 
76 	x = nodealloc(3);
77 	x->nobj = a;
78 	x->narg[0] = b;
79 	x->narg[1] = c;
80 	x->narg[2] = d;
81 	return(x);
82 }
83 
node4(int a,Node * b,Node * c,Node * d,Node * e)84 Node *node4(int a, Node *b, Node *c, Node *d, Node *e)
85 {
86 	Node *x;
87 
88 	x = nodealloc(4);
89 	x->nobj = a;
90 	x->narg[0] = b;
91 	x->narg[1] = c;
92 	x->narg[2] = d;
93 	x->narg[3] = e;
94 	return(x);
95 }
96 
node5(int a,Node * b,Node * c,Node * d,Node * e,Node * f)97 Node *node5(int a, Node *b, Node *c, Node *d, Node *e, Node *f)
98 {
99 	Node *x;
100 
101 	x = nodealloc(5);
102 	x->nobj = a;
103 	x->narg[0] = b;
104 	x->narg[1] = c;
105 	x->narg[2] = d;
106 	x->narg[3] = e;
107 	x->narg[4] = f;
108 	return(x);
109 }
110 
stat1(int a,Node * b)111 Node *stat1(int a, Node *b)
112 {
113 	Node *x;
114 
115 	x = node1(a,b);
116 	x->ntype = NSTAT;
117 	return(x);
118 }
119 
stat2(int a,Node * b,Node * c)120 Node *stat2(int a, Node *b, Node *c)
121 {
122 	Node *x;
123 
124 	x = node2(a,b,c);
125 	x->ntype = NSTAT;
126 	return(x);
127 }
128 
stat3(int a,Node * b,Node * c,Node * d)129 Node *stat3(int a, Node *b, Node *c, Node *d)
130 {
131 	Node *x;
132 
133 	x = node3(a,b,c,d);
134 	x->ntype = NSTAT;
135 	return(x);
136 }
137 
stat4(int a,Node * b,Node * c,Node * d,Node * e)138 Node *stat4(int a, Node *b, Node *c, Node *d, Node *e)
139 {
140 	Node *x;
141 
142 	x = node4(a,b,c,d,e);
143 	x->ntype = NSTAT;
144 	return(x);
145 }
146 
op1(int a,Node * b)147 Node *op1(int a, Node *b)
148 {
149 	Node *x;
150 
151 	x = node1(a,b);
152 	x->ntype = NEXPR;
153 	return(x);
154 }
155 
op2(int a,Node * b,Node * c)156 Node *op2(int a, Node *b, Node *c)
157 {
158 	Node *x;
159 
160 	x = node2(a,b,c);
161 	x->ntype = NEXPR;
162 	return(x);
163 }
164 
op3(int a,Node * b,Node * c,Node * d)165 Node *op3(int a, Node *b, Node *c, Node *d)
166 {
167 	Node *x;
168 
169 	x = node3(a,b,c,d);
170 	x->ntype = NEXPR;
171 	return(x);
172 }
173 
op4(int a,Node * b,Node * c,Node * d,Node * e)174 Node *op4(int a, Node *b, Node *c, Node *d, Node *e)
175 {
176 	Node *x;
177 
178 	x = node4(a,b,c,d,e);
179 	x->ntype = NEXPR;
180 	return(x);
181 }
182 
op5(int a,Node * b,Node * c,Node * d,Node * e,Node * f)183 Node *op5(int a, Node *b, Node *c, Node *d, Node *e, Node *f)
184 {
185 	Node *x;
186 
187 	x = node5(a,b,c,d,e,f);
188 	x->ntype = NEXPR;
189 	return(x);
190 }
191 
celltonode(Cell * a,int b)192 Node *celltonode(Cell *a, int b)
193 {
194 	Node *x;
195 
196 	a->ctype = OCELL;
197 	a->csub = b;
198 	x = node1(0, (Node *) a);
199 	x->ntype = NVALUE;
200 	return(x);
201 }
202 
rectonode(void)203 Node *rectonode(void)	/* make $0 into a Node */
204 {
205 	extern Cell *literal0;
206 	return op1(INDIRECT, celltonode(literal0, CUNK));
207 }
208 
makearr(Node * p)209 Node *makearr(Node *p)
210 {
211 	Cell *cp;
212 
213 	if (isvalue(p)) {
214 		cp = (Cell *) (p->narg[0]);
215 		if (isfcn(cp))
216 			SYNTAX( "%s is a function, not an array", cp->nval );
217 		else if (!isarr(cp)) {
218 			xfree(cp->sval);
219 			cp->sval = (char *) makesymtab(NSYMTAB);
220 			cp->tval = ARR;
221 		}
222 	}
223 	return p;
224 }
225 
226 #define PA2NUM	50	/* max number of pat,pat patterns allowed */
227 int	paircnt;		/* number of them in use */
228 int	pairstack[PA2NUM];	/* state of each pat,pat */
229 
pa2stat(Node * a,Node * b,Node * c)230 Node *pa2stat(Node *a, Node *b, Node *c)	/* pat, pat {...} */
231 {
232 	Node *x;
233 
234 	x = node4(PASTAT2, a, b, c, itonp(paircnt));
235 	if (paircnt++ >= PA2NUM)
236 		SYNTAX( "limited to %d pat,pat statements", PA2NUM );
237 	x->ntype = NSTAT;
238 	return(x);
239 }
240 
linkum(Node * a,Node * b)241 Node *linkum(Node *a, Node *b)
242 {
243 	Node *c;
244 
245 	if (errorflag)	/* don't link things that are wrong */
246 		return a;
247 	if (a == NULL)
248 		return(b);
249 	else if (b == NULL)
250 		return(a);
251 	for (c = a; c->nnext != NULL; c = c->nnext)
252 		;
253 	c->nnext = b;
254 	return(a);
255 }
256 
defn(Cell * v,Node * vl,Node * st)257 void defn(Cell *v, Node *vl, Node *st)	/* turn on FCN bit in definition, */
258 {					/*   body of function, arglist */
259 	Node *p;
260 	int n;
261 
262 	if (isarr(v)) {
263 		SYNTAX( "`%s' is an array name and a function name", v->nval );
264 		return;
265 	}
266 	if (isarg(v->nval) != -1) {
267 		SYNTAX( "`%s' is both function name and argument name", v->nval );
268 		return;
269 	}
270 
271 	v->tval = FCN;
272 	v->sval = (char *) st;
273 	n = 0;	/* count arguments */
274 	for (p = vl; p; p = p->nnext)
275 		n++;
276 	v->fval = n;
277 	DPRINTF("defining func %s (%d args)\n", v->nval, n);
278 }
279 
isarg(const char * s)280 int isarg(const char *s)		/* is s in argument list for current function? */
281 {			/* return -1 if not, otherwise arg # */
282 	extern Node *arglist;
283 	Node *p = arglist;
284 	int n;
285 
286 	for (n = 0; p != NULL; p = p->nnext, n++)
287 		if (strcmp(((Cell *)(p->narg[0]))->nval, s) == 0)
288 			return n;
289 	return -1;
290 }
291 
ptoi(void * p)292 int ptoi(void *p)	/* convert pointer to integer */
293 {
294 	return (int) (long) p;	/* swearing that p fits, of course */
295 }
296 
itonp(int i)297 Node *itonp(int i)	/* and vice versa */
298 {
299 	return (Node *) (long) i;
300 }
301