This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Merge pull request #79 from neilb/taintsupport
[metaconfig.git] / U / perl / d_setlocale.U
CommitLineData
f313dd7e
AC
1?RCS: Copyright (c) 1991-1997, 2004-2006, Raphael Manfredi
2?RCS: Copyright (c) 2019, Karl Williamson
3?RCS:
4?RCS: You may redistribute only under the terms of the Artistic Licence,
5?RCS: as specified in the README file that comes with the distribution.
6?RCS: You may reuse parts of this distribution only within the terms of
7?RCS: that same Artistic Licence; a copy of which may be found at the root
8?RCS: of the source tree for dist 4.0.
9?RCS:
7ba9a688
KW
10?MAKE:d_setlocale d_setlocale_accepts_any_locale_name d_has_C_UTF8: \
11 cat Compile run rm_try i_locale i_wctype d_towupper Setvar Myread
f313dd7e
AC
12?MAKE: -pick add $@ %<
13?S:d_has_C_UTF8:
14?S: This variable is set to either "true" or "false" depending on
15?S: whether the compilation system supports the C.UTF-8 locale.
16?S:.
17?S:d_setlocale:
18?S: This variable conditionally defines HAS_SETLOCALE if setlocale() is
19?S: available to handle locale-specific ctype implementations.
20?S:.
21?S:d_setlocale_accepts_any_locale_name:
22?S: This variable conditionally defines SETLOCALE_ACCEPTS_ANY_LOCALE_NAME
23?S: if setlocale() accepts any locale name.
24?S:.
25?C:HAS_SETLOCALE:
26?C: This symbol, if defined, indicates that the setlocale routine is
27?C: available to handle locale-specific ctype implementations.
28?C:.
29?C:SETLOCALE_ACCEPTS_ANY_LOCALE_NAME:
30?C: This symbol, if defined, indicates that the setlocale routine is
31?C: available and it accepts any input locale name as valid.
32?C:.
33?H:#$d_setlocale HAS_SETLOCALE /**/
34?H:#$d_setlocale_accepts_any_locale_name SETLOCALE_ACCEPTS_ANY_LOCALE_NAME /**/
35?H:.
36?F:!try
7ba9a688 37?T:LC_CTYPE c_utf8_locale
f313dd7e 38: check for setlocale function and behavior
7ba9a688
KW
39case "$d_setlocale" in
40'')
41$cat >&4 <<EOM
f313dd7e
AC
42
43Checking to see if you have setlocale() and its behavior
44EOM
45$cat >try.c <<EOCP
70210eb0 46#include <stdlib.h>
f313dd7e
AC
47#include <string.h>
48#$i_locale I_LOCALE
49#ifdef I_LOCALE
50# include <locale.h>
51#endif
52#$i_wctype I_WCTYPE
53#ifdef I_WCTYPE
54# include <wctype.h>
55#endif
56
57int main() {
58 const char * invalid_name = "\a"; /* This is really invalid! */
59 int accepts_any_locale_name = 0;
60 int has_C_UTF8 = 0;
61 unsigned char bad_setlocale = 255;
62
63 /* If LC_CTYPE isn't defined the compilation will fail, and locales will be
64 * disabled. It's hard to imagine an instance where meaningful locale
65 * handling could be done without LC_CTYPE */
66 const char * name = setlocale(LC_CTYPE, "C");
67
68 if (name == NULL || strcmp(name, "C") != 0) {
69 exit(bad_setlocale);
70 }
71
72 name = setlocale(LC_CTYPE, invalid_name);
73 if (name != NULL) {
74
75 /* Let it pass if it accepts the name but gives back one of the C
76 * locales */
77 if (strcmp(name, "C") != 0 && strcmp(name, "C.UTF-8") != 0) {
78 accepts_any_locale_name = 1;
79 }
80 }
81
82 name = setlocale(LC_CTYPE, "C.UTF-8");
83 if (name != NULL) {
84 unsigned char y_with_diaeresis = ('A' == 193) ? 0xDF : 0xFF;
85
86#$d_towupper HAS_TOWUPPER
87#ifdef HAS_TOWUPPER
88
89 /* We assume that if the machine doesn't have the C99 towupper, it
90 * doesn't have C.UTF-8, even if we successfully changed locales to
91 * include it. This seems safer even on platforms that didn't accept
92 * the really invalid name */
93
94 if (towupper(y_with_diaeresis) == 0x178) {
95 has_C_UTF8 = 1;
96 }
97
98#endif
99
100 }
101
102#if 0
103
104 /* Currently unused code to determine if LC_ALL with disparate values uses
105 * category = value pairs or positional, and to determine the separator
106 * between the categories. We could add code so that if the separator were
107 * > '9', we subtract 10; similarly for 'Z' and 'z', and then just about
108 * every possible ASCII separator would fit in the 5 bits available in the
109 * exit code. This would not be true in EBCDIC. And then if LC_ALL is
110 * positional, we probably would want to know the order of the categories.
111 * Using a file between the C program and the shell script would really be
112 * require to do that */
113#ifdef LC_ALL
114
115 unsigned char min_separator = ' ' - 1;
116 unsigned char separator = min_separator;
117 int uses_name_value_pair_names = 0;
118
119 name = setlocale(LC_ALL, "C");
120 if (name == NULL || strcmp(name, "C") != 0) {
121 exit(bad_setlocale);
122 }
123
124 if (has_C_UTF8) {
125 char * pos;
126
127 name = setlocale(LC_CTYPE, "C.UTF-8");
128 if (name == NULL) {
129 exit(bad_setlocale);
130 }
131 name = setlocale(LC_ALL, NULL);
132 if (name == NULL) {
133 exit(bad_setlocale);
134 }
135
136 pos = strstr(name, "LC_CTYPE" "=C.UTF-8");
137 if (pos != NULL) {
138 uses_name_value_pair_names = 1;
139 if (pos == name) {
140 separator = name[sizeof("LC_CTYPE=C.UTF-8") - 1];
141 }
142 else {
143 separator = *(pos - 1);
144 }
145 }
146 else {
147 pos = strstr(name, "C.UTF-8");
148 if (pos == NULL) {
149 /* bad */
150 }
151 else if (pos == name) {
152 separator = name[sizeof("C.UTF-8") - 1];
153 }
154 else {
155 separator = *(pos - 1);
156 }
157 }
158 }
159
160#endif
161#endif
162
163 exit( 0 /* (separator - min_separator) << 3
164 | uses_name_value_pair_names << 2
165 */
166 | has_C_UTF8 << 1
167 | accepts_any_locale_name);
168
169}
170EOCP
7ba9a688
KW
171val=
172set d_setlocale
173eval $setvar
174case $d_setlocale in
175 $undef) d_setlocale_accepts_any_locale_name="$undef"
176 d_has_C_UTF8="false"
177 ;;
178 *) set try
179 if eval $compile; then
180 echo "Your system has setlocale()..." >&4
181 $run ./try
182 case $? in
22fb5cbe 183 0) echo "and it seems sane; you don't have a C.UTF-8 locale" >&4
7ba9a688
KW
184 d_setlocale="$define"
185 d_setlocale_accepts_any_locale_name="$undef"
186 d_has_C_UTF8="false"
187 ;;
188 1) echo "and it seems sane, but accepts any locale name as valid" >&4
189 d_setlocale="$define"
190 d_setlocale_accepts_any_locale_name="$define"
191 d_has_C_UTF8="false"
192 ;;
22fb5cbe 193 2) echo "and it seems sane; you have a C.UTF-8 locale" >&4
7ba9a688
KW
194 d_setlocale="$define"
195 d_setlocale_accepts_any_locale_name="$undef"
196 d_has_C_UTF8="true"
197 ;;
198 3) echo "and it seems sane, but accepts any locale name as valid" >&4
199 d_setlocale="$define"
200 d_setlocale_accepts_any_locale_name="$define"
201 d_has_C_UTF8="true"
202 ;;
203 *) echo "but it doesn't seem to work, so we won't use it." >&4
204 d_setlocale="$undef"
205 d_setlocale_accepts_any_locale_name="$undef"
206 d_has_C_UTF8="false"
207 ;;
208 esac
209 else
210 echo "your system does not have setlocale()" >&4
f313dd7e
AC
211 d_setlocale="$undef"
212 d_setlocale_accepts_any_locale_name="$undef"
213 d_has_C_UTF8="false"
7ba9a688
KW
214 fi
215esac
f313dd7e 216$rm_try
7ba9a688
KW
217;;
218*) val="$d_setlocale"
219 set d_setlocale
220 eval $setvar
221 case "$d_setlocale" in
222 $undef) echo "There may be other ways to set the locale on your system, so we need to ask:" >&4
223 ;;
224 esac
22fb5cbe 225 rp="Does your system have the C.UTF-8 locale?"
7ba9a688
KW
226 dflt=n
227 . ./myread
228 case "$ans" in
229 [Yy]*) d_has_C_UTF8="true"
22fb5cbe 230 c_utf8_locale=" or C.UTF-8"
7ba9a688
KW
231 ;;
232 *) d_has_C_UTF8="false"
233 c_utf8_locale=""
234 ;;
235 esac
236 case "$d_setlocale" in
237 $define)
238 rp="When you set your locale to something besides C$c_utf8_locale, does it do so, or just pretend to?" >&4
239 dflt=n
240 . ./myread
241 case "$ans" in
242 true|[Yy]*)
243 d_setlocale_accepts_any_locale_name="$undef"
244 ;;
245 *) d_setlocale_accepts_any_locale_name="$define"
246 ;;
247 esac
248 ;;
249 *) d_setlocale_accepts_any_locale_name="$undef"
250 ;;
251 esac
252esac
f313dd7e 253