FreeBSD/Linux Kernel Cross Reference
sys/ddb/db_expr.c
1 /*-
2 * SPDX-License-Identifier: MIT-CMU
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
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@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 /*
29 * Author: David B. Golub, Carnegie Mellon University
30 * Date: 7/90
31 */
32
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD: releng/12.0/sys/ddb/db_expr.c 326403 2017-11-30 15:48:35Z pfg $");
35
36 #include <sys/param.h>
37
38 #include <ddb/ddb.h>
39 #include <ddb/db_lex.h>
40 #include <ddb/db_access.h>
41 #include <ddb/db_command.h>
42
43 static bool db_add_expr(db_expr_t *valuep);
44 static bool db_mult_expr(db_expr_t *valuep);
45 static bool db_shift_expr(db_expr_t *valuep);
46 static bool db_term(db_expr_t *valuep);
47 static bool db_unary(db_expr_t *valuep);
48 static bool db_logical_or_expr(db_expr_t *valuep);
49 static bool db_logical_and_expr(db_expr_t *valuep);
50 static bool db_logical_relation_expr(db_expr_t *valuep);
51
52 static bool
53 db_term(db_expr_t *valuep)
54 {
55 int t;
56
57 t = db_read_token();
58 if (t == tIDENT) {
59 if (!db_value_of_name(db_tok_string, valuep) &&
60 !db_value_of_name_pcpu(db_tok_string, valuep) &&
61 !db_value_of_name_vnet(db_tok_string, valuep)) {
62 db_printf("Symbol '%s' not found\n", db_tok_string);
63 db_error(NULL);
64 /*NOTREACHED*/
65 }
66 return (true);
67 }
68 if (t == tNUMBER) {
69 *valuep = (db_expr_t)db_tok_number;
70 return (true);
71 }
72 if (t == tDOT) {
73 *valuep = (db_expr_t)db_dot;
74 return (true);
75 }
76 if (t == tDOTDOT) {
77 *valuep = (db_expr_t)db_prev;
78 return (true);
79 }
80 if (t == tPLUS) {
81 *valuep = (db_expr_t) db_next;
82 return (true);
83 }
84 if (t == tDITTO) {
85 *valuep = (db_expr_t)db_last_addr;
86 return (true);
87 }
88 if (t == tDOLLAR) {
89 if (!db_get_variable(valuep))
90 return (false);
91 return (true);
92 }
93 if (t == tLPAREN) {
94 if (!db_expression(valuep)) {
95 db_printf("Expression syntax error after '%c'\n", '(');
96 db_error(NULL);
97 /*NOTREACHED*/
98 }
99 t = db_read_token();
100 if (t != tRPAREN) {
101 db_printf("Expression syntax error -- expected '%c'\n", ')');
102 db_error(NULL);
103 /*NOTREACHED*/
104 }
105 return (true);
106 }
107 db_unread_token(t);
108 return (false);
109 }
110
111 static bool
112 db_unary(db_expr_t *valuep)
113 {
114 int t;
115
116 t = db_read_token();
117 if (t == tMINUS) {
118 if (!db_unary(valuep)) {
119 db_printf("Expression syntax error after '%c'\n", '-');
120 db_error(NULL);
121 /*NOTREACHED*/
122 }
123 *valuep = -*valuep;
124 return (true);
125 }
126 if (t == tEXCL) {
127 if(!db_unary(valuep)) {
128 db_printf("Expression syntax error after '%c'\n", '!');
129 db_error(NULL);
130 /* NOTREACHED */
131 }
132 *valuep = (!(*valuep));
133 return (true);
134 }
135 if (t == tBIT_NOT) {
136 if(!db_unary(valuep)) {
137 db_printf("Expression syntax error after '%c'\n", '~');
138 db_error(NULL);
139 /* NOTREACHED */
140 }
141 *valuep = (~(*valuep));
142 return (true);
143 }
144 if (t == tSTAR) {
145 /* indirection */
146 if (!db_unary(valuep)) {
147 db_printf("Expression syntax error after '%c'\n", '*');
148 db_error(NULL);
149 /*NOTREACHED*/
150 }
151 *valuep = db_get_value((db_addr_t)*valuep, sizeof(void *),
152 false);
153 return (true);
154 }
155 db_unread_token(t);
156 return (db_term(valuep));
157 }
158
159 static bool
160 db_mult_expr(db_expr_t *valuep)
161 {
162 db_expr_t lhs, rhs;
163 int t;
164
165 if (!db_unary(&lhs))
166 return (false);
167
168 t = db_read_token();
169 while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH ||
170 t == tBIT_AND ) {
171 if (!db_term(&rhs)) {
172 db_printf("Expression syntax error after '%c'\n",
173 t == tSTAR ? '*' : t == tSLASH ? '/' : t == tPCT ? '%' :
174 t == tHASH ? '#' : '&');
175 db_error(NULL);
176 /*NOTREACHED*/
177 }
178 switch(t) {
179 case tSTAR:
180 lhs *= rhs;
181 break;
182 case tBIT_AND:
183 lhs &= rhs;
184 break;
185 default:
186 if (rhs == 0) {
187 db_error("Division by 0\n");
188 /*NOTREACHED*/
189 }
190 if (t == tSLASH)
191 lhs /= rhs;
192 else if (t == tPCT)
193 lhs %= rhs;
194 else
195 lhs = roundup(lhs, rhs);
196 }
197 t = db_read_token();
198 }
199 db_unread_token(t);
200 *valuep = lhs;
201 return (true);
202 }
203
204 static bool
205 db_add_expr(db_expr_t *valuep)
206 {
207 db_expr_t lhs, rhs;
208 int t;
209
210 if (!db_mult_expr(&lhs))
211 return (false);
212
213 t = db_read_token();
214 while (t == tPLUS || t == tMINUS || t == tBIT_OR) {
215 if (!db_mult_expr(&rhs)) {
216 db_printf("Expression syntax error after '%c'\n",
217 t == tPLUS ? '+' : t == tMINUS ? '-' : '|');
218 db_error(NULL);
219 /*NOTREACHED*/
220 }
221 switch (t) {
222 case tPLUS:
223 lhs += rhs;
224 break;
225 case tMINUS:
226 lhs -= rhs;
227 break;
228 case tBIT_OR:
229 lhs |= rhs;
230 break;
231 default:
232 __unreachable();
233 }
234 t = db_read_token();
235 }
236 db_unread_token(t);
237 *valuep = lhs;
238 return (true);
239 }
240
241 static bool
242 db_shift_expr(db_expr_t *valuep)
243 {
244 db_expr_t lhs, rhs;
245 int t;
246
247 if (!db_add_expr(&lhs))
248 return (false);
249 t = db_read_token();
250 while (t == tSHIFT_L || t == tSHIFT_R) {
251 if (!db_add_expr(&rhs)) {
252 db_printf("Expression syntax error after '%s'\n",
253 t == tSHIFT_L ? "<<" : ">>");
254 db_error(NULL);
255 /*NOTREACHED*/
256 }
257 if (rhs < 0) {
258 db_printf("Negative shift amount %jd\n", (intmax_t)rhs);
259 db_error(NULL);
260 /*NOTREACHED*/
261 }
262 if (t == tSHIFT_L)
263 lhs <<= rhs;
264 else {
265 /* Shift right is unsigned */
266 lhs = (db_addr_t)lhs >> rhs;
267 }
268 t = db_read_token();
269 }
270 db_unread_token(t);
271 *valuep = lhs;
272 return (true);
273 }
274
275 static bool
276 db_logical_relation_expr(
277 db_expr_t *valuep)
278 {
279 db_expr_t lhs, rhs;
280 int t;
281
282 if (!db_shift_expr(&lhs))
283 return (false);
284
285 t = db_read_token();
286 while (t == tLOG_EQ || t == tLOG_NOT_EQ || t == tGREATER ||
287 t == tGREATER_EQ || t == tLESS || t == tLESS_EQ) {
288 if (!db_shift_expr(&rhs)) {
289 db_printf("Expression syntax error after '%s'\n",
290 t == tLOG_EQ ? "==" : t == tLOG_NOT_EQ ? "!=" :
291 t == tGREATER ? ">" : t == tGREATER_EQ ? ">=" :
292 t == tLESS ? "<" : "<=");
293 db_error(NULL);
294 /*NOTREACHED*/
295 }
296 switch(t) {
297 case tLOG_EQ:
298 lhs = (lhs == rhs);
299 break;
300 case tLOG_NOT_EQ:
301 lhs = (lhs != rhs);
302 break;
303 case tGREATER:
304 lhs = (lhs > rhs);
305 break;
306 case tGREATER_EQ:
307 lhs = (lhs >= rhs);
308 break;
309 case tLESS:
310 lhs = (lhs < rhs);
311 break;
312 case tLESS_EQ:
313 lhs = (lhs <= rhs);
314 break;
315 default:
316 __unreachable();
317 }
318 t = db_read_token();
319 }
320 db_unread_token(t);
321 *valuep = lhs;
322 return (true);
323 }
324
325 static bool
326 db_logical_and_expr(
327 db_expr_t *valuep)
328 {
329 db_expr_t lhs, rhs;
330 int t;
331
332 if (!db_logical_relation_expr(&lhs))
333 return (false);
334
335 t = db_read_token();
336 while (t == tLOG_AND) {
337 if (!db_logical_relation_expr(&rhs)) {
338 db_printf("Expression syntax error after '%s'\n", "&&");
339 db_error(NULL);
340 /*NOTREACHED*/
341 }
342 lhs = (lhs && rhs);
343 t = db_read_token();
344 }
345 db_unread_token(t);
346 *valuep = lhs;
347 return (true);
348 }
349
350 static bool
351 db_logical_or_expr(
352 db_expr_t *valuep)
353 {
354 db_expr_t lhs, rhs;
355 int t;
356
357 if (!db_logical_and_expr(&lhs))
358 return(false);
359
360 t = db_read_token();
361 while (t == tLOG_OR) {
362 if (!db_logical_and_expr(&rhs)) {
363 db_printf("Expression syntax error after '%s'\n", "||");
364 db_error(NULL);
365 /*NOTREACHED*/
366 }
367 lhs = (lhs || rhs);
368 t = db_read_token();
369 }
370 db_unread_token(t);
371 *valuep = lhs;
372 return (true);
373 }
374
375 int
376 db_expression(db_expr_t *valuep)
377 {
378 return (db_logical_or_expr(valuep));
379 }
Cache object: 95c19fd2ccacd2f72d508212f6c66495
|