FreeBSD/Linux Kernel Cross Reference
sys/ddb/db_expr.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1993,1992,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 "AS IS"
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 Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: db_expr.c,v $
29 * Revision 2.9 93/11/17 16:22:01 dbg
30 * ANSI-fied.
31 * [93/10/11 dbg]
32 *
33 * Revision 2.8 93/01/14 17:24:58 danner
34 * 64bit cleanup.
35 * [92/11/30 af]
36 *
37 * Revision 2.7 92/08/03 17:31:06 jfriedl
38 * removed silly prototypes
39 * [92/08/02 jfriedl]
40 *
41 * Revision 2.6 92/05/21 17:06:51 jfriedl
42 * Removed unused variable from db_unary().
43 * [92/05/16 jfriedl]
44 *
45 * Revision 2.5 91/10/09 15:59:46 af
46 * Added relational expression etc. to support condition expression.
47 * Supported modifier after indirect expression to specify size,
48 * sign extension and non current task space indirection.
49 * Changed error messages to print more information.
50 * [91/08/29 tak]
51 *
52 * Revision 2.4 91/05/14 15:33:45 mrt
53 * Correcting copyright
54 *
55 * Revision 2.3 91/02/05 17:06:25 mrt
56 * Changed to new Mach copyright
57 * [91/01/31 16:17:46 mrt]
58 *
59 * Revision 2.2 90/08/27 21:50:57 dbg
60 * Use '..' instead of '$$' for db_prev.
61 * Use '+' for db_next.
62 * [90/08/22 dbg]
63 *
64 * Allow repeated unary operators.
65 * [90/08/20 dbg]
66 *
67 * Reflected back rename of db_symbol_value->db_value_of_name
68 * [90/08/20 af]
69 * Reduce lint.
70 * [90/08/07 dbg]
71 * Created.
72 * [90/07/25 dbg]
73 *
74 */
75 /*
76 * Author: David B. Golub, Carnegie Mellon University
77 * Date: 7/90
78 */
79 #include <mach/boolean.h>
80 #include <machine/db_machdep.h>
81 #include <ddb/db_lex.h>
82 #include <ddb/db_access.h>
83 #include <ddb/db_command.h>
84 #include <ddb/db_output.h>
85 #include <ddb/db_sym.h>
86 #include <kern/task.h>
87
88
89 boolean_t
90 db_term(
91 db_expr_t *valuep)
92 {
93 int t;
94
95 switch(t = db_read_token()) {
96 case tIDENT:
97 if (!db_value_of_name(db_tok_string, valuep)) {
98 db_printf("Symbol \"%s\" not found\n", db_tok_string);
99 db_error(0);
100 /*NOTREACHED*/
101 }
102 return TRUE;
103 case tNUMBER:
104 *valuep = db_tok_number;
105 return TRUE;
106 case tDOT:
107 *valuep = (db_expr_t)db_dot;
108 return TRUE;
109 case tDOTDOT:
110 *valuep = (db_expr_t)db_prev;
111 return TRUE;
112 case tPLUS:
113 *valuep = (db_expr_t) db_next;
114 return TRUE;
115 case tQUOTE:
116 *valuep = (db_expr_t)db_last_addr;
117 return TRUE;
118 case tDOLLAR:
119 if (!db_get_variable(valuep))
120 return FALSE;
121 return TRUE;
122 case tLPAREN:
123 if (!db_expression(valuep)) {
124 db_error("Unmatched ()s\n");
125 /*NOTREACHED*/
126 }
127 t = db_read_token();
128 if (t != tRPAREN) {
129 db_printf("')' expected at \"%s...\"\n", db_tok_string);
130 db_error(0);
131 /*NOTREACHED*/
132 }
133 return TRUE;
134 default:
135 db_unread_token(t);
136 return FALSE;
137 }
138 }
139
140 int
141 db_size_option(
142 char *modif,
143 boolean_t *u_option,
144 boolean_t *t_option)
145 {
146 register char *p;
147 int size = sizeof(int);
148
149 *u_option = FALSE;
150 *t_option = FALSE;
151 for (p = modif; *p; p++) {
152 switch(*p) {
153 case 'b':
154 size = sizeof(char);
155 break;
156 case 'h':
157 size = sizeof(short);
158 break;
159 case 'l':
160 size = sizeof(long);
161 break;
162 case 'u':
163 *u_option = TRUE;
164 break;
165 case 't':
166 *t_option = TRUE;
167 break;
168 }
169 }
170 return size;
171 }
172
173 boolean_t
174 db_unary(
175 db_expr_t *valuep)
176 {
177 int t;
178 int size;
179 boolean_t u_opt, t_opt;
180 task_t task;
181 extern task_t db_default_task;
182
183 t = db_read_token();
184 if (t == tMINUS) {
185 if (!db_unary(valuep)) {
186 db_error("Expression syntax error after '-'\n");
187 /*NOTREACHED*/
188 }
189 *valuep = -*valuep;
190 return TRUE;
191 }
192 if (t == tSTAR) {
193 /* indirection */
194 if (!db_unary(valuep)) {
195 db_error("Expression syntax error after '*'\n");
196 /*NOTREACHED*/
197 }
198 task = TASK_NULL;
199 size = sizeof(db_addr_t);
200 u_opt = FALSE;
201 t = db_read_token();
202 if (t == tIDENT && db_tok_string[0] == ':') {
203 size = db_size_option(&db_tok_string[1], &u_opt, &t_opt);
204 if (t_opt)
205 task = db_default_task;
206 } else
207 db_unread_token(t);
208 *valuep = db_get_task_value((db_addr_t)*valuep, size, !u_opt, task);
209 return TRUE;
210 }
211 if (t == tEXCL) {
212 if (!db_unary(valuep)) {
213 db_error("Expression syntax error after '!'\n");
214 /*NOTREACHED*/
215 }
216 *valuep = (!(*valuep));
217 return TRUE;
218 }
219 db_unread_token(t);
220 return db_term(valuep);
221 }
222
223 boolean_t
224 db_mult_expr(
225 db_expr_t *valuep)
226 {
227 db_expr_t lhs, rhs;
228 int t;
229 char c;
230
231 if (!db_unary(&lhs))
232 return FALSE;
233
234 t = db_read_token();
235 while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH
236 || t == tBIT_AND) {
237 c = db_tok_string[0];
238 if (!db_term(&rhs)) {
239 db_printf("Expression syntax error after '%c'\n", c);
240 db_error(0);
241 /*NOTREACHED*/
242 }
243 switch(t) {
244 case tSTAR:
245 lhs *= rhs;
246 break;
247 case tBIT_AND:
248 lhs &= rhs;
249 break;
250 default:
251 if (rhs == 0) {
252 db_error("Divide by 0\n");
253 /*NOTREACHED*/
254 }
255 if (t == tSLASH)
256 lhs /= rhs;
257 else if (t == tPCT)
258 lhs %= rhs;
259 else
260 lhs = ((lhs+rhs-1)/rhs)*rhs;
261 }
262 t = db_read_token();
263 }
264 db_unread_token(t);
265 *valuep = lhs;
266 return TRUE;
267 }
268
269 boolean_t
270 db_add_expr(
271 db_expr_t *valuep)
272 {
273 db_expr_t lhs, rhs;
274 int t;
275 char c;
276
277 if (!db_mult_expr(&lhs))
278 return FALSE;
279
280 t = db_read_token();
281 while (t == tPLUS || t == tMINUS || t == tBIT_OR) {
282 c = db_tok_string[0];
283 if (!db_mult_expr(&rhs)) {
284 db_printf("Expression syntax error after '%c'\n", c);
285 db_error(0);
286 /*NOTREACHED*/
287 }
288 if (t == tPLUS)
289 lhs += rhs;
290 else if (t == tMINUS)
291 lhs -= rhs;
292 else
293 lhs |= rhs;
294 t = db_read_token();
295 }
296 db_unread_token(t);
297 *valuep = lhs;
298 return TRUE;
299 }
300
301 boolean_t
302 db_shift_expr(
303 db_expr_t *valuep)
304 {
305 db_expr_t lhs, rhs;
306 int t;
307
308 if (!db_add_expr(&lhs))
309 return FALSE;
310
311 t = db_read_token();
312 while (t == tSHIFT_L || t == tSHIFT_R) {
313 if (!db_add_expr(&rhs)) {
314 db_printf("Expression syntax error after \"%s\"\n",
315 (t == tSHIFT_L)? "<<": ">>");
316 db_error(0);
317 /*NOTREACHED*/
318 }
319 if (rhs < 0) {
320 db_error("Negative shift amount\n");
321 /*NOTREACHED*/
322 }
323 if (t == tSHIFT_L)
324 lhs <<= rhs;
325 else {
326 /* Shift right is unsigned */
327 lhs = (natural_t) lhs >> rhs;
328 }
329 t = db_read_token();
330 }
331 db_unread_token(t);
332 *valuep = lhs;
333 return TRUE;
334 }
335
336 boolean_t
337 db_logical_relation_expr(
338 db_expr_t *valuep)
339 {
340 db_expr_t lhs, rhs;
341 int t;
342 char op[3];
343
344 if (!db_shift_expr(&lhs))
345 return FALSE;
346
347 t = db_read_token();
348 while (t == tLOG_EQ || t == tLOG_NOT_EQ
349 || t == tGREATER || t == tGREATER_EQ
350 || t == tLESS || t == tLESS_EQ) {
351 op[0] = db_tok_string[0];
352 op[1] = db_tok_string[1];
353 op[2] = 0;
354 if (!db_shift_expr(&rhs)) {
355 db_printf("Expression syntax error after \"%s\"\n", op);
356 db_error(0);
357 /*NOTREACHED*/
358 }
359 switch(t) {
360 case tLOG_EQ:
361 lhs = (lhs == rhs);
362 break;
363 case tLOG_NOT_EQ:
364 lhs = (lhs != rhs);
365 break;
366 case tGREATER:
367 lhs = (lhs > rhs);
368 break;
369 case tGREATER_EQ:
370 lhs = (lhs >= rhs);
371 break;
372 case tLESS:
373 lhs = (lhs < rhs);
374 break;
375 case tLESS_EQ:
376 lhs = (lhs <= rhs);
377 break;
378 }
379 t = db_read_token();
380 }
381 db_unread_token(t);
382 *valuep = lhs;
383 return TRUE;
384 }
385
386 boolean_t
387 db_logical_and_expr(
388 db_expr_t *valuep)
389 {
390 db_expr_t lhs, rhs;
391 int t;
392
393 if (!db_logical_relation_expr(&lhs))
394 return FALSE;
395
396 t = db_read_token();
397 while (t == tLOG_AND) {
398 if (!db_logical_relation_expr(&rhs)) {
399 db_error("Expression syntax error after \"&&\"\n");
400 /*NOTREACHED*/
401 }
402 lhs = (lhs && rhs);
403 }
404 db_unread_token(t);
405 *valuep = lhs;
406 return TRUE;
407 }
408
409 boolean_t
410 db_logical_or_expr(
411 db_expr_t *valuep)
412 {
413 db_expr_t lhs, rhs;
414 int t;
415
416 if (!db_logical_and_expr(&lhs))
417 return(FALSE);
418
419 t = db_read_token();
420 while (t == tLOG_OR) {
421 if (!db_logical_and_expr(&rhs)) {
422 db_error("Expression syntax error after \"||\"\n");
423 /*NOTREACHED*/
424 }
425 lhs = (lhs || rhs);
426 }
427 db_unread_token(t);
428 *valuep = lhs;
429 return TRUE;
430 }
431
432 boolean_t
433 db_expression(
434 db_expr_t *valuep)
435 {
436 return db_logical_or_expr(valuep);
437 }
Cache object: 4636d6ec6f55dd06249f421ec7c82a61
|