last_patch_68 from Vladimir N. Oleynik

This commit is contained in:
Glenn L McGrath
2002-11-27 09:29:49 +00:00
parent ec87d37305
commit 062c74f710
4 changed files with 66 additions and 105 deletions

View File

@@ -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;