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 */ 265b81b6b3SRodney W. Grimes /* 275b81b6b3SRodney W. Grimes * Author: David B. Golub, Carnegie Mellon University 285b81b6b3SRodney W. Grimes * Date: 7/90 295b81b6b3SRodney W. Grimes */ 305b81b6b3SRodney W. Grimes 315b81b6b3SRodney W. Grimes /* 325b81b6b3SRodney W. Grimes * Printf and character output for debugger. 335b81b6b3SRodney W. Grimes */ 345b81b6b3SRodney W. Grimes 35753960f7SDavid E. O'Brien #include <sys/cdefs.h> 36753960f7SDavid E. O'Brien __FBSDID("$FreeBSD$"); 37753960f7SDavid E. O'Brien 38f540b106SGarrett Wollman #include <sys/param.h> 39f540b106SGarrett Wollman #include <sys/systm.h> 40ce9edcf5SPoul-Henning Kamp #include <sys/cons.h> 4137224cd3SMarcel Moolenaar #include <sys/kdb.h> 425de6c5b5SNate Lawson #include <sys/kernel.h> 435de6c5b5SNate Lawson #include <sys/sysctl.h> 445ccbc3ccSBruce Evans 45f540b106SGarrett Wollman #include <machine/stdarg.h> 465ccbc3ccSBruce Evans 47f540b106SGarrett Wollman #include <ddb/ddb.h> 48058284fcSBruce Evans #include <ddb/db_output.h> 495b81b6b3SRodney W. Grimes 505b81b6b3SRodney W. Grimes /* 515b81b6b3SRodney W. Grimes * Character output - tracks position in line. 525b81b6b3SRodney W. Grimes * To do this correctly, we should know how wide 535b81b6b3SRodney W. Grimes * the output device is - then we could zero 545b81b6b3SRodney W. Grimes * the line position when the output device wraps 555b81b6b3SRodney W. Grimes * around to the start of the next line. 565b81b6b3SRodney W. Grimes * 575b81b6b3SRodney W. Grimes * Instead, we count the number of spaces printed 585b81b6b3SRodney W. Grimes * since the last printing character so that we 595b81b6b3SRodney W. Grimes * don't print trailing spaces. This avoids most 605b81b6b3SRodney W. Grimes * of the wraparounds. 615b81b6b3SRodney W. Grimes */ 62f73a856dSPoul-Henning Kamp static int db_output_position = 0; /* output column */ 63f73a856dSPoul-Henning Kamp static int db_last_non_space = 0; /* last non-space character */ 643da6ef3cSBruce Evans db_expr_t db_tab_stop_width = 8; /* how wide are tab stops? */ 655b81b6b3SRodney W. Grimes #define NEXT_TAB(i) \ 665b81b6b3SRodney W. Grimes ((((i) + db_tab_stop_width) / db_tab_stop_width) * db_tab_stop_width) 673da6ef3cSBruce Evans db_expr_t db_max_width = 79; /* output line width */ 68d39d4a6eSJohn Baldwin db_expr_t db_lines_per_page = 20; /* lines per page */ 691e16f609SJohn Baldwin static int db_newlines; /* # lines this page */ 70d39d4a6eSJohn Baldwin static int db_maxlines = -1; /* max lines/page when paging */ 711e16f609SJohn Baldwin static db_page_calloutfcn_t *db_page_callout = NULL; 721e16f609SJohn Baldwin static void *db_page_callout_arg = NULL; 735de6c5b5SNate Lawson static int ddb_use_printf = 0; 745de6c5b5SNate Lawson SYSCTL_INT(_debug, OID_AUTO, ddb_use_printf, CTLFLAG_RW, &ddb_use_printf, 0, 755de6c5b5SNate Lawson "use printf for all ddb output"); 765b81b6b3SRodney W. Grimes 7714e10f99SAlfred Perlstein static void db_putchar(int c, void *arg); 786ddbf1e2SGary Palmer 795b81b6b3SRodney W. Grimes /* 805b81b6b3SRodney W. Grimes * Force pending whitespace. 815b81b6b3SRodney W. Grimes */ 825b81b6b3SRodney W. Grimes void 835b81b6b3SRodney W. Grimes db_force_whitespace() 845b81b6b3SRodney W. Grimes { 855b81b6b3SRodney W. Grimes register int last_print, next_tab; 865b81b6b3SRodney W. Grimes 875b81b6b3SRodney W. Grimes last_print = db_last_non_space; 885b81b6b3SRodney W. Grimes while (last_print < db_output_position) { 895b81b6b3SRodney W. Grimes next_tab = NEXT_TAB(last_print); 905b81b6b3SRodney W. Grimes if (next_tab <= db_output_position) { 915b81b6b3SRodney W. Grimes while (last_print < next_tab) { /* DON'T send a tab!!! */ 925b81b6b3SRodney W. Grimes cnputc(' '); 935b81b6b3SRodney W. Grimes last_print++; 945b81b6b3SRodney W. Grimes } 955b81b6b3SRodney W. Grimes } 965b81b6b3SRodney W. Grimes else { 975b81b6b3SRodney W. Grimes cnputc(' '); 985b81b6b3SRodney W. Grimes last_print++; 995b81b6b3SRodney W. Grimes } 1005b81b6b3SRodney W. Grimes } 1015b81b6b3SRodney W. Grimes db_last_non_space = db_output_position; 1025b81b6b3SRodney W. Grimes } 1035b81b6b3SRodney W. Grimes 1045b81b6b3SRodney W. Grimes /* 1055b81b6b3SRodney W. Grimes * Output character. Buffer whitespace. 1065b81b6b3SRodney W. Grimes */ 1076ddbf1e2SGary Palmer static void 1086ddbf1e2SGary Palmer db_putchar(c, arg) 1095b81b6b3SRodney W. Grimes int c; /* character to output */ 1106ddbf1e2SGary Palmer void * arg; 1115b81b6b3SRodney W. Grimes { 1121e16f609SJohn Baldwin 1135de6c5b5SNate Lawson /* 1145de6c5b5SNate Lawson * If not in the debugger or the user requests it, output data to 1155de6c5b5SNate Lawson * both the console and the message buffer. 1165de6c5b5SNate Lawson */ 11737224cd3SMarcel Moolenaar if (!kdb_active || ddb_use_printf) { 1185de6c5b5SNate Lawson printf("%c", c); 11937224cd3SMarcel Moolenaar if (!kdb_active) 1205de6c5b5SNate Lawson return; 1215de6c5b5SNate Lawson if (c == '\r' || c == '\n') 1225de6c5b5SNate Lawson db_check_interrupt(); 1235de6c5b5SNate Lawson if (c == '\n' && db_maxlines > 0 && db_page_callout != NULL) { 1245de6c5b5SNate Lawson db_newlines++; 1255de6c5b5SNate Lawson if (db_newlines >= db_maxlines) { 1265de6c5b5SNate Lawson db_maxlines = -1; 1275de6c5b5SNate Lawson db_page_callout(db_page_callout_arg); 1285de6c5b5SNate Lawson } 1295de6c5b5SNate Lawson } 1305de6c5b5SNate Lawson return; 1315de6c5b5SNate Lawson } 1325de6c5b5SNate Lawson 1335de6c5b5SNate Lawson /* Otherwise, output data directly to the console. */ 1345b81b6b3SRodney W. Grimes if (c > ' ' && c <= '~') { 1355b81b6b3SRodney W. Grimes /* 1365b81b6b3SRodney W. Grimes * Printing character. 1375b81b6b3SRodney W. Grimes * If we have spaces to print, print them first. 1385b81b6b3SRodney W. Grimes * Use tabs if possible. 1395b81b6b3SRodney W. Grimes */ 1405b81b6b3SRodney W. Grimes db_force_whitespace(); 1415b81b6b3SRodney W. Grimes cnputc(c); 1425b81b6b3SRodney W. Grimes db_output_position++; 1435b81b6b3SRodney W. Grimes db_last_non_space = db_output_position; 1445b81b6b3SRodney W. Grimes } 1455b81b6b3SRodney W. Grimes else if (c == '\n') { 1468a129caeSDavid Greenman /* Newline */ 147d39d4a6eSJohn Baldwin db_force_whitespace(); 1488a129caeSDavid Greenman cnputc(c); 1498a129caeSDavid Greenman db_output_position = 0; 1508a129caeSDavid Greenman db_last_non_space = 0; 1518a129caeSDavid Greenman db_check_interrupt(); 1521e16f609SJohn Baldwin if (db_maxlines > 0 && db_page_callout != NULL) { 1531e16f609SJohn Baldwin db_newlines++; 1541e16f609SJohn Baldwin if (db_newlines >= db_maxlines) { 1551e16f609SJohn Baldwin db_maxlines = -1; 1561e16f609SJohn Baldwin db_page_callout(db_page_callout_arg); 1571e16f609SJohn Baldwin } 1581e16f609SJohn Baldwin } 1598a129caeSDavid Greenman } 1608a129caeSDavid Greenman else if (c == '\r') { 1615b81b6b3SRodney W. Grimes /* Return */ 162d39d4a6eSJohn Baldwin db_force_whitespace(); 1635b81b6b3SRodney W. Grimes cnputc(c); 1645b81b6b3SRodney W. Grimes db_output_position = 0; 1655b81b6b3SRodney W. Grimes db_last_non_space = 0; 1665b81b6b3SRodney W. Grimes db_check_interrupt(); 1675b81b6b3SRodney W. Grimes } 1685b81b6b3SRodney W. Grimes else if (c == '\t') { 1695b81b6b3SRodney W. Grimes /* assume tabs every 8 positions */ 1705b81b6b3SRodney W. Grimes db_output_position = NEXT_TAB(db_output_position); 1715b81b6b3SRodney W. Grimes } 1725b81b6b3SRodney W. Grimes else if (c == ' ') { 1735b81b6b3SRodney W. Grimes /* space */ 1745b81b6b3SRodney W. Grimes db_output_position++; 1755b81b6b3SRodney W. Grimes } 1765b81b6b3SRodney W. Grimes else if (c == '\007') { 1775b81b6b3SRodney W. Grimes /* bell */ 1785b81b6b3SRodney W. Grimes cnputc(c); 1795b81b6b3SRodney W. Grimes } 1805b81b6b3SRodney W. Grimes /* other characters are assumed non-printing */ 1815b81b6b3SRodney W. Grimes } 1825b81b6b3SRodney W. Grimes 1835b81b6b3SRodney W. Grimes /* 1841e16f609SJohn Baldwin * Register callout for providing a pager for output. 1851e16f609SJohn Baldwin */ 1861e16f609SJohn Baldwin void 1871e16f609SJohn Baldwin db_setup_paging(db_page_calloutfcn_t *callout, void *arg, int maxlines) 1881e16f609SJohn Baldwin { 1891e16f609SJohn Baldwin 1901e16f609SJohn Baldwin db_page_callout = callout; 1911e16f609SJohn Baldwin db_page_callout_arg = arg; 1921e16f609SJohn Baldwin db_maxlines = maxlines; 1931e16f609SJohn Baldwin db_newlines = 0; 1941e16f609SJohn Baldwin } 1951e16f609SJohn Baldwin 1961e16f609SJohn Baldwin /* 1971e16f609SJohn Baldwin * A simple paging callout function. If the argument is not null, it 1981e16f609SJohn Baldwin * points to an integer that will be set to 1 if the user asks to quit. 1991e16f609SJohn Baldwin */ 2001e16f609SJohn Baldwin void 2011e16f609SJohn Baldwin db_simple_pager(void *arg) 2021e16f609SJohn Baldwin { 203d39d4a6eSJohn Baldwin int c, done; 2041e16f609SJohn Baldwin 2051e16f609SJohn Baldwin db_printf("--More--\r"); 206d39d4a6eSJohn Baldwin done = 0; 207d39d4a6eSJohn Baldwin while (!done) { 2081e16f609SJohn Baldwin c = cngetc(); 2091e16f609SJohn Baldwin switch (c) { 210d39d4a6eSJohn Baldwin case 'e': 211d39d4a6eSJohn Baldwin case 'j': 2121e16f609SJohn Baldwin case '\n': 2131e16f609SJohn Baldwin /* Just one more line. */ 2141e16f609SJohn Baldwin db_setup_paging(db_simple_pager, arg, 1); 215d39d4a6eSJohn Baldwin done++; 216d39d4a6eSJohn Baldwin break; 217d39d4a6eSJohn Baldwin case 'd': 218d39d4a6eSJohn Baldwin /* Half a page. */ 219d39d4a6eSJohn Baldwin db_setup_paging(db_simple_pager, arg, 220d39d4a6eSJohn Baldwin db_lines_per_page / 2); 221d39d4a6eSJohn Baldwin done++; 222d39d4a6eSJohn Baldwin break; 223d39d4a6eSJohn Baldwin case 'f': 2241e16f609SJohn Baldwin case ' ': 2251e16f609SJohn Baldwin /* Another page. */ 2261e16f609SJohn Baldwin db_setup_paging(db_simple_pager, arg, 227d39d4a6eSJohn Baldwin db_lines_per_page); 228d39d4a6eSJohn Baldwin done++; 229d39d4a6eSJohn Baldwin break; 2301e16f609SJohn Baldwin case 'q': 2311e16f609SJohn Baldwin case 'Q': 2321e16f609SJohn Baldwin case 'x': 2331e16f609SJohn Baldwin case 'X': 2341e16f609SJohn Baldwin /* Quit */ 2351e16f609SJohn Baldwin if (arg != NULL) { 2361e16f609SJohn Baldwin *(int *)arg = 1; 237d39d4a6eSJohn Baldwin done++; 238d39d4a6eSJohn Baldwin break; 2391e16f609SJohn Baldwin } 2401e16f609SJohn Baldwin #if 0 2411e16f609SJohn Baldwin /* FALLTHROUGH */ 2421e16f609SJohn Baldwin default: 2431e16f609SJohn Baldwin cnputc('\007'); 2441e16f609SJohn Baldwin #endif 2451e16f609SJohn Baldwin } 2461e16f609SJohn Baldwin } 247d39d4a6eSJohn Baldwin db_printf(" \r"); 2481e16f609SJohn Baldwin } 2491e16f609SJohn Baldwin 2501e16f609SJohn Baldwin /* 2515b81b6b3SRodney W. Grimes * Return output position 2525b81b6b3SRodney W. Grimes */ 2535b81b6b3SRodney W. Grimes int 2545b81b6b3SRodney W. Grimes db_print_position() 2555b81b6b3SRodney W. Grimes { 2565b81b6b3SRodney W. Grimes return (db_output_position); 2575b81b6b3SRodney W. Grimes } 2585b81b6b3SRodney W. Grimes 2595b81b6b3SRodney W. Grimes /* 2605b81b6b3SRodney W. Grimes * Printing 2615b81b6b3SRodney W. Grimes */ 262381fe1aaSGarrett Wollman void 263b9478d12SBruce Evans #if __STDC__ 264381fe1aaSGarrett Wollman db_printf(const char *fmt, ...) 265b9478d12SBruce Evans #else 266b9478d12SBruce Evans db_printf(fmt) 267b9478d12SBruce Evans const char *fmt; 268b9478d12SBruce Evans #endif 2695b81b6b3SRodney W. Grimes { 2705b81b6b3SRodney W. Grimes va_list listp; 271c7c34a24SBruce Evans 272c7c34a24SBruce Evans va_start(listp, fmt); 273c7c34a24SBruce Evans kvprintf (fmt, db_putchar, NULL, db_radix, listp); 274c7c34a24SBruce Evans va_end(listp); 275c7c34a24SBruce Evans } 276c7c34a24SBruce Evans 277c7c34a24SBruce Evans int db_indent; 278c7c34a24SBruce Evans 279c7c34a24SBruce Evans void 280b9478d12SBruce Evans #if __STDC__ 281c7c34a24SBruce Evans db_iprintf(const char *fmt,...) 282b9478d12SBruce Evans #else 283b9478d12SBruce Evans db_iprintf(fmt) 284b9478d12SBruce Evans const char *fmt; 285b9478d12SBruce Evans #endif 286c7c34a24SBruce Evans { 287c7c34a24SBruce Evans register int i; 288c7c34a24SBruce Evans va_list listp; 289c7c34a24SBruce Evans 290c7c34a24SBruce Evans for (i = db_indent; i >= 8; i -= 8) 291c7c34a24SBruce Evans db_printf("\t"); 292c7c34a24SBruce Evans while (--i >= 0) 293c7c34a24SBruce Evans db_printf(" "); 2945b81b6b3SRodney W. Grimes va_start(listp, fmt); 295791d77e0SPoul-Henning Kamp kvprintf (fmt, db_putchar, NULL, db_radix, listp); 2965b81b6b3SRodney W. Grimes va_end(listp); 2975b81b6b3SRodney W. Grimes } 2985b81b6b3SRodney W. Grimes 2995b81b6b3SRodney W. Grimes /* 300572de915SRodney W. Grimes * End line if too long. 301572de915SRodney W. Grimes */ 302572de915SRodney W. Grimes void 303572de915SRodney W. Grimes db_end_line() 304572de915SRodney W. Grimes { 305572de915SRodney W. Grimes if (db_output_position >= db_max_width) 306572de915SRodney W. Grimes db_printf("\n"); 307572de915SRodney W. Grimes } 308