aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--com32/elflink/ldlinux/cli.c102
-rw-r--r--com32/elflink/ldlinux/ldlinux.c4
2 files changed, 92 insertions, 14 deletions
diff --git a/com32/elflink/ldlinux/cli.c b/com32/elflink/ldlinux/cli.c
index 0e0827d2..172a9f68 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 31a457fd..85066b19 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)) {