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: releng/5.3/sys/ddb/db_output.c 131952 2004-07-10 23:47:20Z marcel $");
   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 static int      db_newlines;                    /* # lines this page */
   69 static int      db_maxlines = -1;               /* max lines per page */
   70 static db_page_calloutfcn_t *db_page_callout = NULL;
   71 static void     *db_page_callout_arg = NULL;
   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 
   78 /*
   79  * Force pending whitespace.
   80  */
   81 void
   82 db_force_whitespace()
   83 {
   84         register int last_print, next_tab;
   85 
   86         last_print = db_last_non_space;
   87         while (last_print < db_output_position) {
   88             next_tab = NEXT_TAB(last_print);
   89             if (next_tab <= db_output_position) {
   90                 while (last_print < next_tab) { /* DON'T send a tab!!! */
   91                         cnputc(' ');
   92                         last_print++;
   93                 }
   94             }
   95             else {
   96                 cnputc(' ');
   97                 last_print++;
   98             }
   99         }
  100         db_last_non_space = db_output_position;
  101 }
  102 
  103 /*
  104  * Output character.  Buffer whitespace.
  105  */
  106 static void
  107 db_putchar(c, arg)
  108         int     c;              /* character to output */
  109         void *  arg;
  110 {
  111 
  112         /*
  113          * If not in the debugger or the user requests it, output data to
  114          * both the console and the message buffer.
  115          */
  116         if (!kdb_active || ddb_use_printf) {
  117                 printf("%c", c);
  118                 if (!kdb_active)
  119                         return;
  120                 if (c == '\r' || c == '\n')
  121                         db_check_interrupt();
  122                 if (c == '\n' && db_maxlines > 0 && db_page_callout != NULL) {
  123                         db_newlines++;
  124                         if (db_newlines >= db_maxlines) {
  125                                 db_maxlines = -1;
  126                                 db_page_callout(db_page_callout_arg);
  127                         }
  128                 }
  129                 return;
  130         }
  131 
  132         /* Otherwise, output data directly to the console. */
  133         if (c > ' ' && c <= '~') {
  134             /*
  135              * Printing character.
  136              * If we have spaces to print, print them first.
  137              * Use tabs if possible.
  138              */
  139             db_force_whitespace();
  140             cnputc(c);
  141             db_output_position++;
  142             db_last_non_space = db_output_position;
  143         }
  144         else if (c == '\n') {
  145             /* Newline */
  146             cnputc(c);
  147             db_output_position = 0;
  148             db_last_non_space = 0;
  149             db_check_interrupt();
  150             if (db_maxlines > 0 && db_page_callout != NULL) {
  151                     db_newlines++;
  152                     if (db_newlines >= db_maxlines) {
  153                             db_maxlines = -1;
  154                             db_page_callout(db_page_callout_arg);
  155                     }
  156             }
  157         }
  158         else if (c == '\r') {
  159             /* Return */
  160             cnputc(c);
  161             db_output_position = 0;
  162             db_last_non_space = 0;
  163             db_check_interrupt();
  164         }
  165         else if (c == '\t') {
  166             /* assume tabs every 8 positions */
  167             db_output_position = NEXT_TAB(db_output_position);
  168         }
  169         else if (c == ' ') {
  170             /* space */
  171             db_output_position++;
  172         }
  173         else if (c == '\007') {
  174             /* bell */
  175             cnputc(c);
  176         }
  177         /* other characters are assumed non-printing */
  178 }
  179 
  180 /*
  181  * Register callout for providing a pager for output.
  182  */
  183 void
  184 db_setup_paging(db_page_calloutfcn_t *callout, void *arg, int maxlines)
  185 {
  186 
  187         db_page_callout = callout;
  188         db_page_callout_arg = arg;
  189         db_maxlines = maxlines;
  190         db_newlines = 0;
  191 }
  192 
  193 /*
  194  * A simple paging callout function.  If the argument is not null, it
  195  * points to an integer that will be set to 1 if the user asks to quit.
  196  */
  197 void
  198 db_simple_pager(void *arg)
  199 {
  200         int c;
  201 
  202         db_printf("--More--\r");
  203         for (;;) {
  204                 c = cngetc();
  205                 switch (c) {
  206                 case '\n':
  207                         /* Just one more line. */
  208                         db_setup_paging(db_simple_pager, arg, 1);
  209                         return;
  210                 case ' ':
  211                         /* Another page. */
  212                         db_setup_paging(db_simple_pager, arg,
  213                             DB_LINES_PER_PAGE);
  214                         return;
  215                 case 'q':
  216                 case 'Q':
  217                 case 'x':
  218                 case 'X':
  219                         /* Quit */
  220                         if (arg != NULL) {
  221                                 *(int *)arg = 1;
  222                                 db_printf("\n");
  223                                 return;
  224                         }
  225 #if 0
  226                         /* FALLTHROUGH */
  227                 default:
  228                         cnputc('\007');
  229 #endif
  230                 }
  231         }
  232 }
  233 
  234 /*
  235  * Return output position
  236  */
  237 int
  238 db_print_position()
  239 {
  240         return (db_output_position);
  241 }
  242 
  243 /*
  244  * Printing
  245  */
  246 void
  247 #if __STDC__
  248 db_printf(const char *fmt, ...)
  249 #else
  250 db_printf(fmt)
  251         const char *fmt;
  252 #endif
  253 {
  254         va_list listp;
  255 
  256         va_start(listp, fmt);
  257         kvprintf (fmt, db_putchar, NULL, db_radix, listp);
  258         va_end(listp);
  259 }
  260 
  261 int db_indent;
  262 
  263 void
  264 #if __STDC__
  265 db_iprintf(const char *fmt,...)
  266 #else
  267 db_iprintf(fmt)
  268         const char *fmt;
  269 #endif
  270 {
  271         register int i;
  272         va_list listp;
  273 
  274         for (i = db_indent; i >= 8; i -= 8)
  275                 db_printf("\t");
  276         while (--i >= 0)
  277                 db_printf(" ");
  278         va_start(listp, fmt);
  279         kvprintf (fmt, db_putchar, NULL, db_radix, listp);
  280         va_end(listp);
  281 }
  282 
  283 /*
  284  * End line if too long.
  285  */
  286 void
  287 db_end_line()
  288 {
  289         if (db_output_position >= db_max_width)
  290             db_printf("\n");
  291 }

Cache object: a5850c9f86cf8f57f103bd9cee6f6705


[ 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.