sys/vfs/msdosfs: Sync with FreeBSD (non functional diffs)
[dragonfly.git] / sys / ddb / db_output.c
CommitLineData
984263bc
MD
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
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 the
24 * rights to redistribute these changes.
25 *
26 * $FreeBSD: src/sys/ddb/db_output.c,v 1.26 1999/08/28 00:41:09 peter Exp $
27 */
28
29/*
30 * Author: David B. Golub, Carnegie Mellon University
31 * Date: 7/90
32 */
33
34/*
35 * Printf and character output for debugger.
36 */
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/cons.h>
877e14ee 41#include <sys/ctype.h>
5fddbda2
MD
42#include <sys/thread2.h>
43#include <sys/spinlock2.h>
984263bc
MD
44
45#include <machine/stdarg.h>
46
47#include <ddb/ddb.h>
48#include <ddb/db_output.h>
49
50/*
51 * Character output - tracks position in line.
52 * To do this correctly, we should know how wide
53 * the output device is - then we could zero
54 * the line position when the output device wraps
55 * around to the start of the next line.
56 *
57 * Instead, we count the number of spaces printed
58 * since the last printing character so that we
59 * don't print trailing spaces. This avoids most
60 * of the wraparounds.
61 */
62static int db_output_position = 0; /* output column */
63static int db_last_non_space = 0; /* last non-space character */
64db_expr_t db_tab_stop_width = 8; /* how wide are tab stops? */
65#define NEXT_TAB(i) \
66 ((((i) + db_tab_stop_width) / db_tab_stop_width) * db_tab_stop_width)
67db_expr_t db_max_width = 79; /* output line width */
68
43c0ece6 69static void db_putchar (int c, void *arg);
984263bc
MD
70
71/*
72 * Force pending whitespace.
73 */
74void
2c9702b2 75db_force_whitespace(void)
984263bc 76{
ad0290bd 77 int last_print, next_tab;
984263bc
MD
78
79 last_print = db_last_non_space;
80 while (last_print < db_output_position) {
81 next_tab = NEXT_TAB(last_print);
82 if (next_tab <= db_output_position) {
83 while (last_print < next_tab) { /* DON'T send a tab!!! */
84 cnputc(' ');
85 last_print++;
86 }
87 }
88 else {
89 cnputc(' ');
90 last_print++;
91 }
92 }
93 db_last_non_space = db_output_position;
94}
95
96/*
97 * Output character. Buffer whitespace.
2c9702b2
SW
98 *
99 * Parameters:
100 * arg: character to output
984263bc
MD
101 */
102static void
2c9702b2 103db_putchar(int c, void *arg)
984263bc 104{
61c31fdc
SZ
105 /*
106 * If not in the debugger, output data to both the console and
107 * the message buffer.
108 */
109 if (!db_active) {
877e14ee
MD
110 if (c == '\r' || c == '\n' || c == '\t' ||
111 isprint(c)) {
112 kprintf("%c", c);
113 } else {
114 kprintf("?");
115 }
61c31fdc
SZ
116 if (!db_active)
117 return;
118 if (c == '\r' || c == '\n')
119 db_check_interrupt();
120 return;
121 }
122
5fddbda2
MD
123 crit_enter_hard();
124
984263bc
MD
125 if (c > ' ' && c <= '~') {
126 /*
127 * Printing character.
128 * If we have spaces to print, print them first.
129 * Use tabs if possible.
130 */
131 db_force_whitespace();
132 cnputc(c);
133 db_output_position++;
134 db_last_non_space = db_output_position;
135 }
136 else if (c == '\n') {
137 /* Newline */
138 cnputc(c);
139 db_output_position = 0;
140 db_last_non_space = 0;
141 db_check_interrupt();
142 }
143 else if (c == '\r') {
144 /* Return */
145 cnputc(c);
146 db_output_position = 0;
147 db_last_non_space = 0;
148 db_check_interrupt();
149 }
150 else if (c == '\t') {
151 /* assume tabs every 8 positions */
152 db_output_position = NEXT_TAB(db_output_position);
153 }
154 else if (c == ' ') {
155 /* space */
156 db_output_position++;
157 }
158 else if (c == '\007') {
159 /* bell */
160 cnputc(c);
161 }
162 /* other characters are assumed non-printing */
5fddbda2 163 crit_exit_hard();
984263bc
MD
164}
165
166/*
167 * Return output position
168 */
169int
2c9702b2 170db_print_position(void)
984263bc
MD
171{
172 return (db_output_position);
173}
174
175/*
176 * Printing
5fddbda2
MD
177 *
178 * NOTE: We bypass subr_prf's cons_spin here by using our own putchar
179 * function.
984263bc
MD
180 */
181void
984263bc 182db_printf(const char *fmt, ...)
984263bc 183{
e2565a42 184 __va_list listp;
984263bc 185
e2565a42 186 __va_start(listp, fmt);
ae71ac09 187 kvcprintf (fmt, db_putchar, NULL, listp);
e2565a42 188 __va_end(listp);
6cef7136 189/* DELAY(100000);*/
984263bc
MD
190}
191
11369a30
MD
192void
193db_vprintf(const char *fmt, __va_list va)
194{
ae71ac09 195 kvcprintf (fmt, db_putchar, NULL, va);
6cef7136 196/* DELAY(100000);*/
11369a30
MD
197}
198
984263bc
MD
199int db_indent;
200
201void
984263bc 202db_iprintf(const char *fmt,...)
984263bc 203{
ad0290bd 204 int i;
e2565a42 205 __va_list listp;
984263bc
MD
206
207 for (i = db_indent; i >= 8; i -= 8)
208 db_printf("\t");
209 while (--i >= 0)
210 db_printf(" ");
e2565a42 211 __va_start(listp, fmt);
ae71ac09 212 kvcprintf (fmt, db_putchar, NULL, listp);
e2565a42 213 __va_end(listp);
984263bc
MD
214}
215
216/*
217 * End line if too long.
218 */
219void
3734708d 220db_end_line(int field_width)
984263bc 221{
3734708d 222 if (db_output_position + field_width > db_max_width)
984263bc
MD
223 db_printf("\n");
224}
fcb52d8a
EN
225
226/*
227 * Simple pager
228 */
229int
230db_more(int *nl)
231{
232 ++*nl;
233 if (*nl == 20) {
234 int c;
235
236 db_printf("--More--");
237 c = cngetc();
238 db_printf("\r");
239 /*
240 * A whole screenfull or just one line?
241 */
242 switch (c) {
243 case '\n': /* just one line */
244 *nl = 19;
245 break;
246 case ' ':
247 *nl = 0; /* another screenfull */
248 break;
249 default: /* exit */
250 db_printf("\n");
251 return(-1);
252 }
253 }
254 return(0);
255}
256
8d0b962d 257/*
258 * Replacement for old '%r' kprintf format.
259 */
260void
261db_format_radix(char *buf, size_t bufsiz, quad_t val, int altflag)
262{
263 const char *fmt;
264
265 if (db_radix == 16) {
266 db_format_hex(buf, bufsiz, val, altflag);
267 return;
268 }
269
270 if (db_radix == 8)
271 fmt = altflag ? "-%#qo" : "-%qo";
272 else
273 fmt = altflag ? "-%#qu" : "-%qu";
274
275 if (val < 0)
276 val = -val;
277 else
278 ++fmt;
279
280 ksnprintf(buf, bufsiz, fmt, val);
281}
282
e4dbb174
SW
283/*
284 * Replacement for old '%z' kprintf format.
285 */
286void
287db_format_hex(char *buf, size_t bufsiz, quad_t val, int altflag)
288{
289 /* Only use alternate form if val is nonzero. */
290 const char *fmt = (altflag && val) ? "-%#qx" : "-%qx";
291
292 if (val < 0)
293 val = -val;
294 else
295 ++fmt;
296
297 ksnprintf(buf, bufsiz, fmt, val);
298}
299
b84c2783
MD
300/* #define TEMPORARY_DEBUGGING */
301#ifdef TEMPORARY_DEBUGGING
302
303/*
304 * Temporary Debugging, only turned on manually by kernel hackers trying
305 * to debug extremely low level code. Adjust PCHAR_ as required.
306 */
307static void PCHAR_(int, void * __unused);
308
309void
310kprintf0(const char *fmt, ...)
311{
312 __va_list ap;
313
314 __va_start(ap, fmt);
ae71ac09 315 kvcprintf(fmt, PCHAR_, NULL, ap);
b84c2783
MD
316 __va_end(ap);
317}
318
319static void
320PCHAR_(int c, void *dummy __unused)
321{
322 const int COMC_TXWAIT = 0x40000;
323 const int COMPORT = 0x2f8; /* 0x3f8 COM1, 0x2f8 COM2 */
324 const int LSR_TXRDY = 0x20;
325 const int BAUD = 9600;
326 const int com_lsr = 5;
327 const int com_data = 0;
328 int wait;
329 static int setbaud;
330
331 if (setbaud == 0) {
332 setbaud = 1;
333 outb(COMPORT+3, 0x83); /* DLAB + 8N1 */
334 outb(COMPORT+0, (115200 / BAUD) & 0xFF);
335 outb(COMPORT+1, (115200 / BAUD) >> 8);
336 outb(COMPORT+3, 0x03); /* 8N1 */
337 outb(COMPORT+4, 0x03); /* RTS+DTR */
338 outb(COMPORT+2, 0x01); /* FIFO_ENABLE */
339 }
340
341 for (wait = COMC_TXWAIT; wait > 0; wait--) {
342 if (inb(COMPORT + com_lsr) & LSR_TXRDY) {
343 outb(COMPORT + com_data, (u_char)c);
344 break;
345 }
346 }
347}
348
349#endif