diff options
author | Denys Vlasenko <dvlasenk@redhat.com> | 2010-09-03 12:51:36 +0200 |
---|---|---|
committer | Denys Vlasenko <dvlasenk@redhat.com> | 2010-09-03 12:51:36 +0200 |
commit | 57ea9b488b096e17418a808d20f263daea468974 (patch) | |
tree | 863e814d727aeb12c4bbbfdd1a8feca6336ea510 /libbb | |
parent | 7063e86d0d6e0be7f8eed4f7b435a7be3f26ecdd (diff) | |
download | busybox-w32-57ea9b488b096e17418a808d20f263daea468974.tar.gz busybox-w32-57ea9b488b096e17418a808d20f263daea468974.tar.bz2 busybox-w32-57ea9b488b096e17418a808d20f263daea468974.zip |
preparatory cleanup patch for tab completion fixes
renames and deinlines a few functions
function old new delta
input_tab - 1041 +1041
complete_cmd_dir_file - 699 +699
complete_username - 121 +121
username_completion 121 - -121
read_line_input 5002 3313 -1689
------------------------------------------------------------------------------
(add/remove: 3/1 grow/shrink: 0/1 up/down: 1861/-1810) Total: 51 bytes
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/lineedit.c | 126 |
1 files changed, 65 insertions, 61 deletions
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 35f1d0031..7bb709f9d 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * Termios command line History and Editing. | 3 | * Command line editing. |
4 | * | 4 | * |
5 | * Copyright (c) 1986-2003 may safely be consumed by a BSD or GPL license. | 5 | * Copyright (c) 1986-2003 may safely be consumed by a BSD or GPL license. |
6 | * Written by: Vladimir Oleynik <dzo@simtreas.ru> | 6 | * Written by: Vladimir Oleynik <dzo@simtreas.ru> |
@@ -194,7 +194,7 @@ static void deinit_S(void) | |||
194 | { | 194 | { |
195 | #if ENABLE_FEATURE_EDITING_FANCY_PROMPT | 195 | #if ENABLE_FEATURE_EDITING_FANCY_PROMPT |
196 | /* This one is allocated only if FANCY_PROMPT is on | 196 | /* This one is allocated only if FANCY_PROMPT is on |
197 | * (otherwise it points to verbatim prompt (NOT malloced) */ | 197 | * (otherwise it points to verbatim prompt (NOT malloced)) */ |
198 | free((char*)cmdedit_prompt); | 198 | free((char*)cmdedit_prompt); |
199 | #endif | 199 | #endif |
200 | #if ENABLE_USERNAME_OR_HOMEDIR | 200 | #if ENABLE_USERNAME_OR_HOMEDIR |
@@ -213,7 +213,7 @@ static size_t load_string(const char *src, int maxsize) | |||
213 | ssize_t len = mbstowcs(command_ps, src, maxsize - 1); | 213 | ssize_t len = mbstowcs(command_ps, src, maxsize - 1); |
214 | if (len < 0) | 214 | if (len < 0) |
215 | len = 0; | 215 | len = 0; |
216 | command_ps[len] = 0; | 216 | command_ps[len] = BB_NUL; |
217 | return len; | 217 | return len; |
218 | } | 218 | } |
219 | static unsigned save_string(char *dst, unsigned maxsize) | 219 | static unsigned save_string(char *dst, unsigned maxsize) |
@@ -234,17 +234,17 @@ static unsigned save_string(char *dst, unsigned maxsize) | |||
234 | int n = srcpos; | 234 | int n = srcpos; |
235 | 235 | ||
236 | /* Convert up to 1st invalid byte (or up to end) */ | 236 | /* Convert up to 1st invalid byte (or up to end) */ |
237 | while ((wc = command_ps[srcpos]) != 0 | 237 | while ((wc = command_ps[srcpos]) != BB_NUL |
238 | && !unicode_is_raw_byte(wc) | 238 | && !unicode_is_raw_byte(wc) |
239 | ) { | 239 | ) { |
240 | srcpos++; | 240 | srcpos++; |
241 | } | 241 | } |
242 | command_ps[srcpos] = 0; | 242 | command_ps[srcpos] = BB_NUL; |
243 | n = wcstombs(dst + dstpos, command_ps + n, maxsize - dstpos); | 243 | n = wcstombs(dst + dstpos, command_ps + n, maxsize - dstpos); |
244 | if (n < 0) /* should not happen */ | 244 | if (n < 0) /* should not happen */ |
245 | break; | 245 | break; |
246 | dstpos += n; | 246 | dstpos += n; |
247 | if (wc == 0) /* usually is */ | 247 | if (wc == BB_NUL) /* usually is */ |
248 | break; | 248 | break; |
249 | 249 | ||
250 | /* We do have invalid byte here! */ | 250 | /* We do have invalid byte here! */ |
@@ -639,7 +639,7 @@ static char *username_path_completion(char *ud) | |||
639 | } | 639 | } |
640 | 640 | ||
641 | /* ~use<tab> - find all users with this prefix */ | 641 | /* ~use<tab> - find all users with this prefix */ |
642 | static NOINLINE void username_completion(const char *ud) | 642 | static NOINLINE void complete_username(const char *ud) |
643 | { | 643 | { |
644 | /* Using _r function to avoid pulling in static buffers */ | 644 | /* Using _r function to avoid pulling in static buffers */ |
645 | char line_buff[256]; | 645 | char line_buff[256]; |
@@ -659,7 +659,7 @@ static NOINLINE void username_completion(const char *ud) | |||
659 | } | 659 | } |
660 | endpwent(); | 660 | endpwent(); |
661 | } | 661 | } |
662 | #endif /* FEATURE_COMMAND_USERNAME_COMPLETION */ | 662 | #endif /* FEATURE_USERNAME_COMPLETION */ |
663 | 663 | ||
664 | enum { | 664 | enum { |
665 | FIND_EXE_ONLY = 0, | 665 | FIND_EXE_ONLY = 0, |
@@ -710,7 +710,7 @@ static int path_parse(char ***p) | |||
710 | return npth; | 710 | return npth; |
711 | } | 711 | } |
712 | 712 | ||
713 | static void exe_n_cwd_tab_completion(char *command, int type) | 713 | static NOINLINE void complete_cmd_dir_file(char *command, int type) |
714 | { | 714 | { |
715 | char *path1[1]; | 715 | char *path1[1]; |
716 | char **paths = path1; | 716 | char **paths = path1; |
@@ -799,24 +799,25 @@ static void exe_n_cwd_tab_completion(char *command, int type) | |||
799 | free(dirbuf); | 799 | free(dirbuf); |
800 | } | 800 | } |
801 | 801 | ||
802 | /* build_match_prefix: | ||
803 | * On entry, matchBuf contains everything up to cursor at the moment <tab> | ||
804 | * was pressed. This function looks at it, figures out what part of it | ||
805 | * constitutes the command/file/directory prefix to use for completion, | ||
806 | * and rewrites matchBuf to contain only that part. | ||
807 | */ | ||
808 | /* Helpers: */ | ||
802 | /* QUOT is used on elements of int_buf[], which are bytes, | 809 | /* QUOT is used on elements of int_buf[], which are bytes, |
803 | * not Unicode chars. Therefore it works correctly even in Unicode mode. | 810 | * not Unicode chars. Therefore it works correctly even in Unicode mode. |
804 | */ | 811 | */ |
805 | #define QUOT (UCHAR_MAX+1) | 812 | #define QUOT (UCHAR_MAX+1) |
806 | |||
807 | #define int_buf (S.find_match__int_buf) | 813 | #define int_buf (S.find_match__int_buf) |
808 | #define pos_buf (S.find_match__pos_buf) | 814 | #define pos_buf (S.find_match__pos_buf) |
809 | /* is must be <= in */ | 815 | static void collapse_pos(int beg, int end) |
810 | static void collapse_pos(int is, int in) | ||
811 | { | 816 | { |
812 | memmove(int_buf+is, int_buf+in, (MAX_LINELEN+1-in) * sizeof(int_buf[0])); | 817 | /* beg must be <= end */ |
813 | memmove(pos_buf+is, pos_buf+in, (MAX_LINELEN+1-in) * sizeof(pos_buf[0])); | 818 | memmove(int_buf+beg, int_buf+end, (MAX_LINELEN+1-end) * sizeof(int_buf[0])); |
819 | memmove(pos_buf+beg, pos_buf+end, (MAX_LINELEN+1-end) * sizeof(pos_buf[0])); | ||
814 | } | 820 | } |
815 | /* On entry, matchBuf contains everything up to cursor at the moment <tab> | ||
816 | * was pressed. This function looks at it, figures out what part of it | ||
817 | * constitutes the command/file/directory prefix to use for completion, | ||
818 | * and rewrites matchBuf to contain only that part. | ||
819 | */ | ||
820 | static NOINLINE int build_match_prefix(char *matchBuf, int *len_with_quotes) | 821 | static NOINLINE int build_match_prefix(char *matchBuf, int *len_with_quotes) |
821 | { | 822 | { |
822 | int i, j; | 823 | int i, j; |
@@ -826,17 +827,16 @@ static NOINLINE int build_match_prefix(char *matchBuf, int *len_with_quotes) | |||
826 | /* int16_t int_buf[MAX_LINELEN + 1]; */ | 827 | /* int16_t int_buf[MAX_LINELEN + 1]; */ |
827 | /* int16_t pos_buf[MAX_LINELEN + 1]; */ | 828 | /* int16_t pos_buf[MAX_LINELEN + 1]; */ |
828 | 829 | ||
829 | /* set to integer dimension characters and own positions */ | ||
830 | for (i = 0;; i++) { | 830 | for (i = 0;; i++) { |
831 | int_buf[i] = (unsigned char)matchBuf[i]; | 831 | int_buf[i] = (unsigned char)matchBuf[i]; |
832 | if (int_buf[i] == 0) { | 832 | if (int_buf[i] == 0) { |
833 | pos_buf[i] = -1; /* end-fo-line indicator */ | 833 | pos_buf[i] = -1; /* end-of-line indicator */ |
834 | break; | 834 | break; |
835 | } | 835 | } |
836 | pos_buf[i] = i; | 836 | pos_buf[i] = i; |
837 | } | 837 | } |
838 | 838 | ||
839 | /* mask \+symbol and convert '\t' to ' ' */ | 839 | /* Mark every \c as "quoted c" */ |
840 | for (i = j = 0; matchBuf[i]; i++, j++) { | 840 | for (i = j = 0; matchBuf[i]; i++, j++) { |
841 | if (matchBuf[i] == '\\') { | 841 | if (matchBuf[i] == '\\') { |
842 | collapse_pos(j, j + 1); | 842 | collapse_pos(j, j + 1); |
@@ -844,7 +844,7 @@ static NOINLINE int build_match_prefix(char *matchBuf, int *len_with_quotes) | |||
844 | i++; | 844 | i++; |
845 | } | 845 | } |
846 | } | 846 | } |
847 | /* mask "symbols" or 'symbols' */ | 847 | /* Quote-mark "chars" and 'chars' */ |
848 | c2 = 0; | 848 | c2 = 0; |
849 | for (i = 0; int_buf[i]; i++) { | 849 | for (i = 0; int_buf[i]; i++) { |
850 | c = int_buf[i]; | 850 | c = int_buf[i]; |
@@ -861,8 +861,10 @@ static NOINLINE int build_match_prefix(char *matchBuf, int *len_with_quotes) | |||
861 | int_buf[i] |= QUOT; | 861 | int_buf[i] |= QUOT; |
862 | } | 862 | } |
863 | 863 | ||
864 | /* skip commands with arguments if line has commands delimiters */ | 864 | /* Remove everything up to command delimiters: |
865 | /* ';' ';;' '&' '|' '&&' '||' but '>&' '<&' '>|' */ | 865 | * ';' ';;' '&' '|' '&&' '||', |
866 | * but careful with '>&' '<&' '>|' | ||
867 | */ | ||
866 | for (i = 0; int_buf[i]; i++) { | 868 | for (i = 0; int_buf[i]; i++) { |
867 | int n; | 869 | int n; |
868 | c = int_buf[i]; | 870 | c = int_buf[i]; |
@@ -879,28 +881,29 @@ static NOINLINE int build_match_prefix(char *matchBuf, int *len_with_quotes) | |||
879 | } | 881 | } |
880 | if (n) { | 882 | if (n) { |
881 | collapse_pos(0, i + n); | 883 | collapse_pos(0, i + n); |
882 | i = -1; /* hack incremet */ | 884 | i = -1; /* hack increment */ |
883 | } | 885 | } |
884 | } | 886 | } |
885 | /* collapse `command...` */ | 887 | /* Remove all `cmd` */ |
886 | for (i = 0; int_buf[i]; i++) { | 888 | for (i = 0; int_buf[i]; i++) { |
887 | if (int_buf[i] == '`') { | 889 | if (int_buf[i] == '`') { |
888 | for (j = i + 1; int_buf[j]; j++) | 890 | for (j = i + 1; int_buf[j]; j++) { |
889 | if (int_buf[j] == '`') { | 891 | if (int_buf[j] == '`') { |
890 | collapse_pos(i, j + 1); | 892 | collapse_pos(i, j + 1); |
891 | j = 0; | 893 | j = 0; |
892 | break; | 894 | break; |
893 | } | 895 | } |
896 | } | ||
894 | if (j) { | 897 | if (j) { |
895 | /* not found closing ` - command mode, collapse all previous */ | 898 | /* No closing ` - command mode, remove all up to ` */ |
896 | collapse_pos(0, i + 1); | 899 | collapse_pos(0, i + 1); |
897 | break; | 900 | break; |
898 | } else | 901 | } |
899 | i--; /* hack incremet */ | 902 | i--; /* hack increment */ |
900 | } | 903 | } |
901 | } | 904 | } |
902 | 905 | ||
903 | /* collapse (command...(command...)...) or {command...{command...}...} */ | 906 | /* Remove (command...(command...)...) and {command...{command...}...} */ |
904 | c = 0; /* "recursive" level */ | 907 | c = 0; /* "recursive" level */ |
905 | c2 = 0; | 908 | c2 = 0; |
906 | for (i = 0; int_buf[i]; i++) { | 909 | for (i = 0; int_buf[i]; i++) { |
@@ -910,7 +913,7 @@ static NOINLINE int build_match_prefix(char *matchBuf, int *len_with_quotes) | |||
910 | else | 913 | else |
911 | c2++; | 914 | c2++; |
912 | collapse_pos(0, i + 1); | 915 | collapse_pos(0, i + 1); |
913 | i = -1; /* hack incremet */ | 916 | i = -1; /* hack increment */ |
914 | } | 917 | } |
915 | } | 918 | } |
916 | for (i = 0; pos_buf[i] >= 0 && (c > 0 || c2 > 0); i++) { | 919 | for (i = 0; pos_buf[i] >= 0 && (c > 0 || c2 > 0); i++) { |
@@ -920,22 +923,23 @@ static NOINLINE int build_match_prefix(char *matchBuf, int *len_with_quotes) | |||
920 | else | 923 | else |
921 | c2--; | 924 | c2--; |
922 | collapse_pos(0, i + 1); | 925 | collapse_pos(0, i + 1); |
923 | i = -1; /* hack incremet */ | 926 | i = -1; /* hack increment */ |
924 | } | 927 | } |
925 | } | 928 | } |
926 | 929 | ||
927 | /* skip first not quote space */ | 930 | /* Remove leading unquoted spaces */ |
928 | for (i = 0; int_buf[i]; i++) | 931 | for (i = 0; int_buf[i]; i++) |
929 | if (int_buf[i] != ' ') | 932 | if (int_buf[i] != ' ') |
930 | break; | 933 | break; |
931 | if (i) | 934 | if (i) |
932 | collapse_pos(0, i); | 935 | collapse_pos(0, i); |
933 | 936 | ||
934 | /* set find mode for completion */ | 937 | /* Determine completion mode */ |
935 | command_mode = FIND_EXE_ONLY; | 938 | command_mode = FIND_EXE_ONLY; |
936 | for (i = 0; int_buf[i]; i++) { | 939 | for (i = 0; int_buf[i]; i++) { |
937 | if (int_buf[i] == ' ' || int_buf[i] == '<' || int_buf[i] == '>') { | 940 | if (int_buf[i] == ' ' || int_buf[i] == '<' || int_buf[i] == '>') { |
938 | if (int_buf[i] == ' ' && command_mode == FIND_EXE_ONLY | 941 | if (int_buf[i] == ' ' |
942 | && command_mode == FIND_EXE_ONLY | ||
939 | && matchBuf[pos_buf[0]] == 'c' | 943 | && matchBuf[pos_buf[0]] == 'c' |
940 | && matchBuf[pos_buf[1]] == 'd' | 944 | && matchBuf[pos_buf[1]] == 'd' |
941 | ) { | 945 | ) { |
@@ -946,9 +950,10 @@ static NOINLINE int build_match_prefix(char *matchBuf, int *len_with_quotes) | |||
946 | } | 950 | } |
947 | } | 951 | } |
948 | } | 952 | } |
953 | |||
954 | /* Remove everything except last word */ | ||
949 | for (i = 0; int_buf[i]; i++) /* quasi-strlen(int_buf) */ | 955 | for (i = 0; int_buf[i]; i++) /* quasi-strlen(int_buf) */ |
950 | continue; | 956 | continue; |
951 | /* find last word */ | ||
952 | for (--i; i >= 0; i--) { | 957 | for (--i; i >= 0; i--) { |
953 | c = int_buf[i]; | 958 | c = int_buf[i]; |
954 | if (c == ' ' || c == '<' || c == '>' || c == '|' || c == '&') { | 959 | if (c == ' ' || c == '<' || c == '>' || c == '|' || c == '&') { |
@@ -956,7 +961,7 @@ static NOINLINE int build_match_prefix(char *matchBuf, int *len_with_quotes) | |||
956 | break; | 961 | break; |
957 | } | 962 | } |
958 | } | 963 | } |
959 | /* skip first not quoted '\'' or '"' */ | 964 | /* Skip all leading unquoted ' or " */ |
960 | for (i = 0; int_buf[i] == '\'' || int_buf[i] == '"'; i++) | 965 | for (i = 0; int_buf[i] == '\'' || int_buf[i] == '"'; i++) |
961 | continue; | 966 | continue; |
962 | /* collapse quote or unquote // or /~ */ | 967 | /* collapse quote or unquote // or /~ */ |
@@ -982,8 +987,8 @@ static NOINLINE int build_match_prefix(char *matchBuf, int *len_with_quotes) | |||
982 | #undef pos_buf | 987 | #undef pos_buf |
983 | 988 | ||
984 | /* | 989 | /* |
985 | * display by column (original idea from ls applet, | 990 | * Display by column (original idea from ls applet, |
986 | * very optimized by me :) | 991 | * very optimized by me [Vladimir] :) |
987 | */ | 992 | */ |
988 | static void showfiles(void) | 993 | static void showfiles(void) |
989 | { | 994 | { |
@@ -1040,7 +1045,7 @@ static char *add_quote_for_spec_chars(char *found) | |||
1040 | } | 1045 | } |
1041 | 1046 | ||
1042 | /* Do TAB completion */ | 1047 | /* Do TAB completion */ |
1043 | static void input_tab(smallint *lastWasTab) | 1048 | static NOINLINE void input_tab(smallint *lastWasTab) |
1044 | { | 1049 | { |
1045 | if (!(state->flags & TAB_COMPLETION)) | 1050 | if (!(state->flags & TAB_COMPLETION)) |
1046 | return; | 1051 | return; |
@@ -1057,7 +1062,7 @@ static void input_tab(smallint *lastWasTab) | |||
1057 | int cursor_mb; | 1062 | int cursor_mb; |
1058 | #endif | 1063 | #endif |
1059 | 1064 | ||
1060 | *lastWasTab = TRUE; /* flop trigger */ | 1065 | *lastWasTab = 1; |
1061 | 1066 | ||
1062 | /* Make a local copy of the string -- | 1067 | /* Make a local copy of the string -- |
1063 | * up to the position of the cursor */ | 1068 | * up to the position of the cursor */ |
@@ -1066,7 +1071,7 @@ static void input_tab(smallint *lastWasTab) | |||
1066 | #else | 1071 | #else |
1067 | { | 1072 | { |
1068 | CHAR_T wc = command_ps[cursor]; | 1073 | CHAR_T wc = command_ps[cursor]; |
1069 | command_ps[cursor] = 0; | 1074 | command_ps[cursor] = BB_NUL; |
1070 | save_string(matchBuf, MAX_LINELEN); | 1075 | save_string(matchBuf, MAX_LINELEN); |
1071 | command_ps[cursor] = wc; | 1076 | command_ps[cursor] = wc; |
1072 | cursor_mb = strlen(matchBuf); | 1077 | cursor_mb = strlen(matchBuf); |
@@ -1084,26 +1089,25 @@ static void input_tab(smallint *lastWasTab) | |||
1084 | * then try completing this word as a username. */ | 1089 | * then try completing this word as a username. */ |
1085 | if (state->flags & USERNAME_COMPLETION) | 1090 | if (state->flags & USERNAME_COMPLETION) |
1086 | if (matchBuf[0] == '~' && strchr(matchBuf, '/') == NULL) | 1091 | if (matchBuf[0] == '~' && strchr(matchBuf, '/') == NULL) |
1087 | username_completion(matchBuf); | 1092 | complete_username(matchBuf); |
1088 | #endif | 1093 | #endif |
1089 | /* Try to match any executable in our path and everything | 1094 | /* Try to match a command in $PATH, or a directory, or a file */ |
1090 | * in the current working directory */ | ||
1091 | if (!matches) | 1095 | if (!matches) |
1092 | exe_n_cwd_tab_completion(matchBuf, find_type); | 1096 | complete_cmd_dir_file(matchBuf, find_type); |
1093 | /* Sort, then remove any duplicates found */ | 1097 | /* Remove duplicates */ |
1094 | if (matches) { | 1098 | if (matches) { |
1095 | unsigned i; | 1099 | unsigned i; |
1096 | unsigned n = 0; | 1100 | unsigned n = 0; |
1097 | qsort_string_vector(matches, num_matches); | 1101 | qsort_string_vector(matches, num_matches); |
1098 | for (i = 0; i < num_matches - 1; ++i) { | 1102 | for (i = 0; i < num_matches - 1; ++i) { |
1099 | if (matches[i] && matches[i+1]) { /* paranoia */ | 1103 | //if (matches[i] && matches[i+1]) { /* paranoia */ |
1100 | if (strcmp(matches[i], matches[i+1]) == 0) { | 1104 | if (strcmp(matches[i], matches[i+1]) == 0) { |
1101 | free(matches[i]); | 1105 | free(matches[i]); |
1102 | matches[i] = NULL; /* paranoia */ | 1106 | //matches[i] = NULL; /* paranoia */ |
1103 | } else { | 1107 | } else { |
1104 | matches[n++] = matches[i]; | 1108 | matches[n++] = matches[i]; |
1105 | } | 1109 | } |
1106 | } | 1110 | //} |
1107 | } | 1111 | } |
1108 | matches[n++] = matches[i]; | 1112 | matches[n++] = matches[i]; |
1109 | num_matches = n; | 1113 | num_matches = n; |
@@ -1113,7 +1117,7 @@ static void input_tab(smallint *lastWasTab) | |||
1113 | beep(); | 1117 | beep(); |
1114 | if (!matches) | 1118 | if (!matches) |
1115 | return; /* no matches at all */ | 1119 | return; /* no matches at all */ |
1116 | /* find minimal match */ | 1120 | /* Find common prefix */ |
1117 | tmp1 = xstrdup(matches[0]); | 1121 | tmp1 = xstrdup(matches[0]); |
1118 | for (tmp = tmp1; *tmp; tmp++) { | 1122 | for (tmp = tmp1; *tmp; tmp++) { |
1119 | for (len_found = 1; len_found < num_matches; len_found++) { | 1123 | for (len_found = 1; len_found < num_matches; len_found++) { |
@@ -1123,7 +1127,7 @@ static void input_tab(smallint *lastWasTab) | |||
1123 | } | 1127 | } |
1124 | } | 1128 | } |
1125 | } | 1129 | } |
1126 | if (*tmp1 == '\0') { /* have unique pfx? */ | 1130 | if (*tmp1 == '\0') { /* have unique prefix? */ |
1127 | free(tmp1); /* no */ | 1131 | free(tmp1); /* no */ |
1128 | return; | 1132 | return; |
1129 | } | 1133 | } |
@@ -1131,10 +1135,10 @@ static void input_tab(smallint *lastWasTab) | |||
1131 | free(tmp1); | 1135 | free(tmp1); |
1132 | len_found = strlen(tmp); | 1136 | len_found = strlen(tmp); |
1133 | } else { /* exactly one match */ | 1137 | } else { /* exactly one match */ |
1134 | tmp = add_quote_for_spec_chars(matches[0]); | 1138 | /* Next <tab> is not a double-tab */ |
1135 | /* for next completion current found */ | 1139 | *lastWasTab = 0; |
1136 | *lastWasTab = FALSE; | ||
1137 | 1140 | ||
1141 | tmp = add_quote_for_spec_chars(matches[0]); | ||
1138 | len_found = strlen(tmp); | 1142 | len_found = strlen(tmp); |
1139 | if (tmp[len_found-1] != '/') { | 1143 | if (tmp[len_found-1] != '/') { |
1140 | tmp[len_found] = ' '; | 1144 | tmp[len_found] = ' '; |
@@ -1199,7 +1203,7 @@ static void input_tab(smallint *lastWasTab) | |||
1199 | } | 1203 | } |
1200 | } | 1204 | } |
1201 | 1205 | ||
1202 | #endif /* FEATURE_COMMAND_TAB_COMPLETION */ | 1206 | #endif /* FEATURE_TAB_COMPLETION */ |
1203 | 1207 | ||
1204 | 1208 | ||
1205 | line_input_t* FAST_FUNC new_line_input_t(int flags) | 1209 | line_input_t* FAST_FUNC new_line_input_t(int flags) |
@@ -1899,7 +1903,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li | |||
1899 | { | 1903 | { |
1900 | int len; | 1904 | int len; |
1901 | #if ENABLE_FEATURE_TAB_COMPLETION | 1905 | #if ENABLE_FEATURE_TAB_COMPLETION |
1902 | smallint lastWasTab = FALSE; | 1906 | smallint lastWasTab = 0; |
1903 | #endif | 1907 | #endif |
1904 | smallint break_out = 0; | 1908 | smallint break_out = 0; |
1905 | #if ENABLE_FEATURE_EDITING_VI | 1909 | #if ENABLE_FEATURE_EDITING_VI |
@@ -2375,7 +2379,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li | |||
2375 | 2379 | ||
2376 | #if ENABLE_FEATURE_TAB_COMPLETION | 2380 | #if ENABLE_FEATURE_TAB_COMPLETION |
2377 | if (ic_raw != '\t') | 2381 | if (ic_raw != '\t') |
2378 | lastWasTab = FALSE; | 2382 | lastWasTab = 0; |
2379 | #endif | 2383 | #endif |
2380 | } /* while (1) */ | 2384 | } /* while (1) */ |
2381 | 2385 | ||
@@ -2469,7 +2473,7 @@ int main(int argc, char **argv) | |||
2469 | l = read_line_input(prompt, buff); | 2473 | l = read_line_input(prompt, buff); |
2470 | if (l <= 0 || buff[l-1] != '\n') | 2474 | if (l <= 0 || buff[l-1] != '\n') |
2471 | break; | 2475 | break; |
2472 | buff[l-1] = 0; | 2476 | buff[l-1] = '\0'; |
2473 | printf("*** read_line_input() returned line =%s=\n", buff); | 2477 | printf("*** read_line_input() returned line =%s=\n", buff); |
2474 | } | 2478 | } |
2475 | printf("*** read_line_input() detect ^D\n"); | 2479 | printf("*** read_line_input() detect ^D\n"); |