diff options
author | Ron Yorston <rmy@pobox.com> | 2014-10-06 12:50:22 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2014-10-06 12:50:22 +0100 |
commit | b04d11dcbadda2620743a1dd923938f2f3043a38 (patch) | |
tree | 971afe425a81304b79e44122e220c7a69efe2616 /shell | |
parent | 124bbf02948b7ac0babb4ead04acd1559db182d3 (diff) | |
parent | 760d035699c4a878f9109544c1d35ea0d5f6b76c (diff) | |
download | busybox-w32-b04d11dcbadda2620743a1dd923938f2f3043a38.tar.gz busybox-w32-b04d11dcbadda2620743a1dd923938f2f3043a38.tar.bz2 busybox-w32-b04d11dcbadda2620743a1dd923938f2f3043a38.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash.c | 65 | ||||
-rw-r--r-- | shell/hush.c | 33 | ||||
-rw-r--r-- | shell/hush_test/hush-misc/unicode1.right | 3 | ||||
-rwxr-xr-x | shell/hush_test/hush-misc/unicode1.tests | 13 |
4 files changed, 81 insertions, 33 deletions
diff --git a/shell/ash.c b/shell/ash.c index 550a98db6..3f3e2f4bc 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -161,6 +161,13 @@ | |||
161 | //config: help | 161 | //config: help |
162 | //config: Enable support for test builtin in ash. | 162 | //config: Enable support for test builtin in ash. |
163 | //config: | 163 | //config: |
164 | //config:config ASH_HELP | ||
165 | //config: bool "help builtin" | ||
166 | //config: default y | ||
167 | //config: depends on ASH | ||
168 | //config: help | ||
169 | //config: Enable help builtin in ash. | ||
170 | //config: | ||
164 | //config:config ASH_CMDCMD | 171 | //config:config ASH_CMDCMD |
165 | //config: bool "'command' command to override shell builtins" | 172 | //config: bool "'command' command to override shell builtins" |
166 | //config: default y | 173 | //config: default y |
@@ -2189,6 +2196,22 @@ lookupvar(const char *name) | |||
2189 | return NULL; | 2196 | return NULL; |
2190 | } | 2197 | } |
2191 | 2198 | ||
2199 | static void reinit_unicode_for_ash(void) | ||
2200 | { | ||
2201 | /* Unicode support should be activated even if LANG is set | ||
2202 | * _during_ shell execution, not only if it was set when | ||
2203 | * shell was started. Therefore, re-check LANG every time: | ||
2204 | */ | ||
2205 | if (ENABLE_FEATURE_CHECK_UNICODE_IN_ENV | ||
2206 | || ENABLE_UNICODE_USING_LOCALE | ||
2207 | ) { | ||
2208 | const char *s = lookupvar("LC_ALL"); | ||
2209 | if (!s) s = lookupvar("LC_CTYPE"); | ||
2210 | if (!s) s = lookupvar("LANG"); | ||
2211 | reinit_unicode(s); | ||
2212 | } | ||
2213 | } | ||
2214 | |||
2192 | /* | 2215 | /* |
2193 | * Search the environment of a builtin command. | 2216 | * Search the environment of a builtin command. |
2194 | */ | 2217 | */ |
@@ -3818,7 +3841,7 @@ getjob(const char *name, int getctl) | |||
3818 | 3841 | ||
3819 | if (is_number(p)) { | 3842 | if (is_number(p)) { |
3820 | num = atoi(p); | 3843 | num = atoi(p); |
3821 | if (num < njobs) { | 3844 | if (num <= njobs) { |
3822 | jp = jobtab + num - 1; | 3845 | jp = jobtab + num - 1; |
3823 | if (jp->used) | 3846 | if (jp->used) |
3824 | goto gotit; | 3847 | goto gotit; |
@@ -7127,7 +7150,15 @@ evalvar(char *p, int flags, struct strlist *var_str_list) | |||
7127 | varunset(p, var, 0, 0); | 7150 | varunset(p, var, 0, 0); |
7128 | 7151 | ||
7129 | if (subtype == VSLENGTH) { | 7152 | if (subtype == VSLENGTH) { |
7130 | cvtnum(varlen > 0 ? varlen : 0); | 7153 | ssize_t n = varlen; |
7154 | if (n > 0) { | ||
7155 | reinit_unicode_for_ash(); | ||
7156 | if (unicode_status == UNICODE_ON) { | ||
7157 | const char *val = lookupvar(var); | ||
7158 | n = unicode_strlen(val); | ||
7159 | } | ||
7160 | } | ||
7161 | cvtnum(n > 0 ? n : 0); | ||
7131 | goto record; | 7162 | goto record; |
7132 | } | 7163 | } |
7133 | 7164 | ||
@@ -9180,8 +9211,8 @@ setinteractive(int on) | |||
9180 | if (!did_banner) { | 9211 | if (!did_banner) { |
9181 | /* note: ash and hush share this string */ | 9212 | /* note: ash and hush share this string */ |
9182 | out1fmt("\n\n%s %s\n" | 9213 | out1fmt("\n\n%s %s\n" |
9183 | "Enter 'help' for a list of built-in commands." | 9214 | IF_ASH_HELP("Enter 'help' for a list of built-in commands.\n") |
9184 | "\n\n", | 9215 | "\n", |
9185 | bb_banner, | 9216 | bb_banner, |
9186 | "built-in shell (ash)" | 9217 | "built-in shell (ash)" |
9187 | ); | 9218 | ); |
@@ -9434,7 +9465,7 @@ static int exportcmd(int, char **) FAST_FUNC; | |||
9434 | #if ENABLE_ASH_GETOPTS | 9465 | #if ENABLE_ASH_GETOPTS |
9435 | static int getoptscmd(int, char **) FAST_FUNC; | 9466 | static int getoptscmd(int, char **) FAST_FUNC; |
9436 | #endif | 9467 | #endif |
9437 | #if !ENABLE_FEATURE_SH_EXTRA_QUIET | 9468 | #if ENABLE_ASH_HELP |
9438 | static int helpcmd(int, char **) FAST_FUNC; | 9469 | static int helpcmd(int, char **) FAST_FUNC; |
9439 | #endif | 9470 | #endif |
9440 | #if MAX_HISTORY | 9471 | #if MAX_HISTORY |
@@ -9510,7 +9541,7 @@ static const struct builtincmd builtintab[] = { | |||
9510 | { BUILTIN_REGULAR "getopts" , getoptscmd }, | 9541 | { BUILTIN_REGULAR "getopts" , getoptscmd }, |
9511 | #endif | 9542 | #endif |
9512 | { BUILTIN_NOSPEC "hash" , hashcmd }, | 9543 | { BUILTIN_NOSPEC "hash" , hashcmd }, |
9513 | #if !ENABLE_FEATURE_SH_EXTRA_QUIET | 9544 | #if ENABLE_ASH_HELP |
9514 | { BUILTIN_NOSPEC "help" , helpcmd }, | 9545 | { BUILTIN_NOSPEC "help" , helpcmd }, |
9515 | #endif | 9546 | #endif |
9516 | #if MAX_HISTORY | 9547 | #if MAX_HISTORY |
@@ -10080,16 +10111,7 @@ preadfd(void) | |||
10080 | # if ENABLE_FEATURE_TAB_COMPLETION | 10111 | # if ENABLE_FEATURE_TAB_COMPLETION |
10081 | line_input_state->path_lookup = pathval(); | 10112 | line_input_state->path_lookup = pathval(); |
10082 | # endif | 10113 | # endif |
10083 | /* Unicode support should be activated even if LANG is set | 10114 | reinit_unicode_for_ash(); |
10084 | * _during_ shell execution, not only if it was set when | ||
10085 | * shell was started. Therefore, re-check LANG every time: | ||
10086 | */ | ||
10087 | { | ||
10088 | const char *s = lookupvar("LC_ALL"); | ||
10089 | if (!s) s = lookupvar("LC_CTYPE"); | ||
10090 | if (!s) s = lookupvar("LANG"); | ||
10091 | reinit_unicode(s); | ||
10092 | } | ||
10093 | nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ, timeout); | 10115 | nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ, timeout); |
10094 | if (nr == 0) { | 10116 | if (nr == 0) { |
10095 | /* Ctrl+C pressed */ | 10117 | /* Ctrl+C pressed */ |
@@ -13059,10 +13081,7 @@ trapcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
13059 | 13081 | ||
13060 | /* ============ Builtins */ | 13082 | /* ============ Builtins */ |
13061 | 13083 | ||
13062 | #if !ENABLE_FEATURE_SH_EXTRA_QUIET | 13084 | #if ENABLE_ASH_HELP |
13063 | /* | ||
13064 | * Lists available builtins | ||
13065 | */ | ||
13066 | static int FAST_FUNC | 13085 | static int FAST_FUNC |
13067 | helpcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | 13086 | helpcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) |
13068 | { | 13087 | { |
@@ -13080,7 +13099,7 @@ helpcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
13080 | col = 0; | 13099 | col = 0; |
13081 | } | 13100 | } |
13082 | } | 13101 | } |
13083 | #if ENABLE_FEATURE_SH_STANDALONE | 13102 | # if ENABLE_FEATURE_SH_STANDALONE |
13084 | { | 13103 | { |
13085 | const char *a = applet_names; | 13104 | const char *a = applet_names; |
13086 | while (*a) { | 13105 | while (*a) { |
@@ -13092,11 +13111,11 @@ helpcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
13092 | a += strlen(a) + 1; | 13111 | a += strlen(a) + 1; |
13093 | } | 13112 | } |
13094 | } | 13113 | } |
13095 | #endif | 13114 | # endif |
13096 | out1fmt("\n\n"); | 13115 | out1fmt("\n\n"); |
13097 | return EXIT_SUCCESS; | 13116 | return EXIT_SUCCESS; |
13098 | } | 13117 | } |
13099 | #endif /* FEATURE_SH_EXTRA_QUIET */ | 13118 | #endif |
13100 | 13119 | ||
13101 | #if MAX_HISTORY | 13120 | #if MAX_HISTORY |
13102 | static int FAST_FUNC | 13121 | static int FAST_FUNC |
diff --git a/shell/hush.c b/shell/hush.c index e1d0ece29..92d790180 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -1977,6 +1977,26 @@ static struct variable *set_vars_and_save_old(char **strings) | |||
1977 | 1977 | ||
1978 | 1978 | ||
1979 | /* | 1979 | /* |
1980 | * Unicode helper | ||
1981 | */ | ||
1982 | static void reinit_unicode_for_hush(void) | ||
1983 | { | ||
1984 | /* Unicode support should be activated even if LANG is set | ||
1985 | * _during_ shell execution, not only if it was set when | ||
1986 | * shell was started. Therefore, re-check LANG every time: | ||
1987 | */ | ||
1988 | if (ENABLE_FEATURE_CHECK_UNICODE_IN_ENV | ||
1989 | || ENABLE_UNICODE_USING_LOCALE | ||
1990 | ) { | ||
1991 | const char *s = get_local_var_value("LC_ALL"); | ||
1992 | if (!s) s = get_local_var_value("LC_CTYPE"); | ||
1993 | if (!s) s = get_local_var_value("LANG"); | ||
1994 | reinit_unicode(s); | ||
1995 | } | ||
1996 | } | ||
1997 | |||
1998 | |||
1999 | /* | ||
1980 | * in_str support | 2000 | * in_str support |
1981 | */ | 2001 | */ |
1982 | static int FAST_FUNC static_get(struct in_str *i) | 2002 | static int FAST_FUNC static_get(struct in_str *i) |
@@ -2042,15 +2062,7 @@ static void get_user_input(struct in_str *i) | |||
2042 | /* Enable command line editing only while a command line | 2062 | /* Enable command line editing only while a command line |
2043 | * is actually being read */ | 2063 | * is actually being read */ |
2044 | do { | 2064 | do { |
2045 | /* Unicode support should be activated even if LANG is set | 2065 | reinit_unicode_for_hush(); |
2046 | * _during_ shell execution, not only if it was set when | ||
2047 | * shell was started. Therefore, re-check LANG every time: | ||
2048 | */ | ||
2049 | const char *s = get_local_var_value("LC_ALL"); | ||
2050 | if (!s) s = get_local_var_value("LC_CTYPE"); | ||
2051 | if (!s) s = get_local_var_value("LANG"); | ||
2052 | reinit_unicode(s); | ||
2053 | |||
2054 | G.flag_SIGINT = 0; | 2066 | G.flag_SIGINT = 0; |
2055 | /* buglet: SIGINT will not make new prompt to appear _at once_, | 2067 | /* buglet: SIGINT will not make new prompt to appear _at once_, |
2056 | * only after <Enter>. (^C will work) */ | 2068 | * only after <Enter>. (^C will work) */ |
@@ -5028,8 +5040,9 @@ static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, cha | |||
5028 | 5040 | ||
5029 | /* Handle any expansions */ | 5041 | /* Handle any expansions */ |
5030 | if (exp_op == 'L') { | 5042 | if (exp_op == 'L') { |
5043 | reinit_unicode_for_hush(); | ||
5031 | debug_printf_expand("expand: length(%s)=", val); | 5044 | debug_printf_expand("expand: length(%s)=", val); |
5032 | val = utoa(val ? strlen(val) : 0); | 5045 | val = utoa(val ? unicode_strlen(val) : 0); |
5033 | debug_printf_expand("%s\n", val); | 5046 | debug_printf_expand("%s\n", val); |
5034 | } else if (exp_op) { | 5047 | } else if (exp_op) { |
5035 | if (exp_op == '%' || exp_op == '#') { | 5048 | if (exp_op == '%' || exp_op == '#') { |
diff --git a/shell/hush_test/hush-misc/unicode1.right b/shell/hush_test/hush-misc/unicode1.right new file mode 100644 index 000000000..d3bbbf697 --- /dev/null +++ b/shell/hush_test/hush-misc/unicode1.right | |||
@@ -0,0 +1,3 @@ | |||
1 | 1 | ||
2 | 1 | ||
3 | Ok | ||
diff --git a/shell/hush_test/hush-misc/unicode1.tests b/shell/hush_test/hush-misc/unicode1.tests new file mode 100755 index 000000000..8788ba910 --- /dev/null +++ b/shell/hush_test/hush-misc/unicode1.tests | |||
@@ -0,0 +1,13 @@ | |||
1 | LANG=en_US.UTF-8 | ||
2 | |||
3 | # A combining character U+300 | ||
4 | a=`printf "\xcc\x80"` | ||
5 | # Should print 1 | ||
6 | echo ${#a} | ||
7 | |||
8 | # A Japanese katakana charachter U+30a3 | ||
9 | a=`printf "\xe3\x82\xa3"` | ||
10 | # Should print 1 | ||
11 | echo ${#a} | ||
12 | |||
13 | echo Ok | ||