diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
commit | d6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch) | |
tree | ece253b876159b39c620e62b6c9b1174642e070e /sys/ddb/db_output.c |
initial import of NetBSD tree
Diffstat (limited to 'sys/ddb/db_output.c')
-rw-r--r-- | sys/ddb/db_output.c | 423 |
1 files changed, 423 insertions, 0 deletions
diff --git a/sys/ddb/db_output.c b/sys/ddb/db_output.c new file mode 100644 index 00000000000..eb6c46f5811 --- /dev/null +++ b/sys/ddb/db_output.c @@ -0,0 +1,423 @@ +/* $NetBSD: db_output.c,v 1.8 1994/06/29 22:41:41 deraadt Exp $ */ + +/* + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ + +/* + * Printf and character output for debugger. + */ +#include <sys/param.h> + +#include <machine/stdarg.h> + +/* + * Character output - tracks position in line. + * To do this correctly, we should know how wide + * the output device is - then we could zero + * the line position when the output device wraps + * around to the start of the next line. + * + * Instead, we count the number of spaces printed + * since the last printing character so that we + * don't print trailing spaces. This avoids most + * of the wraparounds. + */ + +#ifndef DB_MAX_LINE +#define DB_MAX_LINE 24 /* maximum line */ +#define DB_MAX_WIDTH 80 /* maximum width */ +#endif DB_MAX_LINE + +#define DB_MIN_MAX_WIDTH 20 /* minimum max width */ +#define DB_MIN_MAX_LINE 3 /* minimum max line */ +#define CTRL(c) ((c) & 0xff) + +int db_output_position = 0; /* output column */ +int db_output_line = 0; /* output line number */ +int db_last_non_space = 0; /* last non-space character */ +int db_tab_stop_width = 8; /* how wide are tab stops? */ +#define NEXT_TAB(i) \ + ((((i) + db_tab_stop_width) / db_tab_stop_width) * db_tab_stop_width) +int db_max_line = DB_MAX_LINE; /* output max lines */ +int db_max_width = DB_MAX_WIDTH; /* output line width */ + +extern void db_check_interrupt(); + +/* + * Force pending whitespace. + */ +void +db_force_whitespace() +{ + register int last_print, next_tab; + + last_print = db_last_non_space; + while (last_print < db_output_position) { + next_tab = NEXT_TAB(last_print); + if (next_tab <= db_output_position) { + while (last_print < next_tab) { /* DON'T send a tab!!! */ + cnputc(' '); + last_print++; + } + } + else { + cnputc(' '); + last_print++; + } + } + db_last_non_space = db_output_position; +} + +static void +db_more() +{ + register char *p; + int quit_output = 0; + + for (p = "--db_more--"; *p; p++) + cnputc(*p); + switch(cngetc()) { + case ' ': + db_output_line = 0; + break; + case 'q': + case CTRL('c'): + db_output_line = 0; + quit_output = 1; + break; + default: + db_output_line--; + break; + } + p = "\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b"; + while (*p) + cnputc(*p++); + if (quit_output) { + db_error(0); + /* NOTREACHED */ + } +} + +/* + * Output character. Buffer whitespace. + */ +db_putchar(c) + int c; /* character to output */ +{ + if (db_max_line >= DB_MIN_MAX_LINE && db_output_line >= db_max_line-1) + db_more(); + if (c > ' ' && c <= '~') { + /* + * Printing character. + * If we have spaces to print, print them first. + * Use tabs if possible. + */ + db_force_whitespace(); + cnputc(c); + db_output_position++; + if (db_max_width >= DB_MIN_MAX_WIDTH + && db_output_position >= db_max_width-1) { + /* auto new line */ + cnputc('\n'); + db_output_position = 0; + db_last_non_space = 0; + db_output_line++; + } + db_last_non_space = db_output_position; + } + else if (c == '\n') { + /* Return */ + cnputc(c); + db_output_position = 0; + db_last_non_space = 0; + db_output_line++; + db_check_interrupt(); + } + else if (c == '\t') { + /* assume tabs every 8 positions */ + db_output_position = NEXT_TAB(db_output_position); + } + else if (c == ' ') { + /* space */ + db_output_position++; + } + else if (c == '\007') { + /* bell */ + cnputc(c); + } + /* other characters are assumed non-printing */ +} + +/* + * Return output position + */ +int +db_print_position() +{ + return (db_output_position); +} + +/* + * Printing + */ +extern int db_radix; + +/*VARARGS1*/ +#ifdef __STDC__ +db_printf(char *fmt, ...) +#else +db_printf(fmt, va_alist) + char *fmt; +#endif +{ + va_list listp; + va_start(listp, fmt); + db_printf_guts (fmt, listp); + va_end(listp); +} + +/* alternate name */ + +/*VARARGS1*/ +#ifdef __STDC__ +kdbprintf(char *fmt, ...) +#else +kdbprintf(fmt, va_alist) + char *fmt; +#endif +{ + va_list listp; + va_start(listp, fmt); + db_printf_guts (fmt, listp); + va_end(listp); +} + +/* + * End line if too long. + */ +void +db_end_line() +{ + if (db_output_position >= db_max_width) + db_printf("\n"); +} + +/* + * Put a number (base <= 16) in a buffer in reverse order; return an + * optional length and a pointer to the NULL terminated (preceded?) + * buffer. + */ +static char * +db_ksprintn(ul, base, lenp) + register u_long ul; + register int base, *lenp; +{ /* A long in base 8, plus NULL. */ + static char buf[sizeof(long) * NBBY / 3 + 2]; + register char *p; + + p = buf; + do { + *++p = "0123456789abcdef"[ul % base]; + } while (ul /= base); + if (lenp) + *lenp = p - buf; + return (p); +} + +db_printf_guts(fmt, ap) + register const char *fmt; + va_list ap; +{ + register char *p; + register int ch, n; + u_long ul; + int base, lflag, tmp, width; + char padc; + int ladjust; + int sharpflag; + int neg; + + for (;;) { + padc = ' '; + width = 0; + while ((ch = *(u_char *)fmt++) != '%') { + if (ch == '\0') + return; + db_putchar(ch); + } + lflag = 0; + ladjust = 0; + sharpflag = 0; + neg = 0; +reswitch: switch (ch = *(u_char *)fmt++) { + case '0': + padc = '0'; + goto reswitch; + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + for (width = 0;; ++fmt) { + width = width * 10 + ch - '0'; + ch = *fmt; + if (ch < '0' || ch > '9') + break; + } + goto reswitch; + case 'l': + lflag = 1; + goto reswitch; + case '-': + ladjust = 1; + goto reswitch; + case '#': + sharpflag = 1; + goto reswitch; + case 'b': + ul = va_arg(ap, int); + p = va_arg(ap, char *); + for (p = db_ksprintn(ul, *p++, NULL); ch = *p--;) + db_putchar(ch); + + if (!ul) + break; + + for (tmp = 0; n = *p++;) { + if (ul & (1 << (n - 1))) { + db_putchar(tmp ? ',' : '<'); + for (; (n = *p) > ' '; ++p) + db_putchar(n); + tmp = 1; + } else + for (; *p > ' '; ++p); + } + if (tmp) + db_putchar('>'); + break; + case '*': + width = va_arg (ap, int); + if (width < 0) { + ladjust = !ladjust; + width = -width; + } + goto reswitch; + case 'c': + db_putchar(va_arg(ap, int)); + break; + case 's': + p = va_arg(ap, char *); + width -= strlen (p); + if (!ladjust && width > 0) + while (width--) + db_putchar (padc); + while (ch = *p++) + db_putchar(ch); + if (ladjust && width > 0) + while (width--) + db_putchar (padc); + break; + case 'r': + ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); + if ((long)ul < 0) { + neg = 1; + ul = -(long)ul; + } + base = db_radix; + if (base < 8 || base > 16) + base = 10; + goto number; + case 'n': + ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); + base = db_radix; + if (base < 8 || base > 16) + base = 10; + goto number; + case 'd': + ul = lflag ? va_arg(ap, long) : va_arg(ap, int); + if ((long)ul < 0) { + neg = 1; + ul = -(long)ul; + } + base = 10; + goto number; + case 'o': + ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); + base = 8; + goto number; + case 'u': + ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); + base = 10; + goto number; + case 'z': + ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); + if ((long)ul < 0) { + neg = 1; + ul = -(long)ul; + } + base = 16; + goto number; + case 'x': + ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); + base = 16; +number: p = (char *)db_ksprintn(ul, base, &tmp); + if (sharpflag && ul != 0) { + if (base == 8) + tmp++; + else if (base == 16) + tmp += 2; + } + if (neg) + tmp++; + + if (!ladjust && width && (width -= tmp) > 0) + while (width--) + db_putchar(padc); + if (neg) + db_putchar ('-'); + if (sharpflag && ul != 0) { + if (base == 8) { + db_putchar ('0'); + } else if (base == 16) { + db_putchar ('0'); + db_putchar ('x'); + } + } + if (ladjust && width && (width -= tmp) > 0) + while (width--) + db_putchar(padc); + + while (ch = *p--) + db_putchar(ch); + break; + default: + db_putchar('%'); + if (lflag) + db_putchar('l'); + /* FALLTHROUGH */ + case '%': + db_putchar(ch); + } + } +} + |