Annotation of src/usr.bin/window/parser4.c, Revision 1.4
1.4 ! mpech 1: /* $OpenBSD: parser4.c,v 1.3 1997/02/25 00:04:14 downsj Exp $ */
1.1 deraadt 2: /* $NetBSD: parser4.c,v 1.5 1995/09/29 00:44:05 cgd Exp $ */
3:
4: /*
5: * Copyright (c) 1983, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * This code is derived from software contributed to Berkeley by
9: * Edward Wang at The University of California, Berkeley.
10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
19: * 3. All advertising materials mentioning features or use of this software
20: * must display the following acknowledgement:
21: * This product includes software developed by the University of
22: * California, Berkeley and its contributors.
23: * 4. Neither the name of the University nor the names of its contributors
24: * may be used to endorse or promote products derived from this software
25: * without specific prior written permission.
26: *
27: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37: * SUCH DAMAGE.
38: */
39:
40: #ifndef lint
41: #if 0
42: static char sccsid[] = "@(#)parser4.c 8.1 (Berkeley) 6/6/93";
43: #else
1.4 ! mpech 44: static char rcsid[] = "$OpenBSD: parser4.c,v 1.3 1997/02/25 00:04:14 downsj Exp $";
1.1 deraadt 45: #endif
46: #endif /* not lint */
47:
48: #include "parser.h"
49: #include <string.h>
50:
51: /*
52: * | 3
53: * ^ 4
54: * & 5
55: * == != 6
56: * < <= > >= 7
57: * << >> 8
58: * + - 9
59: * * / % 10
60: */
61: p_expr3_10(level, v, flag)
1.4 ! mpech 62: struct value *v;
1.1 deraadt 63: char flag;
64: {
65: struct value l, r;
66: int op;
67: char *opname;
68:
69: if ((level == 10 ? p_expr11(v, flag)
70: : p_expr3_10(level + 1, v, flag)) < 0)
71: return -1;
72: for (;;) {
73: switch (level) {
74: case 3:
75: if (token != T_OR)
76: return 0;
77: opname = "|";
78: break;
79: case 4:
80: if (token != T_XOR)
81: return 0;
82: opname = "^";
83: break;
84: case 5:
85: if (token != T_AND)
86: return 0;
87: opname = "&";
88: break;
89: case 6:
90: if (token == T_EQ)
91: opname = "==";
92: else if (token == T_NE)
93: opname = "!=";
94: else
95: return 0;
96: break;
97: case 7:
98: switch (token) {
99: case T_LT:
100: opname = "<";
101: break;
102: case T_LE:
103: opname = "<=";
104: break;
105: case T_GT:
106: opname = ">";
107: break;
108: case T_GE:
109: opname = ">=";
110: break;
111: default:
112: return 0;
113: }
114: break;
115: case 8:
116: if (token == T_LS)
117: opname = "<<";
118: else if (token == T_RS)
119: opname = ">>";
120: else
121: return 0;
122: break;
123: case 9:
124: if (token == T_PLUS)
125: opname = "+";
126: else if (token == T_MINUS)
127: opname = "-";
128: else
129: return 0;
130: break;
131: case 10:
132: switch (token) {
133: case T_MUL:
134: opname = "*";
135: break;
136: case T_DIV:
137: opname = "/";
138: break;
139: case T_MOD:
140: opname = "%";
141: break;
142: default:
143: return 0;
144: }
145: break;
146: }
147: l = *v;
148: if (l.v_type == V_ERR)
149: flag = 0;
150:
151: op = token;
152: (void) s_gettok();
153: if ((level == 10 ? p_expr11(&r, flag)
154: : p_expr3_10(level + 1, &r, flag)) < 0) {
155: p_synerror();
156: val_free(l);
157: return -1;
158: }
159:
160: if (r.v_type == V_ERR)
161: flag = 0;
162: else switch (op) {
163: case T_EQ:
164: case T_NE:
165: case T_LT:
166: case T_LE:
167: case T_GT:
168: case T_GE:
169: case T_PLUS:
170: if (l.v_type == V_STR) {
171: if (r.v_type == V_NUM)
172: if (p_convstr(&r) < 0)
173: flag = 0;
174: } else
175: if (r.v_type == V_STR)
176: if (p_convstr(&l) < 0)
177: flag = 0;
178: break;
179: case T_LS:
180: case T_RS:
181: if (r.v_type == V_STR) {
182: char *p = r.v_str;
183: r.v_type = V_NUM;
184: r.v_num = strlen(p);
185: str_free(p);
186: }
187: break;
188: case T_OR:
189: case T_XOR:
190: case T_AND:
191: case T_MINUS:
192: case T_MUL:
193: case T_DIV:
194: case T_MOD:
195: default:
196: if (l.v_type == V_STR || r.v_type == V_STR) {
197: p_error("%s: Numeric operands required.",
198: opname);
199: flag = 0;
200: }
201: }
202: if (!flag) {
203: val_free(l);
204: val_free(r);
205: v->v_type = V_ERR;
206: if (p_abort())
207: return -1;
208: continue;
209: }
210:
211: v->v_type = V_NUM;
212: switch (op) {
213: case T_EQ:
214: case T_NE:
215: case T_LT:
216: case T_LE:
217: case T_GT:
218: case T_GE:
219: if (l.v_type == V_STR) {
220: int tmp = strcmp(l.v_str, r.v_str);
221: str_free(l.v_str);
222: str_free(r.v_str);
223: l.v_type = V_NUM;
224: l.v_num = tmp;
225: r.v_type = V_NUM;
226: r.v_num = 0;
227: }
228: break;
229: }
230: switch (op) {
231: case T_OR:
232: v->v_num = l.v_num | r.v_num;
233: break;
234: case T_XOR:
235: v->v_num = l.v_num ^ r.v_num;
236: break;
237: case T_AND:
238: v->v_num = l.v_num & r.v_num;
239: break;
240: case T_EQ:
241: v->v_num = l.v_num == r.v_num;
242: break;
243: case T_NE:
244: v->v_num = l.v_num != r.v_num;
245: break;
246: case T_LT:
247: v->v_num = l.v_num < r.v_num;
248: break;
249: case T_LE:
250: v->v_num = l.v_num <= r.v_num;
251: break;
252: case T_GT:
253: v->v_num = l.v_num > r.v_num;
254: break;
255: case T_GE:
256: v->v_num = l.v_num >= r.v_num;
257: break;
258: case T_LS:
259: if (l.v_type == V_STR) {
260: int i;
261: if ((i = strlen(l.v_str)) > r.v_num)
262: i = r.v_num;
263: v->v_str = str_ncpy(l.v_str, i);
264: v->v_type = V_STR;
265: } else
266: v->v_num = l.v_num << r.v_num;
267: break;
268: case T_RS:
269: if (l.v_type == V_STR) {
270: int i;
271: if ((i = strlen(l.v_str)) > r.v_num)
272: i -= r.v_num;
273: else
274: i = 0;
275: v->v_str = str_cpy(l.v_str + i);
276: v->v_type = V_STR;
277: } else
278: v->v_num = l.v_num >> r.v_num;
279: break;
280: case T_PLUS:
281: if (l.v_type == V_STR) {
282: v->v_str = str_cat(l.v_str, r.v_str);
283: v->v_type = V_STR;
284: } else
285: v->v_num = l.v_num + r.v_num;
286: break;
287: case T_MINUS:
288: v->v_num = l.v_num - r.v_num;
289: break;
290: case T_MUL:
291: v->v_num = l.v_num * r.v_num;
292: break;
293: case T_DIV:
294: v->v_num = l.v_num / r.v_num;
295: break;
296: case T_MOD:
297: v->v_num = l.v_num % r.v_num;
298: break;
299: }
300: val_free(l);
301: val_free(r);
302: }
303: /*NOTREACHED*/
304: }