7 +static void save_command_ps_at_cur_history(void)
9 + if (command_ps[0] != '\0') {
10 + int cur = state->cur_history;
11 + free(state->history[cur]);
12 + state->history[cur] = xstrdup(command_ps);
16 /* state->flags is already checked to be nonzero */
17 -static void get_previous_history(void)
18 +static int get_previous_history(void)
20 - if (command_ps[0] != '\0' || state->history[state->cur_history] == NULL) {
21 - free(state->history[state->cur_history]);
22 - state->history[state->cur_history] = xstrdup(command_ps);
23 + if ((state->flags & DO_HISTORY) && state->cur_history) {
24 + save_command_ps_at_cur_history();
25 + state->cur_history--;
28 - state->cur_history--;
33 static int get_next_history(void)
35 if (state->flags & DO_HISTORY) {
36 - int ch = state->cur_history;
37 - if (ch < state->cnt_history) {
38 - get_previous_history(); /* save the current history line */
39 - state->cur_history = ch + 1;
40 - return state->cur_history;
41 + if (state->cur_history < state->cnt_history) {
42 + save_command_ps_at_cur_history(); /* save the current history line */
43 + return ++state->cur_history;
48 for (hi = state->cnt_history; hi > 0;) {
50 free(state->history[hi]);
51 + state->history[hi] = NULL;
54 for (hi = 0; hi < MAX_HISTORY;) {
58 hl[MAX_LINELEN-1] = '\0';
59 - if (l == 0 || hl[0] == ' ') {
64 @@ -1040,19 +1050,27 @@
66 if (!(state->flags & DO_HISTORY))
71 i = state->cnt_history;
72 - free(state->history[MAX_HISTORY]);
73 - state->history[MAX_HISTORY] = NULL;
74 - /* After max history, remove the oldest command */
75 + /* Don't save dupes */
76 + if (i && strcmp(state->history[i-1], str) == 0)
79 + free(state->history[MAX_HISTORY]); /* redundant, paranoia */
80 + state->history[MAX_HISTORY] = NULL; /* redundant, paranoia */
82 + /* If history[] is full, remove the oldest command */
83 + /* we need to keep history[MAX_HISTORY] empty, hence >=, not > */
84 if (i >= MAX_HISTORY) {
85 free(state->history[0]);
86 for (i = 0; i < MAX_HISTORY-1; i++)
87 state->history[i] = state->history[i+1];
88 + /* i == MAX_HISTORY-1 */
90 -// Maybe "if (!i || strcmp(history[i-1], command) != 0) ..."
91 -// (i.e. do not save dups?)
92 + /* i <= MAX_HISTORY-1 */
93 state->history[i++] = xstrdup(str);
94 + /* i <= MAX_HISTORY */
95 state->cur_history = i;
96 state->cnt_history = i;
97 #if ENABLE_FEATURE_EDITING_SAVEHISTORY
98 @@ -1429,6 +1447,13 @@
104 + for (ic = 0; ic <= MAX_HISTORY; ic++)
105 + bb_error_msg("history[%d]:'%s'", ic, state->history[ic]);
106 + bb_error_msg("cur_history:%d cnt_history:%d", state->cur_history, state->cnt_history);
109 /* Print out the command prompt */
110 parse_and_put_prompt(prompt);
112 @@ -1537,11 +1562,8 @@
113 vi_case(CTRL('P')|vbit:)
115 /* Control-p -- Get previous command from history */
116 - if ((state->flags & DO_HISTORY) && state->cur_history > 0) {
117 - get_previous_history();
118 + if (get_previous_history())
125 @@ -1730,10 +1752,8 @@
128 /* Up Arrow -- Get previous command from history */
129 - if ((state->flags & DO_HISTORY) && state->cur_history > 0) {
130 - get_previous_history();
131 + if (get_previous_history())
137 @@ -1743,7 +1763,7 @@
139 /* Rewrite the line with the selected history item */
141 - command_len = strlen(strcpy(command, state->history[state->cur_history]));
142 + command_len = strlen(strcpy(command, state->history[state->cur_history] ? : ""));
143 /* redraw and go to eol (bol, in vi */
144 redraw(cmdedit_y, (state->flags & VI_MODE) ? 9999 : 0);