About the KDB command line

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

	I am a newer to this KDB developing mail list. And I have used KDB
for some days before I come here. I found KDB is really a wonderful tool for
Linux kernel developer. It helps me much in my developing work of kernel
modules.

	But, I think the KDB command line is not very friendly. If I make a
mistake in the middle of my long command string, I have to input the whole
line again. 

	So I wonder if there is any plan to improve the edit ability of the
command line. Such as "move left", "move right", "insert char", "delete
char", "go to the head", "go to the end" and "move in the history commands",
etc.

	I fail to find these features in the latest patch
"kdb-v2.5-2.4.19-common-1" and "kdb-v2.5-2.4.19-i386-1". Do you think this
requirement is reasonable for KDB?

	In order to ease my fingers, I'd like to add these features to the
KDB patch. So I tried to add some codes to the KDB. The following 2 patches
are for kdb-v2.4-2.4.19. Could you have a try and give me some feedbacks? 

	Only i386 architecture is supported by now. 

	Thank you very much. ^-^

	Sonic Zhang
	12/4/2002

----------------------------------------------------------------------------
----
--- linux-kdb/kdb/kdbmain.c	Wed Dec  4 15:53:39 2002
+++ linux-kdb-cmdline/kdb/kdbmain.c	Wed Dec  4 10:28:36 2002
@@ -691,7 +691,7 @@
  */
 #define KDB_CMD_HISTORY_COUNT	32
 #define CMD_BUFLEN		200	/* kdb_printf: max printline size ==
256 */
-static unsigned int cmd_head, cmd_tail;
+static unsigned int cmd_head=0, cmd_tail=0;
 static unsigned int cmdptr;
 static char cmd_hist[KDB_CMD_HISTORY_COUNT][CMD_BUFLEN];
 
@@ -887,22 +887,22 @@
 #define CTRL_N	14
 
 	/* initial situation */
-	if (cmd_head == cmd_tail) return 1;
+	if (cmd_head == cmd_tail) return 0;
 
 	switch(*cmd) {
-		case '\n':
 		case CTRL_P:
 			if (cmdptr != cmd_tail)
 				cmdptr = (cmdptr-1) % KDB_CMD_HISTORY_COUNT;
-			strcpy(cmd, cmd_hist[cmdptr]);
-			return 0;	
+			strncpy(cmd_hist[cmd_head], cmd_hist[cmdptr],
CMD_BUFLEN);
+			return 1;
 		case CTRL_N:
+			if (cmdptr == cmd_head) return 0;
 			if (cmdptr != (cmd_head-1))
 				cmdptr = (cmdptr+1) % KDB_CMD_HISTORY_COUNT;
-			strcpy(cmd, cmd_hist[cmdptr]);
-			return 0;
+			strncpy(cmd_hist[cmd_head], cmd_hist[cmdptr],
CMD_BUFLEN);
+			return 1;
 	}
-	return 1;
+	return 0;
 }
 
 
@@ -998,7 +998,7 @@
 			return KDB_CMD_GO;
 		}
 		break;
