aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2014-10-06 12:50:22 +0100
committerRon Yorston <rmy@pobox.com>2014-10-06 12:50:22 +0100
commitb04d11dcbadda2620743a1dd923938f2f3043a38 (patch)
tree971afe425a81304b79e44122e220c7a69efe2616 /shell
parent124bbf02948b7ac0babb4ead04acd1559db182d3 (diff)
parent760d035699c4a878f9109544c1d35ea0d5f6b76c (diff)
downloadbusybox-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.c65
-rw-r--r--shell/hush.c33
-rw-r--r--shell/hush_test/hush-misc/unicode1.right3
-rwxr-xr-xshell/hush_test/hush-misc/unicode1.tests13
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
2199static 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
9435static int getoptscmd(int, char **) FAST_FUNC; 9466static int getoptscmd(int, char **) FAST_FUNC;
9436#endif 9467#endif
9437#if !ENABLE_FEATURE_SH_EXTRA_QUIET 9468#if ENABLE_ASH_HELP
9438static int helpcmd(int, char **) FAST_FUNC; 9469static 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 */
13066static int FAST_FUNC 13085static int FAST_FUNC
13067helpcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) 13086helpcmd(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
13102static int FAST_FUNC 13121static 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 */
1982static 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 */
1982static int FAST_FUNC static_get(struct in_str *i) 2002static 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 @@
11
21
3Ok
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 @@
1LANG=en_US.UTF-8
2
3# A combining character U+300
4a=`printf "\xcc\x80"`
5# Should print 1
6echo ${#a}
7
8# A Japanese katakana charachter U+30a3
9a=`printf "\xe3\x82\xa3"`
10# Should print 1
11echo ${#a}
12
13echo Ok