|
|
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
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 the
24: * rights to redistribute these changes.
25: */
26: /*
27: * HISTORY
28: * $Log: db_output.c,v $
29: * Revision 1.1 1992/03/25 21:45:18 pace
30: * Initial revision
31: *
32: * Revision 2.3 91/02/05 17:06:45 mrt
33: * Changed to new Mach copyright
34: * [91/01/31 16:18:41 mrt]
35: *
36: * Revision 2.2 90/08/27 21:51:25 dbg
37: * Put extra features of db_doprnt in _doprnt.
38: * [90/08/20 dbg]
39: * Reduce lint.
40: * [90/08/07 dbg]
41: * Created.
42: * [90/07/25 dbg]
43: *
44: */
45: /*
46: * Author: David B. Golub, Carnegie Mellon University
47: * Date: 7/90
48: */
49:
50: /*
51: * Printf and character output for debugger.
52: */
53:
54: #include "param.h"
55: #include <machine/stdarg.h>
56:
57: /*
58: * Character output - tracks position in line.
59: * To do this correctly, we should know how wide
60: * the output device is - then we could zero
61: * the line position when the output device wraps
62: * around to the start of the next line.
63: *
64: * Instead, we count the number of spaces printed
65: * since the last printing character so that we
66: * don't print trailing spaces. This avoids most
67: * of the wraparounds.
68: */
69: int db_output_position = 0; /* output column */
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_width = 80; /* output line width */
75:
76: extern void db_check_interrupt();
77:
78: /*
79: * Force pending whitespace.
80: */
81: void
82: db_force_whitespace()
83: {
84: register int last_print, next_tab;
85:
86: last_print = db_last_non_space;
87: while (last_print < db_output_position) {
88: next_tab = NEXT_TAB(last_print);
89: if (next_tab <= db_output_position) {
90: cnputc('\t');
91: last_print = next_tab;
92: }
93: else {
94: cnputc(' ');
95: last_print++;
96: }
97: }
98: db_last_non_space = db_output_position;
99: }
100:
101: /*
102: * Output character. Buffer whitespace.
103: */
104: db_putchar(c)
105: int c; /* character to output */
106: {
107: if (c > ' ' && c <= '~') {
108: /*
109: * Printing character.
110: * If we have spaces to print, print them first.
111: * Use tabs if possible.
112: */
113: db_force_whitespace();
114: cnputc(c);
115: db_output_position++;
116: db_last_non_space = db_output_position;
117: }
118: else if (c == '\n') {
119: /* Return */
120: cnputc(c);
121: db_output_position = 0;
122: db_last_non_space = 0;
123: db_check_interrupt();
124: }
125: else if (c == '\t') {
126: /* assume tabs every 8 positions */
127: db_output_position = NEXT_TAB(db_output_position);
128: }
129: else if (c == ' ') {
130: /* space */
131: db_output_position++;
132: }
133: else if (c == '\007') {
134: /* bell */
135: cnputc(c);
136: }
137: /* other characters are assumed non-printing */
138: }
139:
140: /*
141: * Return output position
142: */
143: int
144: db_print_position()
145: {
146: return (db_output_position);
147: }
148:
149: /*
150: * End line if too long.
151: */
152: void
153: db_end_line()
154: {
155: if (db_output_position >= db_max_width)
156: db_printf("\n");
157: }
158:
159: /*
160: * Printing
161: */
162: extern int db_radix;
163:
164: /*VARARGS1*/
165: db_printf(char *fmt, ...)
166: {
167: va_list listp;
168: va_start(listp, fmt);
169: db_printf_guts (fmt, listp);
170: va_end(listp);
171: }
172:
173: /* alternate name */
174:
175: /*VARARGS1*/
176: kdbprintf(char *fmt, ...)
177: {
178: va_list listp;
179: va_start(listp, fmt);
180: db_printf_guts (fmt, listp);
181: va_end(listp);
182: }
183:
184: /*
185: * Put a number (base <= 16) in a buffer in reverse order; return an
186: * optional length and a pointer to the NULL terminated (preceded?)
187: * buffer.
188: */
189: static char *
190: db_ksprintn(ul, base, lenp)
191: register u_long ul;
192: register int base, *lenp;
193: { /* A long in base 8, plus NULL. */
194: static char buf[sizeof(long) * NBBY / 3 + 2];
195: register char *p;
196:
197: p = buf;
198: do {
199: *++p = "0123456789abcdef"[ul % base];
200: } while (ul /= base);
201: if (lenp)
202: *lenp = p - buf;
203: return (p);
204: }
205:
206: db_printf_guts(fmt, ap)
207: register const char *fmt;
208: va_list ap;
209: {
210: register char *p;
211: register int ch, n;
212: u_long ul;
213: int base, lflag, tmp, width;
214: char padc;
215: int ladjust;
216: int sharpflag;
217: int neg;
218:
219: for (;;) {
220: padc = ' ';
221: width = 0;
222: while ((ch = *(u_char *)fmt++) != '%') {
223: if (ch == '\0')
224: return;
225: db_putchar(ch);
226: }
227: lflag = 0;
228: ladjust = 0;
229: sharpflag = 0;
230: neg = 0;
231: reswitch: switch (ch = *(u_char *)fmt++) {
232: case '0':
233: padc = '0';
234: goto reswitch;
235: case '1': case '2': case '3': case '4':
236: case '5': case '6': case '7': case '8': case '9':
237: for (width = 0;; ++fmt) {
238: width = width * 10 + ch - '0';
239: ch = *fmt;
240: if (ch < '0' || ch > '9')
241: break;
242: }
243: goto reswitch;
244: case 'l':
245: lflag = 1;
246: goto reswitch;
247: case '-':
248: ladjust = 1;
249: goto reswitch;
250: case '#':
251: sharpflag = 1;
252: goto reswitch;
253: case 'b':
254: ul = va_arg(ap, int);
255: p = va_arg(ap, char *);
256: for (p = db_ksprintn(ul, *p++, NULL); ch = *p--;)
257: db_putchar(ch);
258:
259: if (!ul)
260: break;
261:
262: for (tmp = 0; n = *p++;) {
263: if (ul & (1 << (n - 1))) {
264: db_putchar(tmp ? ',' : '<');
265: for (; (n = *p) > ' '; ++p)
266: db_putchar(n);
267: tmp = 1;
268: } else
269: for (; *p > ' '; ++p);
270: }
271: if (tmp)
272: db_putchar('>');
273: break;
274: case '*':
275: width = va_arg (ap, int);
276: if (width < 0) {
277: ladjust = !ladjust;
278: width = -width;
279: }
280: goto reswitch;
281: case 'c':
282: db_putchar(va_arg(ap, int));
283: break;
284: case 's':
285: p = va_arg(ap, char *);
286: width -= strlen (p);
287: if (!ladjust && width > 0)
288: while (width--)
289: db_putchar (padc);
290: while (ch = *p++)
291: db_putchar(ch);
292: if (ladjust && width > 0)
293: while (width--)
294: db_putchar (padc);
295: break;
296: case 'r':
297: ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
298: if ((long)ul < 0) {
299: neg = 1;
300: ul = -(long)ul;
301: }
302: base = db_radix;
303: if (base < 8 || base > 16)
304: base = 10;
305: goto number;
306: case 'n':
307: ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
308: base = db_radix;
309: if (base < 8 || base > 16)
310: base = 10;
311: goto number;
312: case 'd':
313: ul = lflag ? va_arg(ap, long) : va_arg(ap, int);
314: if ((long)ul < 0) {
315: neg = 1;
316: ul = -(long)ul;
317: }
318: base = 10;
319: goto number;
320: case 'o':
321: ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
322: base = 8;
323: goto number;
324: case 'u':
325: ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
326: base = 10;
327: goto number;
328: case 'z':
329: ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
330: if ((long)ul < 0) {
331: neg = 1;
332: ul = -(long)ul;
333: }
334: base = 16;
335: goto number;
336: case 'x':
337: ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int);
338: base = 16;
339: number: p = (char *)db_ksprintn(ul, base, &tmp);
340: if (sharpflag && ul != 0) {
341: if (base == 8)
342: tmp++;
343: else if (base == 16)
344: tmp += 2;
345: }
346: if (neg)
347: tmp++;
348:
349: if (!ladjust && width && (width -= tmp) > 0)
350: while (width--)
351: db_putchar(padc);
352: if (neg)
353: db_putchar ('-');
354: if (sharpflag && ul != 0) {
355: if (base == 8) {
356: db_putchar ('0');
357: } else if (base == 16) {
358: db_putchar ('0');
359: db_putchar ('x');
360: }
361: }
362: if (ladjust && width && (width -= tmp) > 0)
363: while (width--)
364: db_putchar(padc);
365:
366: while (ch = *p--)
367: db_putchar(ch);
368: break;
369: default:
370: db_putchar('%');
371: if (lflag)
372: db_putchar('l');
373: /* FALLTHROUGH */
374: case '%':
375: db_putchar(ch);
376: }
377: }
378: }
379:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.