The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/ddb/db_output.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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  Software.Distribution@CS.CMU.EDU
   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  *      Author: David B. Golub, Carnegie Mellon University
   28  *      Date:   7/90
   29  */
   30 
   31 /*
   32  * Printf and character output for debugger.
   33  */
   34 
   35 #include <sys/cdefs.h>
   36 __FBSDID("$FreeBSD$");
   37 
   38 #include <sys/param.h>
   39 #include <sys/systm.h>
   40 #include <sys/cons.h>
   41 #include <sys/kdb.h>
   42 #include <sys/kernel.h>
   43 #include <sys/sysctl.h>
   44 
   45 #include <machine/stdarg.h>
   46 
   47 #include <ddb/ddb.h>
   48 #include <ddb/db_output.h>
   49 
   50 /*
   51  *      Character output - tracks position in line.
   52  *      To do this correctly, we should know how wide
   53  *      the output device is - then we could zero
   54  *      the line position when the output device wraps
   55  *      around to the start of the next line.
   56  *
   57  *      Instead, we count the number of spaces printed
   58  *      since the last printing character so that we
   59  *      don't print trailing spaces.  This avoids most
   60  *      of the wraparounds.
   61  */
   62 static int      db_output_position = 0;         /* output column */
   63 static int      db_last_non_space = 0;          /* last non-space character */
   64 db_expr_t       db_tab_stop_width = 8;          /* how wide are tab stops? */
   65 #define NEXT_TAB(i) \
   66         ((((i) + db_tab_stop_width) / db_tab_stop_width) * db_tab_stop_width)
   67 db_expr_t       db_max_width = 79;              /* output line width */
   68 db_expr_t       db_lines_per_page = 20;         /* lines per page */
   69 volatile int    db_pager_quit;                  /* user requested quit */
   70 static int      db_newlines;                    /* # lines this page */
   71 static int      db_maxlines;                    /* max lines/page when paging */
   72 static int      ddb_use_printf = 0;
   73 SYSCTL_INT(_debug, OID_AUTO, ddb_use_printf, CTLFLAG_RW, &ddb_use_printf, 0,
   74     "use printf for all ddb output");
   75 
   76 static void     db_putchar(int c, void *arg);
   77 static void     db_pager(void);
   78 
   79 /*
   80  * Force pending whitespace.
   81  */
   82 void
   83 db_force_whitespace()
   84 {
   85         register int last_print, next_tab;
   86 
   87         last_print = db_last_non_space;
   88         while (last_print < db_output_position) {
   89             next_tab = NEXT_TAB(last_print);
   90             if (next_tab <= db_output_position) {
   91                 while (last_print < next_tab) { /* DON'T send a tab!!! */
   92                         cnputc(' ');
   93                         last_print++;
   94                 }
   95             }
   96             else {
   97                 cnputc(' ');
   98                 last_print++;
   99             }
  100         }
  101         db_last_non_space = db_output_position;
  102 }
  103 
  104 /*
  105  * Output character.  Buffer whitespace.
  106  */
  107 static void
  108 db_putchar(c, arg)
  109         int     c;              /* character to output */
  110         void *  arg;
  111 {
  112 
  113         /*
  114          * If not in the debugger or the user requests it, output data to
  115          * both the console and the message buffer.
  116          */
  117         if (!kdb_active || ddb_use_printf) {
  118                 printf("%c", c);
  119                 if (!kdb_active)
  120                         return;
  121                 if (c == '\r' || c == '\n')
  122                         db_check_interrupt();
  123                 if (c == '\n' && db_maxlines > 0) {
  124                         db_newlines++;
  125                         if (db_newlines >= db_maxlines)
  126                                 db_pager();
  127                 }
  128                 return;
  129         }
  130 
  131         /* Otherwise, output data directly to the console. */
  132         if (c > ' ' && c <= '~') {
  133             /*
  134              * Printing character.
  135              * If we have spaces to print, print them first.
  136              * Use tabs if possible.
  137              */
  138             db_force_whitespace();
  139             cnputc(c);
  140             db_output_position++;
  141             db_last_non_space = db_output_position;
  142         }
  143         else if (c == '\n') {
  144             /* Newline */
  145             cnputc(c);
  146             db_output_position = 0;
  147             db_last_non_space = 0;
  148             db_check_interrupt();
  149             if (db_maxlines > 0) {
  150                     db_newlines++;
  151                     if (db_newlines >= db_maxlines)
  152                             db_pager();
  153             }
  154         }
  155         else if (c == '\r') {
  156             /* Return */
  157             cnputc(c);
  158             db_output_position = 0;
  159             db_last_non_space = 0;
  160             db_check_interrupt();
  161         }
  162         else if (c == '\t') {
  163             /* assume tabs every 8 positions */
  164             db_output_position = NEXT_TAB(db_output_position);
  165         }
  166         else if (c == ' ') {
  167             /* space */
  168             db_output_position++;
  169         }
  170         else if (c == '\007') {
  171             /* bell */
  172             cnputc(c);
  173         }
  174         /* other characters are assumed non-printing */
  175 }
  176 
  177 /*
  178  * Turn on the pager.
  179  */
  180 void
  181 db_enable_pager(void)
  182 {
  183         if (db_maxlines == 0) {
  184                 db_maxlines = db_lines_per_page;
  185                 db_newlines = 0;
  186                 db_pager_quit = 0;
  187         }
  188 }
  189 
  190 /*
  191  * Turn off the pager.
  192  */
  193 void
  194 db_disable_pager(void)
  195 {
  196         db_maxlines = 0;
  197 }
  198 
  199 /*
  200  * A simple paging callout function.  It supports several simple more(1)-like
  201  * commands as well as a quit command that sets db_pager_quit which db
  202  * commands can poll to see if they should terminate early.
  203  */
  204 void
  205 db_pager(void)
  206 {
  207         int c, done;
  208 
  209         db_printf("--More--\r");
  210         done = 0;
  211         while (!done) {
  212                 c = cngetc();
  213                 switch (c) {
  214                 case 'e':
  215                 case 'j':
  216                 case '\n':
  217                         /* Just one more line. */
  218                         db_maxlines = 1;
  219                         done++;
  220                         break;
  221                 case 'd':
  222                         /* Half a page. */
  223                         db_maxlines = db_lines_per_page / 2;
  224                         done++;
  225                         break;
  226                 case 'f':
  227                 case ' ':
  228                         /* Another page. */
  229                         db_maxlines = db_lines_per_page;
  230                         done++;
  231                         break;
  232                 case 'q':
  233                 case 'Q':
  234                 case 'x':
  235                 case 'X':
  236                         /* Quit */
  237                         db_maxlines = 0;
  238                         db_pager_quit = 1;
  239                         done++;
  240                         break;
  241 #if 0
  242                         /* FALLTHROUGH */
  243                 default:
  244                         cnputc('\007');
  245 #endif
  246                 }
  247         }
  248         db_printf("        ");
  249         db_force_whitespace();
  250         db_printf("\r");
  251         db_newlines = 0;
  252 }
  253 
  254 /*
  255  * Return output position
  256  */
  257 int
  258 db_print_position()
  259 {
  260         return (db_output_position);
  261 }
  262 
  263 /*
  264  * Printing
  265  */
  266 void
  267 #if __STDC__
  268 db_printf(const char *fmt, ...)
  269 #else
  270 db_printf(fmt)
  271         const char *fmt;
  272 #endif
  273 {
  274         va_list listp;
  275 
  276         va_start(listp, fmt);
  277         kvprintf (fmt, db_putchar, NULL, db_radix, listp);
  278         va_end(listp);
  279 }
  280 
  281 int db_indent;
  282 
  283 void
  284 #if __STDC__
  285 db_iprintf(const char *fmt,...)
  286 #else
  287 db_iprintf(fmt)
  288         const char *fmt;
  289 #endif
  290 {
  291         register int i;
  292         va_list listp;
  293 
  294         for (i = db_indent; i >= 8; i -= 8)
  295                 db_printf("\t");
  296         while (--i >= 0)
  297                 db_printf(" ");
  298         va_start(listp, fmt);
  299         kvprintf (fmt, db_putchar, NULL, db_radix, listp);
  300         va_end(listp);
  301 }
  302 
  303 /*
  304  * End line if too long.
  305  */
  306 void
  307 db_end_line(int field_width)
  308 {
  309         if (db_output_position + field_width > db_max_width)
  310             db_printf("\n");
  311 }

Cache object: 9f9d7eb5ff5e0b8889ae56b1d8f01280


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.