aboutsummaryrefslogtreecommitdiff
path: root/sys/ddb
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2003-07-31 17:27:52 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2003-07-31 17:27:52 +0000
commit1e16f6098bf69794d9be2a7722a1ee1ac090508d (patch)
tree2e3958472b2e92004d1cf78c61cbb91760f2f2b8 /sys/ddb
parent69e4c730376c7789a1f05e654f2eaaf3c4937be9 (diff)
downloadsrc-1e16f6098bf69794d9be2a7722a1ee1ac090508d.tar.gz
src-1e16f6098bf69794d9be2a7722a1ee1ac090508d.zip
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
Notes
Notes: svn path=/head/; revision=118268
Diffstat (limited to 'sys/ddb')
-rw-r--r--sys/ddb/db_command.c1
-rw-r--r--sys/ddb/db_output.c66
-rw-r--r--sys/ddb/ddb.h8
3 files changed, 75 insertions, 0 deletions
diff --git a/sys/ddb/db_command.c b/sys/ddb/db_command.c
index ff895c72acf5..56d3ed1f87d3 100644
--- a/sys/ddb/db_command.c
+++ b/sys/ddb/db_command.c
@@ -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) {
/*
diff --git a/sys/ddb/db_output.c b/sys/ddb/db_output.c
index b1efb45ae01a..2fa8554488dd 100644
--- a/sys/ddb/db_output.c
+++ b/sys/ddb/db_output.c
@@ -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 */
@@ -139,6 +151,60 @@ db_putchar(c, arg)
}
/*
+ * 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
*/
int
diff --git a/sys/ddb/ddb.h b/sys/ddb/ddb.h
index 7259e97b6637..1ef452cfd440 100644
--- a/sys/ddb/ddb.h
+++ b/sys/ddb/ddb.h
@@ -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);