|
|
1.1 root 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 [email protected]
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: * Author: David B. Golub, Carnegie Mellon University
28: * Date: 7/90
29: */
30:
31: #include "mach_kdb.h"
32: #if MACH_KDB
33:
34: #include <machine/db_machdep.h>
35:
36: #include <ddb/db_lex.h>
37: #include <ddb/db_variables.h>
38: #include <ddb/db_task_thread.h>
39:
40: extern unsigned long db_maxoff;
41:
42: extern db_expr_t db_radix;
43: extern db_expr_t db_max_width;
44: extern db_expr_t db_tab_stop_width;
45: extern db_expr_t db_max_line;
46: extern int db_set_default_thread();
47: extern int db_get_task_thread();
48: extern int db_arg_variable();
49:
50: #define DB_NWORK 32 /* number of work variable */
51:
52: db_expr_t db_work[DB_NWORK]; /* work variable */
53:
54: struct db_variable db_vars[] = {
55: { "radix", &db_radix, FCN_NULL },
56: { "maxoff", (db_expr_t*)&db_maxoff, FCN_NULL },
57: { "maxwidth", &db_max_width, FCN_NULL },
58: { "tabstops", &db_tab_stop_width, FCN_NULL },
59: { "lines", &db_max_line, FCN_NULL },
60: { "thread", 0, db_set_default_thread },
61: { "task", 0, db_get_task_thread,
62: 1, 2, -1, -1 },
63: { "work", &db_work[0], FCN_NULL,
64: 1, 1, 0, DB_NWORK-1 },
65: { "arg", 0, db_arg_variable,
66: 1, 1, -1, -1 },
67: };
68: struct db_variable *db_evars = db_vars + sizeof(db_vars)/sizeof(db_vars[0]);
69:
70: char *
71: db_get_suffix(suffix, suffix_value)
72: register char *suffix;
73: short *suffix_value;
74: {
75: register value;
76:
77: for (value = 0; *suffix && *suffix != '.' && *suffix != ':'; suffix++) {
78: if (*suffix < '0' || *suffix > '9')
79: return(0);
80: value = value*10 + *suffix - '0';
81: }
82: *suffix_value = value;
83: if (*suffix == '.')
84: suffix++;
85: return(suffix);
86: }
87:
88: static boolean_t
89: db_cmp_variable_name(vp, name, ap)
90: struct db_variable *vp;
91: char *name;
92: register db_var_aux_param_t ap;
93: {
94: register char *var_np, *np;
95: register level;
96:
97: for (np = name, var_np = vp->name; *var_np; ) {
98: if (*np++ != *var_np++)
99: return(FALSE);
100: }
101: for (level = 0; *np && *np != ':' && level < vp->max_level; level++){
102: if ((np = db_get_suffix(np, &ap->suffix[level])) == 0)
103: return(FALSE);
104: }
105: if ((*np && *np != ':') || level < vp->min_level
106: || (level > 0 && (ap->suffix[0] < vp->low
107: || (vp->high >= 0 && ap->suffix[0] > vp->high))))
108: return(FALSE);
109: db_strcpy(ap->modif, (*np)? np+1: "");
110: ap->thread = (db_option(ap->modif, 't')?db_default_thread: THREAD_NULL);
111: ap->level = level;
112: return(TRUE);
113: }
114:
115: int
116: db_find_variable(varp, ap)
117: struct db_variable **varp;
118: db_var_aux_param_t ap;
119: {
120: int t;
121: struct db_variable *vp;
122:
123: t = db_read_token();
124: if (t == tIDENT) {
125: for (vp = db_vars; vp < db_evars; vp++) {
126: if (db_cmp_variable_name(vp, db_tok_string, ap)) {
127: *varp = vp;
128: return (1);
129: }
130: }
131: for (vp = db_regs; vp < db_eregs; vp++) {
132: if (db_cmp_variable_name(vp, db_tok_string, ap)) {
133: *varp = vp;
134: return (1);
135: }
136: }
137: }
138: db_printf("Unknown variable \"$%s\"\n", db_tok_string);
139: db_error(0);
140: return (0);
141: }
142:
143:
144: void db_read_write_variable(); /* forward */
145:
146: int
147: db_get_variable(valuep)
148: db_expr_t *valuep;
149: {
150: struct db_variable *vp;
151: struct db_var_aux_param aux_param;
152: char modif[TOK_STRING_SIZE];
153:
154: aux_param.modif = modif;
155: if (!db_find_variable(&vp, &aux_param))
156: return (0);
157:
158: db_read_write_variable(vp, valuep, DB_VAR_GET, &aux_param);
159:
160: return (1);
161: }
162:
163: int
164: db_set_variable(value)
165: db_expr_t value;
166: {
167: struct db_variable *vp;
168: struct db_var_aux_param aux_param;
169: char modif[TOK_STRING_SIZE];
170:
171: aux_param.modif = modif;
172: if (!db_find_variable(&vp, &aux_param))
173: return (0);
174:
175: db_read_write_variable(vp, &value, DB_VAR_SET, &aux_param);
176:
177: return (1);
178: }
179:
180: void
181: db_read_write_variable(vp, valuep, rw_flag, ap)
182: struct db_variable *vp;
183: db_expr_t *valuep;
184: int rw_flag;
185: db_var_aux_param_t ap;
186: {
187: int (*func)() = vp->fcn;
188: struct db_var_aux_param aux_param;
189:
190: if (ap == 0) {
191: ap = &aux_param;
192: ap->modif = "";
193: ap->level = 0;
194: ap->thread = THREAD_NULL;
195: }
196: if (func == FCN_NULL) {
197: if (rw_flag == DB_VAR_SET)
198: vp->valuep[(ap->level)? (ap->suffix[0] - vp->low): 0] = *valuep;
199: else
200: *valuep = vp->valuep[(ap->level)? (ap->suffix[0] - vp->low): 0];
201: } else
202: (*func)(vp, valuep, rw_flag, ap);
203: }
204:
205: void
206: db_set_cmd()
207: {
208: db_expr_t value;
209: int t;
210: struct db_variable *vp;
211: struct db_var_aux_param aux_param;
212: char modif[TOK_STRING_SIZE];
213:
214: aux_param.modif = modif;
215: t = db_read_token();
216: if (t != tDOLLAR) {
217: db_error("Variable name should be prefixed with $\n");
218: return;
219: }
220: if (!db_find_variable(&vp, &aux_param)) {
221: db_error("Unknown variable\n");
222: return;
223: }
224:
225: t = db_read_token();
226: if (t != tEQ)
227: db_unread_token(t);
228:
229: if (!db_expression(&value)) {
230: db_error("No value\n");
231: return;
232: }
233: if ((t = db_read_token()) == tSEMI_COLON)
234: db_unread_token(t);
235: else if (t != tEOL)
236: db_error("?\n");
237:
238: db_read_write_variable(vp, &value, DB_VAR_SET, &aux_param);
239: }
240:
241: #endif MACH_KDB
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.