xref: /illumos-gate/usr/src/cmd/awk/parse.c (revision 3ee4fc2a)
1*3ee4fc2aSCody Peter Mello /*
2*3ee4fc2aSCody Peter Mello  * Copyright (C) Lucent Technologies 1997
3*3ee4fc2aSCody Peter Mello  * All Rights Reserved
4*3ee4fc2aSCody Peter Mello  *
5*3ee4fc2aSCody Peter Mello  * Permission to use, copy, modify, and distribute this software and
6*3ee4fc2aSCody Peter Mello  * its documentation for any purpose and without fee is hereby
7*3ee4fc2aSCody Peter Mello  * granted, provided that the above copyright notice appear in all
8*3ee4fc2aSCody Peter Mello  * copies and that both that the copyright notice and this
9*3ee4fc2aSCody Peter Mello  * permission notice and warranty disclaimer appear in supporting
10*3ee4fc2aSCody Peter Mello  * documentation, and that the name Lucent Technologies or any of
11*3ee4fc2aSCody Peter Mello  * its entities not be used in advertising or publicity pertaining
12*3ee4fc2aSCody Peter Mello  * to distribution of the software without specific, written prior
13*3ee4fc2aSCody Peter Mello  * permission.
14*3ee4fc2aSCody Peter Mello  *
15*3ee4fc2aSCody Peter Mello  * LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16*3ee4fc2aSCody Peter Mello  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
17*3ee4fc2aSCody Peter Mello  * IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
18*3ee4fc2aSCody Peter Mello  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19*3ee4fc2aSCody Peter Mello  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
20*3ee4fc2aSCody Peter Mello  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
21*3ee4fc2aSCody Peter Mello  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
22*3ee4fc2aSCody Peter Mello  * THIS SOFTWARE.
23*3ee4fc2aSCody Peter Mello  */
24*3ee4fc2aSCody Peter Mello 
257c478bd9Sstevel@tonic-gate /*
267c478bd9Sstevel@tonic-gate  * CDDL HEADER START
277c478bd9Sstevel@tonic-gate  *
287c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
297c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
307c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
317c478bd9Sstevel@tonic-gate  * with the License.
327c478bd9Sstevel@tonic-gate  *
337c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
347c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
357c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
367c478bd9Sstevel@tonic-gate  * and limitations under the License.
377c478bd9Sstevel@tonic-gate  *
387c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
397c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
407c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
417c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
427c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
437c478bd9Sstevel@tonic-gate  *
447c478bd9Sstevel@tonic-gate  * CDDL HEADER END
457c478bd9Sstevel@tonic-gate  */
461ee2e5faSnakanon 
471ee2e5faSnakanon /*
481ee2e5faSnakanon  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
491ee2e5faSnakanon  * Use is subject to license terms.
501ee2e5faSnakanon  */
511ee2e5faSnakanon 
527c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
537c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
547c478bd9Sstevel@tonic-gate 
551ee2e5faSnakanon #define	DEBUG
567c478bd9Sstevel@tonic-gate #include "awk.h"
577c478bd9Sstevel@tonic-gate #include "y.tab.h"
587c478bd9Sstevel@tonic-gate 
591ee2e5faSnakanon Node *
nodealloc(int n)601ee2e5faSnakanon nodealloc(int n)
617c478bd9Sstevel@tonic-gate {
62*3ee4fc2aSCody Peter Mello 	Node *x;
631ee2e5faSnakanon 
641ee2e5faSnakanon 	x = (Node *)malloc(sizeof (Node) + (n - 1) * sizeof (Node *));
657c478bd9Sstevel@tonic-gate 	if (x == NULL)
66*3ee4fc2aSCody Peter Mello 		FATAL("out of space in nodealloc");
677c478bd9Sstevel@tonic-gate 	x->nnext = NULL;
687c478bd9Sstevel@tonic-gate 	x->lineno = lineno;
691ee2e5faSnakanon 	return (x);
707c478bd9Sstevel@tonic-gate }
717c478bd9Sstevel@tonic-gate 
721ee2e5faSnakanon Node *
exptostat(Node * a)731ee2e5faSnakanon exptostat(Node *a)
747c478bd9Sstevel@tonic-gate {
757c478bd9Sstevel@tonic-gate 	a->ntype = NSTAT;
761ee2e5faSnakanon 	return (a);
777c478bd9Sstevel@tonic-gate }
787c478bd9Sstevel@tonic-gate 
791ee2e5faSnakanon Node *
node1(int a,Node * b)801ee2e5faSnakanon node1(int a, Node *b)
817c478bd9Sstevel@tonic-gate {
82*3ee4fc2aSCody Peter Mello 	Node *x;
831ee2e5faSnakanon 
847c478bd9Sstevel@tonic-gate 	x = nodealloc(1);
857c478bd9Sstevel@tonic-gate 	x->nobj = a;
861ee2e5faSnakanon 	x->narg[0] = b;
871ee2e5faSnakanon 	return (x);
887c478bd9Sstevel@tonic-gate }
897c478bd9Sstevel@tonic-gate 
901ee2e5faSnakanon Node *
node2(int a,Node * b,Node * c)911ee2e5faSnakanon node2(int a, Node *b, Node *c)
927c478bd9Sstevel@tonic-gate {
93*3ee4fc2aSCody Peter Mello 	Node *x;
941ee2e5faSnakanon 
957c478bd9Sstevel@tonic-gate 	x = nodealloc(2);
967c478bd9Sstevel@tonic-gate 	x->nobj = a;
977c478bd9Sstevel@tonic-gate 	x->narg[0] = b;
987c478bd9Sstevel@tonic-gate 	x->narg[1] = c;
991ee2e5faSnakanon 	return (x);
1007c478bd9Sstevel@tonic-gate }
1017c478bd9Sstevel@tonic-gate 
1021ee2e5faSnakanon Node *
node3(int a,Node * b,Node * c,Node * d)1031ee2e5faSnakanon node3(int a, Node *b, Node *c, Node *d)
1047c478bd9Sstevel@tonic-gate {
105*3ee4fc2aSCody Peter Mello 	Node *x;
1061ee2e5faSnakanon 
1077c478bd9Sstevel@tonic-gate 	x = nodealloc(3);
1087c478bd9Sstevel@tonic-gate 	x->nobj = a;
1097c478bd9Sstevel@tonic-gate 	x->narg[0] = b;
1107c478bd9Sstevel@tonic-gate 	x->narg[1] = c;
1117c478bd9Sstevel@tonic-gate 	x->narg[2] = d;
1121ee2e5faSnakanon 	return (x);
1137c478bd9Sstevel@tonic-gate }
1147c478bd9Sstevel@tonic-gate 
1151ee2e5faSnakanon Node *
node4(int a,Node * b,Node * c,Node * d,Node * e)1161ee2e5faSnakanon node4(int a, Node *b, Node *c, Node *d, Node *e)
1177c478bd9Sstevel@tonic-gate {
118*3ee4fc2aSCody Peter Mello 	Node *x;
119*3ee4fc2aSCody Peter Mello 
1207c478bd9Sstevel@tonic-gate 	x = nodealloc(4);
1217c478bd9Sstevel@tonic-gate 	x->nobj = a;
1227c478bd9Sstevel@tonic-gate 	x->narg[0] = b;
1237c478bd9Sstevel@tonic-gate 	x->narg[1] = c;
1247c478bd9Sstevel@tonic-gate 	x->narg[2] = d;
1257c478bd9Sstevel@tonic-gate 	x->narg[3] = e;
1261ee2e5faSnakanon 	return (x);
1277c478bd9Sstevel@tonic-gate }
1287c478bd9Sstevel@tonic-gate 
1291ee2e5faSnakanon Node *
stat1(int a,Node * b)130*3ee4fc2aSCody Peter Mello stat1(int a, Node *b)
1317c478bd9Sstevel@tonic-gate {
132*3ee4fc2aSCody Peter Mello 	Node *x;
1331ee2e5faSnakanon 
134*3ee4fc2aSCody Peter Mello 	x = node1(a, b);
1357c478bd9Sstevel@tonic-gate 	x->ntype = NSTAT;
1361ee2e5faSnakanon 	return (x);
1377c478bd9Sstevel@tonic-gate }
1387c478bd9Sstevel@tonic-gate 
1391ee2e5faSnakanon Node *
stat2(int a,Node * b,Node * c)140*3ee4fc2aSCody Peter Mello stat2(int a, Node *b, Node *c)
1417c478bd9Sstevel@tonic-gate {
142*3ee4fc2aSCody Peter Mello 	Node *x;
1431ee2e5faSnakanon 
1441ee2e5faSnakanon 	x = node2(a, b, c);
145*3ee4fc2aSCody Peter Mello 	x->ntype = NSTAT;
1461ee2e5faSnakanon 	return (x);
1477c478bd9Sstevel@tonic-gate }
1487c478bd9Sstevel@tonic-gate 
1491ee2e5faSnakanon Node *
stat3(int a,Node * b,Node * c,Node * d)150*3ee4fc2aSCody Peter Mello stat3(int a, Node *b, Node *c, Node *d)
1517c478bd9Sstevel@tonic-gate {
152*3ee4fc2aSCody Peter Mello 	Node *x;
1531ee2e5faSnakanon 
154*3ee4fc2aSCody Peter Mello 	x = node3(a, b, c, d);
155*3ee4fc2aSCody Peter Mello 	x->ntype = NSTAT;
1561ee2e5faSnakanon 	return (x);
1577c478bd9Sstevel@tonic-gate }
1587c478bd9Sstevel@tonic-gate 
1591ee2e5faSnakanon Node *
stat4(int a,Node * b,Node * c,Node * d,Node * e)160*3ee4fc2aSCody Peter Mello stat4(int a, Node *b, Node *c, Node *d, Node *e)
1617c478bd9Sstevel@tonic-gate {
162*3ee4fc2aSCody Peter Mello 	Node *x;
1631ee2e5faSnakanon 
164*3ee4fc2aSCody Peter Mello 	x = node4(a, b, c, d, e);
1657c478bd9Sstevel@tonic-gate 	x->ntype = NSTAT;
1661ee2e5faSnakanon 	return (x);
1677c478bd9Sstevel@tonic-gate }
1687c478bd9Sstevel@tonic-gate 
1691ee2e5faSnakanon Node *
op1(int a,Node * b)170*3ee4fc2aSCody Peter Mello op1(int a, Node *b)
1717c478bd9Sstevel@tonic-gate {
172*3ee4fc2aSCody Peter Mello 	Node *x;
1731ee2e5faSnakanon 
174*3ee4fc2aSCody Peter Mello 	x = node1(a, b);
1757c478bd9Sstevel@tonic-gate 	x->ntype = NEXPR;
1761ee2e5faSnakanon 	return (x);
1777c478bd9Sstevel@tonic-gate }
1787c478bd9Sstevel@tonic-gate 
1791ee2e5faSnakanon Node *
op2(int a,Node * b,Node * c)180*3ee4fc2aSCody Peter Mello op2(int a, Node *b, Node *c)
1817c478bd9Sstevel@tonic-gate {
182*3ee4fc2aSCody Peter Mello 	Node *x;
1831ee2e5faSnakanon 
184*3ee4fc2aSCody Peter Mello 	x = node2(a, b, c);
1857c478bd9Sstevel@tonic-gate 	x->ntype = NEXPR;
1861ee2e5faSnakanon 	return (x);
1877c478bd9Sstevel@tonic-gate }
1887c478bd9Sstevel@tonic-gate 
1891ee2e5faSnakanon Node *
op3(int a,Node * b,Node * c,Node * d)190*3ee4fc2aSCody Peter Mello op3(int a, Node *b, Node *c, Node *d)
1917c478bd9Sstevel@tonic-gate {
192*3ee4fc2aSCody Peter Mello 	Node *x;
1931ee2e5faSnakanon 
194*3ee4fc2aSCody Peter Mello 	x = node3(a, b, c, d);
195*3ee4fc2aSCody Peter Mello 	x->ntype = NEXPR;
1961ee2e5faSnakanon 	return (x);
1977c478bd9Sstevel@tonic-gate }
1987c478bd9Sstevel@tonic-gate 
1991ee2e5faSnakanon Node *
op4(int a,Node * b,Node * c,Node * d,Node * e)200*3ee4fc2aSCody Peter Mello op4(int a, Node *b, Node *c, Node *d, Node *e)
2017c478bd9Sstevel@tonic-gate {
202*3ee4fc2aSCody Peter Mello 	Node *x;
2031ee2e5faSnakanon 
2041ee2e5faSnakanon 	x = node4(a, b, c, d, e);
205*3ee4fc2aSCody Peter Mello 	x->ntype = NEXPR;
2061ee2e5faSnakanon 	return (x);
2077c478bd9Sstevel@tonic-gate }
2087c478bd9Sstevel@tonic-gate 
2091ee2e5faSnakanon Node *
celltonode(Cell * a,int b)210*3ee4fc2aSCody Peter Mello celltonode(Cell *a, int b)
2117c478bd9Sstevel@tonic-gate {
212*3ee4fc2aSCody Peter Mello 	Node *x;
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate 	a->ctype = OCELL;
2157c478bd9Sstevel@tonic-gate 	a->csub = b;
2161ee2e5faSnakanon 	x = node1(0, (Node *)a);
2177c478bd9Sstevel@tonic-gate 	x->ntype = NVALUE;
2181ee2e5faSnakanon 	return (x);
2197c478bd9Sstevel@tonic-gate }
2207c478bd9Sstevel@tonic-gate 
2211ee2e5faSnakanon Node *
rectonode(void)222*3ee4fc2aSCody Peter Mello rectonode(void)	/* make $0 into a Node */
2237c478bd9Sstevel@tonic-gate {
224*3ee4fc2aSCody Peter Mello 	extern Cell *literal0;
225*3ee4fc2aSCody Peter Mello 	return (op1(INDIRECT, celltonode(literal0, CUNK)));
2267c478bd9Sstevel@tonic-gate }
2277c478bd9Sstevel@tonic-gate 
2281ee2e5faSnakanon Node *
makearr(Node * p)2291ee2e5faSnakanon makearr(Node *p)
2307c478bd9Sstevel@tonic-gate {
2317c478bd9Sstevel@tonic-gate 	Cell *cp;
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate 	if (isvalue(p)) {
2341ee2e5faSnakanon 		cp = (Cell *)(p->narg[0]);
235*3ee4fc2aSCody Peter Mello 		if (isfcn(cp))
236*3ee4fc2aSCody Peter Mello 			SYNTAX("%s is a function, not an array", cp->nval);
2377c478bd9Sstevel@tonic-gate 		else if (!isarr(cp)) {
2387c478bd9Sstevel@tonic-gate 			xfree(cp->sval);
239*3ee4fc2aSCody Peter Mello 			cp->sval = (char *)makesymtab(NSYMTAB);
2407c478bd9Sstevel@tonic-gate 			cp->tval = ARR;
2417c478bd9Sstevel@tonic-gate 		}
2427c478bd9Sstevel@tonic-gate 	}
2431ee2e5faSnakanon 	return (p);
2447c478bd9Sstevel@tonic-gate }
2457c478bd9Sstevel@tonic-gate 
246*3ee4fc2aSCody Peter Mello int	paircnt;	/* number of them in use */
247*3ee4fc2aSCody Peter Mello int	*pairstack;	/* state of each pat,pat */
248*3ee4fc2aSCody Peter Mello 
2491ee2e5faSnakanon Node *
pa2stat(Node * a,Node * b,Node * c)250*3ee4fc2aSCody Peter Mello pa2stat(Node *a, Node *b, Node *c)	/* pat, pat {...} */
2517c478bd9Sstevel@tonic-gate {
252*3ee4fc2aSCody Peter Mello 	Node *x;
2531ee2e5faSnakanon 
254*3ee4fc2aSCody Peter Mello 	x = node4(PASTAT2, a, b, c, itonp(paircnt));
2557c478bd9Sstevel@tonic-gate 	paircnt++;
2567c478bd9Sstevel@tonic-gate 	x->ntype = NSTAT;
2571ee2e5faSnakanon 	return (x);
2587c478bd9Sstevel@tonic-gate }
2597c478bd9Sstevel@tonic-gate 
2601ee2e5faSnakanon Node *
linkum(Node * a,Node * b)2611ee2e5faSnakanon linkum(Node *a, Node *b)
2627c478bd9Sstevel@tonic-gate {
263*3ee4fc2aSCody Peter Mello 	Node *c;
2647c478bd9Sstevel@tonic-gate 
2657c478bd9Sstevel@tonic-gate 	if (errorflag)	/* don't link things that are wrong */
2661ee2e5faSnakanon 		return (a);
2671ee2e5faSnakanon 	if (a == NULL)
2681ee2e5faSnakanon 		return (b);
2691ee2e5faSnakanon 	else if (b == NULL)
2701ee2e5faSnakanon 		return (a);
2717c478bd9Sstevel@tonic-gate 	for (c = a; c->nnext != NULL; c = c->nnext)
2727c478bd9Sstevel@tonic-gate 		;
2737c478bd9Sstevel@tonic-gate 	c->nnext = b;
2741ee2e5faSnakanon 	return (a);
2757c478bd9Sstevel@tonic-gate }
2767c478bd9Sstevel@tonic-gate 
277*3ee4fc2aSCody Peter Mello /* turn on FCN bit in definition, */
278*3ee4fc2aSCody Peter Mello /* body of function, arglist */
2791ee2e5faSnakanon void
defn(Cell * v,Node * vl,Node * st)280*3ee4fc2aSCody Peter Mello defn(Cell *v, Node *vl, Node *st)
2817c478bd9Sstevel@tonic-gate {
2827c478bd9Sstevel@tonic-gate 	Node *p;
2837c478bd9Sstevel@tonic-gate 	int n;
2847c478bd9Sstevel@tonic-gate 
2857c478bd9Sstevel@tonic-gate 	if (isarr(v)) {
286*3ee4fc2aSCody Peter Mello 		SYNTAX("`%s' is an array name and a function name", v->nval);
287*3ee4fc2aSCody Peter Mello 		return;
288*3ee4fc2aSCody Peter Mello 	}
289*3ee4fc2aSCody Peter Mello 	if (isarg(v->nval) != -1) {
290*3ee4fc2aSCody Peter Mello 		SYNTAX("`%s' is both function name and argument name", v->nval);
2917c478bd9Sstevel@tonic-gate 		return;
2927c478bd9Sstevel@tonic-gate 	}
293*3ee4fc2aSCody Peter Mello 
2947c478bd9Sstevel@tonic-gate 	v->tval = FCN;
295*3ee4fc2aSCody Peter Mello 	v->sval = (char *)st;
2967c478bd9Sstevel@tonic-gate 	n = 0;	/* count arguments */
297*3ee4fc2aSCody Peter Mello 	for (p = vl; p != NULL; p = p->nnext)
2987c478bd9Sstevel@tonic-gate 		n++;
2997c478bd9Sstevel@tonic-gate 	v->fval = n;
3001ee2e5faSnakanon 	dprintf(("defining func %s (%d args)\n", v->nval, n));
3017c478bd9Sstevel@tonic-gate }
3027c478bd9Sstevel@tonic-gate 
303*3ee4fc2aSCody Peter Mello /* is s in argument list for current function? */
304*3ee4fc2aSCody Peter Mello /* return -1 if not, otherwise arg # */
3051ee2e5faSnakanon int
isarg(const char * s)306*3ee4fc2aSCody Peter Mello isarg(const char *s)
3077c478bd9Sstevel@tonic-gate {
3087c478bd9Sstevel@tonic-gate 	extern Node *arglist;
3097c478bd9Sstevel@tonic-gate 	Node *p = arglist;
3107c478bd9Sstevel@tonic-gate 	int n;
3117c478bd9Sstevel@tonic-gate 
312*3ee4fc2aSCody Peter Mello 	for (n = 0; p != NULL; p = p->nnext, n++)
313*3ee4fc2aSCody Peter Mello 		if (strcmp(((Cell *)(p->narg[0]))->nval, s) == 0)
3141ee2e5faSnakanon 			return (n);
3151ee2e5faSnakanon 	return (-1);
3167c478bd9Sstevel@tonic-gate }
317*3ee4fc2aSCody Peter Mello 
318*3ee4fc2aSCody Peter Mello int
ptoi(void * p)319*3ee4fc2aSCody Peter Mello ptoi(void *p)	/* convert pointer to integer */
320*3ee4fc2aSCody Peter Mello {
321*3ee4fc2aSCody Peter Mello 	return ((int)(long)p);	/* swearing that p fits, of course */
322*3ee4fc2aSCody Peter Mello }
323*3ee4fc2aSCody Peter Mello 
324*3ee4fc2aSCody Peter Mello Node *
itonp(int i)325*3ee4fc2aSCody Peter Mello itonp(int i)	/* and vice versa */
326*3ee4fc2aSCody Peter Mello {
327*3ee4fc2aSCody Peter Mello 	return ((Node *)(long)i);
328*3ee4fc2aSCody Peter Mello }
329