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