Subject: kern/4504: Implementation of command line history to ddb
To: None <gnats-bugs@gnats.netbsd.org>
From: None <kivinen@ssh.fi>
List: netbsd-bugs
Date: 11/16/1997 13:06:13
>Number: 4504
>Category: kern
>Synopsis: ddb doesn't have command line history (ctrl-p/ctrl-n)
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Sun Nov 16 03:20:02 1997
>Last-Modified:
>Originator: Tero Kivinen
>Organization:
SSH Communications Security Ltd
>Release: 1.2
>Environment:
System: NetBSD taulu.ssh.fi 1.2 NetBSD 1.2 (TAULU) #50: Mon Feb 24 21:40:52 EET 1997 kivinen@taulu.ssh.fi:/usr/src/sys/arch/i386/compile/TAULU i386
>Description:
There isn't a command line history in ddb.
>How-To-Repeat:
Try Ctrl-p or Ctrl-n in the ddb prompt, nothing happens :-)
>Fix:
I implemented command line history to mach 3.0 ddb in 1993 and I
patched that version to Netbsd 1.2 ddb last February. I think this
could be added to default distribution. To enable command line history
add
options DB_HISTORY_SIZE=4000
to kernel config file (allocate 4000 bytes for command line history).
By default DB_HISTORY_SIZE is 0 which disables the command line
history.
----------------------------------------------------------------------
*** /sys/ddb/db_input.c.orig Mon Feb 5 03:57:02 1996
--- /sys/ddb/db_input.c Mon Feb 17 17:11:24 1997
***************
*** 41,46 ****
--- 41,50 ----
#include <dev/cons.h>
+ #ifndef DB_HISTORY_SIZE
+ #define DB_HISTORY_SIZE 0
+ #endif /* DB_HISTORY_SIZE */
+
/*
* Character input and editing.
*/
***************
*** 54,59 ****
--- 58,71 ----
char * db_lbuf_end; /* end of input line buffer */
char * db_lc; /* current character */
char * db_le; /* one past last character */
+ #if DB_HISTORY_SIZE != 0
+ char db_history[DB_HISTORY_SIZE]; /* start of history buffer */
+ int db_history_size = DB_HISTORY_SIZE;/* size of history buffer */
+ char * db_history_curr = db_history; /* start of current line */
+ char * db_history_last = db_history; /* start of last line */
+ char * db_history_prev = (char *) 0; /* start of previous line */
+ #endif
+
#define CTRL(c) ((c) & 0x1f)
#define isspace(c) ((c) == ' ' || (c) == '\t')
***************
*** 105,110 ****
--- 117,147 ----
db_le -= n;
}
+ void
+ db_delete_line()
+ {
+ db_delete(db_le - db_lc, DEL_FWD);
+ db_delete(db_lc - db_lbuf_start, DEL_BWD);
+ db_le = db_lc = db_lbuf_start;
+ }
+
+ #if DB_HISTORY_SIZE != 0
+ #define INC_DB_CURR() \
+ do { \
+ db_history_curr++; \
+ if (db_history_curr > \
+ db_history + db_history_size - 1) \
+ db_history_curr = db_history; \
+ } while (0)
+ #define DEC_DB_CURR() \
+ do { \
+ db_history_curr--; \
+ if (db_history_curr < db_history) \
+ db_history_curr = db_history + \
+ db_history_size - 1; \
+ } while (0)
+ #endif
+
/* returns TRUE at end-of-line */
int
db_inputchar(c)
***************
*** 155,160 ****
--- 192,201 ----
if (db_lc < db_le)
db_delete(db_le - db_lc, DEL_FWD);
break;
+ case CTRL('u'):
+ /* delete line */
+ db_delete_line();
+ break;
case CTRL('t'):
/* twiddle last 2 characters */
if (db_lc >= db_lbuf_start + 2) {
***************
*** 167,172 ****
--- 208,264 ----
cnputc(db_lc[-1]);
}
break;
+ #if DB_HISTORY_SIZE != 0
+ case CTRL('p'):
+ DEC_DB_CURR();
+ while (db_history_curr != db_history_last) {
+ DEC_DB_CURR();
+ if (*db_history_curr == '\0')
+ break;
+ }
+ db_delete_line();
+ if (db_history_curr == db_history_last) {
+ INC_DB_CURR();
+ db_le = db_lc = db_lbuf_start;
+ } else {
+ register char *p;
+ INC_DB_CURR();
+ for (p = db_history_curr, db_le = db_lbuf_start;
+ *p; ) {
+ *db_le++ = *p++;
+ if (p == db_history + db_history_size) {
+ p = db_history;
+ }
+ }
+ db_lc = db_le;
+ }
+ db_putstring(db_lbuf_start, db_le - db_lbuf_start);
+ break;
+ case CTRL('n'):
+ while (db_history_curr != db_history_last) {
+ if (*db_history_curr == '\0')
+ break;
+ INC_DB_CURR();
+ }
+ if (db_history_curr != db_history_last) {
+ INC_DB_CURR();
+ db_delete_line();
+ if (db_history_curr != db_history_last) {
+ register char *p;
+ for (p = db_history_curr,
+ db_le = db_lbuf_start; *p;) {
+ *db_le++ = *p++;
+ if (p == db_history +
+ db_history_size) {
+ p = db_history;
+ }
+ }
+ db_lc = db_le;
+ }
+ db_putstring(db_lbuf_start, db_le - db_lbuf_start);
+ }
+ break;
+ #endif
case CTRL('r'):
db_putstring("^R\n", 3);
if (db_le > db_lbuf_start) {
***************
*** 176,181 ****
--- 268,311 ----
break;
case '\n':
case '\r':
+ #if DB_HISTORY_SIZE != 0
+ /* Check if it same than previous line */
+ if (db_history_curr == db_history_prev) {
+ register char *pp, *pc;
+
+ /* Is it unmodified */
+ for (pp = db_history_prev, pc = db_lbuf_start;
+ pc != db_le && *pp; pp++, pc++) {
+ if (*pp != *pc)
+ break;
+ if (++pp == db_history + db_history_size) {
+ pp = db_history;
+ }
+ if (++pc == db_history + db_history_size) {
+ pc = db_history;
+ }
+ }
+ if (!*pp && pc == db_le) {
+ /* Repeted previous line, not saved */
+ db_history_curr = db_history_last;
+ *db_le++ = c;
+ return (TRUE);
+ }
+ }
+ if (db_le != db_lbuf_start) {
+ register char *p;
+ db_history_prev = db_history_last;
+ for (p = db_lbuf_start; p != db_le; p++) {
+ *db_history_last++ = *p;
+ if (db_history_last == db_history +
+ db_history_size) {
+ db_history_last = db_history;
+ }
+ }
+ *db_history_last++ = '\0';
+ }
+ db_history_curr = db_history_last;
+ #endif
*db_le++ = c;
return (1);
default:
>Audit-Trail:
>Unformatted: