aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorbug1 <bug1@69ca8d6d-28ef-0310-b511-8ec308f3f277>2002-11-27 09:29:49 +0000
committerbug1 <bug1@69ca8d6d-28ef-0310-b511-8ec308f3f277>2002-11-27 09:29:49 +0000
commit47d7956d5f6abb47dbc1118720fc5d8b3749bca7 (patch)
tree1bed61e79f91852c991adac367156ed21aa9d136 /shell
parent818911efee4ae1269cdd0cd1593c48342d281426 (diff)
downloadbusybox-w32-47d7956d5f6abb47dbc1118720fc5d8b3749bca7.tar.gz
busybox-w32-47d7956d5f6abb47dbc1118720fc5d8b3749bca7.tar.bz2
busybox-w32-47d7956d5f6abb47dbc1118720fc5d8b3749bca7.zip
last_patch_68 from Vladimir N. Oleynik
git-svn-id: svn://busybox.net/trunk/busybox@6028 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'shell')
-rw-r--r--shell/cmdedit.c162
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 @@
89#endif /* advanced FEATURES */ 89#endif /* advanced FEATURES */
90 90
91 91
92
93struct history {
94 char *s;
95 struct history *p;
96 struct history *n;
97};
98
99/* Maximum length of the linked list for the command line history */ 92/* Maximum length of the linked list for the command line history */
100static const int MAX_HISTORY = 15; 93#define MAX_HISTORY 15
101 94#if MAX_HISTORY < 1
102/* First element in command line list */ 95#warning cmdedit: You set MAX_HISTORY < 1. The history algorithm switched off.
103static struct history *his_front = NULL; 96#else
104 97static char *history[MAX_HISTORY+1]; /* history + current */
105/* Last element in command line list */ 98/* saved history lines */
106static struct history *his_end = NULL; 99static int n_history;
107 100/* current pointer to history line */
101static int cur_history;
102#endif
108 103
109#include <termios.h> 104#include <termios.h>
110#define setTermSettings(fd,argp) tcsetattr(fd,TCSANOW,argp) 105#define setTermSettings(fd,argp) tcsetattr(fd,TCSANOW,argp)
@@ -116,7 +111,6 @@ static struct termios initial_settings, new_settings;
116 111
117static 112static
118volatile int cmdedit_termw = 80; /* actual terminal width */ 113volatile int cmdedit_termw = 80; /* actual terminal width */
119static int history_counter = 0; /* Number of commands in history list */
120static 114static
121volatile int handlers_sets = 0; /* Set next bites: */ 115volatile int handlers_sets = 0; /* Set next bites: */
122 116
@@ -148,7 +142,7 @@ static int my_euid;
148#endif 142#endif
149 143
150#ifdef CONFIG_FEATURE_SH_FANCY_PROMPT 144#ifdef CONFIG_FEATURE_SH_FANCY_PROMPT
151static char *hostname_buf = ""; 145static char *hostname_buf;
152static int num_ok_lines = 1; 146static int num_ok_lines = 1;
153#endif 147#endif
154 148
@@ -207,19 +201,6 @@ static void cmdedit_reset_term(void)
207 handlers_sets &= ~SET_WCHG_HANDLERS; 201 handlers_sets &= ~SET_WCHG_HANDLERS;
208 } 202 }
209 fflush(stdout); 203 fflush(stdout);
210#if 0
211//#ifdef CONFIG_FEATURE_CLEAN_UP
212 if (his_front) {
213 struct history *n;
214
215 while (his_front != his_end) {
216 n = his_front->n;
217 free(his_front->s);
218 free(his_front);
219 his_front = n;
220 }
221 }
222#endif
223} 204}
224 205
225 206
@@ -368,7 +349,7 @@ static void parse_prompt(const char *prmt_ptr)
368#endif 349#endif
369 case 'h': 350 case 'h':
370 pbuf = hostname_buf; 351 pbuf = hostname_buf;
371 if (*pbuf == 0) { 352 if (pbuf == 0) {
372 pbuf = xcalloc(256, 1); 353 pbuf = xcalloc(256, 1);
373 if (gethostname(pbuf, 255) < 0) { 354 if (gethostname(pbuf, 255) < 0) {
374 strcpy(pbuf, "?"); 355 strcpy(pbuf, "?");
@@ -1122,18 +1103,29 @@ static void input_tab(int *lastWasTab)
1122} 1103}
1123#endif /* CONFIG_FEATURE_COMMAND_TAB_COMPLETION */ 1104#endif /* CONFIG_FEATURE_COMMAND_TAB_COMPLETION */
1124 1105
1125static void get_previous_history(struct history **hp, struct history *p) 1106#if MAX_HISTORY >= 1
1107static void get_previous_history(void)
1126{ 1108{
1127 if ((*hp)->s) 1109 if(command_ps[0] != 0 || history[cur_history] == 0) {
1128 free((*hp)->s); 1110 free(history[cur_history]);
1129 (*hp)->s = xstrdup(command_ps); 1111 history[cur_history] = xstrdup(command_ps);
1130 *hp = p; 1112 }
1113 cur_history--;
1131} 1114}
1132 1115
1133static inline void get_next_history(struct history **hp) 1116static int get_next_history(void)
1134{ 1117{
1135 get_previous_history(hp, (*hp)->n); 1118 int ch = cur_history;
1119
1120 if (ch < n_history) {
1121 get_previous_history(); /* save the current history line */
1122 return (cur_history = ch+1);
1123 } else {
1124 beep();
1125 return 0;
1126 }
1136} 1127}
1128#endif
1137 1129
1138enum { 1130enum {
1139 ESC = 27, 1131 ESC = 27,
@@ -1165,7 +1157,6 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
1165 int break_out = 0; 1157 int break_out = 0;
1166 int lastWasTab = FALSE; 1158 int lastWasTab = FALSE;
1167 unsigned char c = 0; 1159 unsigned char c = 0;
1168 struct history *hp = his_end;
1169 1160
1170 /* prepare before init handlers */ 1161 /* prepare before init handlers */
1171 cmdedit_y = 0; /* quasireal y, not true work if line > xt*yt */ 1162 cmdedit_y = 0; /* quasireal y, not true work if line > xt*yt */
@@ -1271,31 +1262,26 @@ prepare_to_die:
1271 printf("\033[J"); 1262 printf("\033[J");
1272 break; 1263 break;
1273 case 12: 1264 case 12:
1274 {
1275 /* Control-l -- clear screen */ 1265 /* Control-l -- clear screen */
1276 int old_cursor = cursor;
1277 printf("\033[H"); 1266 printf("\033[H");
1278 redraw(0, len-old_cursor); 1267 redraw(0, len-cursor);
1279 }
1280 break; 1268 break;
1269#if MAX_HISTORY >= 1
1281 case 14: 1270 case 14:
1282 /* Control-n -- Get next command in history */ 1271 /* Control-n -- Get next command in history */
1283 if (hp && hp->n && hp->n->s) { 1272 if (get_next_history())
1284 get_next_history(&hp);
1285 goto rewrite_line; 1273 goto rewrite_line;
1286 } else {
1287 beep();
1288 }
1289 break; 1274 break;
1290 case 16: 1275 case 16:
1291 /* Control-p -- Get previous command from history */ 1276 /* Control-p -- Get previous command from history */
1292 if (hp && hp->p) { 1277 if (cur_history > 0) {
1293 get_previous_history(&hp, hp->p); 1278 get_previous_history();
1294 goto rewrite_line; 1279 goto rewrite_line;
1295 } else { 1280 } else {
1296 beep(); 1281 beep();
1297 } 1282 }
1298 break; 1283 break;
1284#endif
1299 case 21: 1285 case 21:
1300 /* Control-U -- Clear line before cursor */ 1286 /* Control-U -- Clear line before cursor */
1301 if (cursor) { 1287 if (cursor) {
@@ -1319,10 +1305,11 @@ prepare_to_die:
1319 input_tab(&lastWasTab); 1305 input_tab(&lastWasTab);
1320 break; 1306 break;
1321#endif 1307#endif
1308#if MAX_HISTORY >= 1
1322 case 'A': 1309 case 'A':
1323 /* Up Arrow -- Get previous command from history */ 1310 /* Up Arrow -- Get previous command from history */
1324 if (hp && hp->p) { 1311 if (cur_history > 0) {
1325 get_previous_history(&hp, hp->p); 1312 get_previous_history();
1326 goto rewrite_line; 1313 goto rewrite_line;
1327 } else { 1314 } else {
1328 beep(); 1315 beep();
@@ -1330,21 +1317,16 @@ prepare_to_die:
1330 break; 1317 break;
1331 case 'B': 1318 case 'B':
1332 /* Down Arrow -- Get next command in history */ 1319 /* Down Arrow -- Get next command in history */
1333 if (hp && hp->n && hp->n->s) { 1320 if (!get_next_history())
1334 get_next_history(&hp);
1335 goto rewrite_line;
1336 } else {
1337 beep();
1338 }
1339 break; 1321 break;
1340
1341 /* Rewrite the line with the selected history item */ 1322 /* Rewrite the line with the selected history item */
1342 rewrite_line: 1323rewrite_line:
1343 /* change command */ 1324 /* change command */
1344 len = strlen(strcpy(command, hp->s)); 1325 len = strlen(strcpy(command, history[cur_history]));
1345 /* redraw and go to end line */ 1326 /* redraw and go to end line */
1346 redraw(cmdedit_y, 0); 1327 redraw(cmdedit_y, 0);
1347 break; 1328 break;
1329#endif
1348 case 'C': 1330 case 'C':
1349 /* Right Arrow -- Move forward one character */ 1331 /* Right Arrow -- Move forward one character */
1350 input_forward(); 1332 input_forward();
@@ -1428,53 +1410,33 @@ prepare_to_die:
1428 setTermSettings(0, (void *) &initial_settings); 1410 setTermSettings(0, (void *) &initial_settings);
1429 handlers_sets &= ~SET_RESET_TERM; 1411 handlers_sets &= ~SET_RESET_TERM;
1430 1412
1413#if MAX_HISTORY >= 1
1431 /* Handle command history log */ 1414 /* Handle command history log */
1415 /* cleanup may be saved current command line */
1416 free(history[MAX_HISTORY]);
1417 history[MAX_HISTORY] = 0;
1432 if (len) { /* no put empty line */ 1418 if (len) { /* no put empty line */
1433 1419 int i = n_history;
1434 struct history *h = his_end;
1435 char *ss;
1436
1437 ss = xstrdup(command); /* duplicate */
1438
1439 if (h == 0) {
1440 /* No previous history -- this memory is never freed */
1441 h = his_front = xmalloc(sizeof(struct history));
1442 h->n = xmalloc(sizeof(struct history));
1443
1444 h->p = NULL;
1445 h->s = ss;
1446 h->n->p = h;
1447 h->n->n = NULL;
1448 h->n->s = NULL;
1449 his_end = h->n;
1450 history_counter++;
1451 } else {
1452 /* Add a new history command -- this memory is never freed */
1453 h->n = xmalloc(sizeof(struct history));
1454
1455 h->n->p = h;
1456 h->n->n = NULL;
1457 h->n->s = NULL;
1458 h->s = ss;
1459 his_end = h->n;
1460
1461 /* After max history, remove the oldest command */ 1420 /* After max history, remove the oldest command */
1462 if (history_counter >= MAX_HISTORY) { 1421 if (i >= MAX_HISTORY) {
1463 1422 free(history[0]);
1464 struct history *p = his_front->n; 1423 for(i = 0; i < (MAX_HISTORY-1); i++)
1465 1424 history[i] = history[i+1];
1466 p->p = NULL;
1467 free(his_front->s);
1468 free(his_front);
1469 his_front = p;
1470 } else {
1471 history_counter++;
1472 }
1473 } 1425 }
1426 history[i++] = xstrdup(command);
1427 cur_history = i;
1428 n_history = i;
1474#if defined(CONFIG_FEATURE_SH_FANCY_PROMPT) 1429#if defined(CONFIG_FEATURE_SH_FANCY_PROMPT)
1475 num_ok_lines++; 1430 num_ok_lines++;
1476#endif 1431#endif
1477 } 1432 }
1433#else /* MAX_HISTORY < 1 */
1434#if defined(CONFIG_FEATURE_SH_FANCY_PROMPT)
1435 if (len) { /* no put empty line */
1436 num_ok_lines++;
1437 }
1438#endif
1439#endif /* MAX_HISTORY >= 1 */
1478 if(break_out>0) { 1440 if(break_out>0) {
1479 command[len++] = '\n'; /* set '\n' */ 1441 command[len++] = '\n'; /* set '\n' */
1480 command[len] = 0; 1442 command[len] = 0;