|
|
1.1.1.2 root 1: /*
1.1 root 2: * Mach Operating System
3: * Copyright (c) 1991,1990 Carnegie Mellon University
4: * All Rights Reserved.
1.1.1.2 root 5: *
1.1 root 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.
1.1.1.2 root 11: *
1.1 root 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.
1.1.1.2 root 15: *
1.1 root 16: * Carnegie Mellon requests users of this software to return to
1.1.1.2 root 17: *
1.1 root 18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
1.1.1.2 root 22: *
1.1 root 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: #if MACH_KDB
32:
33: /*
34: * Printf and character output for debugger.
35: */
36:
1.1.1.3 ! root 37: #include <kern/printf.h>
1.1.1.2 root 38: #include <stdarg.h>
1.1 root 39: #include <mach/boolean.h>
40: #include <machine/db_machdep.h>
1.1.1.3 ! root 41: #include <device/cons.h>
! 42: #include <ddb/db_command.h>
1.1 root 43: #include <ddb/db_lex.h>
44: #include <ddb/db_output.h>
45:
46: /*
47: * Character output - tracks position in line.
48: * To do this correctly, we should know how wide
49: * the output device is - then we could zero
50: * the line position when the output device wraps
51: * around to the start of the next line.
52: *
53: * Instead, we count the number of spaces printed
54: * since the last printing character so that we
55: * don't print trailing spaces. This avoids most
56: * of the wraparounds.
57: */
58:
59: #ifndef DB_MAX_LINE
60: #define DB_MAX_LINE 24 /* maximum line */
61: #define DB_MAX_WIDTH 80 /* maximum width */
1.1.1.2 root 62: #endif /* DB_MAX_LINE */
1.1 root 63:
64: #define DB_MIN_MAX_WIDTH 20 /* minimum max width */
65: #define DB_MIN_MAX_LINE 3 /* minimum max line */
66: #define CTRL(c) ((c) & 0xff)
67:
68: int db_output_position = 0; /* output column */
69: int db_output_line = 0; /* output line number */
70: int db_last_non_space = 0; /* last non-space character */
71: int db_tab_stop_width = 8; /* how wide are tab stops? */
72: #define NEXT_TAB(i) \
73: ((((i) + db_tab_stop_width) / db_tab_stop_width) * db_tab_stop_width)
74: int db_max_line = DB_MAX_LINE; /* output max lines */
75: int db_max_width = DB_MAX_WIDTH; /* output line width */
76:
77: extern void db_check_interrupt();
78:
79: /*
80: * Force pending whitespace.
81: */
82: void
1.1.1.3 ! root 83: db_force_whitespace(void)
1.1 root 84: {
85: register int last_print, next_tab;
86:
87: last_print = db_last_non_space;
88: while (last_print < db_output_position) {
89: next_tab = NEXT_TAB(last_print);
90: if (next_tab <= db_output_position) {
91: cnputc('\t');
92: last_print = next_tab;
93: }
94: else {
95: cnputc(' ');
96: last_print++;
97: }
98: }
99: db_last_non_space = db_output_position;
100: }
101:
102: static void
103: db_more()
104: {
105: register char *p;
106: boolean_t quit_output = FALSE;
107:
108: for (p = "--db_more--"; *p; p++)
109: cnputc(*p);
110: switch(cngetc()) {
111: case ' ':
112: db_output_line = 0;
113: break;
114: case 'q':
115: case CTRL('c'):
116: db_output_line = 0;
117: quit_output = TRUE;
118: break;
119: default:
120: db_output_line--;
121: break;
122: }
123: p = "\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b";
124: while (*p)
125: cnputc(*p++);
126: if (quit_output) {
127: db_error(0);
128: /* NOTREACHED */
129: }
130: }
131:
132: /*
133: * Output character. Buffer whitespace.
134: */
135: void
136: db_putchar(c)
137: int c; /* character to output */
138: {
139: if (db_max_line >= DB_MIN_MAX_LINE && db_output_line >= db_max_line-1)
140: db_more();
141: if (c > ' ' && c <= '~') {
142: /*
143: * Printing character.
144: * If we have spaces to print, print them first.
145: * Use tabs if possible.
146: */
147: db_force_whitespace();
148: cnputc(c);
149: db_output_position++;
150: if (db_max_width >= DB_MIN_MAX_WIDTH
151: && db_output_position >= db_max_width-1) {
152: /* auto new line */
153: cnputc('\n');
154: db_output_position = 0;
155: db_last_non_space = 0;
156: db_output_line++;
157: }
158: db_last_non_space = db_output_position;
159: }
160: else if (c == '\n') {
161: /* Return */
162: cnputc(c);
163: db_output_position = 0;
164: db_last_non_space = 0;
165: db_output_line++;
166: db_check_interrupt();
167: }
168: else if (c == '\t') {
169: /* assume tabs every 8 positions */
170: db_output_position = NEXT_TAB(db_output_position);
171: }
172: else if (c == ' ') {
173: /* space */
174: db_output_position++;
175: }
176: else if (c == '\007') {
177: /* bell */
178: cnputc(c);
179: }
180: /* other characters are assumed non-printing */
181: }
182:
183: void
184: db_id_putc(char c, vm_offset_t dummy)
185: {
186: db_putchar(c);
187: }
188:
189: /*
190: * Return output position
191: */
192: int
1.1.1.3 ! root 193: db_print_position(void)
1.1 root 194: {
195: return (db_output_position);
196: }
197:
198: /*
199: * End line if too long.
200: */
1.1.1.3 ! root 201: void db_end_line(void)
1.1 root 202: {
203: if (db_output_position >= db_max_width-1)
204: db_printf("\n");
205: }
206:
207: /*VARARGS1*/
208: void
1.1.1.2 root 209: db_printf(const char *fmt, ...)
1.1 root 210: {
211: va_list listp;
212:
213: #ifdef db_printf_enter
214: db_printf_enter(); /* optional multiP serialization */
215: #endif
1.1.1.2 root 216: va_start(listp, fmt);
1.1.1.3 ! root 217: _doprnt(fmt, listp, db_id_putc, db_radix, 0);
1.1 root 218: va_end(listp);
219: }
220:
221: /* alternate name */
222:
223: /*VARARGS1*/
224: void
1.1.1.2 root 225: kdbprintf(const char *fmt, ...)
1.1 root 226: {
227: va_list listp;
1.1.1.2 root 228: va_start(listp, fmt);
1.1.1.3 ! root 229: _doprnt(fmt, listp, db_id_putc, db_radix, 0);
1.1 root 230: va_end(listp);
231: }
232:
1.1.1.2 root 233: #endif /* MACH_KDB */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.