Remove some duplicate FreeBSD CVS IDs, move some IDs to better places.
[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  * $DragonFly: src/sys/ddb/db_expr.c,v 1.3 2003/08/27 10:47:13 rob Exp $
28  */
29
30 /*
31  *      Author: David B. Golub, Carnegie Mellon University
32  *      Date:   7/90
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(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                 db_error("Symbol not found\n");
57                 /*NOTREACHED*/
58             }
59             return (TRUE);
60         }
61         if (t == tNUMBER) {
62             *valuep = (db_expr_t)db_tok_number;
63             return (TRUE);
64         }
65         if (t == tDOT) {
66             *valuep = (db_expr_t)db_dot;
67             return (TRUE);
68         }
69         if (t == tDOTDOT) {
70             *valuep = (db_expr_t)db_prev;
71             return (TRUE);
72         }
73         if (t == tPLUS) {
74             *valuep = (db_expr_t) db_next;
75             return (TRUE);
76         }
77         if (t == tDITTO) {
78             *valuep = (db_expr_t)db_last_addr;
79             return (TRUE);
80         }
81         if (t == tDOLLAR) {
82             if (!db_get_variable(valuep))
83                 return (FALSE);
84             return (TRUE);
85         }
86         if (t == tLPAREN) {
87             if (!db_expression(valuep)) {
88                 db_error("Syntax error\n");
89                 /*NOTREACHED*/
90             }
91             t = db_read_token();
92             if (t != tRPAREN) {
93                 db_error("Syntax error\n");
94                 /*NOTREACHED*/
95             }
96             return (TRUE);
97         }
98         db_unread_token(t);
99         return (FALSE);
100 }
101
102 static boolean_t
103 db_unary(valuep)
104         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(int), 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(valuep)
132         db_expr_t *valuep;
133 {
134         db_expr_t       lhs, rhs;
135         int             t;
136
137         if (!db_unary(&lhs))
138             return (FALSE);
139
140         t = db_read_token();
141         while (t == tSTAR || t == tSLASH || t == tPCT || t == tHASH) {
142             if (!db_term(&rhs)) {
143                 db_error("Syntax error\n");
144                 /*NOTREACHED*/
145             }
146             if (t == tSTAR)
147                 lhs *= rhs;
148             else {
149                 if (rhs == 0) {
150                     db_error("Divide by 0\n");
151                     /*NOTREACHED*/
152                 }
153                 if (t == tSLASH)
154                     lhs /= rhs;
155                 else if (t == tPCT)
156                     lhs %= rhs;
157                 else
158                     lhs = ((lhs+rhs-1)/rhs)*rhs;
159             }
160             t = db_read_token();
161         }
162         db_unread_token(t);
163         *valuep = lhs;
164         return (TRUE);
165 }
166
167 static boolean_t
168 db_add_expr(valuep)
169         db_expr_t *valuep;
170 {
171         db_expr_t       lhs, rhs;
172         int             t;
173
174         if (!db_mult_expr(&lhs))
175             return (FALSE);
176
177         t = db_read_token();
178         while (t == tPLUS || t == tMINUS) {
179             if (!db_mult_expr(&rhs)) {
180                 db_error("Syntax error\n");
181                 /*NOTREACHED*/
182             }
183             if (t == tPLUS)
184                 lhs += rhs;
185             else
186                 lhs -= rhs;
187             t = db_read_token();
188         }
189         db_unread_token(t);
190         *valuep = lhs;
191         return (TRUE);
192 }
193
194 static boolean_t
195 db_shift_expr(valuep)
196         db_expr_t *valuep;
197 {
198         db_expr_t       lhs, rhs;
199         int             t;
200
201         if (!db_add_expr(&lhs))
202             return (FALSE);
203
204         t = db_read_token();
205         while (t == tSHIFT_L || t == tSHIFT_R) {
206             if (!db_add_expr(&rhs)) {
207                 db_error("Syntax error\n");
208                 /*NOTREACHED*/
209             }
210             if (rhs < 0) {
211                 db_error("Negative shift amount\n");
212                 /*NOTREACHED*/
213             }
214             if (t == tSHIFT_L)
215                 lhs <<= rhs;
216             else {
217                 /* Shift right is unsigned */
218                 lhs = (unsigned) lhs >> rhs;
219             }
220             t = db_read_token();
221         }
222         db_unread_token(t);
223         *valuep = lhs;
224         return (TRUE);
225 }
226
227 int
228 db_expression(valuep)
229         db_expr_t *valuep;
230 {
231         return (db_shift_expr(valuep));
232 }