Liu Aleaxander
2010-Oct-03 15:54 UTC
[syslinux] [PATCH 0/3] elflink: Another small fixes on CLI
Hi, This is a another small set of fixes about CLI on elflink branch. Liu Aleaxander (3): elflink: use 'input' as the prompt of the CLI elflink: Add ctrl-R key bind support elflink: handle the NULL return of edit_cmdline core/elflink/cli.c | 88 +++++++++++++++++++++++++++++++++++++++++--- core/elflink/load_env32.c | 4 ++- 2 files changed, 85 insertions(+), 7 deletions(-) -- 1.7.2.3
Liu Aleaxander
2010-Oct-03 15:54 UTC
[syslinux] [PATCH 1/3] elflink: use 'input' as the prompt of the CLI
Use the paramter 'input' of fucntion edit_cmdline as the prompt of the CLI. I guess this is what the 'input' parameter used for. It's is more extendable than using a specify prompt. And, for now, let's use the 'syslinux' as the prompt.:) Signed-off-by: Liu Aleaxander <Aleaxander at gmail.com> --- core/elflink/cli.c | 10 +++++----- core/elflink/load_env32.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/elflink/cli.c b/core/elflink/cli.c index 408921e..9770839 100644 --- a/core/elflink/cli.c +++ b/core/elflink/cli.c @@ -89,7 +89,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */ , strncpy(cmdline, input, MAX_CMDLINE_LEN); cmdline[MAX_CMDLINE_LEN - 1] = '\0'; - len = cursor = strlen(cmdline); + len = cursor = 0;//strlen(cmdline); prev_len = 0; x = y = 0; @@ -114,9 +114,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) { @@ -131,8 +131,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); diff --git a/core/elflink/load_env32.c b/core/elflink/load_env32.c index 99bf7a3..26ad01f 100644 --- a/core/elflink/load_env32.c +++ b/core/elflink/load_env32.c @@ -72,7 +72,7 @@ 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); /* feng: give up the aux check here */ //aux = list_entry(cli_history_head.next, typeof(*aux), list); //if (strcmp(aux->command, cmdline)) { -- 1.7.2.3
Liu Aleaxander
2010-Oct-03 15:54 UTC
[syslinux] [PATCH 2/3] elflink: Add ctrl-R key bind support
This patch would add the CTRL-R key bind support. It would have the basic feature of the CTRL-R key bind in bash. While, don't expect it will do exactly like what bash will do. Signed-off-by: Liu Aleaxander <Aleaxander at gmail.com> --- core/elflink/cli.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 78 insertions(+), 2 deletions(-) diff --git a/core/elflink/cli.c b/core/elflink/cli.c index 9770839..23702d2 100644 --- a/core/elflink/cli.c +++ b/core/elflink/cli.c @@ -64,6 +64,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)) @@ -86,10 +145,9 @@ 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 = 0;//strlen(cmdline); + len = cursor = 0; prev_len = 0; x = y = 0; @@ -315,6 +373,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) { -- 1.7.2.3
Liu Aleaxander
2010-Oct-03 15:54 UTC
[syslinux] [PATCH 3/3] elflink: handle the NULL return of edit_cmdline
When use ctrl-c to cancle the current input, the edit_cmdline function will return a NULL string. While, the called didn't handle that case, and an error would be happened. Signed-off-by: Liu Aleaxander <Aleaxander at gmail.com> --- core/elflink/load_env32.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/core/elflink/load_env32.c b/core/elflink/load_env32.c index 26ad01f..8e1cfbb 100644 --- a/core/elflink/load_env32.c +++ b/core/elflink/load_env32.c @@ -73,6 +73,8 @@ void enter_cmdline(void) /* Enter endless command line prompt, should support "exit" */ while (1) { 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)) { -- 1.7.2.3