From 504cbda269081d4cbd82df1c44b151ee217d11e4 Mon Sep 17 00:00:00 2001 From: Johnothan King Date: Thu, 8 Apr 2021 19:49:48 -0700 Subject: [PATCH] Fix 'printf %T' ignoring the current locale in LC_TIME (#263) src/lib/libast/tm/tmlocale.c: - Load the locale set by LC_TIME or LC_ALL if it hasn't been loaded before or if it was loaded previously but isn't the current locale. src/cmd/ksh93/tests/locale.sh: - Add a regression test using the nl_NL.UTF-8 and ja_JP.UTF-8 locales. Fixes: https://github.com/ksh93/ksh/issues/261 --- NEWS | 3 +++ src/cmd/ksh93/tests/locale.sh | 21 ++++++++++++++++++++- src/lib/libast/tm/tmlocale.c | 8 +++++++- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 26dc9d08f..b8074837d 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,9 @@ Any uppercase BUG_* names are modernish shell bug IDs. - Path-bound builtins will now be used by restricted shells if /opt/ast/bin is in the $PATH upon invoking the shell or before setting it to restricted. +- Fixed a bug that caused "printf '%T\n' now" to ignore $LC_ALL and $LC_TIME + if the current locale was previously set, unset then set again. + 2021-04-07: - The $LC_TIME variable is now recognized by ksh and if set to an invalid diff --git a/src/cmd/ksh93/tests/locale.sh b/src/cmd/ksh93/tests/locale.sh index c1043efe5..f556c0256 100755 --- a/src/cmd/ksh93/tests/locale.sh +++ b/src/cmd/ksh93/tests/locale.sh @@ -85,10 +85,29 @@ do [[ $locale == *[Jj][Ii][Ss] ]] || continue done unset LC_ALL +# Test the effect of setting a locale, followed by setting a different locale +# then setting the previous locale. The output from 'printf %T' should use +# the current locale. +# https://github.com/ksh93/ksh/issues/261 +((SHOPT_MULTIBYTE)) && for locale in "${locales[@]}" +do [[ $locale == *nl_NL*[Uu][Tt][Ff]* ]] && nl_NL=$locale + [[ $locale == *ja_JP*[Uu][Tt][Ff]* ]] && ja_JP=$locale +done +if [[ -n $nl_NL ]] && [[ -n $ja_JP ]]; then + LC_ALL=$nl_NL + exp=$(printf '%(%A)T' now) + LC_ALL=$ja_JP + printf '%T' now > /dev/null + LC_ALL=$nl_NL + got=$(printf '%(%A)T' now) + [[ $exp == $got ]] || err_exit "'printf %T' ignores changes to LC_ALL when locale is set, unset then set (expected $exp, got $got)" +fi +unset LC_ALL + # this locale is supported by ast on all platforms # EU for { decimal_point="," thousands_sep="." } -if((SHOPT_MULTIBYTE)); then +if ((SHOPT_MULTIBYTE)); then locale=C_EU.UTF-8 else locale=C_EU diff --git a/src/lib/libast/tm/tmlocale.c b/src/lib/libast/tm/tmlocale.c index 71a8b50ca..ef06422cd 100644 --- a/src/lib/libast/tm/tmlocale.c +++ b/src/lib/libast/tm/tmlocale.c @@ -637,8 +637,14 @@ tmlocale(void) else if (tm_info.deformat != tm_info.format[TM_DEFAULT]) state.format = tm_info.deformat; } + + /* load the locale set in LC_TIME */ li = LCINFO(AST_LC_TIME); - if (!li->data) + if (!li->data || state.locale != li) + { load(li); + state.locale = li; + } + return tm_info.format; }