Subject: kernel debugger patch ...
To: None <port-i386@NetBSD.ORG>
From: Robert.V.Baron <rvb@gluck.coda.cs.cmu.edu>
List: port-i386
Date: 01/10/1998 20:56:00
I've been reapplying some of my local changes of NetBSD 1.2 into NetBSD
1.3. I noticed that I've had a patch that enables ^n and ^p for the
kernel debugger. I've submitted a "bug report" with the change, but I
thought I'd also just include the patch here since people might want
the change and it sometimes takes a while for code to get into -current.
Added command line history. Ctrl-P = previous, Ctrl-N = next. If
DB_HISTORY_SIZE is 0 then command history is disabled.
[92/02/17 kivinen]
Index: src/sys/ddb/db_extern.h
diff -c src/sys/ddb/db_extern.h:1.1.1.1 src/sys/ddb/db_extern.h:1.2
*** src/sys/ddb/db_extern.h:1.1.1.1 Thu Jun 26 07:22:45 1997
--- src/sys/ddb/db_extern.h Sat Jan 10 05:52:36 1998
***************
*** 68,73 ****
--- 68,74 ----
void db_putstring __P((char *, int));
void db_putnchars __P((int, int));
void db_delete __P((int, int));
+ void db_delete_line __P((void));
int db_inputchar __P((int));
int db_readline __P((char *, int));
void db_check_interrupt __P((void));
Index: src/sys/ddb/db_input.c
diff -c src/sys/ddb/db_input.c:1.1.1.1 src/sys/ddb/db_input.c:1.2
*** src/sys/ddb/db_input.c:1.1.1.1 Mon Feb 5 07:25:34 1996
--- src/sys/ddb/db_input.c Sat Jan 10 05:52:37 1998
***************
*** 45,50 ****
--- 45,54 ----
* Character input and editing.
*/
+ #ifndef DB_HISTORY_SIZE
+ #define DB_HISTORY_SIZE 4000
+ #endif DB_HISTORY_SIZE
+
/*
* We don't track output position while editing input,
* since input always ends with a new-line. We just
***************
*** 54,59 ****
--- 58,70 ----
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 ****
--- 116,146 ----
db_le -= n;
}
+ void
+ db_delete_line(void)
+ {
+ 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 ****
--- 191,200 ----
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,181 ****
cnputc(db_lc[-1]);
}
break;
case CTRL('r'):
db_putstring("^R\n", 3);
if (db_le > db_lbuf_start) {
! db_putstring(db_lbuf_start, db_le - db_lbuf_start);
! db_putnchars(BACKUP, db_le - db_lc);
}
break;
case '\n':
case '\r':
*db_le++ = c;
return (1);
default:
--- 207,316 ----
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) {
! db_putstring(db_lbuf_start, db_le - db_lbuf_start);
! db_putnchars(BACKUP, db_le - db_lc);
}
break;
case '\n':
case '\r':
+ #if DB_HISTORY_SIZE != 0
+ /*
+ * Check whether current line is the same
+ * as previous saved line. If it is, don`t
+ * save it.
+ */
+ if (db_history_curr == db_history_prev) {
+ register char *pp, *pc;
+
+ /*
+ * Is it the same?
+ */
+ for (pp = db_history_prev, pc = db_lbuf_start;
+ pc != db_le && *pp; ) {
+ if (*pp != *pc)
+ break;
+ if (++pp == db_history + db_history_size) {
+ pp = db_history;
+ }
+ pc++;
+ }
+ if (!*pp && pc == db_le) {
+ /*
+ * Repeated previous line. Don`t save.
+ */
+ db_history_curr = db_history_last;
+ *db_le++ = c;
+ return (1);
+ }
+ }
+ 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:
***************
*** 206,212 ****
db_force_whitespace(); /* synch output position */
db_lbuf_start = lstart;
! db_lbuf_end = lstart + lsize;
db_lc = lstart;
db_le = lstart;
--- 341,347 ----
db_force_whitespace(); /* synch output position */
db_lbuf_start = lstart;
! db_lbuf_end = lstart + lsize - 1;
db_lc = lstart;
db_le = lstart;