-	case KDB_REASON_CALL:	
+	case KDB_REASON_CALL:
 		if (!regs)
 			kdb_printf("kdb() called with no registers,
restricted function\n");
 		break;
@@ -1059,6 +1059,10 @@
 			KDB_STATE_SET(LONGJMP);
 #endif	/* KDB_HAVE_LONGJMP */
 
+
+		cmdbuf = cmd_hist[cmd_head];
+		*cmdbuf = '\0';
+
 do_full_getstr:
 #if defined(CONFIG_SMP)
 		kdb_printf(kdbgetenv("PROMPT"), smp_processor_id());
@@ -1066,15 +1070,15 @@
 		kdb_printf(kdbgetenv("PROMPT"));
 #endif
 
-		cmdbuf = cmd_hist[cmd_head];
-		*cmdbuf = '\0';
 		/*
 		 * Fetch command from keyboard
 		 */
 		cmdbuf = kdb_getstr(cmdbuf, CMD_BUFLEN, defcmd_in_progress ?
"[defcmd]" : "");
-		if (*cmdbuf < 32 && *cmdbuf != '\n')
-			if (handle_ctrl_cmd(cmdbuf))
-				goto do_full_getstr;
+		if (*cmdbuf < 32 && *cmdbuf != '\n') {
+			if (!handle_ctrl_cmd(cmdbuf)) *cmdbuf = '\0';
+			cmdbuf = cmd_hist[cmd_head];
+			goto do_full_getstr;
+		}

 		if (*cmdbuf != '\n') {
 			cmd_head = (cmd_head+1) % KDB_CMD_HISTORY_COUNT;


--- linux-kdb/kdb/kdb_io.c	Wed Dec  4 16:09:02 2002
+++ linux-kdb-cmdline/kdb/kdb_io.c	Wed Dec  4 16:18:42 2002
@@ -206,7 +206,7 @@

 	if (kdb_nextline == linecount) {
 #ifdef KDB_HAVE_LONGJMP
-		char buf1[16];
+		char buf1[16]="";
 #if defined(CONFIG_SMP)
 		char buf2[32];
 #endif
@@ -246,7 +246,7 @@
 		if (logging)
 			printk("%s", moreprompt);

-		kdb_read(buf1, sizeof(buf1));
+		kdb_read(buf1, 2); // '2' indicates to return immediately
after getting one key.
 		kdb_nextline = 1;	/* Really set output line 1 */

 		if ((buf1[0] == 'q') || (buf1[0] == 'Q'))

----------------------------------------------------------------------------
----
----------------------------------------------------------------------------
----

--- linux-kdb/arch/i386/kdb/kdba_io.c	Tue Dec  3 13:25:48 2002
+++ linux-kdb-cmdline/arch/i386/kdb/kdba_io.c	Wed Dec  4 16:51:03 2002
@@ -219,15 +219,6 @@
 			ch = 8;
 		if (ch == '\t')
 			ch = ' ';
-		if (ch == 8) {		/* BS */
-			;
-		} else if (ch == 13) {	/* Enter */
-			kdb_printf("\n");
-		} else {
-			if (!isprint(ch))
-				return(-1);
-			kdb_printf("%c", ch);
-		}
 		return ch;
 	}
 	return -1;
@@ -335,6 +326,24 @@
 		return 8;
 	}
 
+	// Arrow Key and Del Key
+	switch (scancode) {
+	case 0x53: // Del
+		return 4;
+	case 0x47: // Home
+		return 1;
+	case 0x4F: // End
+		return 5;
+	case 0x4B: // Left
+		return 2;
+	case 0x48: // Up
+		return 16;
+	case 0x50: // Down
+		return 14;
+	case 0x4D: // Right
+		return 6;
+	}
+
 	if (scancode == 0xe0) {
 		return -1;
 	}
@@ -407,11 +416,6 @@
 		return 13;
 	}
 
-	/*
-	 * echo the character.
-	 */
-	kdb_printf("%c", keychar&0xff);
-
 	return keychar & 0xff;
 }
 #endif	/* CONFIG_VT_CONSOLE */
@@ -460,12 +464,51 @@
 	NULL
 };
 
