diff options
Diffstat (limited to 'shell')
-rw-r--r-- | shell/cmdedit.c | 162 |
1 files changed, 62 insertions, 100 deletions
diff --git a/shell/cmdedit.c b/shell/cmdedit.c index eee32131a..b6e743eb4 100644 --- a/shell/cmdedit.c +++ b/shell/cmdedit.c @@ -89,22 +89,17 @@ #endif /* advanced FEATURES */ - -struct history { - char *s; - struct history *p; - struct history *n; -}; - /* Maximum length of the linked list for the command line history */ -static const int MAX_HISTORY = 15; - -/* First element in command line list */ -static struct history *his_front = NULL; - -/* Last element in command line list */ -static struct history *his_end = NULL; - +#define MAX_HISTORY 15 +#if MAX_HISTORY < 1 +#warning cmdedit: You set MAX_HISTORY < 1. The history algorithm switched off. +#else +static char *history[MAX_HISTORY+1]; /* history + current */ +/* saved history lines */ +static int n_history; +/* current pointer to history line */ +static int cur_history; +#endif #include <termios.h> #define setTermSettings(fd,argp) tcsetattr(fd,TCSANOW,argp) @@ -116,7 +111,6 @@ static struct termios initial_settings, new_settings; static volatile int cmdedit_termw = 80; /* actual terminal width */ -static int history_counter = 0; /* Number of commands in history list */ static volatile int handlers_sets = 0; /* Set next bites: */ @@ -148,7 +142,7 @@ static int my_euid; #endif #ifdef CONFIG_FEATURE_SH_FANCY_PROMPT -static char *hostname_buf = ""; +static char *hostname_buf; static int num_ok_lines = 1; #endif @@ -207,19 +201,6 @@ static void cmdedit_reset_term(void) handlers_sets &= ~SET_WCHG_HANDLERS; } fflush(stdout); -#if 0 -//#ifdef CONFIG_FEATURE_CLEAN_UP - if (his_front) { - struct history *n; - - while (his_front != his_end) { - n = his_front->n; - free(his_front->s); - free(his_front); - his_front = n; - } - } -#endif } @@ -368,7 +349,7 @@ static void parse_prompt(const char *prmt_ptr) #endif case 'h': pbuf = hostname_buf; - if (*pbuf == 0) { + if (pbuf == 0) { pbuf = xcalloc(256, 1); if (gethostname(pbuf, 255) < 0) { strcpy(pbuf, "?"); @@ -1122,18 +1103,29 @@ static void input_tab(int *lastWasTab) } #endif /* CONFIG_FEATURE_COMMAND_TAB_COMPLETION */ -static void get_previous_history(struct history **hp, struct history *p) +#if MAX_HISTORY >= 1 +static void get_previous_history(void) { - if ((*hp)->s) - free((*hp)->s); - (*hp)->s = xstrdup(command_ps); - *hp = p; + if(command_ps[0] != 0 || history[cur_history] == 0) { + free(history[cur_history]); + history[cur_history] = xstrdup(command_ps); + } + cur_history--; } -static inline void get_next_history(struct history **hp) +static int get_next_history(void) { - get_previous_history(hp, (*hp)->n); + int ch = cur_history; + + if (ch < n_history) { + get_previous_history(); /* save the current history line */ + return (cur_history = ch+1); + } else { + beep(); + return 0; + } } +#endif enum { ESC = 27, @@ -1165,7 +1157,6 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) int break_out = 0; int lastWasTab = FALSE; unsigned char c = 0; - struct history *hp = his_end; /* prepare before init handlers */ cmdedit_y = 0; /* quasireal y, not true work if line > xt*yt */ @@ -1271,31 +1262,26 @@ prepare_to_die: printf("\033[J"); break; case 12: - { /* Control-l -- clear screen */ - int old_cursor = cursor; printf("\033[H"); - redraw(0, len-old_cursor); - } + redraw(0, len-cursor); break; +#if MAX_HISTORY >= 1 case 14: /* Control-n -- Get next command in history */ - if (hp && hp->n && hp->n->s) { - get_next_history(&hp); + if (get_next_history()) goto rewrite_line; - } else { - beep(); - } break; case 16: /* Control-p -- Get previous command from history */ - if (hp && hp->p) { - get_previous_history(&hp, hp->p); + if (cur_history > 0) { + get_previous_history(); goto rewrite_line; } else { beep(); } break; +#endif case 21: /* Control-U -- Clear line before cursor */ if (cursor) { @@ -1319,10 +1305,11 @@ prepare_to_die: input_tab(&lastWasTab); break; #endif +#if MAX_HISTORY >= 1 case 'A': /* Up Arrow -- Get previous command from history */ - if (hp && hp->p) { - get_previous_history(&hp, hp->p); + if (cur_history > 0) { + get_previous_history(); goto rewrite_line; } else { beep(); @@ -1330,21 +1317,16 @@ prepare_to_die: break; case 'B': /* Down Arrow -- Get next command in history */ - if (hp && hp->n && hp->n->s) { - get_next_history(&hp); - goto rewrite_line; - } else { - beep(); - } + if (!get_next_history()) break; - /* Rewrite the line with the selected history item */ - rewrite_line: +rewrite_line: /* change command */ - len = strlen(strcpy(command, hp->s)); + len = strlen(strcpy(command, history[cur_history])); /* redraw and go to end line */ redraw(cmdedit_y, 0); break; +#endif case 'C': /* Right Arrow -- Move forward one character */ input_forward(); @@ -1428,53 +1410,33 @@ prepare_to_die: setTermSettings(0, (void *) &initial_settings); handlers_sets &= ~SET_RESET_TERM; +#if MAX_HISTORY >= 1 /* Handle command history log */ + /* cleanup may be saved current command line */ + free(history[MAX_HISTORY]); + history[MAX_HISTORY] = 0; if (len) { /* no put empty line */ - - struct history *h = his_end; - char *ss; - - ss = xstrdup(command); /* duplicate */ - - if (h == 0) { - /* No previous history -- this memory is never freed */ - h = his_front = xmalloc(sizeof(struct history)); - h->n = xmalloc(sizeof(struct history)); - - h->p = NULL; - h->s = ss; - h->n->p = h; - h->n->n = NULL; - h->n->s = NULL; - his_end = h->n; - history_counter++; - } else { - /* Add a new history command -- this memory is never freed */ - h->n = xmalloc(sizeof(struct history)); - - h->n->p = h; - h->n->n = NULL; - h->n->s = NULL; - h->s = ss; - his_end = h->n; - + int i = n_history; /* After max history, remove the oldest command */ - if (history_counter >= MAX_HISTORY) { - - struct history *p = his_front->n; - - p->p = NULL; - free(his_front->s); - free(his_front); - his_front = p; - } else { - history_counter++; - } + if (i >= MAX_HISTORY) { + free(history[0]); + for(i = 0; i < (MAX_HISTORY-1); i++) + history[i] = history[i+1]; } + history[i++] = xstrdup(command); + cur_history = i; + n_history = i; #if defined(CONFIG_FEATURE_SH_FANCY_PROMPT) num_ok_lines++; #endif } +#else /* MAX_HISTORY < 1 */ +#if defined(CONFIG_FEATURE_SH_FANCY_PROMPT) + if (len) { /* no put empty line */ + num_ok_lines++; + } +#endif +#endif /* MAX_HISTORY >= 1 */ if(break_out>0) { command[len++] = '\n'; /* set '\n' */ command[len] = 0; |