diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2006-12-19 01:10:25 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2006-12-19 01:10:25 +0000 |
commit | 7f1dc21a5df2aecd58c57e9fb59797401eea7270 (patch) | |
tree | cfd384d3994055fc83eaab3666b8e379c823f28a | |
parent | 8eb3b391ad9999a3c01c6a90939e443729edb5f6 (diff) | |
download | busybox-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.c | 236 |
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; | |||
94 | static int cur_history; | 77 | static 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 */ | |||
119 | static int cmdedit_y; /* pseudoreal y terminal position */ | 102 | static int cmdedit_y; /* pseudoreal y terminal position */ |
120 | static int cmdedit_prmt_len; /* lenght prompt without colores string */ | 103 | static int cmdedit_prmt_len; /* lenght prompt without colores string */ |
121 | 104 | ||
122 | static int cursor; /* required global for signal handler */ | 105 | static int cursor; /* required globals for signal handler */ |
123 | static int len; /* --- "" - - "" - -"- --""-- --""--- */ | 106 | static int len; /* --- "" - - "" -- -"- --""-- --""--- */ |
124 | static char *command_ps; /* --- "" - - "" - -"- --""-- --""--- */ | 107 | static char *command_ps; /* --- "" - - "" -- -"- --""-- --""--- */ |
125 | static | 108 | static SKIP_FEATURE_SH_FANCY_PROMPT(const) char *cmdedit_prompt; /* -- */ |
126 | #ifndef CONFIG_FEATURE_SH_FANCY_PROMPT | ||
127 | const | ||
128 | #endif | ||
129 | char *cmdedit_prompt; /* --- "" - - "" - -"- --""-- --""--- */ | ||
130 | 109 | ||
131 | #ifdef CONFIG_FEATURE_GETUSERNAME_AND_HOMEDIR | 110 | #if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR |
132 | static char *user_buf = ""; | 111 | static char *user_buf = ""; |
133 | static char *home_pwd_buf = ""; | 112 | static char *home_pwd_buf = ""; |
134 | static int my_euid; | 113 | static int my_euid; |
135 | #endif | 114 | #endif |
136 | 115 | ||
137 | #ifdef CONFIG_FEATURE_SH_FANCY_PROMPT | 116 | #if ENABLE_FEATURE_SH_FANCY_PROMPT |
138 | static char *hostname_buf; | 117 | static char *hostname_buf; |
139 | static int num_ok_lines = 1; | 118 | static 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 |
146 | static int my_euid; | 125 | static int my_euid; |
147 | #endif | 126 | #endif |
148 | 127 | ||
149 | static int my_uid; | 128 | static int my_uid; |
150 | static int my_gid; | 129 | static int my_gid; |
151 | 130 | ||
152 | #endif /* CONFIG_FEATURE_COMMAND_TAB_COMPLETION */ | 131 | #endif /* FEATURE_COMMAND_TAB_COMPLETION */ |
153 | 132 | ||
154 | static void cmdedit_setwidth(int w, int redraw_flg); | 133 | static 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 |
294 | static void parse_prompt(const char *prmt_ptr) | 273 | static 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 |
437 | static char *delbuf; /* a (malloced) place to store deleted characters */ | 416 | static char *delbuf; /* a (malloced) place to store deleted characters */ |
438 | static char *delp; | 417 | static 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 |
473 | static void put(void) | 452 | static 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 | ||
561 | static char **matches; | 540 | static char **matches; |
562 | static int num_matches; | 541 | static 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 | ||
588 | static void username_tab_completion(char *ud, char *with_shash_flg) | 567 | static 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 | ||
638 | enum { | 617 | enum { |
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 |
645 | const char *cmdedit_path_lookup; | 624 | const 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 | |||
1026 | static void input_tab(int *lastWasTab) | 1004 | static 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 |
1168 | static void get_previous_history(void) | 1142 | static 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 |
1192 | void load_history ( const char *fromfile ) | 1166 | void 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 |
1268 | static int vi_mode; | 1242 | static int vi_mode; |
1269 | 1243 | ||
1270 | void setvimode ( int viflag ) | 1244 | void 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; |
1483 | prepare_to_die: | 1457 | prepare_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 | ||
1889 | const char *applet_name = "debug stuff usage"; | 1861 | const 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 { |