FreeBSD/Linux Kernel Cross Reference
sys/ddb/db_output.c
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_output.c,v $
29 * Revision 2.12 93/11/17 16:23:49 dbg
30 * Added ANSI function prototypes, including stdarg.h.
31 * Moved iprintf here from kern/printf.c, and renamed it
32 * db_iprintf.
33 * [93/10/08 dbg]
34 *
35 * Revision 2.11 93/05/13 14:39:34 rvb
36 * db_putc is used by the luna; rename it here.
37 * [93/05/13 rvb]
38 *
39 * Revision 2.10 93/05/10 17:45:56 rvb
40 * _doprint assumes 1st arg of putc type function is char not int.
41 * Make db_id_putc conform.
42 * [93/04/27 Ian Dall <DALL@hfrd.dsto.gov.au>]
43 *
44 * Call _doprnt with the right number of arguments. Define db_id_putc
45 * which has an extra dummy argument cf db_putchar. Use db_id_putc
46 * instead of db_putchar in call to _doprnt.
47 * [93/04/25 Ian Dall <DALL@hfrd.dsto.gov.au>]
48 *
49 * Revision 2.9 93/01/14 17:25:24 danner
50 * 64bit cleanup.
51 * [92/11/30 af]
52 *
53 * Revision 2.8 92/08/03 17:31:38 jfriedl
54 * removed silly prototypes
55 * [92/08/02 jfriedl]
56 *
57 * Revision 2.7 92/05/21 17:07:20 jfriedl
58 * Added void type to functions that needed it.
59 * [92/05/16 jfriedl]
60 *
61 * Revision 2.6 91/10/09 16:01:26 af
62 * Added "more" like function.
63 * [91/08/29 tak]
64 *
65 * Revision 2.5 91/07/09 23:15:54 danner
66 * Include machine/db_machdep.c.
67 * When db_printf is invoked, call db_printing on luna. This is used
68 * to trigger a screen clear. Under luna88k conditional.
69 * [91/07/08 danner]
70 *
71 * Revision 2.4 91/05/14 15:34:51 mrt
72 * Correcting copyright
73 *
74 * Revision 2.3 91/02/05 17:06:45 mrt
75 * Changed to new Mach copyright
76 * [91/01/31 16:18:41 mrt]
77 *
78 * Revision 2.2 90/08/27 21:51:25 dbg
79 * Put extra features of db_doprnt in _doprnt.
80 * [90/08/20 dbg]
81 * Reduce lint.
82 * [90/08/07 dbg]
83 * Created.
84 * [90/07/25 dbg]
85 *
86 */
87 /*
88 * Author: David B. Golub, Carnegie Mellon University
89 * Date: 7/90
90 */
91
92 /*
93 * Printf and character output for debugger.
94 */
95
96 #include <mach/boolean.h>
97 #include <sys/stdarg.h>
98 #include <machine/db_machdep.h> /* must come before kern_io.h,
99 since it may override cn* routines */
100 #include <kern/kern_io.h> /* _doprnt */
101 #include <ddb/db_lex.h>
102 #include <ddb/db_output.h>
103 #include <ddb/db_input.h>
104 #include <ddb/db_command.h> /* db_error */
105
106 /*
107 * Character output - tracks position in line.
108 * To do this correctly, we should know how wide
109 * the output device is - then we could zero
110 * the line position when the output device wraps
111 * around to the start of the next line.
112 *
113 * Instead, we count the number of spaces printed
114 * since the last printing character so that we
115 * don't print trailing spaces. This avoids most
116 * of the wraparounds.
117 */
118
119 #ifndef DB_MAX_LINE
120 #define DB_MAX_LINE 24 /* maximum line */
121 #define DB_MAX_WIDTH 80 /* maximum width */
122 #endif /* DB_MAX_LINE */
123
124 #define DB_MIN_MAX_WIDTH 20 /* minimum max width */
125 #define DB_MIN_MAX_LINE 3 /* minimum max line */
126 #define CTRL(c) ((c) & 0x1f)
127
128 int db_output_position = 0; /* output column */
129 int db_output_line = 0; /* output line number */
130 int db_last_non_space = 0; /* last non-space character */
131 int db_tab_stop_width = 8; /* how wide are tab stops? */
132 #define NEXT_TAB(i) \
133 ((((i) + db_tab_stop_width) / db_tab_stop_width) * db_tab_stop_width)
134 int db_max_line = DB_MAX_LINE; /* output max lines */
135 int db_max_width = DB_MAX_WIDTH; /* output line width */
136
137 /*
138 * Force pending whitespace.
139 */
140 void
141 db_force_whitespace(void)
142 {
143 register int last_print, next_tab;
144
145 last_print = db_last_non_space;
146 while (last_print < db_output_position) {
147 next_tab = NEXT_TAB(last_print);
148 if (next_tab <= db_output_position) {
149 cnputc('\t');
150 last_print = next_tab;
151 }
152 else {
153 cnputc(' ');
154 last_print++;
155 }
156 }
157 db_last_non_space = db_output_position;
158 }
159
160 static void
161 db_more(void)
162 {
163 register char *p;
164 boolean_t quit_output = FALSE;
165
166 for (p = "--db_more--"; *p; p++)
167 cnputc(*p);
168 switch(cngetc()) {
169 case ' ':
170 db_output_line = 0;
171 break;
172 case 'q':
173 case CTRL('c'):
174 db_output_line = 0;
175 quit_output = TRUE;
176 break;
177 default:
178 db_output_line--;
179 break;
180 }
181 p = "\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b";
182 while (*p)
183 cnputc(*p++);
184 if (quit_output) {
185 db_error(0);
186 /* NOTREACHED */
187 }
188 }
189
190 /*
191 * Output character. Buffer whitespace.
192 */
193 void
194 db_putchar(
195 int c) /* character to output */
196 {
197 if (db_max_line >= DB_MIN_MAX_LINE && db_output_line >= db_max_line-1)
198 db_more();
199 if (c > ' ' && c <= '~') {
200 /*
201 * Printing character.
202 * If we have spaces to print, print them first.
203 * Use tabs if possible.
204 */
205 db_force_whitespace();
206 cnputc(c);
207 db_output_position++;
208 if (db_max_width >= DB_MIN_MAX_WIDTH
209 && db_output_position >= db_max_width-1) {
210 /* auto new line */
211 cnputc('\n');
212 db_output_position = 0;
213 db_last_non_space = 0;
214 db_output_line++;
215 }
216 db_last_non_space = db_output_position;
217 }
218 else if (c == '\n') {
219 /* Return */
220 cnputc(c);
221 db_output_position = 0;
222 db_last_non_space = 0;
223 db_output_line++;
224 db_check_interrupt();
225 }
226 else if (c == '\t') {
227 /* assume tabs every 8 positions */
228 db_output_position = NEXT_TAB(db_output_position);
229 }
230 else if (c == ' ') {
231 /* space */
232 db_output_position++;
233 }
234 else if (c == '\007') {
235 /* bell */
236 cnputc(c);
237 }
238 /* other characters are assumed non-printing */
239 }
240
241 /*
242 * Return output position
243 */
244 int
245 db_print_position(void)
246 {
247 return db_output_position;
248 }
249
250 /*
251 * End line if too long.
252 */
253 void db_end_line(void)
254 {
255 if (db_output_position >= db_max_width-1)
256 db_printf("\n");
257 }
258
259 /*
260 * Printing
261 */
262
263 /*VARARGS1*/
264 void
265 db_printf(const char *fmt, ...)
266 {
267 va_list listp;
268
269 #ifdef db_printf_enter
270 db_printf_enter(); /* optional multiP serialization */
271 #endif
272
273 va_start(listp, fmt);
274 _doprnt(fmt, &listp, (void (*)(char, void *))db_putchar, db_radix, 0);
275 va_end(listp);
276 }
277
278 /* alternate name */
279
280 /*VARARGS1*/
281 void
282 kdbprintf(const char *fmt, ...)
283 {
284 va_list listp;
285
286 va_start(listp, fmt);
287 _doprnt(fmt, &listp, (void (*)(char, void *))db_putchar, db_radix, 0);
288 va_end(listp);
289 }
290
291 /*
292 * Printing with indentation.
293 */
294
295 int db_indent = 0;
296
297 /*VARARGS1*/
298 void db_iprintf(const char *fmt, ...)
299 {
300 va_list listp;
301 register int i;
302
303 for (i = db_indent; i > 0; ){
304 if (i >= 8) {
305 db_printf("\t");
306 i -= 8;
307 }
308 else {
309 db_printf(" ");
310 i--;
311 }
312 }
313
314 va_start(listp, fmt);
315 _doprnt(fmt, &listp, (void (*)(char, void *))db_putchar, 16, 0);
316 va_end(listp);
317 }
318
Cache object: 58b84944a58bd7355becc728f2ade304
|