db_expr.c revision 1.11.4.1 1 /* $NetBSD: db_expr.c,v 1.11.4.1 2002/01/10 19:52:38 thorpej Exp $ */
2
3 /*
4 * Mach Operating System
5 * Copyright (c) 1991,1990 Carnegie Mellon University
6 * All Rights Reserved.
7 *
8 * Permission to use, copy, modify and distribute this software and its
9 * documentation is hereby granted, provided that both the copyright
10 * notice and this permission notice appear in all copies of the
11 * software, derivative works or modified versions, and any portions
12 * thereof, and that both notices appear in supporting documentation.
13 *
14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 *
18 * Carnegie Mellon requests users of this software to return to
19 *
20 * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
21 * School of Computer Science
22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890
24 *
25 * any improvements or extensions that they make and grant Carnegie the
26 * rights to redistribute these changes.
27 *
28 * Author: David B. Golub, Carnegie Mellon University
29 * Date: 7/90
30 */
31
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: db_expr.c,v 1.11.4.1 2002/01/10 19:52:38 thorpej Exp $");
34
35 #include <sys/param.h>
36 #include <sys/proc.h>
37
38 #include <machine/db_machdep.h>
39
40 #include <ddb/db_lex.h>
41 #include <ddb/db_access.h>
42 #include <ddb/db_command.h>
43 #include <ddb/db_sym.h>
44 #include <ddb/db_extern.h>
45 #include <ddb/db_variables.h>
46
47 boolean_t
48 db_term(valuep)
49 db_expr_t *valuep;
50 {
51 int t;
52
53 t = db_read_token();
54 if (t == tIDENT) {
55 if (!db_value_of_name(db_tok_string, valuep)) {
56 extern int db_radix;
57 db_expr_t v = 0;
58 int i, c, byte;
59
60 /* See if we can make a number out of all of it */
61 for (i = 0; (c = db_tok_string[i]) != '\0'; i++) {
62 byte = 0;
63 if (c >= '0' && c <= '9')
64 byte = c - '0';
65 else if (db_radix == 16 && c >= 'a' && c <= 'f')
66 byte = c - 'a' + 10;
67 else if (db_radix == 16 && c >= 'A' && c <= 'F')
68 byte = c - 'A' + 10;
69 else
70 db_error("Symbol not found\n");
71 /*NOTREACHED*/
72 v = v * db_radix + byte;
73 }
74 *valuep = (db_expr_t)v;
75 }
76 return (TRUE);
77 }
78 if (t == tNUMBER) {
79 *valuep = (db_expr_t)db_tok_number;
80 return (TRUE);
81 }
82 if (t == tDOT) {
83 *valuep = (db_expr_t)db_dot;
84 return (TRUE);
85 }
86 if (t == tDOTDOT) {
87 *valuep = (db_expr_t)db_prev;
88 return (TRUE);
89 }
90 if (t == tPLUS) {
91 *valuep = (db_expr_t) db_next;
92 return (TRUE);
93 }
94 if (t == tDITTO) {
95 *valuep = (db_expr_t)db_last_addr;
96 return (TRUE);
97 }
98 if (t == tDOLLAR) {
99 if (!db_get_variable(valuep))
100 return (FALSE);
101 return (TRUE);
102 }
103 if (t == tLPAREN) {
104 if (!db_expression(valuep)) {
105 db_error("Syntax error\n");
106 /*NOTREACHED*/
107 }
108 t = db_read_token();
109 if (t != tRPAREN) {
110 db_error("Syntax error\n");
111 /*NOTREACHED*/
112 }
113 return (TRUE);
114 }
115 db_unread_token(t);
116 return (FALSE);
117 }
118
119 boolean_t
120 db_unary(valuep)
121 db_expr_t *valuep;
122 {
123 int t;
124
125 t = db_read_token();
126 if (t == tMINUS) {
127 if (!db_unary(valuep)) {
128 db_error("Syntax error\n");
129 /*NOTREACHED*/
130 }
131 *valuep = -*valuep;
132 return (TRUE);
133 }
134 if (t == tSTAR) {
135 /* indirection */
136 if (!db_unary(valuep)) {
137 db_error("Syntax error\n");
138 /*NOTREACHED*/
139 }
140 *valuep = db_get_value((db_addr_t)*valuep, sizeof(db_expr_t),
141 FALSE);
142 return (TRUE);
143 }
144 db_unread_token(t);
145 return (db_term(valuep));
146 }
147
148 boolean_t
149 db_mult_expr(valuep)
150 db_expr_t *valuep;
151 {
152 db_expr_t lhs, rhs;
153 int t;
154
155 if (!db_unary(&lhs))
156 return (FALSE);
157
158 t = db_read_token();
159 while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH) {
160 if (!db_term(&rhs)) {
161 db_error("Syntax error\n");
162 /*NOTREACHED*/
163 }
164 if (t == tSTAR)
165 lhs *= rhs;
166 else {
167 if (rhs == 0) {
168 db_error("Divide by 0\n");
169 /*NOTREACHED*/
170 }
171 if (t == tSLASH)
172 lhs /= rhs;
173 else if (t == tPCT)
174 lhs %= rhs;
175 else
176 lhs = ((lhs+rhs-1)/rhs)*rhs;
177 }
178 t = db_read_token();
179 }
180 db_unread_token(t);
181 *valuep = lhs;
182 return (TRUE);
183 }
184
185 boolean_t
186 db_add_expr(valuep)
187 db_expr_t *valuep;
188 {
189 db_expr_t lhs, rhs;
190 int t;
191
192 if (!db_mult_expr(&lhs))
193 return (FALSE);
194
195 t = db_read_token();
196 while (t == tPLUS || t == tMINUS) {
197 if (!db_mult_expr(&rhs)) {
198 db_error("Syntax error\n");
199 /*NOTREACHED*/
200 }
201 if (t == tPLUS)
202 lhs += rhs;
203 else
204 lhs -= rhs;
205 t = db_read_token();
206 }
207 db_unread_token(t);
208 *valuep = lhs;
209 return (TRUE);
210 }
211
212 boolean_t
213 db_shift_expr(valuep)
214 db_expr_t *valuep;
215 {
216 db_expr_t lhs, rhs;
217 int t;
218
219 if (!db_add_expr(&lhs))
220 return (FALSE);
221
222 t = db_read_token();
223 while (t == tSHIFT_L || t == tSHIFT_R) {
224 if (!db_add_expr(&rhs)) {
225 db_error("Syntax error\n");
226 /*NOTREACHED*/
227 }
228 if (rhs < 0) {
229 db_error("Negative shift amount\n");
230 /*NOTREACHED*/
231 }
232 if (t == tSHIFT_L)
233 lhs <<= rhs;
234 else {
235 /* Shift right is unsigned */
236 lhs = (unsigned long) lhs >> rhs;
237 }
238 t = db_read_token();
239 }
240 db_unread_token(t);
241 *valuep = lhs;
242 return (TRUE);
243 }
244
245 int
246 db_expression(valuep)
247 db_expr_t *valuep;
248 {
249 return (db_shift_expr(valuep));
250 }
251