FreeBSD/Linux Kernel Cross Reference
sys/ddb/db_expr.c
1 /*-
2 * Mach Operating System
3 * Copyright (c) 1991,1990 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie the
24 * rights to redistribute these changes.
25 */
26 /*
27 * Author: David B. Golub, Carnegie Mellon University
28 * Date: 7/90
29 */
30
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD: releng/11.0/sys/ddb/db_expr.c 299970 2016-05-16 19:42:38Z pfg $");
33
34 #include <sys/param.h>
35
36 #include <ddb/ddb.h>
37 #include <ddb/db_lex.h>
38 #include <ddb/db_access.h>
39 #include <ddb/db_command.h>
40
41 static bool db_add_expr(db_expr_t *valuep);
42 static bool db_mult_expr(db_expr_t *valuep);
43 static bool db_shift_expr(db_expr_t *valuep);
44 static bool db_term(db_expr_t *valuep);
45 static bool db_unary(db_expr_t *valuep);
46 static bool db_logical_or_expr(db_expr_t *valuep);
47 static bool db_logical_and_expr(db_expr_t *valuep);
48 static bool db_logical_relation_expr(db_expr_t *valuep);
49
50 static bool
51 db_term(db_expr_t *valuep)
52 {
53 int t;
54
55 t = db_read_token();
56 if (t == tIDENT) {
57 if (!db_value_of_name(db_tok_string, valuep) &&
58 !db_value_of_name_pcpu(db_tok_string, valuep) &&
59 !db_value_of_name_vnet(db_tok_string, valuep)) {
60 db_error("Symbol not found\n");
61 /*NOTREACHED*/
62 }
63 return (true);
64 }
65 if (t == tNUMBER) {
66 *valuep = (db_expr_t)db_tok_number;
67 return (true);
68 }
69 if (t == tDOT) {
70 *valuep = (db_expr_t)db_dot;
71 return (true);
72 }
73 if (t == tDOTDOT) {
74 *valuep = (db_expr_t)db_prev;
75 return (true);
76 }
77 if (t == tPLUS) {
78 *valuep = (db_expr_t) db_next;
79 return (true);
80 }
81 if (t == tDITTO) {
82 *valuep = (db_expr_t)db_last_addr;
83 return (true);
84 }
85 if (t == tDOLLAR) {
86 if (!db_get_variable(valuep))
87 return (false);
88 return (true);
89 }
90 if (t == tLPAREN) {
91 if (!db_expression(valuep)) {
92 db_error("Syntax error\n");
93 /*NOTREACHED*/
94 }
95 t = db_read_token();
96 if (t != tRPAREN) {
97 db_error("Syntax error\n");
98 /*NOTREACHED*/
99 }
100 return (true);
101 }
102 db_unread_token(t);
103 return (false);
104 }
105
106 static bool
107 db_unary(db_expr_t *valuep)
108 {
109 int t;
110
111 t = db_read_token();
112 if (t == tMINUS) {
113 if (!db_unary(valuep)) {
114 db_printf("Expression syntax error after '%c'\n", '-');
115 db_error(NULL);
116 /*NOTREACHED*/
117 }
118 *valuep = -*valuep;
119 return (true);
120 }
121 if (t == tEXCL) {
122 if(!db_unary(valuep)) {
123 db_printf("Expression syntax error after '%c'\n", '!');
124 db_error(NULL);
125 /* NOTREACHED */
126 }
127 *valuep = (!(*valuep));
128 return (true);
129 }
130 if (t == tBIT_NOT) {
131 if(!db_unary(valuep)) {
132 db_printf("Expression syntax error after '%c'\n", '~');
133 db_error(NULL);
134 /* NOTREACHED */
135 }
136 *valuep = (~(*valuep));
137 return (true);
138 }
139 if (t == tSTAR) {
140 /* indirection */
141 if (!db_unary(valuep)) {
142 db_printf("Expression syntax error after '%c'\n", '*');
143 db_error(NULL);
144 /*NOTREACHED*/
145 }
146 *valuep = db_get_value((db_addr_t)*valuep, sizeof(void *),
147 false);
148 return (true);
149 }
150 db_unread_token(t);
151 return (db_term(valuep));
152 }
153
154 static bool
155 db_mult_expr(db_expr_t *valuep)
156 {
157 db_expr_t lhs, rhs;
158 int t;
159
160 if (!db_unary(&lhs))
161 return (false);
162
163 t = db_read_token();
164 while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH ||
165 t == tBIT_AND ) {
166 if (!db_term(&rhs)) {
167 db_printf("Expression syntax error after '%c'\n", '!');
168 db_error(NULL);
169 /*NOTREACHED*/
170 }
171 switch(t) {
172 case tSTAR:
173 lhs *= rhs;
174 break;
175 case tBIT_AND:
176 lhs &= rhs;
177 break;
178 default:
179 if (rhs == 0) {
180 db_error("Divide by 0\n");
181 /*NOTREACHED*/
182 }
183 if (t == tSLASH)
184 lhs /= rhs;
185 else if (t == tPCT)
186 lhs %= rhs;
187 else
188 lhs = roundup(lhs, rhs);
189 }
190 t = db_read_token();
191 }
192 db_unread_token(t);
193 *valuep = lhs;
194 return (true);
195 }
196
197 static bool
198 db_add_expr(db_expr_t *valuep)
199 {
200 db_expr_t lhs, rhs;
201 int t;
202 char c;
203
204 if (!db_mult_expr(&lhs))
205 return (false);
206
207 t = db_read_token();
208 while (t == tPLUS || t == tMINUS || t == tBIT_OR) {
209 if (!db_mult_expr(&rhs)) {
210 c = db_tok_string[0];
211 db_printf("Expression syntax error after '%c'\n", c);
212 db_error(NULL);
213 /*NOTREACHED*/
214 }
215 switch (t) {
216 case tPLUS:
217 lhs += rhs;
218 break;
219 case tMINUS:
220 lhs -= rhs;
221 break;
222 case tBIT_OR:
223 lhs |= rhs;
224 break;
225 default:
226 __unreachable();
227 }
228 t = db_read_token();
229 }
230 db_unread_token(t);
231 *valuep = lhs;
232 return (true);
233 }
234
235 static bool
236 db_shift_expr(db_expr_t *valuep)
237 {
238 db_expr_t lhs, rhs;
239 int t;
240
241 if (!db_add_expr(&lhs))
242 return (false);
243 t = db_read_token();
244 while (t == tSHIFT_L || t == tSHIFT_R) {
245 if (!db_add_expr(&rhs)) {
246 db_error("Syntax error\n");
247 /*NOTREACHED*/
248 }
249 if (rhs < 0) {
250 db_error("Negative shift amount\n");
251 /*NOTREACHED*/
252 }
253 if (t == tSHIFT_L)
254 lhs <<= rhs;
255 else {
256 /* Shift right is unsigned */
257 lhs = (unsigned) lhs >> rhs;
258 }
259 t = db_read_token();
260 }
261 db_unread_token(t);
262 *valuep = lhs;
263 return (true);
264 }
265
266 static bool
267 db_logical_relation_expr(
268 db_expr_t *valuep)
269 {
270 db_expr_t lhs, rhs;
271 int t;
272 char op[3];
273
274 if (!db_shift_expr(&lhs))
275 return (false);
276
277 t = db_read_token();
278 while (t == tLOG_EQ || t == tLOG_NOT_EQ || t == tGREATER ||
279 t == tGREATER_EQ || t == tLESS || t == tLESS_EQ) {
280 op[0] = db_tok_string[0];
281 op[1] = db_tok_string[1];
282 op[2] = 0;
283 if (!db_shift_expr(&rhs)) {
284 db_printf("Expression syntax error after \"%s\"\n", op);
285 db_error(NULL);
286 /*NOTREACHED*/
287 }
288 switch(t) {
289 case tLOG_EQ:
290 lhs = (lhs == rhs);
291 break;
292 case tLOG_NOT_EQ:
293 lhs = (lhs != rhs);
294 break;
295 case tGREATER:
296 lhs = (lhs > rhs);
297 break;
298 case tGREATER_EQ:
299 lhs = (lhs >= rhs);
300 break;
301 case tLESS:
302 lhs = (lhs < rhs);
303 break;
304 case tLESS_EQ:
305 lhs = (lhs <= rhs);
306 break;
307 default:
308 __unreachable();
309 }
310 t = db_read_token();
311 }
312 db_unread_token(t);
313 *valuep = lhs;
314 return (true);
315 }
316
317 static bool
318 db_logical_and_expr(
319 db_expr_t *valuep)
320 {
321 db_expr_t lhs, rhs;
322 int t;
323
324 if (!db_logical_relation_expr(&lhs))
325 return (false);
326
327 t = db_read_token();
328 while (t == tLOG_AND) {
329 if (!db_logical_relation_expr(&rhs)) {
330 db_printf("Expression syntax error after '%s'\n", "&&");
331 db_error(NULL);
332 /*NOTREACHED*/
333 }
334 lhs = (lhs && rhs);
335 t = db_read_token();
336 }
337 db_unread_token(t);
338 *valuep = lhs;
339 return (true);
340 }
341
342 static bool
343 db_logical_or_expr(
344 db_expr_t *valuep)
345 {
346 db_expr_t lhs, rhs;
347 int t;
348
349 if (!db_logical_and_expr(&lhs))
350 return(false);
351
352 t = db_read_token();
353 while (t == tLOG_OR) {
354 if (!db_logical_and_expr(&rhs)) {
355 db_printf("Expression syntax error after '%s'\n", "||");
356 db_error(NULL);
357 /*NOTREACHED*/
358 }
359 lhs = (lhs || rhs);
360 t = db_read_token();
361 }
362 db_unread_token(t);
363 *valuep = lhs;
364 return (true);
365 }
366
367 int
368 db_expression(db_expr_t *valuep)
369 {
370 return (db_logical_or_expr(valuep));
371 }
Cache object: 1cdc7c62db7856b05c55324f10310491
|