|
|
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: #include "mach_kdb.h"
27: #if MACH_KDB
28:
29: #include <kern/thread.h>
30:
31: #include <machine/db_machdep.h>
32: #include <ddb/db_lex.h>
33: #include <ddb/db_variables.h>
34: #include <ddb/db_command.h>
35:
36:
37:
38: /*
39: * debugger macro support
40: */
41:
42: #define DB_MACRO_LEVEL 5 /* max macro nesting */
43: #define DB_NARGS 10 /* max args */
44: #define DB_NUSER_MACRO 10 /* max user macros */
45:
46: int db_macro_free = DB_NUSER_MACRO;
47: struct db_user_macro {
48: char m_name[TOK_STRING_SIZE];
49: char m_lbuf[DB_LEX_LINE_SIZE];
50: int m_size;
51: } db_user_macro[DB_NUSER_MACRO];
52:
53: int db_macro_level = 0;
54: db_expr_t db_macro_args[DB_MACRO_LEVEL][DB_NARGS];
55:
56: static struct db_user_macro *
57: db_lookup_macro(name)
58: char *name;
59: {
60: register struct db_user_macro *mp;
61:
62: for (mp = db_user_macro; mp < &db_user_macro[DB_NUSER_MACRO]; mp++) {
63: if (mp->m_name[0] == 0)
64: continue;
65: if (strcmp(mp->m_name, name) == 0)
66: return(mp);
67: }
68: return(0);
69: }
70:
71: void
72: db_def_macro_cmd()
73: {
74: register char *p;
75: register c;
76: register struct db_user_macro *mp, *ep;
77:
78: if (db_read_token() != tIDENT) {
79: db_printf("Bad macro name \"%s\"\n", db_tok_string);
80: db_error(0);
81: /* NOTREACHED */
82: }
83: if ((mp = db_lookup_macro(db_tok_string)) == 0) {
84: if (db_macro_free <= 0)
85: db_error("Too many macros\n");
86: /* NOTREACHED */
87: ep = &db_user_macro[DB_NUSER_MACRO];
88: for (mp = db_user_macro; mp < ep && mp->m_name[0]; mp++);
89: if (mp >= ep)
90: db_error("ddb: internal error(macro)\n");
91: /* NOTREACHED */
92: db_macro_free--;
93: db_strcpy(mp->m_name, db_tok_string);
94: }
95: for (c = db_read_char(); c == ' ' || c == '\t'; c = db_read_char());
96: for (p = mp->m_lbuf; c > 0; c = db_read_char())
97: *p++ = c;
98: *p = 0;
99: mp->m_size = p - mp->m_lbuf;
100: }
101:
102: void
103: db_del_macro_cmd()
104: {
105: register struct db_user_macro *mp;
106:
107: if (db_read_token() != tIDENT
108: || (mp = db_lookup_macro(db_tok_string)) == 0) {
109: db_printf("No such macro \"%s\"\n", db_tok_string);
110: db_error(0);
111: /* NOTREACHED */
112: } else {
113: mp->m_name[0] = 0;
114: db_macro_free++;
115: }
116: }
117:
118: void
119: db_show_macro()
120: {
121: register struct db_user_macro *mp;
122: int t;
123: char *name = 0;
124:
125: if ((t = db_read_token()) == tIDENT)
126: name = db_tok_string;
127: else
128: db_unread_token(t);
129: for (mp = db_user_macro; mp < &db_user_macro[DB_NUSER_MACRO]; mp++) {
130: if (mp->m_name[0] == 0)
131: continue;
132: if (name && strcmp(mp->m_name, name))
133: continue;
134: db_printf("%s: %s", mp->m_name, mp->m_lbuf);
135: }
136: }
137:
138: int
139: db_exec_macro(name)
140: char *name;
141: {
142: register struct db_user_macro *mp;
143: register n;
144:
145: if ((mp = db_lookup_macro(name)) == 0)
146: return(-1);
147: if (db_macro_level+1 >= DB_MACRO_LEVEL) {
148: db_macro_level = 0;
149: db_error("Too many macro nest\n");
150: /* NOTREACHED */
151: }
152: for (n = 0;
153: n < DB_NARGS &&
154: db_expression(&db_macro_args[db_macro_level+1][n]);
155: n++);
156: while (n < DB_NARGS)
157: db_macro_args[db_macro_level+1][n++] = 0;
158: db_macro_level++;
159: db_exec_cmd_nest(mp->m_lbuf, mp->m_size);
160: db_macro_level--;
161: return(0);
162: }
163:
164: int
165: /* ARGSUSED */
166: db_arg_variable(vp, valuep, flag, ap)
167: struct db_variable *vp;
168: db_expr_t *valuep;
169: int flag;
170: db_var_aux_param_t ap;
171: {
172: if (ap->level != 1 || ap->suffix[0] < 1 || ap->suffix[0] > DB_NARGS) {
173: db_error("Bad $arg variable\n");
174: /* NOTREACHED */
175: }
176: if (flag == DB_VAR_GET)
177: *valuep = db_macro_args[db_macro_level][ap->suffix[0]-1];
178: else
179: db_macro_args[db_macro_level][ap->suffix[0]-1] = *valuep;
180: return(0);
181: }
182:
183: #endif MACH_KDB
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.