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