xref: /original-bsd/usr.bin/window/parser2.c (revision b72553ae)
1c2717aaeSedward /*
2*b72553aeSbostic  * Copyright (c) 1983, 1993
3*b72553aeSbostic  *	The Regents of the University of California.  All rights reserved.
4bac0d407Sbostic  *
58e751acfSbostic  * This code is derived from software contributed to Berkeley by
68e751acfSbostic  * Edward Wang at The University of California, Berkeley.
78e751acfSbostic  *
8122a1d9eSbostic  * %sccs.include.redist.c%
9c2717aaeSedward  */
10c2717aaeSedward 
11bac0d407Sbostic #ifndef lint
12*b72553aeSbostic static char sccsid[] = "@(#)parser2.c	8.1 (Berkeley) 06/06/93";
13bac0d407Sbostic #endif /* not lint */
14bac0d407Sbostic 
15fff12678Sedward #include "parser.h"
1610d0ed1cSedward #include "var.h"
1710d0ed1cSedward #include "lcmd.h"
18b163fd54Sedward #include "alias.h"
19fff12678Sedward 
20fff12678Sedward /*
21fff12678Sedward  * name == 0 means we don't have a function name but
22fff12678Sedward  * want to parse the arguments anyway.  flag == 0 in this case.
23fff12678Sedward  */
p_function(name,v,flag)24fff12678Sedward p_function(name, v, flag)
25fff12678Sedward char *name;
26fff12678Sedward register struct value *v;
27fff12678Sedward {
28fff12678Sedward 	struct value t;
29b163fd54Sedward 	register struct lcmd_tab *c = 0;
30b163fd54Sedward 	register struct alias *a = 0;
31adcadf3cSedward 	register struct lcmd_arg *ap;		/* this arg */
32adcadf3cSedward 	struct lcmd_arg *lp = 0;		/* list arg */
33fff12678Sedward 	register i;
349faa66aeSedward 	struct value av[LCMD_NARG + 1];
35c42e298aSedward 	register struct value *vp;
36fff12678Sedward 
37b163fd54Sedward 	if (name != 0)
38b163fd54Sedward 		if (c = lcmd_lookup(name))
39b163fd54Sedward 			name = c->lc_name;
40b163fd54Sedward 		else if (a = alias_lookup(name))
41b163fd54Sedward 			name = a->a_name;
42b163fd54Sedward 		else {
43b163fd54Sedward 			p_error("%s: No such command or alias.", name);
44fff12678Sedward 			flag = 0;
45fff12678Sedward 		}
46fff12678Sedward 
479faa66aeSedward 	for (vp = av; vp < &av[LCMD_NARG + 1]; vp++)
48c42e298aSedward 		vp->v_type = V_ERR;
49fff12678Sedward 
5092cbc4a8Sedward 	if (token == T_LP)
5192cbc4a8Sedward 		(void) s_gettok();
5292cbc4a8Sedward 	i = 0;
5392cbc4a8Sedward 	for (;;) {
54adcadf3cSedward 		ap = 0;
55adcadf3cSedward 		vp = 0;
5692cbc4a8Sedward 		if (token == T_COMMA)		/* null argument */
5792cbc4a8Sedward 			t.v_type = V_ERR;
5892cbc4a8Sedward 		else {
5992cbc4a8Sedward 			if (p_expr0(&t, flag) < 0)
6092cbc4a8Sedward 				break;
6192cbc4a8Sedward 			if (t.v_type == V_ERR)
6292cbc4a8Sedward 				flag = 0;
6392cbc4a8Sedward 		}
64fff12678Sedward 		if (token != T_ASSIGN) {
65adcadf3cSedward 			if (i >= LCMD_NARG ||
66adcadf3cSedward 			    c != 0 && (ap = lp) == 0 &&
67adcadf3cSedward 			    (ap = c->lc_arg + i)->arg_name == 0) {
68b163fd54Sedward 				p_error("%s: Too many arguments.", name);
69fff12678Sedward 				flag = 0;
70fff12678Sedward 			} else
719faa66aeSedward 				vp = &av[i++];
72fff12678Sedward 		} else {
73fff12678Sedward 			char *tmp;
749faa66aeSedward 			if (p_convstr(&t) < 0)
75fff12678Sedward 				goto abort;
76b163fd54Sedward 			tmp = t.v_type == V_STR ? t.v_str : 0;
77fff12678Sedward 			(void) s_gettok();
78fff12678Sedward 			if (p_expr(&t, flag) < 0) {
79fff12678Sedward 				if (tmp)
80fff12678Sedward 					str_free(tmp);
81fff12678Sedward 				p_synerror();
82fff12678Sedward 				goto abort;
83fff12678Sedward 			}
84fff12678Sedward 			if (t.v_type == V_ERR)
85fff12678Sedward 				flag = 0;
86fff12678Sedward 			if (tmp) {
87b163fd54Sedward 				if (c == 0) {
88b163fd54Sedward 					/* an aliase */
89b163fd54Sedward 					p_error("%s: Bad alias syntax.", name);
90b163fd54Sedward 					flag = 0;
91b163fd54Sedward 				} else {
92c42e298aSedward 					for (ap = c->lc_arg, vp = av;
93b163fd54Sedward 					     ap != 0 && ap->arg_name != 0 &&
94adcadf3cSedward 					     (*ap->arg_name == '\0' ||
95b163fd54Sedward 					      !str_match(tmp, ap->arg_name,
96adcadf3cSedward 							ap->arg_minlen));
97b163fd54Sedward 					     ap++, vp++)
98b163fd54Sedward 						;
999faa66aeSedward 					if (ap == 0 || ap->arg_name == 0) {
100fff12678Sedward 						p_error("%s: Unknown argument \"%s\".",
101b163fd54Sedward 							name, tmp);
102fff12678Sedward 						flag = 0;
103fff12678Sedward 						ap = 0;
1049faa66aeSedward 						vp = 0;
105fff12678Sedward 					}
106b163fd54Sedward 				}
107fff12678Sedward 				str_free(tmp);
108fff12678Sedward 			}
109fff12678Sedward 		}
110fff12678Sedward 		if (ap != 0) {
111adcadf3cSedward 			if (ap->arg_flags & ARG_LIST) {
112adcadf3cSedward 				i = vp - av + 1;
113adcadf3cSedward 				lp = ap;
114adcadf3cSedward 			}
115c42e298aSedward 			if (vp->v_type != V_ERR) {
116adcadf3cSedward 				if (*ap->arg_name)
117fff12678Sedward 					p_error("%s: Argument %d (%s) duplicated.",
118adcadf3cSedward 						name, vp - av + 1,
119fff12678Sedward 						ap->arg_name);
120adcadf3cSedward 				else
121adcadf3cSedward 					p_error("%s: Argument %d duplicated.",
122adcadf3cSedward 						name, vp - av + 1);
123fff12678Sedward 				flag = 0;
1249faa66aeSedward 				vp = 0;
125fff12678Sedward 			} else if (t.v_type == V_ERR) {
126fff12678Sedward 				/* do nothing */
127adcadf3cSedward 			} else if ((ap->arg_flags&ARG_TYPE) == ARG_NUM &&
128adcadf3cSedward 				   t.v_type != V_NUM ||
129adcadf3cSedward 				   (ap->arg_flags&ARG_TYPE) == ARG_STR &&
130adcadf3cSedward 				   t.v_type != V_STR) {
131adcadf3cSedward 				if (*ap->arg_name)
132fff12678Sedward 					p_error("%s: Argument %d (%s) type mismatch.",
133adcadf3cSedward 						name, vp - av + 1,
134fff12678Sedward 						ap->arg_name);
135adcadf3cSedward 				else
136adcadf3cSedward 					p_error("%s: Argument %d type mismatch.",
137adcadf3cSedward 						name, vp - av + 1);
138fff12678Sedward 				flag = 0;
1399faa66aeSedward 				vp = 0;
140fff12678Sedward 			}
1419faa66aeSedward 		}
1429faa66aeSedward 		if (vp != 0)
1439faa66aeSedward 			*vp = t;
1449faa66aeSedward 		else
1459faa66aeSedward 			val_free(t);
146fff12678Sedward 		if (token == T_COMMA)
147fff12678Sedward 			(void) s_gettok();
148fff12678Sedward 	}
149fff12678Sedward 
150fff12678Sedward 	if (p_erred())
151fff12678Sedward 		flag = 0;
15292cbc4a8Sedward 	if (token == T_RP)
15392cbc4a8Sedward 		(void) s_gettok();
15492cbc4a8Sedward 	else if (token != T_EOL && token != T_EOF)
1559faa66aeSedward 		flag = 0;		/* look for legal follow set */
156fff12678Sedward 	v->v_type = V_ERR;
157fff12678Sedward 	if (flag)
158fff12678Sedward 		if (c != 0)
159b163fd54Sedward 			(*c->lc_func)(v, av);
160b163fd54Sedward 		else
161801312e7Sedward 			if (a->a_flags & A_INUSE)
162801312e7Sedward 				p_error("%s: Recursive alias.", a->a_name);
163801312e7Sedward 			else {
164801312e7Sedward 				a->a_flags |= A_INUSE;
165b163fd54Sedward 				if (dolongcmd(a->a_buf, av, i) < 0)
166b163fd54Sedward 					p_memerror();
167801312e7Sedward 				a->a_flags &= ~A_INUSE;
168801312e7Sedward 			}
169b163fd54Sedward 	if (p_abort()) {
170b163fd54Sedward 		val_free(*v);
171b163fd54Sedward 		v->v_type = V_ERR;
172b163fd54Sedward 		goto abort;
173b163fd54Sedward 	}
174c42e298aSedward 	for (vp = av; vp < &av[LCMD_NARG]; vp++)
175c42e298aSedward 		val_free(*vp);
176fff12678Sedward 	return 0;
177fff12678Sedward abort:
178c42e298aSedward 	for (vp = av; vp < &av[LCMD_NARG]; vp++)
179c42e298aSedward 		val_free(*vp);
180fff12678Sedward 	return -1;
181fff12678Sedward }
182fff12678Sedward 
p_assign(name,v,flag)183fff12678Sedward p_assign(name, v, flag)
184fff12678Sedward char *name;
185fff12678Sedward struct value *v;
186fff12678Sedward char flag;
187fff12678Sedward {
188fff12678Sedward 	(void) s_gettok();
189fff12678Sedward 
190fff12678Sedward 	if (p_expr(v, flag) < 0) {
191fff12678Sedward 		p_synerror();
192fff12678Sedward 		return -1;
193fff12678Sedward 	}
194fff12678Sedward 	switch (v->v_type) {
195fff12678Sedward 	case V_STR:
196fff12678Sedward 	case V_NUM:
197fff12678Sedward 		if (flag && var_set(name, v) == 0) {
198fff12678Sedward 			p_memerror();
199fff12678Sedward 			val_free(*v);
200fff12678Sedward 			return -1;
201fff12678Sedward 		}
202fff12678Sedward 		break;
203fff12678Sedward 	}
204fff12678Sedward 	return 0;
205fff12678Sedward }
206