]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/ddb/db_expr.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / 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
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 the
24  * rights to redistribute these changes.
25  */
26 /*
27  *      Author: David B. Golub, Carnegie Mellon University
28  *      Date:   7/90
29  */
30
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33
34 #include <sys/param.h>
35
36 #include <ddb/ddb.h>
37 #include <ddb/db_lex.h>
38 #include <ddb/db_access.h>
39 #include <ddb/db_command.h>
40
41 static boolean_t        db_add_expr(db_expr_t *valuep);
42 static boolean_t        db_mult_expr(db_expr_t *valuep);
43 static boolean_t        db_shift_expr(db_expr_t *valuep);
44 static boolean_t        db_term(db_expr_t *valuep);
45 static boolean_t        db_unary(db_expr_t *valuep);
46
47 static boolean_t
48 db_term(db_expr_t *valuep)
49 {
50         int     t;
51
52         t = db_read_token();
53         if (t == tIDENT) {
54             if (!db_value_of_name(db_tok_string, valuep) &&
55                 !db_value_of_name_pcpu(db_tok_string, valuep) &&
56                 !db_value_of_name_vnet(db_tok_string, valuep)) {
57                 db_error("Symbol not found\n");
58                 /*NOTREACHED*/
59             }
60             return (TRUE);
61         }
62         if (t == tNUMBER) {
63             *valuep = (db_expr_t)db_tok_number;
64             return (TRUE);
65         }
66         if (t == tDOT) {
67             *valuep = (db_expr_t)db_dot;
68             return (TRUE);
69         }
70         if (t == tDOTDOT) {
71             *valuep = (db_expr_t)db_prev;
72             return (TRUE);
73         }
74         if (t == tPLUS) {
75             *valuep = (db_expr_t) db_next;
76             return (TRUE);
77         }
78         if (t == tDITTO) {
79             *valuep = (db_expr_t)db_last_addr;
80             return (TRUE);
81         }
82         if (t == tDOLLAR) {
83             if (!db_get_variable(valuep))
84                 return (FALSE);
85             return (TRUE);
86         }
87         if (t == tLPAREN) {
88             if (!db_expression(valuep)) {
89                 db_error("Syntax error\n");
90                 /*NOTREACHED*/
91             }
92             t = db_read_token();
93             if (t != tRPAREN) {
94                 db_error("Syntax error\n");
95                 /*NOTREACHED*/
96             }
97             return (TRUE);
98         }
99         db_unread_token(t);
100         return (FALSE);
101 }
102
103 static boolean_t
104 db_unary(db_expr_t *valuep)
105 {
106         int     t;
107
108         t = db_read_token();
109         if (t == tMINUS) {
110             if (!db_unary(valuep)) {
111                 db_error("Syntax error\n");
112                 /*NOTREACHED*/
113             }
114             *valuep = -*valuep;
115             return (TRUE);
116         }
117         if (t == tSTAR) {
118             /* indirection */
119             if (!db_unary(valuep)) {
120                 db_error("Syntax error\n");
121                 /*NOTREACHED*/
122             }
123             *valuep = db_get_value((db_addr_t)*valuep, sizeof(void *), FALSE);
124             return (TRUE);
125         }
126         db_unread_token(t);
127         return (db_term(valuep));
128 }
129
130 static boolean_t
131 db_mult_expr(db_expr_t *valuep)
132 {
133         db_expr_t       lhs, rhs;
134         int             t;
135
136         if (!db_unary(&lhs))
137             return (FALSE);
138
139         t = db_read_token();
140         while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH) {
141             if (!db_term(&rhs)) {
142                 db_error("Syntax error\n");
143                 /*NOTREACHED*/
144             }
145             if (t == tSTAR)
146                 lhs *= rhs;
147             else {
148                 if (rhs == 0) {
149                     db_error("Divide by 0\n");
150                     /*NOTREACHED*/
151                 }
152                 if (t == tSLASH)
153                     lhs /= rhs;
154                 else if (t == tPCT)
155                     lhs %= rhs;
156                 else
157                     lhs = ((lhs+rhs-1)/rhs)*rhs;
158             }
159             t = db_read_token();
160         }
161         db_unread_token(t);
162         *valuep = lhs;
163         return (TRUE);
164 }
165
166 static boolean_t
167 db_add_expr(db_expr_t *valuep)
168 {
169         db_expr_t       lhs, rhs;
170         int             t;
171
172         if (!db_mult_expr(&lhs))
173             return (FALSE);
174
175         t = db_read_token();
176         while (t == tPLUS || t == tMINUS) {
177             if (!db_mult_expr(&rhs)) {
178                 db_error("Syntax error\n");
179                 /*NOTREACHED*/
180             }
181             if (t == tPLUS)
182                 lhs += rhs;
183             else
184                 lhs -= rhs;
185             t = db_read_token();
186         }
187         db_unread_token(t);
188         *valuep = lhs;
189         return (TRUE);
190 }
191
192 static boolean_t
193 db_shift_expr(db_expr_t *valuep)
194 {
195         db_expr_t       lhs, rhs;
196         int             t;
197
198         if (!db_add_expr(&lhs))
199             return (FALSE);
200
201         t = db_read_token();
202         while (t == tSHIFT_L || t == tSHIFT_R) {
203             if (!db_add_expr(&rhs)) {
204                 db_error("Syntax error\n");
205                 /*NOTREACHED*/
206             }
207             if (rhs < 0) {
208                 db_error("Negative shift amount\n");
209                 /*NOTREACHED*/
210             }
211             if (t == tSHIFT_L)
212                 lhs <<= rhs;
213             else {
214                 /* Shift right is unsigned */
215                 lhs = (unsigned) lhs >> rhs;
216             }
217             t = db_read_token();
218         }
219         db_unread_token(t);
220         *valuep = lhs;
221         return (TRUE);
222 }
223
224 int
225 db_expression(db_expr_t *valuep)
226 {
227         return (db_shift_expr(valuep));
228 }