[syslinux] [GIT PULL] elflink changes

Matt Fleming matt at console-pimps.org
Wed Mar 16 11:48:36 PDT 2011


Hi,

I picked up the following patches from Liu Aleaxander that he sent to
the mailing list last year. They add some new features to the command
line interface code and fix a couple of bugs.

The following changes since commit 9ded45991b4fc83b40af963feb773ddca2589d74:

  ldlinux: Parse and store the "onerror" command line (2011-03-09 14:32:36 +0000)

are available in the git repository at:
  git://git.zytor.com/users/mfleming/syslinux.git for-hpa/elflink/cmdline

Liu Aleaxander (6):
      elflink: Fix the wrong malloc size in enter_cmdline
      elflink: Do clear screen even if we have no pDraw_Menu method
      elflink: Add Ctrl-p + Ctrl-n key binds
      elflink: use 'input' as the prompt of the CLI
      elflink: Add ctrl-R key bind support
      elflink: handle the NULL return of edit_cmdline

 com32/elflink/ldlinux/cli.c     |  102 ++++++++++++++++++++++++++++++++++-----
 com32/elflink/ldlinux/ldlinux.c |    4 +-
 2 files changed, 92 insertions(+), 14 deletions(-)

diff --git a/com32/elflink/ldlinux/cli.c b/com32/elflink/ldlinux/cli.c
index 77d32cd..defc6d0 100644
--- a/com32/elflink/ldlinux/cli.c
+++ b/com32/elflink/ldlinux/cli.c
@@ -68,6 +68,65 @@ int mygetkey(clock_t timeout)
     }
 }
 
+static const char * cmd_reverse_search(int *cursor)
+{
+    int key;
+    int i = 0;
+    char buf[MAX_CMDLINE_LEN];
+    const char *p = NULL;
+    struct cli_command *last_found;
+    struct cli_command *last_good = NULL;
+
+    last_found = list_entry(cli_history_head.next, typeof(*last_found), list);
+
+    memset(buf, 0, MAX_CMDLINE_LEN);
+
+    printf("\033[1G\033[1;36m(reverse-i-search)`': \033[0m");
+    while (1) {
+        key = mygetkey(0);
+
+	if (key == KEY_CTRL('C')) {
+	    return NULL;
+	} else if (key == KEY_CTRL('R')) {
+	    if (i == 0)
+		continue; /* User typed nothing yet */
+	    /* User typed 'CTRL-R' again, so try the next */
+	    last_found = list_entry(last_found->list.next, typeof(*last_found), list);
+	} else if (key >= ' ' && key <= 'z') {
+	        buf[i++] = key;
+	} else {
+	    /* Treat other input chars as terminal */
+	    break;
+	}
+
+	while (last_found != &cli_history_head) {
+	    p = strstr(last_found->command, buf);
+	    if (p)
+	        break;
+	    last_found = list_entry(last_found->list.next, typeof(*last_found), list);
+	}
+
+	if (!p && !last_good) {
+	    return NULL;
+	} else if (!p) {
+	    continue;
+	} else {
+	    last_good = last_found;
+            *cursor = p - last_good->command;
+	}
+
+	printf("\033[?7l\033[?25l");
+	/* Didn't handle the line wrap case here */
+	printf("\033[1G\033[1;36m(reverse-i-search)\033[0m`%s': %s", 
+		buf, last_good->command ? : "");
+	printf("\033[K\r");
+    }
+
+    return last_good ? last_good->command : NULL;
+}
+
+
+
 const char *edit_cmdline(const char *input, int top /*, int width */ ,
 			 int (*pDraw_Menu) (int, int, int),
 			 void (*show_fkey) (int))
@@ -90,22 +149,20 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
 	    width = 80;
     }
 
-    strncpy(cmdline, input, MAX_CMDLINE_LEN);
     cmdline[MAX_CMDLINE_LEN - 1] = '\0';
 
