stdio.h defines BUFSIZ
[unix-history] / usr / src / usr.bin / window / parser4.c
CommitLineData
60de5df9 1/*
46e9ea25
KB
2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved.
4 *
3dd3a9e5
KB
5 * This code is derived from software contributed to Berkeley by
6 * Edward Wang at The University of California, Berkeley.
7 *
87f529ec 8 * %sccs.include.redist.c%
60de5df9
EW
9 */
10
46e9ea25 11#ifndef lint
3dd3a9e5 12static char sccsid[] = "@(#)parser4.c 3.8 (Berkeley) %G%";
46e9ea25
KB
13#endif /* not lint */
14
8318d219
EW
15#include "parser.h"
16
17/*
18 * | 3
19 * ^ 4
20 * & 5
21 * == != 6
22 * < <= > >= 7
23 * << >> 8
24 * + - 9
25 * * / % 10
26 */
27p_expr3_10(level, v, flag)
28register struct value *v;
29char flag;
30{
0180c2d9 31 struct value l, r;
8318d219
EW
32 int op;
33 char *opname;
34
0180c2d9
EW
35 if ((level == 10 ? p_expr11(v, flag)
36 : p_expr3_10(level + 1, v, flag)) < 0)
37 return -1;
8318d219
EW
38 for (;;) {
39 switch (level) {
40 case 3:
41 if (token != T_OR)
42 return 0;
43 opname = "|";
44 break;
45 case 4:
46 if (token != T_XOR)
47 return 0;
48 opname = "^";
49 break;
50 case 5:
51 if (token != T_AND)
52 return 0;
53 opname = "&";
54 break;
55 case 6:
56 if (token == T_EQ)
57 opname = "==";
58 else if (token == T_NE)
59 opname = "!=";
60 else
61 return 0;
62 break;
63 case 7:
64 switch (token) {
65 case T_LT:
66 opname = "<";
67 break;
68 case T_LE:
69 opname = "<=";
70 break;
71 case T_GT:
72 opname = ">";
73 break;
74 case T_GE:
75 opname = ">=";
76 break;
77 default:
78 return 0;
79 }
80 break;
81 case 8:
82 if (token == T_LS)
83 opname = "<<";
84 else if (token == T_RS)
85 opname = ">>";
86 else
87 return 0;
88 break;
89 case 9:
90 if (token == T_PLUS)
91 opname = "+";
92 else if (token == T_MINUS)
93 opname = "-";
94 else
95 return 0;
96 break;
97 case 10:
98 switch (token) {
99 case T_MUL:
100 opname = "*";
101 break;
102 case T_DIV:
103 opname = "/";
104 break;
105 case T_MOD:
106 opname = "%";
107 break;
108 default:
109 return 0;
110 }
111 break;
112 }
0180c2d9
EW
113 l = *v;
114 if (l.v_type == V_ERR)
8318d219
EW
115 flag = 0;
116
117 op = token;
118 (void) s_gettok();
0180c2d9
EW
119 if ((level == 10 ? p_expr11(&r, flag)
120 : p_expr3_10(level + 1, &r, flag)) < 0) {
121 p_synerror();
122 val_free(l);
123 return -1;
8318d219
EW
124 }
125
0180c2d9 126 if (r.v_type == V_ERR)
8318d219 127 flag = 0;
0180c2d9 128 else switch (op) {
8318d219
EW
129 case T_EQ:
130 case T_NE:
131 case T_LT:
132 case T_LE:
133 case T_GT:
134 case T_GE:
0180c2d9
EW
135 case T_PLUS:
136 if (l.v_type == V_STR) {
137 if (r.v_type == V_NUM)
138 if (p_convstr(&r) < 0)
139 flag = 0;
140 } else
141 if (r.v_type == V_STR)
142 if (p_convstr(&l) < 0)
143 flag = 0;
144 break;
145 case T_LS:
146 case T_RS:
147 if (r.v_type == V_STR) {
148 char *p = r.v_str;
149 r.v_type = V_NUM;
150 r.v_num = strlen(p);
151 str_free(p);
8318d219
EW
152 }
153 break;
0180c2d9
EW
154 case T_OR:
155 case T_XOR:
156 case T_AND:
157 case T_MINUS:
158 case T_MUL:
159 case T_DIV:
160 case T_MOD:
8318d219 161 default:
0180c2d9
EW
162 if (l.v_type == V_STR || r.v_type == V_STR) {
163 p_error("%s: Numeric operands required.",
8318d219
EW
164 opname);
165 flag = 0;
166 }
167 }
8318d219 168 if (!flag) {
0180c2d9
EW
169 val_free(l);
170 val_free(r);
8318d219 171 v->v_type = V_ERR;
0180c2d9
EW
172 if (p_abort())
173 return -1;
8318d219
EW
174 continue;
175 }
176
0180c2d9
EW
177 v->v_type = V_NUM;
178 switch (op) {
179 case T_EQ:
180 case T_NE:
181 case T_LT:
182 case T_LE:
183 case T_GT:
184 case T_GE:
185 if (l.v_type == V_STR) {
186 int tmp = strcmp(l.v_str, r.v_str);
187 str_free(l.v_str);
188 str_free(r.v_str);
189 l.v_type = V_NUM;
190 l.v_num = tmp;
191 r.v_type = V_NUM;
192 r.v_num = 0;
193 }
194 break;
195 }
8318d219
EW
196 switch (op) {
197 case T_OR:
0180c2d9 198 v->v_num = l.v_num | r.v_num;
8318d219
EW
199 break;
200 case T_XOR:
0180c2d9 201 v->v_num = l.v_num ^ r.v_num;
8318d219
EW
202 break;
203 case T_AND:
0180c2d9 204 v->v_num = l.v_num & r.v_num;
8318d219
EW
205 break;
206 case T_EQ:
0180c2d9 207 v->v_num = l.v_num == r.v_num;
8318d219
EW
208 break;
209 case T_NE:
0180c2d9 210 v->v_num = l.v_num != r.v_num;
8318d219
EW
211 break;
212 case T_LT:
0180c2d9 213 v->v_num = l.v_num < r.v_num;
8318d219
EW
214 break;
215 case T_LE:
0180c2d9 216 v->v_num = l.v_num <= r.v_num;
8318d219
EW
217 break;
218 case T_GT:
0180c2d9 219 v->v_num = l.v_num > r.v_num;
8318d219
EW
220 break;
221 case T_GE:
0180c2d9 222 v->v_num = l.v_num >= r.v_num;
8318d219
EW
223 break;
224 case T_LS:
0180c2d9
EW
225 if (l.v_type == V_STR) {
226 int i;
227 if ((i = strlen(l.v_str)) > r.v_num)
228 i = r.v_num;
229 v->v_str = str_ncpy(l.v_str, i);
230 v->v_type = V_STR;
231 } else
232 v->v_num = l.v_num << r.v_num;
8318d219
EW
233 break;
234 case T_RS:
0180c2d9
EW
235 if (l.v_type == V_STR) {
236 int i;
237 if ((i = strlen(l.v_str)) > r.v_num)
238 i -= r.v_num;
239 else
240 i = 0;
241 v->v_str = str_cpy(l.v_str + i);
242 v->v_type = V_STR;
243 } else
244 v->v_num = l.v_num >> r.v_num;
8318d219
EW
245 break;
246 case T_PLUS:
0180c2d9
EW
247 if (l.v_type == V_STR) {
248 v->v_str = str_cat(l.v_str, r.v_str);
249 v->v_type = V_STR;
250 } else
251 v->v_num = l.v_num + r.v_num;
8318d219
EW
252 break;
253 case T_MINUS:
0180c2d9 254 v->v_num = l.v_num - r.v_num;
8318d219
EW
255 break;
256 case T_MUL:
0180c2d9 257 v->v_num = l.v_num * r.v_num;
8318d219
EW
258 break;
259 case T_DIV:
0180c2d9 260 v->v_num = l.v_num / r.v_num;
8318d219
EW
261 break;
262 case T_MOD:
0180c2d9 263 v->v_num = l.v_num % r.v_num;
8318d219
EW
264 break;
265 }
0180c2d9
EW
266 val_free(l);
267 val_free(r);
8318d219
EW
268 }
269 /*NOTREACHED*/
270}