xref: /dragonfly/usr.bin/window/parser1.c (revision 333227be)
1 /*
2  * Copyright (c) 1983, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Edward Wang at The University of California, Berkeley.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *	This product includes software developed by the University of
19  *	California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  * @(#)parser1.c	8.1 (Berkeley) 6/6/93
37  * $FreeBSD: src/usr.bin/window/parser1.c,v 1.1.1.1.14.1 2001/05/17 09:45:00 obrien Exp $
38  * $DragonFly: src/usr.bin/window/parser1.c,v 1.2 2003/06/17 04:29:34 dillon Exp $
39  */
40 
41 #include "parser.h"
42 
43 p_start()
44 {
45 	char flag = 1;
46 
47 	(void) s_gettok();
48 	for (;;) {
49 		p_statementlist(flag);
50 		if (token == T_EOF || p_abort())
51 			break;
52 		flag = 0;
53 		p_synerror();
54 		while (token != T_EOL && token != T_EOF) {
55 			if (token == T_STR)
56 				str_free(token_str);
57 			(void) s_gettok();
58 		}
59 		if (token == T_EOL)
60 			(void) s_gettok();
61 		p_clearerr();
62 	}
63 }
64 
65 p_statementlist(flag)
66 char flag;
67 {
68 	for (; p_statement(flag) >= 0; p_clearerr())
69 		;
70 }
71 
72 p_statement(flag)
73 char flag;
74 {
75 	switch (token) {
76 	case T_EOL:
77 		(void) s_gettok();
78 		return 0;
79 	case T_IF:
80 		return p_if(flag);
81 	default:
82 		return p_expression(flag);
83 	}
84 }
85 
86 p_if(flag)
87 char flag;
88 {
89 	struct value t;
90 	char true = 0;
91 
92 top:
93 	(void) s_gettok();
94 
95 	if (p_expr(&t, flag) < 0) {
96 		p_synerror();
97 		return -1;
98 	}
99 	switch (t.v_type) {
100 	case V_NUM:
101 		true = !true && t.v_num != 0;
102 		break;
103 	case V_STR:
104 		p_error("if: Numeric value required.");
105 		str_free(t.v_str);
106 	case V_ERR:
107 		flag = 0;
108 		break;
109 	}
110 
111 	if (token != T_THEN) {
112 		p_synerror();
113 		return -1;
114 	}
115 
116 	(void) s_gettok();
117 	p_statementlist(flag && true);
118 	if (p_erred())
119 		return -1;
120 
121 	if (token == T_ELSIF)
122 		goto top;
123 
124 	if (token == T_ELSE) {
125 		(void) s_gettok();
126 		p_statementlist(flag && !true);
127 		if (p_erred())
128 			return -1;
129 	}
130 
131 	if (token == T_ENDIF) {
132 		(void) s_gettok();
133 		return 0;
134 	}
135 
136 	p_synerror();
137 	return -1;
138 }
139 
140 p_expression(flag)
141 char flag;
142 {
143 	struct value t;
144 	char *cmd;
145 	int p_function(), p_assign();
146 
147 	switch (token) {
148 	case T_NUM:
149 		t.v_type = V_NUM;
150 		t.v_num = token_num;
151 		(void) s_gettok();
152 		break;
153 	case T_STR:
154 		t.v_type = V_STR;
155 		t.v_str = token_str;
156 		(void) s_gettok();
157 		break;
158 	default:
159 		if (p_expr(&t, flag) < 0)
160 			return -1;
161 		if (token == T_EOF) {
162 			val_free(t);
163 			return 0;
164 		}
165 	}
166 	if (token != T_ASSIGN && p_convstr(&t) < 0)
167 		return -1;
168 	cmd = t.v_type == V_STR ? t.v_str : 0;
169 	if ((*(token == T_ASSIGN ? p_assign : p_function))(cmd, &t, flag) < 0) {
170 		if (cmd)
171 			str_free(cmd);
172 		return -1;
173 	}
174 	if (cmd)
175 		str_free(cmd);
176 	val_free(t);
177 	if (token == T_EOL)
178 		(void) s_gettok();
179 	else if (token != T_EOF) {
180 		p_synerror();
181 		return -1;
182 	}
183 	return 0;
184 }
185 
186 p_convstr(v)
187 register struct value *v;
188 {
189 	if (v->v_type != V_NUM)
190 		return 0;
191 	if ((v->v_str = str_itoa(v->v_num)) == 0) {
192 		p_memerror();
193 		v->v_type = V_ERR;
194 		return -1;
195 	}
196 	v->v_type = V_STR;
197 	return 0;
198 }
199 
200 p_synerror()
201 {
202 	if (!cx.x_synerred) {
203 		cx.x_synerred = cx.x_erred = 1;
204 		error("Syntax error.");
205 	}
206 }
207 
208 /*VARARGS1*/
209 p_error(msg, a, b, c)
210 char *msg;
211 {
212 	if (!cx.x_erred) {
213 		cx.x_erred = 1;
214 		error(msg, a, b, c);
215 	}
216 }
217 
218 p_memerror()
219 {
220 	cx.x_erred = cx.x_abort = 1;
221 	error("Out of memory.");
222 }
223