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