1 /*
2 * Mach Operating System
3 * Copyright (c) 1993,1992,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 "AS IS"
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 Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: db_variables.c,v $
29 * Revision 2.9 93/11/17 16:26:27 dbg
30 * Added ANSI function prototypes.
31 * [93/10/07 dbg]
32 *
33 * Revision 2.8 93/01/14 17:26:05 danner
34 * 64bit cleanup.
35 * [92/11/30 af]
36 *
37 * Revision 2.7 92/08/03 17:32:20 jfriedl
38 * removed silly prototypes
39 * [92/08/02 jfriedl]
40 *
41 * Revision 2.6 92/05/21 17:08:11 jfriedl
42 * Added void to db_read_write_variable().
43 * Removed unused variable 'func' from db_set_cmd().
44 * [92/05/16 jfriedl]
45 *
46 * Revision 2.5 91/10/09 16:03:59 af
47 * Added suffix handling and thread handling of variables.
48 * Added new variables: lines, task, thread, work and arg.
49 * Moved db_read_variable and db_write_variable to db_variables.h
50 * as macros, and added db_read_write_variable instead.
51 * Changed some error messages.
52 * [91/08/29 tak]
53 *
54 * Revision 2.4 91/05/14 15:36:57 mrt
55 * Correcting copyright
56 *
57 * Revision 2.3 91/02/05 17:07:19 mrt
58 * Changed to new Mach copyright
59 * [91/01/31 16:19:46 mrt]
60 *
61 * Revision 2.2 90/08/27 21:53:24 dbg
62 * New db_read/write_variable functions. Should be used instead
63 * of dereferencing valuep directly, which might not be a true
64 * pointer if there is an fcn() access function.
65 * [90/08/20 af]
66 *
67 * Fix declarations.
68 * Check for trailing garbage after last expression on command line.
69 * [90/08/10 14:34:54 dbg]
70 *
71 * Created.
72 * [90/07/25 dbg]
73 *
74 */
75 /*
76 * Author: David B. Golub, Carnegie Mellon University
77 * Date: 7/90
78 */
79
80 #include <machine/db_machdep.h>
81
82 #include <kern/strings.h>
83
84 #include <ddb/db_lex.h>
85 #include <ddb/db_variables.h>
86 #include <ddb/db_task_thread.h>
87 #include <ddb/db_macro.h>
88 #include <ddb/db_command.h>
89 #include <ddb/db_output.h>
90
91 extern unsigned long db_maxoff;
92
93 extern db_expr_t db_radix;
94 extern db_expr_t db_max_width;
95 extern db_expr_t db_tab_stop_width;
96 extern db_expr_t db_max_line;
97
98 #define DB_NWORK 32 /* number of work variable */
99
100 db_expr_t db_work[DB_NWORK]; /* work variable */
101
102 struct db_variable db_vars[] = {
103 { "radix", &db_radix, FCN_NULL },
104 { "maxoff", (db_expr_t*)&db_maxoff, FCN_NULL },
105 { "maxwidth", &db_max_width, FCN_NULL },
106 { "tabstops", &db_tab_stop_width, FCN_NULL },
107 { "lines", &db_max_line, FCN_NULL },
108 { "thread", 0, db_set_default_thread },
109 { "task", 0, db_get_task_thread,
110 1, 2, -1, -1 },
111 { "work", &db_work[0], FCN_NULL,
112 1, 1, 0, DB_NWORK-1 },
113 { "arg", 0, db_arg_variable,
114 1, 1, -1, -1 },
115 };
116 struct db_variable *db_evars = db_vars + sizeof(db_vars)/sizeof(db_vars[0]);
117
118 char *
119 db_get_suffix(
120 register char *suffix,
121 short *suffix_value)
122 {
123 register int value;
124
125 for (value = 0; *suffix && *suffix != '.' && *suffix != ':'; suffix++) {
126 if (*suffix < '' || *suffix > '9')
127 return 0;
128 value = value*10 + *suffix - '';
129 }
130 *suffix_value = value;
131 if (*suffix == '.')
132 suffix++;
133 return suffix;
134 }
135
136 static boolean_t
137 db_cmp_variable_name(
138 struct db_variable *vp,
139 char *name,
140 register db_var_aux_param_t ap)
141 {
142 register char *var_np, *np;
143 register int level;
144
145 for (np = name, var_np = vp->name; *var_np; ) {
146 if (*np++ != *var_np++)
147 return FALSE;
148 }
149 for (level = 0; *np && *np != ':' && level < vp->max_level; level++){
150 if ((np = db_get_suffix(np, &ap->suffix[level])) == 0)
151 return FALSE;
152 }
153 if ((*np && *np != ':') || level < vp->min_level
154 || (level > 0 && (ap->suffix[0] < vp->low
155 || (vp->high >= 0 && ap->suffix[0] > vp->high))))
156 return FALSE;
157 strcpy(ap->modif, (*np) ? np+1 : "");
158 ap->thread = (db_option(ap->modif, 't'))
159 ? db_default_thread
160 : THREAD_NULL;
161 ap->level = level;
162 return TRUE;
163 }
164
165 boolean_t
166 db_find_variable(
167 struct db_variable **varp,
168 db_var_aux_param_t ap)
169 {
170 int t;
171 struct db_variable *vp;
172
173 t = db_read_token();
174 if (t == tIDENT) {
175 for (vp = db_vars; vp < db_evars; vp++) {
176 if (db_cmp_variable_name(vp, db_tok_string, ap)) {
177 *varp = vp;
178 return TRUE;
179 }
180 }
181 for (vp = db_regs; vp < db_eregs; vp++) {
182 if (db_cmp_variable_name(vp, db_tok_string, ap)) {
183 *varp = vp;
184 return TRUE;
185 }
186 }
187 }
188 db_printf("Unknown variable \"$%s\"\n", db_tok_string);
189 db_error(0);
190 return FALSE;
191 }
192
193
194 boolean_t
195 db_get_variable(
196 db_expr_t *valuep)
197 {
198 struct db_variable *vp;
199 struct db_var_aux_param aux_param;
200 char modif[TOK_STRING_SIZE];
201
202 aux_param.modif = modif;
203 if (!db_find_variable(&vp, &aux_param))
204 return FALSE;
205
206 db_read_write_variable(vp, valuep, DB_VAR_GET, &aux_param);
207
208 return TRUE;
209 }
210
211 boolean_t
212 db_set_variable(
213 db_expr_t value)
214 {
215 struct db_variable *vp;
216 struct db_var_aux_param aux_param;
217 char modif[TOK_STRING_SIZE];
218
219 aux_param.modif = modif;
220 if (!db_find_variable(&vp, &aux_param))
221 return FALSE;
222
223 db_read_write_variable(vp, &value, DB_VAR_SET, &aux_param);
224
225 return TRUE;
226 }
227
228 void
229 db_read_write_variable(
230 struct db_variable *vp,
231 db_expr_t *valuep,
232 int rw_flag,
233 db_var_aux_param_t ap)
234 {
235 db_rw_var_fcn_t func = vp->fcn;
236 struct db_var_aux_param aux_param;
237
238 if (ap == 0) {
239 ap = &aux_param;
240 ap->modif = "";
241 ap->level = 0;
242 ap->thread = THREAD_NULL;
243 }
244 if (func == FCN_NULL) {
245 if (rw_flag == DB_VAR_SET)
246 vp->valuep[(ap->level)? (ap->suffix[0] - vp->low): 0] = *valuep;
247 else
248 *valuep = vp->valuep[(ap->level)? (ap->suffix[0] - vp->low): 0];
249 } else
250 (*func)(vp, valuep, rw_flag, ap);
251 }
252
253 void
254 db_set_cmd()
255 {
256 db_expr_t value;
257 int t;
258 struct db_variable *vp;
259 struct db_var_aux_param aux_param;
260 char modif[TOK_STRING_SIZE];
261
262 aux_param.modif = modif;
263 t = db_read_token();
264 if (t != tDOLLAR) {
265 db_error("Variable name should be prefixed with $\n");
266 return;
267 }
268 if (!db_find_variable(&vp, &aux_param)) {
269 db_error("Unknown variable\n");
270 return;
271 }
272
273 t = db_read_token();
274 if (t != tEQ)
275 db_unread_token(t);
276
277 if (!db_expression(&value)) {
278 db_error("No value\n");
279 return;
280 }
281 if ((t = db_read_token()) == tSEMI_COLON)
282 db_unread_token(t);
283 else if (t != tEOL)
284 db_error("?\n");
285
286 db_read_write_variable(vp, &value, DB_VAR_SET, &aux_param);
287 }
Cache object: e0116142d681e35abf50becc1754113b
|