diff options
author | Karl Williamson <khw@cpan.org> | 2019-02-16 22:12:41 -0700 |
---|---|---|
committer | Karl Williamson <khw@cpan.org> | 2019-03-04 13:01:37 -0700 |
commit | 2e3ef32f4acc106de6ae8170099f09a36d4ef490 (patch) | |
tree | 1182ba2bcee9a62e52f350e618dcdf86680da670 | |
parent | 0806cdda2789ca6394976d1ff3e65dd59bcb8d1b (diff) | |
download | perl-2e3ef32f4acc106de6ae8170099f09a36d4ef490.tar.gz |
Improve setlocale() detection in Configure-ish files
This also now notes some behavior of setlocale
-rwxr-xr-x | Configure | 181 | ||||
-rw-r--r-- | Cross/config.sh-arm-linux | 1 | ||||
-rw-r--r-- | Cross/config.sh-arm-linux-n770 | 1 | ||||
-rw-r--r-- | NetWare/config.wc | 1 | ||||
-rw-r--r-- | Porting/config.sh | 1 | ||||
-rwxr-xr-x | config_h.SH | 17 | ||||
-rw-r--r-- | configure.com | 2 | ||||
-rw-r--r-- | metaconfig.h | 1 | ||||
-rw-r--r-- | plan9/config_sh.sample | 1 | ||||
-rw-r--r-- | symbian/config.sh | 1 | ||||
-rw-r--r-- | uconfig.h | 21 | ||||
-rw-r--r-- | uconfig.sh | 1 | ||||
-rw-r--r-- | uconfig64.sh | 1 | ||||
-rw-r--r-- | win32/config.ce | 1 | ||||
-rw-r--r-- | win32/config.gc | 1 | ||||
-rw-r--r-- | win32/config.vc | 1 |
16 files changed, 215 insertions, 18 deletions
@@ -762,7 +762,9 @@ d_sethostent_r='' sethostent_r_proto='' d_setitimer='' d_setlinebuf='' +d_has_C_UTF8='' d_setlocale='' +d_setlocale_accepts_any_locale_name='' d_setlocale_r='' setlocale_r_proto='' d_setnent='' @@ -17787,10 +17789,6 @@ eval $inlibc set setlinebuf d_setlinebuf eval $inlibc -: see if setlocale exists -set setlocale d_setlocale -eval $inlibc - : see if locale.h is available set locale.h i_locale eval $inhdr @@ -17803,6 +17801,179 @@ eval $inhdr set towupper d_towupper eval $inlibc +: check for setlocale function and behavior +$cat <<EOM + +Checking to see if you have setlocale() and its behavior +EOM +$cat >try.c <<EOCP +#$i_stdlib I_STDLIB +#ifdef I_STDLIB +# include <stdlib.h> +#endif +#include <string.h> +#$i_locale I_LOCALE +#ifdef I_LOCALE +# include <locale.h> +#endif +#$i_wctype I_WCTYPE +#ifdef I_WCTYPE +# include <wctype.h> +#endif + +int main() { + const char * invalid_name = "\a"; /* This is really invalid! */ + int accepts_any_locale_name = 0; + int has_C_UTF8 = 0; + unsigned char bad_setlocale = 255; + + /* If LC_CTYPE isn't defined the compilation will fail, and locales will be + * disabled. It's hard to imagine an instance where meaningful locale + * handling could be done without LC_CTYPE */ + const char * name = setlocale(LC_CTYPE, "C"); + + if (name == NULL || strcmp(name, "C") != 0) { + exit(bad_setlocale); + } + + name = setlocale(LC_CTYPE, invalid_name); + if (name != NULL) { + + /* Let it pass if it accepts the name but gives back one of the C + * locales */ + if (strcmp(name, "C") != 0 && strcmp(name, "C.UTF-8") != 0) { + accepts_any_locale_name = 1; + } + } + + name = setlocale(LC_CTYPE, "C.UTF-8"); + if (name != NULL) { + unsigned char y_with_diaeresis = ('A' == 193) ? 0xDF : 0xFF; + +#$d_towupper HAS_TOWUPPER +#ifdef HAS_TOWUPPER + + /* We assume that if the machine doesn't have the C99 towupper, it + * doesn't have C.UTF-8, even if we successfully changed locales to + * include it. This seems safer even on platforms that didn't accept + * the really invalid name */ + + if (towupper(y_with_diaeresis) == 0x178) { + has_C_UTF8 = 1; + } + +#endif + + } + +#if 0 + + /* Currently unused code to determine if LC_ALL with disparate values uses + * category=value pairs or positional, and to determine the separator + * between the categories. We could add code so that if the separator were + * > '9', we subtract 10; similarly for 'Z' and 'z', and then just about + * every possible ASCII separator would fit in the 5 bits available in the + * exit code. This would not be true in EBCDIC. And then if LC_ALL is + * positional, we probably would want to know the order of the categories. + * Using a file between the C program and the shell script would really be + * require to do that */ +#ifdef LC_ALL + + unsigned char min_separator = ' ' - 1; + unsigned char separator = min_separator; + int uses_name_value_pair_names = 0; + + name = setlocale(LC_ALL, "C"); + if (name == NULL || strcmp(name, "C") != 0) { + exit(bad_setlocale); + } + + if (has_C_UTF8) { + char * pos; + + name = setlocale(LC_CTYPE, "C.UTF-8"); + if (name == NULL) { + exit(bad_setlocale); + } + name = setlocale(LC_ALL, NULL); + if (name == NULL) { + exit(bad_setlocale); + } + + pos = strstr(name, "LC_CTYPE=C.UTF-8"); + if (pos != NULL) { + uses_name_value_pair_names = 1; + if (pos == name) { + separator = name[sizeof("LC_CTYPE=C.UTF-8") - 1]; + } + else { + separator = *(pos - 1); + } + } + else { + pos = strstr(name, "C.UTF-8"); + if (pos == NULL) { + /* bad */ + } + else if (pos == name) { + separator = name[sizeof("C.UTF-8") - 1]; + } + else { + separator = *(pos - 1); + } + } + } + +#endif +#endif + + exit( 0 /* (separator - min_separator) << 3 + | uses_name_value_pair_names << 2 + */ + | has_C_UTF8 << 1 + | accepts_any_locale_name); + +} +EOCP +set try +if eval $compile; then + echo "Your system has setlocale()..." >&4 + $run ./try + case $? in + 0) echo "and it seems sane" >&4 + d_setlocale="$define" + d_setlocale_accepts_any_locale_name="$undef" + d_has_C_UTF8="false" + ;; + 1) echo "and it seems sane, but accepts any locale name as valid" >&4 + d_setlocale="$define" + d_setlocale_accepts_any_locale_name="$define" + d_has_C_UTF8="false" + ;; + 2) echo "and it seems sane" >&4 + d_setlocale="$define" + d_setlocale_accepts_any_locale_name="$undef" + d_has_C_UTF8="true" + ;; + 3) echo "and it seems sane, but accepts any locale name as valid" >&4 + d_setlocale="$define" + d_setlocale_accepts_any_locale_name="$define" + d_has_C_UTF8="true" + ;; + *) echo "but it doesn't seem to work, so we won't use it." >&4 + d_setlocale="$undef" + d_setlocale_accepts_any_locale_name="$undef" + d_has_C_UTF8="false" + ;; + esac +else + echo "your system does not have setlocale()" >&4 + d_setlocale="$undef" + d_setlocale_accepts_any_locale_name="$undef" + d_has_C_UTF8="false" +fi +$rm_try + : see if setlocale_r exists set setlocale_r d_setlocale_r eval $inlibc @@ -24055,6 +24226,7 @@ d_gmtime64='$d_gmtime64' d_gmtime_r='$d_gmtime_r' d_gnulibc='$d_gnulibc' d_grpasswd='$d_grpasswd' +d_has_C_UTF8='$d_has_C_UTF8' d_hasmntopt='$d_hasmntopt' d_htonl='$d_htonl' d_hypot='$d_hypot' @@ -24242,6 +24414,7 @@ d_sethostent_r='$d_sethostent_r' d_setitimer='$d_setitimer' d_setlinebuf='$d_setlinebuf' d_setlocale='$d_setlocale' +d_setlocale_accepts_any_locale_name='$d_setlocale_accepts_any_locale_name' d_setlocale_r='$d_setlocale_r' d_setnent='$d_setnent' d_setnetent_r='$d_setnetent_r' diff --git a/Cross/config.sh-arm-linux b/Cross/config.sh-arm-linux index 2410ca5836..13a1427381 100644 --- a/Cross/config.sh-arm-linux +++ b/Cross/config.sh-arm-linux @@ -492,6 +492,7 @@ d_sethostent_r='undef' d_setitimer='define' d_setlinebuf='define' d_setlocale='define' +d_setlocale_accepts_any_locale_name='undef' d_setlocale_r='undef' d_setnent='define' d_setnetent_r='undef' diff --git a/Cross/config.sh-arm-linux-n770 b/Cross/config.sh-arm-linux-n770 index 6ad6445020..d1e1c30070 100644 --- a/Cross/config.sh-arm-linux-n770 +++ b/Cross/config.sh-arm-linux-n770 @@ -491,6 +491,7 @@ d_sethostent_r='undef' d_setitimer='define' d_setlinebuf='define' d_setlocale='define' +d_setlocale_accepts_any_locale_name='undef' d_setlocale_r='undef' d_setnent='define' d_setnetent_r='undef' diff --git a/NetWare/config.wc b/NetWare/config.wc index c6b909aa1d..9173c9de0f 100644 --- a/NetWare/config.wc +++ b/NetWare/config.wc @@ -481,6 +481,7 @@ d_sethostent_r='undef' d_setitimer='undef' d_setlinebuf='undef' d_setlocale='define' +d_setlocale_accepts_any_locale_name='undef' d_setlocale_r='undef' d_setnent='undef' d_setnetent_r='undef' diff --git a/Porting/config.sh b/Porting/config.sh index 6d38469c32..2a0532df52 100644 --- a/Porting/config.sh +++ b/Porting/config.sh @@ -507,6 +507,7 @@ d_sethostent_r='undef' d_setitimer='define' d_setlinebuf='define' d_setlocale='define' +d_setlocale_accepts_any_locale_name='undef' d_setlocale_r='undef' d_setnent='define' d_setnetent_r='undef' diff --git a/config_h.SH b/config_h.SH index 316c3718c2..f26ed2f3bb 100755 --- a/config_h.SH +++ b/config_h.SH @@ -439,12 +439,6 @@ sed <<!GROK!THIS! >$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un */ #$d_setlinebuf HAS_SETLINEBUF /**/ -/* HAS_SETLOCALE: - * This symbol, if defined, indicates that the setlocale routine is - * available to handle locale-specific ctype implementations. - */ -#$d_setlocale HAS_SETLOCALE /**/ - /* HAS_SETPGID: * This symbol, if defined, indicates that the setpgid(pid, gpid) * routine is available to set process group ID. @@ -3266,6 +3260,17 @@ sed <<!GROK!THIS! >$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un */ #$d_setitimer HAS_SETITIMER /**/ +/* HAS_SETLOCALE: + * This symbol, if defined, indicates that the setlocale routine is + * available to handle locale-specific ctype implementations. + */ +/* SETLOCALE_ACCEPTS_ANY_LOCALE_NAME: + * This symbol, if defined, indicates that the setlocale routine is + * available and it accepts any input locale name as valid. + */ +#$d_setlocale HAS_SETLOCALE /**/ +#$d_setlocale_accepts_any_locale_name SETLOCALE_ACCEPTS_ANY_LOCALE_NAME /**/ + /* HAS_SETPROCTITLE: * This symbol, if defined, indicates that the setproctitle routine is * available to set process title. diff --git a/configure.com b/configure.com index 0140c5cdec..1f3e73c681 100644 --- a/configure.com +++ b/configure.com @@ -5438,6 +5438,7 @@ $ d_mbtowc="define" $ d_mktime="define" $ d_nl_langinfo="define" $ d_setlocale="define" +$ d_setlocale_accepts_any_locale_name="undef" $ d_stdiobase="define" $ d_stdio_cnt_lval="define" $ d_stdio_ptr_lval="define" @@ -6312,6 +6313,7 @@ $ WC "d_sethent='" + d_sethent + "'" $ WC "d_setitimer='" + d_setitimer + "'" $ WC "d_setlinebuf='undef'" $ WC "d_setlocale='" + d_setlocale + "'" +$ WC "d_setlocale_accepts_any_locale_name='" + d_setlocale_accepts_any_locale_name + "'" $ WC "d_setnent='" + d_setnent + "'" $ WC "d_setpent='" + d_setpent + "'" $ WC "d_setpgid='" + d_setpgid + "'" diff --git a/metaconfig.h b/metaconfig.h index 801586243b..73e0ab0257 100644 --- a/metaconfig.h +++ b/metaconfig.h @@ -26,4 +26,5 @@ * I_WCTYPE * HAS_TOWLOWER * HAS_TOWUPPER + * SETLOCALE_ACCEPTS_ANY_LOCALE_NAME */ diff --git a/plan9/config_sh.sample b/plan9/config_sh.sample index c709967081..78bc1daf03 100644 --- a/plan9/config_sh.sample +++ b/plan9/config_sh.sample @@ -492,6 +492,7 @@ d_sethostent_r='undef' d_setitimer='undef' d_setlinebuf='define' d_setlocale='define' +d_setlocale_accepts_any_locale_name='undef' d_setlocale_r='undef' d_setnent='undef' d_setnetent_r='undef' diff --git a/symbian/config.sh b/symbian/config.sh index 655847a5cf..8b3122b286 100644 --- a/symbian/config.sh +++ b/symbian/config.sh @@ -439,6 +439,7 @@ d_sethostent_r='undef' d_setitimer='undef' d_setlinebuf='undef' d_setlocale='undef' +d_setlocale_accepts_any_locale_name='undef' d_setlocale_r='undef' d_setnent='undef' d_setnetent_r='undef' @@ -404,12 +404,6 @@ */ /*#define HAS_SETLINEBUF / **/ -/* HAS_SETLOCALE: - * This symbol, if defined, indicates that the setlocale routine is - * available to handle locale-specific ctype implementations. - */ -/*#define HAS_SETLOCALE / **/ - /* HAS_SETPGID: * This symbol, if defined, indicates that the setpgid(pid, gpid) * routine is available to set process group ID. @@ -3231,6 +3225,17 @@ */ /*#define HAS_SETITIMER / **/ +/* HAS_SETLOCALE: + * This symbol, if defined, indicates that the setlocale routine is + * available to handle locale-specific ctype implementations. + */ +/* SETLOCALE_ACCEPTS_ANY_LOCALE_NAME: + * This symbol, if defined, indicates that the setlocale routine is + * available and it accepts any input locale name as valid. + */ +/*#define HAS_SETLOCALE / **/ +/*#define SETLOCALE_ACCEPTS_ANY_LOCALE_NAME / **/ + /* HAS_SETPROCTITLE: * This symbol, if defined, indicates that the setproctitle routine is * available to set process title. @@ -5236,6 +5241,6 @@ #endif /* Generated from: - * 5ad5aeb4fcee5fe869bed0368fc2430fdf0ad7011927820be7d0e6fa076334c5 config_h.SH - * 2caca0ed689d83f195e6d1887fcf6a1702cceaa595de14be09580f91d06f5d62 uconfig.sh + * 2cc5c49f1266887de8224d2804aae6f80c43da0a62782d74866d5e828194698d config_h.SH + * d6d2fc8bf209b3d6db681ac0994a29a281afe35c3a96bb62079cb15b0605d035 uconfig.sh * ex: set ro: */ diff --git a/uconfig.sh b/uconfig.sh index 3367267a41..f55def4255 100644 --- a/uconfig.sh +++ b/uconfig.sh @@ -432,6 +432,7 @@ d_sethostent_r='undef' d_setitimer='undef' d_setlinebuf='undef' d_setlocale='undef' +d_setlocale_accepts_any_locale_name='undef' d_setlocale_r='undef' d_setnent='undef' d_setnetent_r='undef' diff --git a/uconfig64.sh b/uconfig64.sh index b6d3f8230e..bfc6049b74 100644 --- a/uconfig64.sh +++ b/uconfig64.sh @@ -432,6 +432,7 @@ d_sethostent_r='undef' d_setitimer='undef' d_setlinebuf='undef' d_setlocale='undef' +d_setlocale_accepts_any_locale_name='undef' d_setlocale_r='undef' d_setnent='undef' d_setnetent_r='undef' diff --git a/win32/config.ce b/win32/config.ce index 8bf862a502..d8eb67d17b 100644 --- a/win32/config.ce +++ b/win32/config.ce @@ -479,6 +479,7 @@ d_sethostent_r='undef' d_setitimer='undef' d_setlinebuf='undef' d_setlocale='define' +d_setlocale_accepts_any_locale_name='undef' d_setlocale_r='undef' d_setnent='undef' d_setnetent_r='undef' diff --git a/win32/config.gc b/win32/config.gc index d5697e35f4..66de52d7c0 100644 --- a/win32/config.gc +++ b/win32/config.gc @@ -480,6 +480,7 @@ d_sethostent_r='undef' d_setitimer='undef' d_setlinebuf='undef' d_setlocale='define' +d_setlocale_accepts_any_locale_name='undef' d_setlocale_r='undef' d_setnent='undef' d_setnetent_r='undef' diff --git a/win32/config.vc b/win32/config.vc index 676f25506e..5ece80459a 100644 --- a/win32/config.vc +++ b/win32/config.vc @@ -480,6 +480,7 @@ d_sethostent_r='undef' d_setitimer='undef' d_setlinebuf='undef' d_setlocale='define' +d_setlocale_accepts_any_locale_name='undef' d_setlocale_r='undef' d_setnent='undef' d_setnetent_r='undef' |