hush: make ${#var} unicode-aware

This mimics bash

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2014-08-13 09:57:44 +02:00
parent 45b4ecc868
commit c538d5bcc3
3 changed files with 35 additions and 10 deletions

View File

@ -1976,6 +1976,22 @@ static struct variable *set_vars_and_save_old(char **strings)
} }
/*
* Unicode helper
*/
static void reinit_unicode_for_hush(void)
{
/* Unicode support should be activated even if LANG is set
* _during_ shell execution, not only if it was set when
* shell was started. Therefore, re-check LANG every time:
*/
const char *s = get_local_var_value("LC_ALL");
if (!s) s = get_local_var_value("LC_CTYPE");
if (!s) s = get_local_var_value("LANG");
reinit_unicode(s);
}
/* /*
* in_str support * in_str support
*/ */
@ -2042,15 +2058,7 @@ static void get_user_input(struct in_str *i)
/* Enable command line editing only while a command line /* Enable command line editing only while a command line
* is actually being read */ * is actually being read */
do { do {
/* Unicode support should be activated even if LANG is set reinit_unicode_for_hush();
* _during_ shell execution, not only if it was set when
* shell was started. Therefore, re-check LANG every time:
*/
const char *s = get_local_var_value("LC_ALL");
if (!s) s = get_local_var_value("LC_CTYPE");
if (!s) s = get_local_var_value("LANG");
reinit_unicode(s);
G.flag_SIGINT = 0; G.flag_SIGINT = 0;
/* buglet: SIGINT will not make new prompt to appear _at once_, /* buglet: SIGINT will not make new prompt to appear _at once_,
* only after <Enter>. (^C will work) */ * only after <Enter>. (^C will work) */
@ -5028,8 +5036,9 @@ static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, cha
/* Handle any expansions */ /* Handle any expansions */
if (exp_op == 'L') { if (exp_op == 'L') {
reinit_unicode_for_hush();
debug_printf_expand("expand: length(%s)=", val); debug_printf_expand("expand: length(%s)=", val);
val = utoa(val ? strlen(val) : 0); val = utoa(val ? unicode_strlen(val) : 0);
debug_printf_expand("%s\n", val); debug_printf_expand("%s\n", val);
} else if (exp_op) { } else if (exp_op) {
if (exp_op == '%' || exp_op == '#') { if (exp_op == '%' || exp_op == '#') {

View File

@ -0,0 +1,3 @@
1
1
Ok

View File

@ -0,0 +1,13 @@
LANG=en_US.UTF-8
# A combining character U+300
a=`printf "\xcc\x80"`
# Should print 1
echo ${#a}
# A Japanese katakana charachter U+30a3
a=`printf "\xe3\x82\xa3"`
# Should print 1
echo ${#a}
echo Ok