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