+#define CMD_BUFLEN 256
+
+static void kdb_printprompt(void)
+{
+#if defined(CONFIG_SMP)
+	kdb_printf(kdbgetenv("PROMPT"), smp_processor_id());
+#else
+	kdb_printf(kdbgetenv("PROMPT"));
+#endif
+}
+
+static int kdb_promptlength(void)
+{
+#if defined(CONFIG_SMP)
+	char promptstr[30];
+	snprintf(promptstr, 30, kdbgetenv("PROMPT"), smp_processor_id());
+	return strlen(promptstr);
+#else
+	return strlen(kdbgetenv("PROMPT");
+#endif
+}
+
+// The bufsize must >= 2 .
+// If bufsize == 2, that means this routine returns immediately after
receiving one key.
 char *
 kdba_read(char *buffer, size_t bufsize)
 {
 	char	*cp = buffer;
 	char	*bufend = buffer+bufsize-2;	/* Reserve space for newline
and null byte */
 
+	char	*lastchar;
+	char	tmp;
+	static char	tmpbuffer[CMD_BUFLEN];
+	int len = strlen(buffer);
+
+	if (len > 0 ) {
+		cp += len;
+		if (*(buffer+len-1) == '\n')
+			cp--;
+	}
+
+	lastchar = cp;
+	*cp = '\0';
+	kdb_printf("%s", buffer);
+
 	for (;;) {
 		int key;
 		get_char_func *f;
@@ -479,23 +522,102 @@
 			if (key != -1)
 				break;
 		}
+		if (bufsize <= 2) {
+			*buffer++ = (char)key;
+			*buffer = '\0';
+			return buffer;
+		}
 
-		/* Echo is done in the low level functions */
 		switch (key) {
 		case 8: /* backspace */
 			if (cp > buffer) {
-				kdb_printf("\b \b");
+				if (cp < lastchar) {
+					memcpy(tmpbuffer, cp, lastchar -
cp);
+					memcpy(cp-1, tmpbuffer, lastchar -
cp);
+				}
+				*(--lastchar) = '\0';
 				--cp;
+				kdb_printf("\b%s \r", cp);
+				tmp = *cp;
+				*cp = '\0';
+				kdb_printprompt();
+				kdb_printf("%s", buffer);
+				*cp = tmp;
 			}
 			break;
-		case 10: /* enter */
 		case 13: /* enter */
-			*cp++ = '\n';
-			*cp++ = '\0';
+			*lastchar++ = '\n';
+			*lastchar++ = '\0';
+			kdb_printf("\n");
 			return buffer;
+		case 4: /* Del */
+			if(cp < lastchar) {
+				memcpy(tmpbuffer, cp+1, lastchar - cp -1);
+				memcpy(cp, tmpbuffer, lastchar - cp -1);
+				*(--lastchar) = '\0';
+				kdb_printf("%s \r", cp);
+				tmp = *cp;
+				*cp = '\0';
+				kdb_printprompt();
+				kdb_printf("%s", buffer);
+				*cp = tmp;
+			}
+			break;
+		case 1: /* Home */
+			if(cp > buffer) {
+				kdb_printf("\r");
+				kdb_printprompt();
+				cp = buffer;
+			}
+			break;
+		case 5: /* End */
+			if(cp < lastchar) {
+				kdb_printf("%s", cp);
+				cp = lastchar;
+			}
+			break;
+		case 2: /* Left */
+			if (cp > buffer) {
+				kdb_printf("\b");
+				--cp;
+			}
+			break;
+		case 14: /* Down */
+			memset(tmpbuffer, ' ',
kdb_promptlength()+(lastchar-buffer));
+			*(tmpbuffer+kdb_promptlength()+(lastchar-buffer)) =
'\0';
+			kdb_printf("\r%s\r", tmpbuffer);
+			*lastchar = (char)key;
+			*(lastchar+1) = '\0';
+			return lastchar;
+		case 6: /* Right */
+			if (cp < lastchar) {
+				kdb_printf("%c", *cp);
+				++cp;
+			}
+			break;
+		case 16: /* Up */
+			memset(tmpbuffer, ' ',
kdb_promptlength()+(lastchar-buffer));
+			*(tmpbuffer+kdb_promptlength()+(lastchar-buffer)) =
'\0';
+			kdb_printf("\r%s\r", tmpbuffer);
+			*lastchar = (char)key;
+			*(lastchar+1) = '\0';
+			return lastchar;
 		default:
-			if (cp < bufend)
-				*cp++ = key;
+			if (key >= 32 &&lastchar < bufend) {
+				if (cp < lastchar) {
+					memcpy(tmpbuffer, cp, lastchar -
cp);
+					memcpy(cp+1, tmpbuffer, lastchar -
cp);
+				}
+				*(++lastchar) = '\0';
+				*cp = key;
+				kdb_printf("%s\r", cp);
+				++cp;
+				tmp = *cp;
+				*cp = '\0';
+				kdb_printprompt();
+				kdb_printf("%s", buffer);
+				*cp = tmp;
+			}
 			break;
 		}
 	}

----------------------------------------------------------------------------
----




[Index of Archives]     [Linux Kernel Development]     [Linux Kernel Newbies]     [Linux USB Development]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux