Add a one-shot callout facility to db_printf() that executes the registered

callout when a specified number of lines have been output.  This can be
used to implement pagers for ddb commands that output a lot of text.  A
simple paging function is included that automatically rearms itself when
fired.

Reviewed by:	bde, julian
This commit is contained in:
John Baldwin 2003-07-31 17:27:52 +00:00
parent 69e4c73037
commit 1e16f6098b
3 changed files with 75 additions and 0 deletions

View File

@ -344,6 +344,7 @@ db_command(last_cmdp, cmd_table, aux_cmd_tablep, aux_cmd_tablep_end)
* Execute the command.
*/
(*cmd->fcn)(addr, have_addr, count, modif);
db_setup_paging(NULL, NULL, -1);
if (cmd->flag & CS_SET_DOT) {
/*

View File

@ -62,6 +62,10 @@ db_expr_t 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)
db_expr_t db_max_width = 79; /* output line width */
static int db_newlines; /* # lines this page */
static int db_maxlines = -1; /* max lines per page */
static db_page_calloutfcn_t *db_page_callout = NULL;
static void *db_page_callout_arg = NULL;
static void db_putchar(int c, void *arg);
@ -98,6 +102,7 @@ db_putchar(c, arg)
int c; /* character to output */
void * arg;
{
if (c > ' ' && c <= '~') {
/*
* Printing character.
@ -115,6 +120,13 @@ db_putchar(c, arg)
db_output_position = 0;
db_last_non_space = 0;
db_check_interrupt();
if (db_maxlines > 0 && db_page_callout != NULL) {
db_newlines++;
if (db_newlines >= db_maxlines) {
db_maxlines = -1;
db_page_callout(db_page_callout_arg);
}
}
}
else if (c == '\r') {
/* Return */
@ -138,6 +150,60 @@ db_putchar(c, arg)
/* other characters are assumed non-printing */
}
/*
* Register callout for providing a pager for output.
*/
void
db_setup_paging(db_page_calloutfcn_t *callout, void *arg, int maxlines)
{
db_page_callout = callout;
db_page_callout_arg = arg;
db_maxlines = maxlines;
db_newlines = 0;
}
/*
* A simple paging callout function. If the argument is not null, it
* points to an integer that will be set to 1 if the user asks to quit.
*/
void
db_simple_pager(void *arg)
{
int c;
db_printf("--More--\r");
for (;;) {
c = cngetc();
switch (c) {
case '\n':
/* Just one more line. */
db_setup_paging(db_simple_pager, arg, 1);
return;
case ' ':
/* Another page. */
db_setup_paging(db_simple_pager, arg,
DB_LINES_PER_PAGE);
return;
case 'q':
case 'Q':
case 'x':
case 'X':
/* Quit */
if (arg != NULL) {
*(int *)arg = 1;
db_printf("\n");
return;
}
#if 0
/* FALLTHROUGH */
default:
cnputc('\007');
#endif
}
}
}
/*
* Return output position
*/

View File

@ -39,9 +39,13 @@
#include <machine/db_machdep.h> /* type definitions */
#define DB_LINES_PER_PAGE 20
typedef void db_cmdfcn_t(db_expr_t addr, boolean_t have_addr, db_expr_t count,
char *modif);
typedef void db_page_calloutfcn_t(void *arg);
#define DB_COMMAND(cmd_name, func_name) \
DB_SET(cmd_name, func_name, db_cmd_set, 0, NULL)
#define DB_SHOW_COMMAND(cmd_name, func_name) \
@ -100,6 +104,8 @@ void db_read_bytes(vm_offset_t addr, size_t size, char *data);
int db_readline(char *lstart, int lsize);
void db_restart_at_pc(boolean_t watchpt);
void db_set_watchpoints(void);
void db_setup_paging(db_page_calloutfcn_t *callout, void *arg,
int maxlines);
void db_skip_to_eol(void);
boolean_t db_stop_at_pc(boolean_t *is_breakpoint);
#define db_strcpy strcpy
@ -139,6 +145,8 @@ db_cmdfcn_t ipc_port_print;
db_cmdfcn_t vm_page_print;
#endif
db_page_calloutfcn_t db_simple_pager;
/* Scare the user with backtrace of curthread to console. */
void db_print_backtrace(void);