15b81b6b3SRodney W. Grimes /* 25b81b6b3SRodney W. Grimes * Mach Operating System 35b81b6b3SRodney W. Grimes * Copyright (c) 1991,1990 Carnegie Mellon University 45b81b6b3SRodney W. Grimes * All Rights Reserved. 55b81b6b3SRodney W. Grimes * 65b81b6b3SRodney W. Grimes * Permission to use, copy, modify and distribute this software and its 75b81b6b3SRodney W. Grimes * documentation is hereby granted, provided that both the copyright 85b81b6b3SRodney W. Grimes * notice and this permission notice appear in all copies of the 95b81b6b3SRodney W. Grimes * software, derivative works or modified versions, and any portions 105b81b6b3SRodney W. Grimes * thereof, and that both notices appear in supporting documentation. 115b81b6b3SRodney W. Grimes * 125b81b6b3SRodney W. Grimes * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 135b81b6b3SRodney W. Grimes * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 145b81b6b3SRodney W. Grimes * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 155b81b6b3SRodney W. Grimes * 165b81b6b3SRodney W. Grimes * Carnegie Mellon requests users of this software to return to 175b81b6b3SRodney W. Grimes * 185b81b6b3SRodney W. Grimes * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 195b81b6b3SRodney W. Grimes * School of Computer Science 205b81b6b3SRodney W. Grimes * Carnegie Mellon University 215b81b6b3SRodney W. Grimes * Pittsburgh PA 15213-3890 225b81b6b3SRodney W. Grimes * 235b81b6b3SRodney W. Grimes * any improvements or extensions that they make and grant Carnegie the 245b81b6b3SRodney W. Grimes * rights to redistribute these changes. 255b81b6b3SRodney W. Grimes * 265ccbc3ccSBruce Evans * $Id: db_output.c,v 1.14 1995/12/07 12:44:53 davidg Exp $ 275b81b6b3SRodney W. Grimes */ 280edf66ecSRodney W. Grimes 295b81b6b3SRodney W. Grimes /* 305b81b6b3SRodney W. Grimes * Author: David B. Golub, Carnegie Mellon University 315b81b6b3SRodney W. Grimes * Date: 7/90 325b81b6b3SRodney W. Grimes */ 335b81b6b3SRodney W. Grimes 345b81b6b3SRodney W. Grimes /* 355b81b6b3SRodney W. Grimes * Printf and character output for debugger. 365b81b6b3SRodney W. Grimes */ 375b81b6b3SRodney W. Grimes 38f540b106SGarrett Wollman #include <sys/param.h> 39f540b106SGarrett Wollman #include <sys/systm.h> 405ccbc3ccSBruce Evans 415ccbc3ccSBruce Evans #include <machine/cons.h> 42f540b106SGarrett Wollman #include <machine/stdarg.h> 435ccbc3ccSBruce Evans 44f540b106SGarrett Wollman #include <ddb/ddb.h> 45058284fcSBruce Evans #include <ddb/db_output.h> 465b81b6b3SRodney W. Grimes 475b81b6b3SRodney W. Grimes /* 485b81b6b3SRodney W. Grimes * Character output - tracks position in line. 495b81b6b3SRodney W. Grimes * To do this correctly, we should know how wide 505b81b6b3SRodney W. Grimes * the output device is - then we could zero 515b81b6b3SRodney W. Grimes * the line position when the output device wraps 525b81b6b3SRodney W. Grimes * around to the start of the next line. 535b81b6b3SRodney W. Grimes * 545b81b6b3SRodney W. Grimes * Instead, we count the number of spaces printed 555b81b6b3SRodney W. Grimes * since the last printing character so that we 565b81b6b3SRodney W. Grimes * don't print trailing spaces. This avoids most 575b81b6b3SRodney W. Grimes * of the wraparounds. 585b81b6b3SRodney W. Grimes */ 59f73a856dSPoul-Henning Kamp static int db_output_position = 0; /* output column */ 60f73a856dSPoul-Henning Kamp static int db_last_non_space = 0; /* last non-space character */ 615b81b6b3SRodney W. Grimes int db_tab_stop_width = 8; /* how wide are tab stops? */ 625b81b6b3SRodney W. Grimes #define NEXT_TAB(i) \ 635b81b6b3SRodney W. Grimes ((((i) + db_tab_stop_width) / db_tab_stop_width) * db_tab_stop_width) 645b81b6b3SRodney W. Grimes int db_max_width = 80; /* output line width */ 655b81b6b3SRodney W. Grimes 66058284fcSBruce Evans static char *db_ksprintn __P((u_long ul, int base, int *lenp)); 67058284fcSBruce Evans static void db_printf_guts __P((const char *, va_list)); 685b81b6b3SRodney W. Grimes 695b81b6b3SRodney W. Grimes /* 705b81b6b3SRodney W. Grimes * Force pending whitespace. 715b81b6b3SRodney W. Grimes */ 725b81b6b3SRodney W. Grimes void 735b81b6b3SRodney W. Grimes db_force_whitespace() 745b81b6b3SRodney W. Grimes { 755b81b6b3SRodney W. Grimes register int last_print, next_tab; 765b81b6b3SRodney W. Grimes 775b81b6b3SRodney W. Grimes last_print = db_last_non_space; 785b81b6b3SRodney W. Grimes while (last_print < db_output_position) { 795b81b6b3SRodney W. Grimes next_tab = NEXT_TAB(last_print); 805b81b6b3SRodney W. Grimes if (next_tab <= db_output_position) { 815b81b6b3SRodney W. Grimes while (last_print < next_tab) { /* DON'T send a tab!!! */ 825b81b6b3SRodney W. Grimes cnputc(' '); 835b81b6b3SRodney W. Grimes last_print++; 845b81b6b3SRodney W. Grimes } 855b81b6b3SRodney W. Grimes } 865b81b6b3SRodney W. Grimes else { 875b81b6b3SRodney W. Grimes cnputc(' '); 885b81b6b3SRodney W. Grimes last_print++; 895b81b6b3SRodney W. Grimes } 905b81b6b3SRodney W. Grimes } 915b81b6b3SRodney W. Grimes db_last_non_space = db_output_position; 925b81b6b3SRodney W. Grimes } 935b81b6b3SRodney W. Grimes 945b81b6b3SRodney W. Grimes /* 955b81b6b3SRodney W. Grimes * Output character. Buffer whitespace. 965b81b6b3SRodney W. Grimes */ 97381fe1aaSGarrett Wollman void 985b81b6b3SRodney W. Grimes db_putchar(c) 995b81b6b3SRodney W. Grimes int c; /* character to output */ 1005b81b6b3SRodney W. Grimes { 1015b81b6b3SRodney W. Grimes if (c > ' ' && c <= '~') { 1025b81b6b3SRodney W. Grimes /* 1035b81b6b3SRodney W. Grimes * Printing character. 1045b81b6b3SRodney W. Grimes * If we have spaces to print, print them first. 1055b81b6b3SRodney W. Grimes * Use tabs if possible. 1065b81b6b3SRodney W. Grimes */ 1075b81b6b3SRodney W. Grimes db_force_whitespace(); 1085b81b6b3SRodney W. Grimes cnputc(c); 1095b81b6b3SRodney W. Grimes db_output_position++; 1105b81b6b3SRodney W. Grimes db_last_non_space = db_output_position; 1115b81b6b3SRodney W. Grimes } 1125b81b6b3SRodney W. Grimes else if (c == '\n') { 1138a129caeSDavid Greenman /* Newline */ 1148a129caeSDavid Greenman cnputc(c); 1158a129caeSDavid Greenman db_output_position = 0; 1168a129caeSDavid Greenman db_last_non_space = 0; 1178a129caeSDavid Greenman db_check_interrupt(); 1188a129caeSDavid Greenman } 1198a129caeSDavid Greenman else if (c == '\r') { 1205b81b6b3SRodney W. Grimes /* Return */ 1215b81b6b3SRodney W. Grimes cnputc(c); 1225b81b6b3SRodney W. Grimes db_output_position = 0; 1235b81b6b3SRodney W. Grimes db_last_non_space = 0; 1245b81b6b3SRodney W. Grimes db_check_interrupt(); 1255b81b6b3SRodney W. Grimes } 1265b81b6b3SRodney W. Grimes else if (c == '\t') { 1275b81b6b3SRodney W. Grimes /* assume tabs every 8 positions */ 1285b81b6b3SRodney W. Grimes db_output_position = NEXT_TAB(db_output_position); 1295b81b6b3SRodney W. Grimes } 1305b81b6b3SRodney W. Grimes else if (c == ' ') { 1315b81b6b3SRodney W. Grimes /* space */ 1325b81b6b3SRodney W. Grimes db_output_position++; 1335b81b6b3SRodney W. Grimes } 1345b81b6b3SRodney W. Grimes else if (c == '\007') { 1355b81b6b3SRodney W. Grimes /* bell */ 1365b81b6b3SRodney W. Grimes cnputc(c); 1375b81b6b3SRodney W. Grimes } 1385b81b6b3SRodney W. Grimes /* other characters are assumed non-printing */ 1395b81b6b3SRodney W. Grimes } 1405b81b6b3SRodney W. Grimes 1415b81b6b3SRodney W. Grimes /* 1425b81b6b3SRodney W. Grimes * Return output position 1435b81b6b3SRodney W. Grimes */ 1445b81b6b3SRodney W. Grimes int 1455b81b6b3SRodney W. Grimes db_print_position() 1465b81b6b3SRodney W. Grimes { 1475b81b6b3SRodney W. Grimes return (db_output_position); 1485b81b6b3SRodney W. Grimes } 1495b81b6b3SRodney W. Grimes 1505b81b6b3SRodney W. Grimes /* 1515b81b6b3SRodney W. Grimes * Printing 1525b81b6b3SRodney W. Grimes */ 153381fe1aaSGarrett Wollman void 154381fe1aaSGarrett Wollman db_printf(const char *fmt, ...) 1555b81b6b3SRodney W. Grimes { 1565b81b6b3SRodney W. Grimes va_list listp; 1575b81b6b3SRodney W. Grimes va_start(listp, fmt); 1585b81b6b3SRodney W. Grimes db_printf_guts (fmt, listp); 1595b81b6b3SRodney W. Grimes va_end(listp); 1605b81b6b3SRodney W. Grimes } 1615b81b6b3SRodney W. Grimes 1625b81b6b3SRodney W. Grimes /* 163572de915SRodney W. Grimes * End line if too long. 164572de915SRodney W. Grimes */ 165572de915SRodney W. Grimes void 166572de915SRodney W. Grimes db_end_line() 167572de915SRodney W. Grimes { 168572de915SRodney W. Grimes if (db_output_position >= db_max_width) 169572de915SRodney W. Grimes db_printf("\n"); 170572de915SRodney W. Grimes } 171572de915SRodney W. Grimes 172572de915SRodney W. Grimes /* 1735b81b6b3SRodney W. Grimes * Put a number (base <= 16) in a buffer in reverse order; return an 1745b81b6b3SRodney W. Grimes * optional length and a pointer to the NULL terminated (preceded?) 1755b81b6b3SRodney W. Grimes * buffer. 1765b81b6b3SRodney W. Grimes */ 1775b81b6b3SRodney W. Grimes static char * 1785b81b6b3SRodney W. Grimes db_ksprintn(ul, base, lenp) 1795b81b6b3SRodney W. Grimes register u_long ul; 1805b81b6b3SRodney W. Grimes register int base, *lenp; 1815b81b6b3SRodney W. Grimes { /* A long in base 8, plus NULL. */ 1825b81b6b3SRodney W. Grimes static char buf[sizeof(long) * NBBY / 3 + 2]; 1835b81b6b3SRodney W. Grimes register char *p; 1845b81b6b3SRodney W. Grimes 1855b81b6b3SRodney W. Grimes p = buf; 1865b81b6b3SRodney W. Grimes do { 1875b81b6b3SRodney W. Grimes *++p = "0123456789abcdef"[ul % base]; 1885b81b6b3SRodney W. Grimes } while (ul /= base); 1895b81b6b3SRodney W. Grimes if (lenp) 1905b81b6b3SRodney W. Grimes *lenp = p - buf; 1915b81b6b3SRodney W. Grimes return (p); 1925b81b6b3SRodney W. Grimes } 1935b81b6b3SRodney W. Grimes 194381fe1aaSGarrett Wollman static void 1955b81b6b3SRodney W. Grimes db_printf_guts(fmt, ap) 1965b81b6b3SRodney W. Grimes register const char *fmt; 1975b81b6b3SRodney W. Grimes va_list ap; 1985b81b6b3SRodney W. Grimes { 1995b81b6b3SRodney W. Grimes register char *p; 2005b81b6b3SRodney W. Grimes register int ch, n; 2015b81b6b3SRodney W. Grimes u_long ul; 2025b81b6b3SRodney W. Grimes int base, lflag, tmp, width; 2035b81b6b3SRodney W. Grimes char padc; 2045b81b6b3SRodney W. Grimes int ladjust; 2055b81b6b3SRodney W. Grimes int sharpflag; 2065b81b6b3SRodney W. Grimes int neg; 2075b81b6b3SRodney W. Grimes 2085b81b6b3SRodney W. Grimes for (;;) { 2095b81b6b3SRodney W. Grimes padc = ' '; 2105b81b6b3SRodney W. Grimes width = 0; 2115b81b6b3SRodney W. Grimes while ((ch = *(u_char *)fmt++) != '%') { 2125b81b6b3SRodney W. Grimes if (ch == '\0') 2135b81b6b3SRodney W. Grimes return; 2145b81b6b3SRodney W. Grimes db_putchar(ch); 2155b81b6b3SRodney W. Grimes } 2165b81b6b3SRodney W. Grimes lflag = 0; 2175b81b6b3SRodney W. Grimes ladjust = 0; 2185b81b6b3SRodney W. Grimes sharpflag = 0; 2195b81b6b3SRodney W. Grimes neg = 0; 2205b81b6b3SRodney W. Grimes reswitch: switch (ch = *(u_char *)fmt++) { 2215b81b6b3SRodney W. Grimes case '0': 2225b81b6b3SRodney W. Grimes padc = '0'; 2235b81b6b3SRodney W. Grimes goto reswitch; 2245b81b6b3SRodney W. Grimes case '1': case '2': case '3': case '4': 2255b81b6b3SRodney W. Grimes case '5': case '6': case '7': case '8': case '9': 2265b81b6b3SRodney W. Grimes for (width = 0;; ++fmt) { 2275b81b6b3SRodney W. Grimes width = width * 10 + ch - '0'; 2285b81b6b3SRodney W. Grimes ch = *fmt; 2295b81b6b3SRodney W. Grimes if (ch < '0' || ch > '9') 2305b81b6b3SRodney W. Grimes break; 2315b81b6b3SRodney W. Grimes } 2325b81b6b3SRodney W. Grimes goto reswitch; 2335b81b6b3SRodney W. Grimes case 'l': 2345b81b6b3SRodney W. Grimes lflag = 1; 2355b81b6b3SRodney W. Grimes goto reswitch; 2365b81b6b3SRodney W. Grimes case '-': 2375b81b6b3SRodney W. Grimes ladjust = 1; 2385b81b6b3SRodney W. Grimes goto reswitch; 2395b81b6b3SRodney W. Grimes case '#': 2405b81b6b3SRodney W. Grimes sharpflag = 1; 2415b81b6b3SRodney W. Grimes goto reswitch; 2425b81b6b3SRodney W. Grimes case 'b': 2435b81b6b3SRodney W. Grimes ul = va_arg(ap, int); 2445b81b6b3SRodney W. Grimes p = va_arg(ap, char *); 245169cd910SPoul-Henning Kamp for (p = db_ksprintn(ul, *p++, NULL); *p;p--) 246169cd910SPoul-Henning Kamp db_putchar(*p); 2475b81b6b3SRodney W. Grimes 2485b81b6b3SRodney W. Grimes if (!ul) 2495b81b6b3SRodney W. Grimes break; 2505b81b6b3SRodney W. Grimes 251169cd910SPoul-Henning Kamp for (tmp = 0; *p;) { 252169cd910SPoul-Henning Kamp n = *p++; 2535b81b6b3SRodney W. Grimes if (ul & (1 << (n - 1))) { 2545b81b6b3SRodney W. Grimes db_putchar(tmp ? ',' : '<'); 2555b81b6b3SRodney W. Grimes for (; (n = *p) > ' '; ++p) 2565b81b6b3SRodney W. Grimes db_putchar(n); 2575b81b6b3SRodney W. Grimes tmp = 1; 2585b81b6b3SRodney W. Grimes } else 2595b81b6b3SRodney W. Grimes for (; *p > ' '; ++p); 2605b81b6b3SRodney W. Grimes } 2615b81b6b3SRodney W. Grimes if (tmp) 2625b81b6b3SRodney W. Grimes db_putchar('>'); 2635b81b6b3SRodney W. Grimes break; 2645b81b6b3SRodney W. Grimes case '*': 2655b81b6b3SRodney W. Grimes width = va_arg (ap, int); 2665b81b6b3SRodney W. Grimes if (width < 0) { 2675b81b6b3SRodney W. Grimes ladjust = !ladjust; 2685b81b6b3SRodney W. Grimes width = -width; 2695b81b6b3SRodney W. Grimes } 2705b81b6b3SRodney W. Grimes goto reswitch; 2715b81b6b3SRodney W. Grimes case 'c': 2725b81b6b3SRodney W. Grimes db_putchar(va_arg(ap, int)); 2735b81b6b3SRodney W. Grimes break; 2745b81b6b3SRodney W. Grimes case 's': 2755b81b6b3SRodney W. Grimes p = va_arg(ap, char *); 276d2984da1SBruce Evans if (p == NULL) 277d2984da1SBruce Evans p = "(null)"; 2785b81b6b3SRodney W. Grimes width -= strlen (p); 2795b81b6b3SRodney W. Grimes if (!ladjust && width > 0) 2805b81b6b3SRodney W. Grimes while (width--) 2815b81b6b3SRodney W. Grimes db_putchar (padc); 282169cd910SPoul-Henning Kamp for (;*p;p++) 283169cd910SPoul-Henning Kamp db_putchar(*p); 2845b81b6b3SRodney W. Grimes if (ladjust && width > 0) 2855b81b6b3SRodney W. Grimes while (width--) 2865b81b6b3SRodney W. Grimes db_putchar (padc); 2875b81b6b3SRodney W. Grimes break; 2885b81b6b3SRodney W. Grimes case 'r': 2895b81b6b3SRodney W. Grimes ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 2905b81b6b3SRodney W. Grimes if ((long)ul < 0) { 2915b81b6b3SRodney W. Grimes neg = 1; 2925b81b6b3SRodney W. Grimes ul = -(long)ul; 2935b81b6b3SRodney W. Grimes } 2945b81b6b3SRodney W. Grimes base = db_radix; 2955b81b6b3SRodney W. Grimes if (base < 8 || base > 16) 2965b81b6b3SRodney W. Grimes base = 10; 2975b81b6b3SRodney W. Grimes goto number; 2985b81b6b3SRodney W. Grimes case 'n': 2995b81b6b3SRodney W. Grimes ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 3005b81b6b3SRodney W. Grimes base = db_radix; 3015b81b6b3SRodney W. Grimes if (base < 8 || base > 16) 3025b81b6b3SRodney W. Grimes base = 10; 3035b81b6b3SRodney W. Grimes goto number; 3045b81b6b3SRodney W. Grimes case 'd': 3055b81b6b3SRodney W. Grimes ul = lflag ? va_arg(ap, long) : va_arg(ap, int); 3065b81b6b3SRodney W. Grimes if ((long)ul < 0) { 3075b81b6b3SRodney W. Grimes neg = 1; 3085b81b6b3SRodney W. Grimes ul = -(long)ul; 3095b81b6b3SRodney W. Grimes } 3105b81b6b3SRodney W. Grimes base = 10; 3115b81b6b3SRodney W. Grimes goto number; 3125b81b6b3SRodney W. Grimes case 'o': 3135b81b6b3SRodney W. Grimes ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 3145b81b6b3SRodney W. Grimes base = 8; 3155b81b6b3SRodney W. Grimes goto number; 3165b81b6b3SRodney W. Grimes case 'u': 3175b81b6b3SRodney W. Grimes ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 3185b81b6b3SRodney W. Grimes base = 10; 3195b81b6b3SRodney W. Grimes goto number; 3205b81b6b3SRodney W. Grimes case 'z': 3215b81b6b3SRodney W. Grimes ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 3225b81b6b3SRodney W. Grimes if ((long)ul < 0) { 3235b81b6b3SRodney W. Grimes neg = 1; 3245b81b6b3SRodney W. Grimes ul = -(long)ul; 3255b81b6b3SRodney W. Grimes } 3265b81b6b3SRodney W. Grimes base = 16; 3275b81b6b3SRodney W. Grimes goto number; 3285b81b6b3SRodney W. Grimes case 'x': 3295b81b6b3SRodney W. Grimes ul = lflag ? va_arg(ap, u_long) : va_arg(ap, u_int); 3305b81b6b3SRodney W. Grimes base = 16; 3315b81b6b3SRodney W. Grimes number: p = (char *)db_ksprintn(ul, base, &tmp); 3325b81b6b3SRodney W. Grimes if (sharpflag && ul != 0) { 3335b81b6b3SRodney W. Grimes if (base == 8) 3345b81b6b3SRodney W. Grimes tmp++; 3355b81b6b3SRodney W. Grimes else if (base == 16) 3365b81b6b3SRodney W. Grimes tmp += 2; 3375b81b6b3SRodney W. Grimes } 3385b81b6b3SRodney W. Grimes if (neg) 3395b81b6b3SRodney W. Grimes tmp++; 3405b81b6b3SRodney W. Grimes 3415b81b6b3SRodney W. Grimes if (!ladjust && width && (width -= tmp) > 0) 3425b81b6b3SRodney W. Grimes while (width--) 3435b81b6b3SRodney W. Grimes db_putchar(padc); 3445b81b6b3SRodney W. Grimes if (neg) 3455b81b6b3SRodney W. Grimes db_putchar ('-'); 3465b81b6b3SRodney W. Grimes if (sharpflag && ul != 0) { 3475b81b6b3SRodney W. Grimes if (base == 8) { 3485b81b6b3SRodney W. Grimes db_putchar ('0'); 3495b81b6b3SRodney W. Grimes } else if (base == 16) { 3505b81b6b3SRodney W. Grimes db_putchar ('0'); 3515b81b6b3SRodney W. Grimes db_putchar ('x'); 3525b81b6b3SRodney W. Grimes } 3535b81b6b3SRodney W. Grimes } 3545b81b6b3SRodney W. Grimes if (ladjust && width && (width -= tmp) > 0) 3555b81b6b3SRodney W. Grimes while (width--) 3565b81b6b3SRodney W. Grimes db_putchar(padc); 3575b81b6b3SRodney W. Grimes 358169cd910SPoul-Henning Kamp for (;*p;p--) 359169cd910SPoul-Henning Kamp db_putchar(*p); 3605b81b6b3SRodney W. Grimes break; 3615b81b6b3SRodney W. Grimes default: 3625b81b6b3SRodney W. Grimes db_putchar('%'); 3635b81b6b3SRodney W. Grimes if (lflag) 3645b81b6b3SRodney W. Grimes db_putchar('l'); 3655b81b6b3SRodney W. Grimes /* FALLTHROUGH */ 3665b81b6b3SRodney W. Grimes case '%': 3675b81b6b3SRodney W. Grimes db_putchar(ch); 3685b81b6b3SRodney W. Grimes } 3695b81b6b3SRodney W. Grimes } 3705b81b6b3SRodney W. Grimes } 371