1 # Helper macros for finding a locale using a specific character set.
3 # Copyright © 2023-2024 Nick Bowler
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <https://www.gnu.org/licenses/>.
18 # TEST_UTF8_LOCALE([variable], [action-if-found], [action-if-not-found])
20 # Try to find a supported UTF-8 locale. If any is found, the given shell
21 # variable is set to the name of one such locale, and action-if-found is
24 # If no suitable locale is found, then variable is set to the empty string
25 # and action-if-not-found is expanded. If no action is specified, the
26 # default action in this scenario is to skip the current test group.
28 # Since m4sh overrides LC_ALL, it is recommended to use the locale by
29 # setting LC_ALL to the detected value when running a program.
30 m4_defun([TEST_UTF8_LOCALE],
31 [AS_VAR_SET([$1], [`_TEST_UTF8_LOCALE`])
32 AS_VAR_IF([$1], [""], [m4_default([$3], [AT_SKIP_IF([:])])], [$2])])
34 m4_defun([_TEST_UTF8_LOCALE], [m4_require([_TEST_NLS_SETUP])dnl
35 test_find_locale_charmap '[[Uu][Tt][Ff]-*8]' 'sjis' '\246' '\357\275\246'])
37 # Output shell function definitions to implement locale detection.
39 # - test_check_locale_charmap name regex
41 # Returns success if setting LC_ALL to the given locale name results in a
42 # charmap string that matches the given regex (as interpreted by 'grep').
44 # - test_check_locale_iconv name fromcode input output
46 # Returns success if setting LC_ALL to the given locale name results in
47 # "iconv -f fromcode" translating the given input to the given output.
49 # The input and output are awk strings, use octal escapes to encode
50 # byte sequences. Choose characters with encodings that avoid
51 # problematic control characters such as NUL or LF.
53 # - test_find_locale regex fromcode input output
55 # Try to find a locale with a particular character encoding.
57 # By default, the user's own LC_CTYPE is preferred. Otherwise, the first
58 # match in the output of "locale -a" is chosen, filtered by the given regex.
59 # However, if that locale starts with "C" we prefer the next one as HP-UX
60 # has a C.utf8 locale which does not work.
62 # A locale is considered acceptable if either test_check_locale_charmap regex
63 # or test_check_locale_iconv fromcode input output reports success.
65 m4_defun_once([_TEST_NLS_SETUP], [m4_divert_push([HEADER-COPYRIGHT])
66 # save user locale setting before m4sh clobbers it
69 m4_divert([PREPARE_TESTS])
70 test_check_locale_charmap () {
71 LC_ALL=$[1] locale -ck charmap 2>&AS_MESSAGE_LOG_FD | grep "$[2]" >/dev/null 2>&1
74 test_check_locale_iconv () {
75 $AWK 'BEGIN { printf "'"${3:-x}"'"; }' |
76 { LC_ALL=$[1] iconv -f "$[2]" 2>&AS_MESSAGE_LOG_FD; echo; } |
77 $AWK 'NR==1 { pass = ($[0] == "'"$[4]"'"); } END { exit(!pass); }'
80 test_find_locale_charmap () {
81 re=$[1] fromcode=$[2] input=$[3] output=$[4]
86 init_ctype=`locale 2>&AS_MESSAGE_LOG_FD | $AWK -F= '$[1] == "LC_CTYPE" {
87 $[1] = ""; sub(/^ "/, ""); sub(/"$/, ""); print
90 LC_ALL=$save_LC_ALL found_locale=
91 if test_check_locale_charmap "$init_ctype" "$re" ||
92 test_check_locale_iconv "$init_ctype" "$fromcode" "$input" "$output"
94 found_locale=$init_ctype
99 set x `locale -a | grep "$re"`; shift
101 if test_check_locale_charmap "$arg" "$re" ||
102 test_check_locale_iconv "$arg" "$fromcode" "$input" "$output"
105 case $found_locale in
114 if test ${found_locale:+y}; then
115 AS_ECHO(["found matching locale $found_locale"]) >&AS_MESSAGE_LOG_FD
116 LC_ALL=$found_locale locale >&AS_MESSAGE_LOG_FD 2>&1
117 AS_ECHO(["$found_locale"])
119 AS_ECHO(["failed to find any suitable locale"]) >&AS_MESSAGE_LOG_FD
122 m4_divert_pop([PREPARE_TESTS])