FreeBSD/Linux Kernel Cross Reference
sys/ddb/db_output.c
1 /* $NetBSD: db_output.c,v 1.27 2002/02/15 07:33:51 simonb Exp $ */
2
3 /*
4 * Mach Operating System
5 * Copyright (c) 1991,1990 Carnegie Mellon University
6 * All Rights Reserved.
7 *
8 * Permission to use, copy, modify and distribute this software and its
9 * documentation is hereby granted, provided that both the copyright
10 * notice and this permission notice appear in all copies of the
11 * software, derivative works or modified versions, and any portions
12 * thereof, and that both notices appear in supporting documentation.
13 *
14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 *
18 * Carnegie Mellon requests users of this software to return to
19 *
20 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
21 * School of Computer Science
22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890
24 *
25 * any improvements or extensions that they make and grant Carnegie the
26 * rights to redistribute these changes.
27 */
28
29 /*
30 * Printf and character output for debugger.
31 */
32
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: db_output.c,v 1.27 2002/02/15 07:33:51 simonb Exp $");
35
36 #include <sys/param.h>
37 #include <sys/systm.h>
38
39 #include <machine/stdarg.h>
40
41 #include <dev/cons.h>
42
43 #include <machine/db_machdep.h>
44
45 #include <ddb/db_command.h>
46 #include <ddb/db_output.h>
47 #include <ddb/db_interface.h>
48 #include <ddb/db_sym.h>
49 #include <ddb/db_extern.h>
50
51 /*
52 * Character output - tracks position in line.
53 * To do this correctly, we should know how wide
54 * the output device is - then we could zero
55 * the line position when the output device wraps
56 * around to the start of the next line.
57 *
58 * Instead, we count the number of spaces printed
59 * since the last printing character so that we
60 * don't print trailing spaces. This avoids most
61 * of the wraparounds.
62 */
63
64 #ifndef DB_MAX_LINE
65 #define DB_MAX_LINE 24 /* maximum line */
66 #endif /* DB_MAX_LINE */
67 #ifndef DB_MAX_WIDTH
68 #define DB_MAX_WIDTH 80 /* maximum width */
69 #endif /* DB_MAX_WIDTH */
70
71 #define DB_MIN_MAX_WIDTH 20 /* minimum max width */
72 #define DB_MIN_MAX_LINE 3 /* minimum max line */
73 #define CTRL(c) ((c) & 0xff)
74
75 int db_output_line = 0; /* output line number */
76 int db_tab_stop_width = 8; /* how wide are tab stops? */
77 int db_max_line = DB_MAX_LINE; /* output max lines */
78 int db_max_width = DB_MAX_WIDTH; /* output line width */
79
80 static int db_output_position = 0; /* output column */
81 static int db_last_non_space = 0; /* last non-space character */
82
83 static void db_more(void);
84
85 /*
86 * Force pending whitespace.
87 */
88 void
89 db_force_whitespace(void)
90 {
91 int last_print, next_tab;
92
93 last_print = db_last_non_space;
94 while (last_print < db_output_position) {
95 next_tab = DB_NEXT_TAB(last_print);
96 if (next_tab <= db_output_position) {
97 while (last_print < next_tab) { /* DON'T send a tab!! */
98 cnputc(' ');
99 last_print++;
100 }
101 } else {
102 cnputc(' ');
103 last_print++;
104 }
105 }
106 db_last_non_space = db_output_position;
107 }
108
109 static void
110 db_more(void)
111 {
112 char *p;
113 int quit_output = 0;
114
115 for (p = "--db_more--"; *p; p++)
116 cnputc(*p);
117 switch(cngetc()) {
118 case ' ':
119 db_output_line = 0;
120 break;
121 case 'q':
122 case CTRL('c'):
123 db_output_line = 0;
124 quit_output = 1;
125 break;
126 default:
127 db_output_line--;
128 break;
129 }
130 p = "\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b";
131 while (*p)
132 cnputc(*p++);
133 if (quit_output) {
134 db_error(0);
135 /* NOTREACHED */
136 }
137 }
138
139 /*
140 * Output character. Buffer whitespace.
141 */
142 void
143 db_putchar(int c)
144 {
145 if (db_max_line >= DB_MIN_MAX_LINE && db_output_line >= db_max_line-1)
146 db_more();
147 if (c > ' ' && c <= '~') {
148 /*
149 * Printing character.
150 * If we have spaces to print, print them first.
151 * Use tabs if possible.
152 */
153 db_force_whitespace();
154 cnputc(c);
155 db_output_position++;
156 if (db_max_width >= DB_MIN_MAX_WIDTH
157 && db_output_position >= db_max_width) {
158 /* auto new line */
159 cnputc('\n');
160 db_output_position = 0;
161 db_last_non_space = 0;
162 db_output_line++;
163 }
164 db_last_non_space = db_output_position;
165 } else if (c == '\n') {
166 /* Return */
167 cnputc(c);
168 db_output_position = 0;
169 db_last_non_space = 0;
170 db_output_line++;
171 db_check_interrupt();
172 } else if (c == '\t') {
173 /* assume tabs every 8 positions */
174 db_output_position = DB_NEXT_TAB(db_output_position);
175 } else if (c == ' ') {
176 /* space */
177 db_output_position++;
178 } else if (c == '\007') {
179 /* bell */
180 cnputc(c);
181 }
182 /* other characters are assumed non-printing */
183 }
184
185 /*
186 * Return output position
187 */
188 int
189 db_print_position(void)
190 {
191
192 return (db_output_position);
193 }
194
195 /*
196 * End line if too long.
197 */
198 void
199 db_end_line(void)
200 {
201
202 if (db_output_position >= db_max_width)
203 db_printf("\n");
204 }
205
206 /*
207 * Replacement for old '%r' kprintf format.
208 */
209 void
210 db_format_radix(char *buf, size_t bufsiz, quad_t val, int altflag)
211 {
212 const char *fmt;
213
214 if (db_radix == 16) {
215 db_format_hex(buf, bufsiz, val, altflag);
216 return;
217 }
218
219 if (db_radix == 8)
220 fmt = altflag ? "-%#qo" : "-%qo";
221 else
222 fmt = altflag ? "-%#qu" : "-%qu";
223
224 if (val < 0)
225 val = -val;
226 else
227 ++fmt;
228
229 snprintf(buf, bufsiz, fmt, val);
230 }
231
232 /*
233 * Replacement for old '%z' kprintf format.
234 */
235 void
236 db_format_hex(char *buf, size_t bufsiz, quad_t val, int altflag)
237 {
238 /* Only use alternate form if val is nonzero. */
239 const char *fmt = (altflag && val) ? "-%#qx" : "-%qx";
240
241 if (val < 0)
242 val = -val;
243 else
244 ++fmt;
245
246 snprintf(buf, bufsiz, fmt, val);
247 }
Cache object: 7f5ac629f25238607881044133691e09
|