aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2006-12-19 01:10:25 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2006-12-19 01:10:25 +0000
commit7f1dc21a5df2aecd58c57e9fb59797401eea7270 (patch)
treecfd384d3994055fc83eaab3666b8e379c823f28a
parent8eb3b391ad9999a3c01c6a90939e443729edb5f6 (diff)
downloadbusybox-w32-7f1dc21a5df2aecd58c57e9fb59797401eea7270.tar.gz
busybox-w32-7f1dc21a5df2aecd58c57e9fb59797401eea7270.tar.bz2
busybox-w32-7f1dc21a5df2aecd58c57e9fb59797401eea7270.zip
cmdedit: use qsort for sorting command completion results; style fixes
-rw-r--r--shell/cmdedit.c236
1 files changed, 104 insertions, 132 deletions
diff --git a/shell/cmdedit.c b/shell/cmdedit.c
index ceaa2e885..187aa545b 100644
--- a/shell/cmdedit.c
+++ b/shell/cmdedit.c
@@ -12,12 +12,10 @@
12 * Erik Andersen <andersen@codepoet.org> (Majorly adjusted for busybox) 12 * Erik Andersen <andersen@codepoet.org> (Majorly adjusted for busybox)
13 * 13 *
14 * This code is 'as is' with no warranty. 14 * This code is 'as is' with no warranty.
15 *
16 *
17 */ 15 */
18 16
19/* 17/*
20 Usage and Known bugs: 18 Usage and known bugs:
21 Terminal key codes are not extensive, and more will probably 19 Terminal key codes are not extensive, and more will probably
22 need to be added. This version was created on Debian GNU/Linux 2.x. 20 need to be added. This version was created on Debian GNU/Linux 2.x.
23 Delete, Backspace, Home, End, and the arrow keys were tested 21 Delete, Backspace, Home, End, and the arrow keys were tested
@@ -30,57 +28,42 @@
30 - not true viewing if length prompt less terminal width 28 - not true viewing if length prompt less terminal width
31 */ 29 */
32 30
33
34#include "busybox.h" 31#include "busybox.h"
35#include <stdio.h>
36#include <errno.h>
37#include <unistd.h>
38#include <stdlib.h>
39#include <string.h>
40#include <sys/ioctl.h> 32#include <sys/ioctl.h>
41#include <ctype.h>
42#include <signal.h>
43#include <limits.h>
44 33
45#include "cmdedit.h" 34#include "cmdedit.h"
46 35
47 36
48#ifdef CONFIG_LOCALE_SUPPORT 37#if ENABLE_LOCALE_SUPPORT
49#define Isprint(c) isprint((c)) 38#define Isprint(c) isprint(c)
50#else 39#else
51#define Isprint(c) ( (c) >= ' ' && (c) != ((unsigned char)'\233') ) 40#define Isprint(c) ((c) >= ' ' && (c) != ((unsigned char)'\233'))
52#endif 41#endif
53 42
54#ifdef TEST
55 43
56/* pretect redefined for test */ 44/* FIXME: obsolete CONFIG item? */
57#undef CONFIG_FEATURE_COMMAND_EDITING 45#define ENABLE_FEATURE_NONPRINTABLE_INVERSE_PUT 0
58#undef CONFIG_FEATURE_COMMAND_TAB_COMPLETION 46
59#undef CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION
60#undef CONFIG_FEATURE_NONPRINTABLE_INVERSE_PUT
61#undef CONFIG_FEATURE_CLEAN_UP
62 47
63#define CONFIG_FEATURE_COMMAND_EDITING 48#ifdef TEST
64#define CONFIG_FEATURE_COMMAND_TAB_COMPLETION 49
65#define CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION 50#define ENABLE_FEATURE_COMMAND_EDITING 0
66#define CONFIG_FEATURE_NONPRINTABLE_INVERSE_PUT 51#define ENABLE_FEATURE_COMMAND_TAB_COMPLETION 0
67#define CONFIG_FEATURE_CLEAN_UP 52#define ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION 0
53#define ENABLE_FEATURE_NONPRINTABLE_INVERSE_PUT 0
54#define ENABLE_FEATURE_CLEAN_UP 0
68 55
69#endif /* TEST */ 56#endif /* TEST */
70 57
71#ifdef CONFIG_FEATURE_COMMAND_TAB_COMPLETION
72#include <dirent.h>
73#include <sys/stat.h>
74#endif
75 58
76#ifdef CONFIG_FEATURE_COMMAND_EDITING 59#if ENABLE_FEATURE_COMMAND_EDITING
77 60
78#if defined(CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION) || defined(CONFIG_FEATURE_SH_FANCY_PROMPT) 61#if ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION || ENABLE_FEATURE_SH_FANCY_PROMPT
79#define CONFIG_FEATURE_GETUSERNAME_AND_HOMEDIR 62#define ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR 1
80#endif 63#endif
81 64
82/* Maximum length of the linked list for the command line history */ 65/* Maximum length of the linked list for the command line history */
83#ifndef CONFIG_FEATURE_COMMAND_HISTORY 66#if !ENABLE_FEATURE_COMMAND_HISTORY
84#define MAX_HISTORY 15 67#define MAX_HISTORY 15
85#else 68#else
86#define MAX_HISTORY (CONFIG_FEATURE_COMMAND_HISTORY + 0) 69#define MAX_HISTORY (CONFIG_FEATURE_COMMAND_HISTORY + 0)
@@ -94,7 +77,7 @@ static int n_history;
94static int cur_history; 77static int cur_history;
95#endif 78#endif
96 79
97#include <termios.h> 80//#include <termios.h>
98#define setTermSettings(fd,argp) tcsetattr(fd,TCSANOW,argp) 81#define setTermSettings(fd,argp) tcsetattr(fd,TCSANOW,argp)
99#define getTermSettings(fd,argp) tcgetattr(fd, argp); 82#define getTermSettings(fd,argp) tcgetattr(fd, argp);
100 83
@@ -119,37 +102,33 @@ static int cmdedit_x; /* real x terminal position */
119static int cmdedit_y; /* pseudoreal y terminal position */ 102static int cmdedit_y; /* pseudoreal y terminal position */
120static int cmdedit_prmt_len; /* lenght prompt without colores string */ 103static int cmdedit_prmt_len; /* lenght prompt without colores string */
121 104
122static int cursor; /* required global for signal handler */ 105static int cursor; /* required globals for signal handler */
123static int len; /* --- "" - - "" - -"- --""-- --""--- */ 106static int len; /* --- "" - - "" -- -"- --""-- --""--- */
124static char *command_ps; /* --- "" - - "" - -"- --""-- --""--- */ 107static char *command_ps; /* --- "" - - "" -- -"- --""-- --""--- */
125static 108static SKIP_FEATURE_SH_FANCY_PROMPT(const) char *cmdedit_prompt; /* -- */
126#ifndef CONFIG_FEATURE_SH_FANCY_PROMPT
127 const
128#endif
129char *cmdedit_prompt; /* --- "" - - "" - -"- --""-- --""--- */
130 109
131#ifdef CONFIG_FEATURE_GETUSERNAME_AND_HOMEDIR 110#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR
132static char *user_buf = ""; 111static char *user_buf = "";
133static char *home_pwd_buf = ""; 112static char *home_pwd_buf = "";
134static int my_euid; 113static int my_euid;
135#endif 114#endif
136 115
137#ifdef CONFIG_FEATURE_SH_FANCY_PROMPT 116#if ENABLE_FEATURE_SH_FANCY_PROMPT
138static char *hostname_buf; 117static char *hostname_buf;
139static int num_ok_lines = 1; 118static int num_ok_lines = 1;
140#endif 119#endif
141 120
142 121
143#ifdef CONFIG_FEATURE_COMMAND_TAB_COMPLETION 122#if ENABLE_FEATURE_COMMAND_TAB_COMPLETION
144 123
145#ifndef CONFIG_FEATURE_GETUSERNAME_AND_HOMEDIR 124#if !ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR
146static int my_euid; 125static int my_euid;
147#endif 126#endif
148 127
149static int my_uid; 128static int my_uid;
150static int my_gid; 129static int my_gid;
151 130
152#endif /* CONFIG_FEATURE_COMMAND_TAB_COMPLETION */ 131#endif /* FEATURE_COMMAND_TAB_COMPLETION */
153 132
154static void cmdedit_setwidth(int w, int redraw_flg); 133static void cmdedit_setwidth(int w, int redraw_flg);
155 134
@@ -163,7 +142,7 @@ static void win_changed(int nsig)
163 get_terminal_width_height(0, &width, NULL); 142 get_terminal_width_height(0, &width, NULL);
164 cmdedit_setwidth(width, nsig == SIGWINCH); 143 cmdedit_setwidth(width, nsig == SIGWINCH);
165 } 144 }
166 /* Unix not all standart in recall signal */ 145 /* Unix not all standard in recall signal */
167 146
168 if (nsig == -SIGWINCH) /* save previous handler */ 147 if (nsig == -SIGWINCH) /* save previous handler */
169 previous_SIGWINCH_handler = signal(SIGWINCH, win_changed); 148 previous_SIGWINCH_handler = signal(SIGWINCH, win_changed);
@@ -198,7 +177,7 @@ static void cmdedit_set_out_char(int next_char)
198 177
199 if (c == 0) 178 if (c == 0)
200 c = ' '; /* destroy end char? */ 179 c = ' '; /* destroy end char? */
201#ifdef CONFIG_FEATURE_NONPRINTABLE_INVERSE_PUT 180#if ENABLE_FEATURE_NONPRINTABLE_INVERSE_PUT
202 if (!Isprint(c)) { /* Inverse put non-printable characters */ 181 if (!Isprint(c)) { /* Inverse put non-printable characters */
203 if (c >= 128) 182 if (c >= 128)
204 c -= 128; 183 c -= 128;
@@ -290,7 +269,7 @@ static void put_prompt(void)
290 cmdedit_y = 0; /* new quasireal y */ 269 cmdedit_y = 0; /* new quasireal y */
291} 270}
292 271
293#ifndef CONFIG_FEATURE_SH_FANCY_PROMPT 272#if !ENABLE_FEATURE_SH_FANCY_PROMPT
294static void parse_prompt(const char *prmt_ptr) 273static void parse_prompt(const char *prmt_ptr)
295{ 274{
296 cmdedit_prompt = prmt_ptr; 275 cmdedit_prompt = prmt_ptr;
@@ -323,12 +302,12 @@ static void parse_prompt(const char *prmt_ptr)
323 int l; 302 int l;
324 303
325 c = bb_process_escape_sequence(&prmt_ptr); 304 c = bb_process_escape_sequence(&prmt_ptr);
326 if(prmt_ptr==cp) { 305 if (prmt_ptr==cp) {
327 if (*cp == 0) 306 if (*cp == 0)
328 break; 307 break;
329 c = *prmt_ptr++; 308 c = *prmt_ptr++;
330 switch (c) { 309 switch (c) {
331#ifdef CONFIG_FEATURE_GETUSERNAME_AND_HOMEDIR 310#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR
332 case 'u': 311 case 'u':
333 pbuf = user_buf; 312 pbuf = user_buf;
334 break; 313 break;
@@ -351,7 +330,7 @@ static void parse_prompt(const char *prmt_ptr)
351 case '$': 330 case '$':
352 c = my_euid == 0 ? '#' : '$'; 331 c = my_euid == 0 ? '#' : '$';
353 break; 332 break;
354#ifdef CONFIG_FEATURE_GETUSERNAME_AND_HOMEDIR 333#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR
355 case 'w': 334 case 'w':
356 pbuf = pwd_buf; 335 pbuf = pwd_buf;
357 l = strlen(home_pwd_buf); 336 l = strlen(home_pwd_buf);
@@ -391,7 +370,7 @@ static void parse_prompt(const char *prmt_ptr)
391 } 370 }
392 buf2[l] = 0; 371 buf2[l] = 0;
393 c = (char)strtol(buf2, 0, 16); 372 c = (char)strtol(buf2, 0, 16);
394 if(c==0) 373 if (c==0)
395 c = '?'; 374 c = '?';
396 pbuf = buf; 375 pbuf = buf;
397 break; 376 break;
@@ -404,7 +383,7 @@ static void parse_prompt(const char *prmt_ptr)
404 } 383 }
405 } 384 }
406 } 385 }
407 if(pbuf == buf) 386 if (pbuf == buf)
408 *pbuf = c; 387 *pbuf = c;
409 cur_prmt_len = strlen(pbuf); 388 cur_prmt_len = strlen(pbuf);
410 prmt_len += cur_prmt_len; 389 prmt_len += cur_prmt_len;
@@ -412,7 +391,7 @@ static void parse_prompt(const char *prmt_ptr)
412 cmdedit_prmt_len += cur_prmt_len; 391 cmdedit_prmt_len += cur_prmt_len;
413 prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_len+1), pbuf); 392 prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_len+1), pbuf);
414 } 393 }
415 if(pwd_buf!=(char *)bb_msg_unknown) 394 if (pwd_buf!=(char *)bb_msg_unknown)
416 free(pwd_buf); 395 free(pwd_buf);
417 cmdedit_prompt = prmt_mem_ptr; 396 cmdedit_prompt = prmt_mem_ptr;
418 put_prompt(); 397 put_prompt();
@@ -432,7 +411,7 @@ static void redraw(int y, int back_cursor)
432 input_backward(back_cursor); 411 input_backward(back_cursor);
433} 412}
434 413
435#ifdef CONFIG_FEATURE_COMMAND_EDITING_VI 414#if ENABLE_FEATURE_COMMAND_EDITING_VI
436#define DELBUFSIZ 128 415#define DELBUFSIZ 128
437static char *delbuf; /* a (malloced) place to store deleted characters */ 416static char *delbuf; /* a (malloced) place to store deleted characters */
438static char *delp; 417static char *delp;
@@ -448,7 +427,7 @@ static void input_delete(int save)
448 if (j == len) 427 if (j == len)
449 return; 428 return;
450 429
451#ifdef CONFIG_FEATURE_COMMAND_EDITING_VI 430#if ENABLE_FEATURE_COMMAND_EDITING_VI
452 if (save) { 431 if (save) {
453 if (newdelflag) { 432 if (newdelflag) {
454 if (!delbuf) 433 if (!delbuf)
@@ -469,7 +448,7 @@ static void input_delete(int save)
469 input_backward(cursor - j); /* back to old pos cursor */ 448 input_backward(cursor - j); /* back to old pos cursor */
470} 449}
471 450
472#ifdef CONFIG_FEATURE_COMMAND_EDITING_VI 451#if ENABLE_FEATURE_COMMAND_EDITING_VI
473static void put(void) 452static void put(void)
474{ 453{
475 int ocursor, j = delp - delbuf; 454 int ocursor, j = delp - delbuf;
@@ -532,7 +511,7 @@ static void cmdedit_init(void)
532 } 511 }
533 512
534 if ((handlers_sets & SET_ATEXIT) == 0) { 513 if ((handlers_sets & SET_ATEXIT) == 0) {
535#ifdef CONFIG_FEATURE_GETUSERNAME_AND_HOMEDIR 514#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR
536 struct passwd *entry; 515 struct passwd *entry;
537 516
538 my_euid = geteuid(); 517 my_euid = geteuid();
@@ -543,20 +522,20 @@ static void cmdedit_init(void)
543 } 522 }
544#endif 523#endif
545 524
546#ifdef CONFIG_FEATURE_COMMAND_TAB_COMPLETION 525#if ENABLE_FEATURE_COMMAND_TAB_COMPLETION
547 526
548#ifndef CONFIG_FEATURE_GETUSERNAME_AND_HOMEDIR 527#if !ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR
549 my_euid = geteuid(); 528 my_euid = geteuid();
550#endif 529#endif
551 my_uid = getuid(); 530 my_uid = getuid();
552 my_gid = getgid(); 531 my_gid = getgid();
553#endif /* CONFIG_FEATURE_COMMAND_TAB_COMPLETION */ 532#endif /* FEATURE_COMMAND_TAB_COMPLETION */
554 handlers_sets |= SET_ATEXIT; 533 handlers_sets |= SET_ATEXIT;
555 atexit(cmdedit_reset_term); /* be sure to do this only once */ 534 atexit(cmdedit_reset_term); /* be sure to do this only once */
556 } 535 }
557} 536}
558 537
559#ifdef CONFIG_FEATURE_COMMAND_TAB_COMPLETION 538#if ENABLE_FEATURE_COMMAND_TAB_COMPLETION
560 539
561static char **matches; 540static char **matches;
562static int num_matches; 541static int num_matches;
@@ -583,7 +562,7 @@ static int is_execute(const struct stat *st)
583 return FALSE; 562 return FALSE;
584} 563}
585 564
586#ifdef CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION 565#if ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION
587 566
588static void username_tab_completion(char *ud, char *with_shash_flg) 567static void username_tab_completion(char *ud, char *with_shash_flg)
589{ 568{
@@ -633,7 +612,7 @@ static void username_tab_completion(char *ud, char *with_shash_flg)
633 endpwent(); 612 endpwent();
634 } 613 }
635} 614}
636#endif /* CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION */ 615#endif /* FEATURE_COMMAND_USERNAME_COMPLETION */
637 616
638enum { 617enum {
639 FIND_EXE_ONLY = 0, 618 FIND_EXE_ONLY = 0,
@@ -641,7 +620,7 @@ enum {
641 FIND_FILE_ONLY = 2, 620 FIND_FILE_ONLY = 2,
642}; 621};
643 622
644#ifdef CONFIG_ASH 623#if ENABLE_ASH
645const char *cmdedit_path_lookup; 624const char *cmdedit_path_lookup;
646#else 625#else
647#define cmdedit_path_lookup getenv("PATH") 626#define cmdedit_path_lookup getenv("PATH")
@@ -703,7 +682,7 @@ static char *add_quote_for_spec_chars(char *found, int add)
703 s[l++] = '\\'; 682 s[l++] = '\\';
704 s[l++] = *found++; 683 s[l++] = *found++;
705 } 684 }
706 if(add) 685 if (add)
707 s[l++] = (char)add; 686 s[l++] = (char)add;
708 s[l] = 0; 687 s[l] = 0;
709 return s; 688 return s;
@@ -734,7 +713,7 @@ static void exe_n_cwd_tab_completion(char *command, int type)
734 strcpy(dirbuf, command); 713 strcpy(dirbuf, command);
735 /* set dir only */ 714 /* set dir only */
736 dirbuf[(pfind - command) + 1] = 0; 715 dirbuf[(pfind - command) + 1] = 0;
737#ifdef CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION 716#if ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION
738 if (dirbuf[0] == '~') /* ~/... or ~user/... */ 717 if (dirbuf[0] == '~') /* ~/... or ~user/... */
739 username_tab_completion(dirbuf, dirbuf); 718 username_tab_completion(dirbuf, dirbuf);
740#endif 719#endif
@@ -777,7 +756,7 @@ static void exe_n_cwd_tab_completion(char *command, int type)
777 char *e = found + strlen(found) - 1; 756 char *e = found + strlen(found) - 1;
778 757
779 add_chr = '/'; 758 add_chr = '/';
780 if(*e == '/') 759 if (*e == '/')
781 *e = '\0'; 760 *e = '\0';
782 } else { 761 } else {
783 /* not put found file if search only dirs for cd */ 762 /* not put found file if search only dirs for cd */
@@ -832,12 +811,12 @@ static int find_match(char *matchBuf, int *len_with_quotes)
832 collapse_pos(j, j + 1); 811 collapse_pos(j, j + 1);
833 int_buf[j] |= QUOT; 812 int_buf[j] |= QUOT;
834 i++; 813 i++;
835#ifdef CONFIG_FEATURE_NONPRINTABLE_INVERSE_PUT 814#if ENABLE_FEATURE_NONPRINTABLE_INVERSE_PUT
836 if (matchBuf[i] == '\t') /* algorithm equivalent */ 815 if (matchBuf[i] == '\t') /* algorithm equivalent */
837 int_buf[j] = ' ' | QUOT; 816 int_buf[j] = ' ' | QUOT;
838#endif 817#endif
839 } 818 }
840#ifdef CONFIG_FEATURE_NONPRINTABLE_INVERSE_PUT 819#if ENABLE_FEATURE_NONPRINTABLE_INVERSE_PUT
841 else if (matchBuf[i] == '\t') 820 else if (matchBuf[i] == '\t')
842 int_buf[j] = ' '; 821 int_buf[j] = ' ';
843#endif 822#endif
@@ -986,7 +965,7 @@ static void showfiles(void)
986 /* find the longest file name- use that as the column width */ 965 /* find the longest file name- use that as the column width */
987 for (row = 0; row < nrows; row++) { 966 for (row = 0; row < nrows; row++) {
988 l = strlen(matches[row]); 967 l = strlen(matches[row]);
989 if(add_char_to_match[row]) 968 if (add_char_to_match[row])
990 l++; 969 l++;
991 if (column_width < l) 970 if (column_width < l)
992 column_width = l; 971 column_width = l;
@@ -996,7 +975,7 @@ static void showfiles(void)
996 975
997 if (ncols > 1) { 976 if (ncols > 1) {
998 nrows /= ncols; 977 nrows /= ncols;
999 if(nfiles % ncols) 978 if (nfiles % ncols)
1000 nrows++; /* round up fractionals */ 979 nrows++; /* round up fractionals */
1001 } else { 980 } else {
1002 ncols = 1; 981 ncols = 1;
@@ -1012,7 +991,7 @@ static void showfiles(void)
1012 acol = str_add_chr[0] ? column_width - 1 : column_width; 991 acol = str_add_chr[0] ? column_width - 1 : column_width;
1013 printf("%s%s", matches[n], str_add_chr); 992 printf("%s%s", matches[n], str_add_chr);
1014 l = strlen(matches[n]); 993 l = strlen(matches[n]);
1015 while(l < acol) { 994 while (l < acol) {
1016 putchar(' '); 995 putchar(' ');
1017 l++; 996 l++;
1018 } 997 }
@@ -1022,7 +1001,6 @@ static void showfiles(void)
1022 } 1001 }
1023} 1002}
1024 1003
1025
1026static void input_tab(int *lastWasTab) 1004static void input_tab(int *lastWasTab)
1027{ 1005{
1028 /* Do TAB completion */ 1006 /* Do TAB completion */
@@ -1057,7 +1035,7 @@ static void input_tab(int *lastWasTab)
1057 /* Free up any memory already allocated */ 1035 /* Free up any memory already allocated */
1058 input_tab(0); 1036 input_tab(0);
1059 1037
1060#ifdef CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION 1038#if ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION
1061 /* If the word starts with `~' and there is no slash in the word, 1039 /* If the word starts with `~' and there is no slash in the word,
1062 * then try completing this word as a username. */ 1040 * then try completing this word as a username. */
1063 1041
@@ -1069,34 +1047,30 @@ static void input_tab(int *lastWasTab)
1069 * in the current working directory that matches. */ 1047 * in the current working directory that matches. */
1070 exe_n_cwd_tab_completion(matchBuf, find_type); 1048 exe_n_cwd_tab_completion(matchBuf, find_type);
1071 /* Remove duplicate found and sort */ 1049 /* Remove duplicate found and sort */
1072 if(matches) { 1050 if (matches) {
1073 int i, j, n, srt; 1051 int i, n;
1074 /* bubble */ 1052 /* strcmp is int(*f)(const char*, const char*) */
1075 n = num_matches; 1053 /* qsort wants int(*f)(const void*, const void*) */
1076 for(i=0; i<(n-1); i++) { 1054 /* We cheat here :) */
1077 for(j=i+1; j<n; j++) { 1055 qsort(matches, num_matches, sizeof(char*), (void*)strcmp);
1078 if(matches[i]!=NULL && matches[j]!=NULL) { 1056 i = 0;
1079 srt = strcmp(matches[i], matches[j]); 1057 while (i < num_matches - 1) {
1080 if(srt == 0) { 1058 n = i + 1;
1081 free(matches[j]); 1059 if (matches[i] && matches[n]) {
1082 matches[j]=0; 1060 while (n < num_matches
1083 } else if(srt > 0) { 1061 && !strcmp(matches[i], matches[n])) {
1084 tmp1 = matches[i]; 1062 free(matches[n]);
1085 matches[i] = matches[j]; 1063 matches[n] = 0;
1086 matches[j] = tmp1; 1064 n++;
1087 srt = add_char_to_match[i];
1088 add_char_to_match[i] = add_char_to_match[j];
1089 add_char_to_match[j] = srt;
1090 }
1091 } 1065 }
1092 } 1066 }
1067 i = n;
1093 } 1068 }
1094 j = n;
1095 n = 0; 1069 n = 0;
1096 for(i=0; i<j; i++) 1070 for(i = 0; i < num_matches; i++)
1097 if(matches[i]) { 1071 if (matches[i]) {
1098 matches[n]=matches[i]; 1072 matches[n] = matches[i];
1099 add_char_to_match[n]=add_char_to_match[i]; 1073 add_char_to_match[n] = add_char_to_match[i];
1100 n++; 1074 n++;
1101 } 1075 }
1102 num_matches = n; 1076 num_matches = n;
@@ -1162,12 +1136,12 @@ static void input_tab(int *lastWasTab)
1162 } 1136 }
1163 } 1137 }
1164} 1138}
1165#endif /* CONFIG_FEATURE_COMMAND_TAB_COMPLETION */ 1139#endif /* FEATURE_COMMAND_TAB_COMPLETION */
1166 1140
1167#if MAX_HISTORY > 0 1141#if MAX_HISTORY > 0
1168static void get_previous_history(void) 1142static void get_previous_history(void)
1169{ 1143{
1170 if(command_ps[0] != 0 || history[cur_history] == 0) { 1144 if (command_ps[0] != 0 || history[cur_history] == 0) {
1171 free(history[cur_history]); 1145 free(history[cur_history]);
1172 history[cur_history] = xstrdup(command_ps); 1146 history[cur_history] = xstrdup(command_ps);
1173 } 1147 }
@@ -1188,7 +1162,7 @@ static int get_next_history(void)
1188 } 1162 }
1189} 1163}
1190 1164
1191#ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY 1165#if ENABLE_FEATURE_COMMAND_SAVEHISTORY
1192void load_history ( const char *fromfile ) 1166void load_history ( const char *fromfile )
1193{ 1167{
1194 FILE *fp; 1168 FILE *fp;
@@ -1207,12 +1181,12 @@ void load_history ( const char *fromfile )
1207 char * hl = xmalloc_getline(fp); 1181 char * hl = xmalloc_getline(fp);
1208 int l; 1182 int l;
1209 1183
1210 if(!hl) 1184 if (!hl)
1211 break; 1185 break;
1212 l = strlen(hl); 1186 l = strlen(hl);
1213 if(l >= BUFSIZ) 1187 if (l >= BUFSIZ)
1214 hl[BUFSIZ-1] = 0; 1188 hl[BUFSIZ-1] = 0;
1215 if(l == 0 || hl[0] == ' ') { 1189 if (l == 0 || hl[0] == ' ') {
1216 free(hl); 1190 free(hl);
1217 continue; 1191 continue;
1218 } 1192 }
@@ -1264,7 +1238,7 @@ enum {
1264 * 1238 *
1265 */ 1239 */
1266 1240
1267#ifdef CONFIG_FEATURE_COMMAND_EDITING_VI 1241#if ENABLE_FEATURE_COMMAND_EDITING_VI
1268static int vi_mode; 1242static int vi_mode;
1269 1243
1270void setvimode ( int viflag ) 1244void setvimode ( int viflag )
@@ -1392,7 +1366,7 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
1392 int lastWasTab = FALSE; 1366 int lastWasTab = FALSE;
1393 unsigned char c; 1367 unsigned char c;
1394 unsigned int ic; 1368 unsigned int ic;
1395#ifdef CONFIG_FEATURE_COMMAND_EDITING_VI 1369#if ENABLE_FEATURE_COMMAND_EDITING_VI
1396 unsigned int prevc; 1370 unsigned int prevc;
1397 int vi_cmdmode = 0; 1371 int vi_cmdmode = 0;
1398#endif 1372#endif
@@ -1434,7 +1408,7 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
1434 1408
1435 ic = c; 1409 ic = c;
1436 1410
1437#ifdef CONFIG_FEATURE_COMMAND_EDITING_VI 1411#if ENABLE_FEATURE_COMMAND_EDITING_VI
1438 newdelflag = 1; 1412 newdelflag = 1;
1439 if (vi_cmdmode) 1413 if (vi_cmdmode)
1440 ic |= vbit; 1414 ic |= vbit;
@@ -1465,7 +1439,7 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
1465 vi_case( case CNTRL('C')|vbit: ) 1439 vi_case( case CNTRL('C')|vbit: )
1466 /* Control-c -- stop gathering input */ 1440 /* Control-c -- stop gathering input */
1467 goto_new_line(); 1441 goto_new_line();
1468#ifndef CONFIG_ASH 1442#if !ENABLE_ASH
1469 command[0] = 0; 1443 command[0] = 0;
1470 len = 0; 1444 len = 0;
1471 lastWasTab = FALSE; 1445 lastWasTab = FALSE;
@@ -1481,7 +1455,7 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ])
1481 if (len == 0) { 1455 if (len == 0) {
1482 errno = 0; 1456 errno = 0;
1483prepare_to_die: 1457prepare_to_die:
1484#if !defined(CONFIG_ASH) 1458#if !ENABLE_ASH
1485 printf("exit"); 1459 printf("exit");
1486 goto_new_line(); 1460 goto_new_line();
1487 /* cmdedit_reset_term() called in atexit */ 1461 /* cmdedit_reset_term() called in atexit */
@@ -1512,7 +1486,7 @@ prepare_to_die:
1512 input_backspace(); 1486 input_backspace();
1513 break; 1487 break;
1514 case '\t': 1488 case '\t':
1515#ifdef CONFIG_FEATURE_COMMAND_TAB_COMPLETION 1489#if ENABLE_FEATURE_COMMAND_TAB_COMPLETION
1516 input_tab(&lastWasTab); 1490 input_tab(&lastWasTab);
1517#endif 1491#endif
1518 break; 1492 break;
@@ -1629,7 +1603,7 @@ prepare_to_die:
1629 goto clear_to_eol; 1603 goto clear_to_eol;
1630 break; 1604 break;
1631 } 1605 }
1632 switch(c) { 1606 switch (c) {
1633 case 'w': 1607 case 'w':
1634 case 'W': 1608 case 'W':
1635 case 'e': 1609 case 'e':
@@ -1692,7 +1666,7 @@ prepare_to_die:
1692 putchar('\b'); 1666 putchar('\b');
1693 } 1667 }
1694 break; 1668 break;
1695#endif /* CONFIG_FEATURE_COMMAND_EDITING_VI */ 1669#endif /* FEATURE_COMMAND_EDITING_VI */
1696 1670
1697 case ESC: 1671 case ESC:
1698 1672
@@ -1719,11 +1693,11 @@ prepare_to_die:
1719 1693
1720 if (safe_read(0, &dummy, 1) < 1) 1694 if (safe_read(0, &dummy, 1) < 1)
1721 goto prepare_to_die; 1695 goto prepare_to_die;
1722 if(dummy != '~') 1696 if (dummy != '~')
1723 c = 0; 1697 c = 0;
1724 } 1698 }
1725 switch (c) { 1699 switch (c) {
1726#ifdef CONFIG_FEATURE_COMMAND_TAB_COMPLETION 1700#if ENABLE_FEATURE_COMMAND_TAB_COMPLETION
1727 case '\t': /* Alt-Tab */ 1701 case '\t': /* Alt-Tab */
1728 1702
1729 input_tab(&lastWasTab); 1703 input_tab(&lastWasTab);
@@ -1784,7 +1758,7 @@ rewrite_line:
1784 break; 1758 break;
1785 1759
1786 default: /* If it's regular input, do the normal thing */ 1760 default: /* If it's regular input, do the normal thing */
1787#ifdef CONFIG_FEATURE_NONPRINTABLE_INVERSE_PUT 1761#if ENABLE_FEATURE_NONPRINTABLE_INVERSE_PUT
1788 /* Control-V -- Add non-printable symbol */ 1762 /* Control-V -- Add non-printable symbol */
1789 if (c == CNTRL('V')) { 1763 if (c == CNTRL('V')) {
1790 if (safe_read(0, &c, 1) < 1) 1764 if (safe_read(0, &c, 1) < 1)
@@ -1854,12 +1828,12 @@ rewrite_line:
1854 history[i++] = xstrdup(command); 1828 history[i++] = xstrdup(command);
1855 cur_history = i; 1829 cur_history = i;
1856 n_history = i; 1830 n_history = i;
1857#if defined(CONFIG_FEATURE_SH_FANCY_PROMPT) 1831#if ENABLE_FEATURE_SH_FANCY_PROMPT
1858 num_ok_lines++; 1832 num_ok_lines++;
1859#endif 1833#endif
1860 } 1834 }
1861#else /* MAX_HISTORY == 0 */ 1835#else /* MAX_HISTORY == 0 */
1862#if defined(CONFIG_FEATURE_SH_FANCY_PROMPT) 1836#if ENABLE_FEATURE_SH_FANCY_PROMPT
1863 if (len > 0) { /* no put empty line */ 1837 if (len > 0) { /* no put empty line */
1864 num_ok_lines++; 1838 num_ok_lines++;
1865 } 1839 }
@@ -1869,26 +1843,24 @@ rewrite_line:
1869 command[len++] = '\n'; /* set '\n' */ 1843 command[len++] = '\n'; /* set '\n' */
1870 command[len] = 0; 1844 command[len] = 0;
1871 } 1845 }
1872#if defined(CONFIG_FEATURE_CLEAN_UP) && defined(CONFIG_FEATURE_COMMAND_TAB_COMPLETION) 1846#if ENABLE_FEATURE_CLEAN_UP && ENABLE_FEATURE_COMMAND_TAB_COMPLETION
1873 input_tab(0); /* strong free */ 1847 input_tab(0); /* strong free */
1874#endif 1848#endif
1875#if defined(CONFIG_FEATURE_SH_FANCY_PROMPT) 1849#if ENABLE_FEATURE_SH_FANCY_PROMPT
1876 free(cmdedit_prompt); 1850 free(cmdedit_prompt);
1877#endif 1851#endif
1878 cmdedit_reset_term(); 1852 cmdedit_reset_term();
1879 return len; 1853 return len;
1880} 1854}
1881 1855
1882 1856#endif /* FEATURE_COMMAND_EDITING */
1883
1884#endif /* CONFIG_FEATURE_COMMAND_EDITING */
1885 1857
1886 1858
1887#ifdef TEST 1859#ifdef TEST
1888 1860
1889const char *applet_name = "debug stuff usage"; 1861const char *applet_name = "debug stuff usage";
1890 1862
1891#ifdef CONFIG_FEATURE_NONPRINTABLE_INVERSE_PUT 1863#if ENABLE_FEATURE_NONPRINTABLE_INVERSE_PUT
1892#include <locale.h> 1864#include <locale.h>
1893#endif 1865#endif
1894 1866
@@ -1896,7 +1868,7 @@ int main(int argc, char **argv)
1896{ 1868{
1897 char buff[BUFSIZ]; 1869 char buff[BUFSIZ];
1898 char *prompt = 1870 char *prompt =
1899#if defined(CONFIG_FEATURE_SH_FANCY_PROMPT) 1871#if ENABLE_FEATURE_SH_FANCY_PROMPT
1900 "\\[\\033[32;1m\\]\\u@\\[\\x1b[33;1m\\]\\h:\ 1872 "\\[\\033[32;1m\\]\\u@\\[\\x1b[33;1m\\]\\h:\
1901\\[\\033[34;1m\\]\\w\\[\\033[35;1m\\] \ 1873\\[\\033[34;1m\\]\\w\\[\\033[35;1m\\] \
1902\\!\\[\\e[36;1m\\]\\$ \\[\\E[0m\\]"; 1874\\!\\[\\e[36;1m\\]\\$ \\[\\E[0m\\]";
@@ -1904,13 +1876,13 @@ int main(int argc, char **argv)
1904 "% "; 1876 "% ";
1905#endif 1877#endif
1906 1878
1907#ifdef CONFIG_FEATURE_NONPRINTABLE_INVERSE_PUT 1879#if ENABLE_FEATURE_NONPRINTABLE_INVERSE_PUT
1908 setlocale(LC_ALL, ""); 1880 setlocale(LC_ALL, "");
1909#endif 1881#endif
1910 while(1) { 1882 while (1) {
1911 int l; 1883 int l;
1912 l = cmdedit_read_input(prompt, buff); 1884 l = cmdedit_read_input(prompt, buff);
1913 if(l > 0 && buff[l-1] == '\n') { 1885 if (l > 0 && buff[l-1] == '\n') {
1914 buff[l-1] = 0; 1886 buff[l-1] = 0;
1915 printf("*** cmdedit_read_input() returned line =%s=\n", buff); 1887 printf("*** cmdedit_read_input() returned line =%s=\n", buff);
1916 } else { 1888 } else {