|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * @OSF_COPYRIGHT@
24: */
25: /*
26: * HISTORY
27: *
28: * Revision 1.1.1.1 1998/09/22 21:05:48 wsanchez
29: * Import of Mac OS X kernel (~semeria)
30: *
31: * Revision 1.1.1.1 1998/03/07 02:26:09 wsanchez
32: * Import of OSF Mach kernel (~mburg)
33: *
34: * Revision 1.2.19.1 1997/03/27 18:46:35 barbou
35: * ri-osc CR1561: make operators "logical and", "logical or"
36: * lex correctly.
37: * [1995/09/20 15:26:38 bolinger]
38: * [97/02/25 barbou]
39: *
40: * Revision 1.2.10.2 1995/01/06 19:10:13 devrcs
41: * mk6 CR668 - 1.3b26 merge
42: * * Revision 1.2.3.5 1994/05/06 18:39:16 tmt
43: * Merged osc1.3dec/shared with osc1.3b19
44: * Merge Alpha changes into osc1.312b source code.
45: * 64bit cleanup.
46: * * End1.3merge
47: * [1994/11/04 08:49:27 dwm]
48: *
49: * Revision 1.2.10.1 1994/09/23 01:19:06 ezf
50: * change marker to not FREE
51: * [1994/09/22 21:09:53 ezf]
52: *
53: * Revision 1.2.3.3 1993/07/27 18:27:15 elliston
54: * Add ANSI prototypes. CR #9523.
55: * [1993/07/27 18:11:36 elliston]
56: *
57: * Revision 1.2.3.2 1993/06/09 02:20:06 gm
58: * Added to OSF/1 R1.3 from NMK15.0.
59: * [1993/06/02 20:56:16 jeffc]
60: *
61: * Revision 1.2 1993/04/19 16:02:09 devrcs
62: * Allow unprefixed (0x) hexadecimal constants starting by a letter:
63: * unknown symbols are tentatively interpreted as hexadecimal constants,
64: * and ambiguities are reported.
65: * [93/03/24 barbou]
66: *
67: * Changes from mk78:
68: * Removed unused variable from db_unary().
69: * [92/05/16 jfriedl]
70: * [93/02/02 bruel]
71: *
72: * Added string format arguments [[email protected]]
73: * [92/12/03 bernadat]
74: *
75: * Revision 1.1 1992/09/30 02:01:04 robert
76: * Initial revision
77: *
78: * $EndLog$
79: */
80: /* CMU_HIST */
81: /*
82: * Revision 2.5 91/10/09 15:59:46 af
83: * Revision 2.4.3.1 91/10/05 13:06:04 jeffreyh
84: * Added relational expression etc. to support condition expression.
85: * Supported modifier after indirect expression to specify size,
86: * sign extention and non current task space indirection.
87: * Changed error messages to print more information.
88: * [91/08/29 tak]
89: *
90: * Revision 2.4.3.1 91/10/05 13:06:04 jeffreyh
91: * Added relational expression etc. to support condition expression.
92: * Supported modifier after indirect expression to specify size,
93: * sign extention and non current task space indirection.
94: * Changed error messages to print more information.
95: * [91/08/29 tak]
96: *
97: * Revision 2.4 91/05/14 15:33:45 mrt
98: * Correcting copyright
99: *
100: * Revision 2.3 91/02/05 17:06:25 mrt
101: * Changed to new Mach copyright
102: * [91/01/31 16:17:46 mrt]
103: *
104: * Revision 2.2 90/08/27 21:50:57 dbg
105: * Use '..' instead of '$$' for db_prev.
106: * Use '+' for db_next.
107: * [90/08/22 dbg]
108: *
109: * Allow repeated unary operators.
110: * [90/08/20 dbg]
111: *
112: * Reflected back rename of db_symbol_value->db_value_of_name
113: * [90/08/20 af]
114: * Reduce lint.
115: * [90/08/07 dbg]
116: * Created.
117: * [90/07/25 dbg]
118: *
119: */
120: /* CMU_ENDHIST */
121: /*
122: * Mach Operating System
123: * Copyright (c) 1991,1990 Carnegie Mellon University
124: * All Rights Reserved.
125: *
126: * Permission to use, copy, modify and distribute this software and its
127: * documentation is hereby granted, provided that both the copyright
128: * notice and this permission notice appear in all copies of the
129: * software, derivative works or modified versions, and any portions
130: * thereof, and that both notices appear in supporting documentation.
131: *
132: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
133: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
134: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
135: *
136: * Carnegie Mellon requests users of this software to return to
137: *
138: * Software Distribution Coordinator or [email protected]
139: * School of Computer Science
140: * Carnegie Mellon University
141: * Pittsburgh PA 15213-3890
142: *
143: * any improvements or extensions that they make and grant Carnegie Mellon
144: * the rights to redistribute these changes.
145: */
146: /*
147: */
148: /*
149: * Author: David B. Golub, Carnegie Mellon University
150: * Date: 7/90
151: */
152:
153: #include <mach/boolean.h>
154: #include <machine/db_machdep.h>
155: #include <ddb/db_access.h>
156: #include <ddb/db_command.h>
157: #include <ddb/db_expr.h>
158: #include <ddb/db_lex.h>
159: #include <ddb/db_output.h> /* For db_printf() */
160: #include <ddb/db_sym.h>
161: #include <ddb/db_variables.h>
162: #include <kern/task.h>
163:
164:
165:
166: /* Prototypes for functions local to this file. XXX -- should be static!
167: */
168: boolean_t db_term(db_expr_t *valuep);
169: boolean_t db_unary(db_expr_t *valuep);
170: boolean_t db_mult_expr(db_expr_t *valuep);
171: boolean_t db_add_expr(db_expr_t *valuep);
172: boolean_t db_shift_expr(db_expr_t *valuep);
173: boolean_t db_logical_relation_expr(db_expr_t *valuep);
174: boolean_t db_logical_and_expr(db_expr_t *valuep);
175: boolean_t db_logical_or_expr(db_expr_t *valuep);
176:
177:
178: /* try to interpret unknown symbols as hexadecimal constants */
179: int db_allow_unprefixed_hexa = 1;
180:
181: boolean_t
182: db_term(db_expr_t *valuep)
183: {
184: int t;
185: boolean_t valid_symbol = FALSE;
186: boolean_t valid_hexa = FALSE;
187:
188: switch(t = db_read_token()) {
189: case tIDENT:
190: if (db_value_of_name(db_tok_string, valuep)) {
191: valid_symbol = TRUE;
192: }
193: if (db_allow_unprefixed_hexa && db_radix == 16 &&
194: db_tok_string) {
195: char *cp;
196: int value;
197:
198: value = 0;
199: valid_hexa = TRUE;
200: for (cp = db_tok_string; *cp; cp++) {
201: if (*cp >= 'a' && *cp <= 'f') {
202: value = value * 16 + 10 + (*cp - 'a');
203: } else if (*cp >= 'A' && *cp <= 'F') {
204: value = value * 16 + 10 + (*cp - 'A');
205: } else if (*cp >= '0' && *cp <= '9') {
206: value = value * 16 + (*cp - '0');
207: } else {
208: valid_hexa = FALSE;
209: break;
210: }
211: }
212: if (valid_hexa) {
213: if (valid_symbol) {
214: db_printf("Ambiguous constant %x used as a symbol\n",
215: value);
216: } else {
217: *valuep = (db_expr_t)value;
218: }
219: }
220: }
221: if (!valid_symbol && !valid_hexa) {
222: db_printf("Symbol \"%s\" not found\n", db_tok_string);
223: db_error(0);
224: /*NOTREACHED*/
225: }
226: return (TRUE);
227: case tNUMBER:
228: *valuep = /*(db_expr_t)*/db_tok_number;
229: return (TRUE);
230: case tDOT:
231: *valuep = (db_expr_t)db_dot;
232: return (TRUE);
233: case tDOTDOT:
234: *valuep = (db_expr_t)db_prev;
235: return (TRUE);
236: case tPLUS:
237: *valuep = (db_expr_t) db_next;
238: return (TRUE);
239: case tQUOTE:
240: *valuep = (db_expr_t)db_last_addr;
241: return (TRUE);
242: case tDOLLAR:
243: if (!db_get_variable(valuep))
244: return (FALSE);
245: return (TRUE);
246: case tLPAREN:
247: if (!db_expression(valuep)) {
248: db_error("Unmached ()s\n");
249: /*NOTREACHED*/
250: }
251: t = db_read_token();
252: if (t != tRPAREN) {
253: db_printf("')' expected at \"%s...\"\n", db_tok_string);
254: db_error(0);
255: /*NOTREACHED*/
256: }
257: return (TRUE);
258: case tSTRING:
259: {
260: static db_tok_offset = 0;
261: char *sp, *cp;
262:
263: sp = (char *)db_tok_string + db_tok_offset;
264: *valuep = *(int *)sp;
265: for (cp = sp;
266: *cp && cp < sp + sizeof (int);
267: cp++);
268: if (cp == sp + sizeof (int) && *cp) {
269: db_tok_offset += sizeof (int);
270: db_unread_token(t);
271: } else {
272: db_tok_offset = 0;
273: }
274: return (TRUE);
275: }
276: default:
277: db_unread_token(t);
278: return (FALSE);
279: }
280: }
281:
282: int
283: db_size_option(
284: char *modif,
285: boolean_t *u_option,
286: boolean_t *t_option)
287: {
288: register char *p;
289: int size = sizeof(int);
290:
291: *u_option = FALSE;
292: *t_option = FALSE;
293: for (p = modif; *p; p++) {
294: switch(*p) {
295: case 'b':
296: size = sizeof(char);
297: break;
298: case 'h':
299: size = sizeof(short);
300: break;
301: case 'l':
302: size = sizeof(long);
303: break;
304: case 'u':
305: *u_option = TRUE;
306: break;
307: case 't':
308: *t_option = TRUE;
309: break;
310: }
311: }
312: return(size);
313: }
314:
315: boolean_t
316: db_unary(db_expr_t *valuep)
317: {
318: int t;
319: int size;
320: boolean_t u_opt, t_opt;
321: task_t task;
322: extern task_t db_default_task;
323:
324: t = db_read_token();
325: if (t == tMINUS) {
326: if (!db_unary(valuep)) {
327: db_error("Expression syntax error after '-'\n");
328: /*NOTREACHED*/
329: }
330: *valuep = -*valuep;
331: return (TRUE);
332: }
333: if (t == tSTAR) {
334: /* indirection */
335: if (!db_unary(valuep)) {
336: db_error("Expression syntax error after '*'\n");
337: /*NOTREACHED*/
338: }
339: task = TASK_NULL;
340: size = sizeof(db_addr_t);
341: u_opt = FALSE;
342: t = db_read_token();
343: if (t == tIDENT && db_tok_string[0] == ':') {
344: size = db_size_option(&db_tok_string[1], &u_opt, &t_opt);
345: if (t_opt)
346: task = db_default_task;
347: } else
348: db_unread_token(t);
349: *valuep = db_get_task_value((db_addr_t)*valuep, size, !u_opt, task);
350: return (TRUE);
351: }
352: if (t == tEXCL) {
353: if (!db_unary(valuep)) {
354: db_error("Expression syntax error after '!'\n");
355: /*NOTREACHED*/
356: }
357: *valuep = (!(*valuep));
358: return (TRUE);
359: }
360: db_unread_token(t);
361: return (db_term(valuep));
362: }
363:
364: boolean_t
365: db_mult_expr(db_expr_t *valuep)
366: {
367: db_expr_t lhs, rhs;
368: int t;
369: char c;
370:
371: if (!db_unary(&lhs))
372: return (FALSE);
373:
374: t = db_read_token();
375: while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH
376: || t == tBIT_AND) {
377: c = db_tok_string[0];
378: if (!db_term(&rhs)) {
379: db_printf("Expression syntax error after '%c'\n", c);
380: db_error(0);
381: /*NOTREACHED*/
382: }
383: switch(t) {
384: case tSTAR:
385: lhs *= rhs;
386: break;
387: case tBIT_AND:
388: lhs &= rhs;
389: break;
390: default:
391: if (rhs == 0) {
392: db_error("Divide by 0\n");
393: /*NOTREACHED*/
394: }
395: if (t == tSLASH)
396: lhs /= rhs;
397: else if (t == tPCT)
398: lhs %= rhs;
399: else
400: lhs = ((lhs+rhs-1)/rhs)*rhs;
401: }
402: t = db_read_token();
403: }
404: db_unread_token(t);
405: *valuep = lhs;
406: return (TRUE);
407: }
408:
409: boolean_t
410: db_add_expr(db_expr_t *valuep)
411: {
412: db_expr_t lhs, rhs;
413: int t;
414: char c;
415:
416: if (!db_mult_expr(&lhs))
417: return (FALSE);
418:
419: t = db_read_token();
420: while (t == tPLUS || t == tMINUS || t == tBIT_OR) {
421: c = db_tok_string[0];
422: if (!db_mult_expr(&rhs)) {
423: db_printf("Expression syntax error after '%c'\n", c);
424: db_error(0);
425: /*NOTREACHED*/
426: }
427: if (t == tPLUS)
428: lhs += rhs;
429: else if (t == tMINUS)
430: lhs -= rhs;
431: else
432: lhs |= rhs;
433: t = db_read_token();
434: }
435: db_unread_token(t);
436: *valuep = lhs;
437: return (TRUE);
438: }
439:
440: boolean_t
441: db_shift_expr(db_expr_t *valuep)
442: {
443: db_expr_t lhs, rhs;
444: int t;
445:
446: if (!db_add_expr(&lhs))
447: return (FALSE);
448:
449: t = db_read_token();
450: while (t == tSHIFT_L || t == tSHIFT_R) {
451: if (!db_add_expr(&rhs)) {
452: db_printf("Expression syntax error after \"%s\"\n",
453: (t == tSHIFT_L)? "<<": ">>");
454: db_error(0);
455: /*NOTREACHED*/
456: }
457: if (rhs < 0) {
458: db_error("Negative shift amount\n");
459: /*NOTREACHED*/
460: }
461: if (t == tSHIFT_L)
462: lhs <<= rhs;
463: else {
464: /* Shift right is unsigned */
465: lhs = (natural_t) lhs >> rhs;
466: }
467: t = db_read_token();
468: }
469: db_unread_token(t);
470: *valuep = lhs;
471: return (TRUE);
472: }
473:
474: boolean_t
475: db_logical_relation_expr(db_expr_t *valuep)
476: {
477: db_expr_t lhs, rhs;
478: int t;
479: char op[3];
480:
481: if (!db_shift_expr(&lhs))
482: return(FALSE);
483:
484: t = db_read_token();
485: while (t == tLOG_EQ || t == tLOG_NOT_EQ
486: || t == tGREATER || t == tGREATER_EQ
487: || t == tLESS || t == tLESS_EQ) {
488: op[0] = db_tok_string[0];
489: op[1] = db_tok_string[1];
490: op[2] = 0;
491: if (!db_shift_expr(&rhs)) {
492: db_printf("Expression syntax error after \"%s\"\n", op);
493: db_error(0);
494: /*NOTREACHED*/
495: }
496: switch(t) {
497: case tLOG_EQ:
498: lhs = (lhs == rhs);
499: break;
500: case tLOG_NOT_EQ:
501: lhs = (lhs != rhs);
502: break;
503: case tGREATER:
504: lhs = (lhs > rhs);
505: break;
506: case tGREATER_EQ:
507: lhs = (lhs >= rhs);
508: break;
509: case tLESS:
510: lhs = (lhs < rhs);
511: break;
512: case tLESS_EQ:
513: lhs = (lhs <= rhs);
514: break;
515: }
516: t = db_read_token();
517: }
518: db_unread_token(t);
519: *valuep = lhs;
520: return (TRUE);
521: }
522:
523: boolean_t
524: db_logical_and_expr(db_expr_t *valuep)
525: {
526: db_expr_t lhs, rhs;
527: int t;
528:
529: if (!db_logical_relation_expr(&lhs))
530: return(FALSE);
531:
532: t = db_read_token();
533: while (t == tLOG_AND) {
534: if (!db_logical_relation_expr(&rhs)) {
535: db_error("Expression syntax error after \"&&\"\n");
536: /*NOTREACHED*/
537: }
538: lhs = (lhs && rhs);
539: t = db_read_token();
540: }
541: db_unread_token(t);
542: *valuep = lhs;
543: return (TRUE);
544: }
545:
546: boolean_t
547: db_logical_or_expr(db_expr_t *valuep)
548: {
549: db_expr_t lhs, rhs;
550: int t;
551:
552: if (!db_logical_and_expr(&lhs))
553: return(FALSE);
554:
555: t = db_read_token();
556: while (t == tLOG_OR) {
557: if (!db_logical_and_expr(&rhs)) {
558: db_error("Expression syntax error after \"||\"\n");
559: /*NOTREACHED*/
560: }
561: lhs = (lhs || rhs);
562: t = db_read_token();
563: }
564: db_unread_token(t);
565: *valuep = lhs;
566: return (TRUE);
567: }
568:
569: int
570: db_expression(db_expr_t *valuep)
571: {
572: return (db_logical_or_expr(valuep));
573: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.