-    len = cursor = strlen(cmdline);
+    len = cursor = 0;
     prev_len = 0;
     x = y = 0;
 
     while (!done) {
-	if (redraw > 1 && pDraw_Menu != NULL) {
+	if (redraw > 1) {
 	    /* Clear and redraw whole screen */
 	    /* Enable ASCII on G0 and DEC VT on G1; do it in this order
 	       to avoid confusing the Linux console */
-	    /* clear_screen();
-	       draw_menu(-1, top, 1); */
 	    clear_screen();
-	    (*pDraw_Menu) (-1, top, 1);
+	    if (pDraw_Menu)
+		    (*pDraw_Menu) (-1, top, 1);
 	    prev_len = 0;
 	    // printf("\033[0m\033[2J\033[H");
 	}
@@ -119,9 +176,9 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
 	    printf("\033[?7l\033[?25l");
 	    if (y)
 		printf("\033[%dA", y);
-	    printf("\033[1G\033[1;36m> \033[0m");
+	    printf("\033[1G\033[1;36m%s \033[0m", input);
 
-	    x = 2;
+	    x = strlen(input);
 	    y = 0;
 	    at = 0;
 	    while (at < prev_len) {
@@ -136,8 +193,8 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
 	    }
 	    printf("\033[K\r");
 
-	    dy = y - (cursor + 2) / width;
-	    x = (cursor + 2) % width;
+	    dy = y - (cursor + strlen(input) + 1) / width;
+	    x = (cursor + strlen(input) + 1) % width;
 
 	    if (dy) {
 		printf("\033[%dA", dy);
@@ -286,6 +343,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
 		redraw = 1;
 	    }
 	    break;
+	case KEY_CTRL('P'):
 	case KEY_UP:
 	    {
 		if (!list_empty(&cli_history_head)) {
@@ -302,6 +360,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
 		}
 	    }
 	    break;
+	case KEY_CTRL('N'):
 	case KEY_DOWN:
 	    {
 		if (!list_empty(&cli_history_head)) {
@@ -318,6 +377,24 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
 		}
 	    }
 	    break;
+	case KEY_CTRL('R'):
+	    {
+	         /* 
+	          * Handle this case in another function, since it's 
+	          * a kind of special.
+	          */
+	        const char *p = cmd_reverse_search(&cursor);
+	        if (p) {
+	            strcpy(cmdline, p);
+		    len = strlen(cmdline);
+	        } else {
+	            cmdline[0] = '\0';
+		    len = 0;
+	        }
+	        redraw = 1;
+	    }
+	    break;
+
 	default:
 	    if (key >= ' ' && key <= 0xFF && len < MAX_CMDLINE_LEN - 1) {
 		if (cursor == len) {
@@ -369,9 +446,8 @@ void process_command(const char *cmd, bool history)
 	if (history) {
 		struct cli_command  *comm;
 
-		comm = (struct cli_command *)malloc(sizeof(struct cli_command *));
-		comm->command =
-			(char *)malloc(sizeof(char) * (strlen(cmd) + 1));
+		comm = malloc(sizeof(struct cli_command));
+		comm->command = malloc(sizeof(char) * (strlen(cmd) + 1));
 		strcpy(comm->command, cmd);
 		list_add(&(comm->list), &cli_history_head);
 	}
diff --git a/com32/elflink/ldlinux/ldlinux.c b/com32/elflink/ldlinux/ldlinux.c
index b5a4409..5ebbd7f 100644
--- a/com32/elflink/ldlinux/ldlinux.c
+++ b/com32/elflink/ldlinux/ldlinux.c
@@ -17,7 +17,9 @@ static void enter_cmdline(void)
 
 	/* Enter endless command line prompt, should support "exit" */
 	while (1) {
-		cmdline = edit_cmdline("", 1, NULL, NULL);
+		cmdline = edit_cmdline("syslinux$", 1, NULL, NULL);
+		if (!cmdline)
+			continue;
 		/* feng: give up the aux check here */
 		//aux = list_entry(cli_history_head.next, typeof(*aux), list);
 		//if (strcmp(aux->command, cmdline)) {




More information about the Syslinux mailing list