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