Import c99types.h and related probes from cdecl99.
[dxcommon.git] / snippet / test-nls.at
blob684eb9817f8aecb2f7f983ff16724bd951d70d5b
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
22 # expanded.
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
67 _orig_LC_ALL=$LC_ALL
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]
83   save_LC_ALL=$LC_ALL
84   LC_ALL=$_orig_LC_ALL
86   init_ctype=`locale 2>&AS_MESSAGE_LOG_FD | $AWK -F= '$[1] == "LC_CTYPE" {
87     $[1] = ""; sub(/^ "/, ""); sub(/"$/, ""); print
88   }'`
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"
93   then
94     found_locale=$init_ctype
95   fi
97   case $found_locale in
98   C*|"")
99     set x `locale -a | grep "$re"`; shift
100     for arg; do
101       if test_check_locale_charmap "$arg" "$re" ||
102          test_check_locale_iconv "$arg" "$fromcode" "$input" "$output"
103       then
104         found_locale=$arg;
105         case $found_locale in
106         C*) :;;
107         *) break ;;
108         esac
109       fi
110     done
111     ;;
112   esac
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"])
118   else
119     AS_ECHO(["failed to find any suitable locale"]) >&AS_MESSAGE_LOG_FD
120   fi
122 m4_divert_pop([PREPARE_TESTS])