>From 36a9ca3f924853f22af5ac5228c35ca81bddf6cf Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sat, 25 Jan 2020 16:03:15 +0100 Subject: [PATCH 1/3] iswdigit: New module. * m4/iswdigit.m4: New file. * lib/wctype.in.h (iswdigit): Potentially override. (iswdigit, rpl_iswdigit): Test REPLACE_ISWDIGIT, not REPLACE_ISWCNTRL. * lib/iswdigit.c: New file. * m4/wctype_h.m4 (gl_WCTYPE_H_DEFAULTS): Initialize GNULIB_ISWDIGIT, REPLACE_ISWDIGIT. * modules/wctype-h (Makefile.am): Substitute GNULIB_ISWDIGIT, REPLACE_ISWDIGIT. * modules/iswdigit: New file. * doc/posix-functions/iswdigit.texi: Mention the portability problem. --- ChangeLog | 14 +++++ doc/posix-functions/iswdigit.texi | 3 + lib/iswdigit.c | 26 ++++++++ lib/wctype.in.h | 79 ++++++++++++++++++------ m4/iswdigit.m4 | 122 ++++++++++++++++++++++++++++++++++++++ m4/wctype_h.m4 | 4 +- modules/iswdigit | 31 ++++++++++ modules/wctype-h | 2 + 8 files changed, 262 insertions(+), 19 deletions(-) create mode 100644 lib/iswdigit.c create mode 100644 m4/iswdigit.m4 create mode 100644 modules/iswdigit diff --git a/ChangeLog b/ChangeLog index 88285ee..75bf56e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,19 @@ 2020-01-25 Bruno Haible + iswdigit: New module. + * m4/iswdigit.m4: New file. + * lib/wctype.in.h (iswdigit): Potentially override. + (iswdigit, rpl_iswdigit): Test REPLACE_ISWDIGIT, not REPLACE_ISWCNTRL. + * lib/iswdigit.c: New file. + * m4/wctype_h.m4 (gl_WCTYPE_H_DEFAULTS): Initialize GNULIB_ISWDIGIT, + REPLACE_ISWDIGIT. + * modules/wctype-h (Makefile.am): Substitute GNULIB_ISWDIGIT, + REPLACE_ISWDIGIT. + * modules/iswdigit: New file. + * doc/posix-functions/iswdigit.texi: Mention the portability problem. + +2020-01-25 Bruno Haible + hard-locale tests: Make it easy to reuse the musl test. * m4/musl.m4: New file, extracted from modules/hard-locale-tests. * modules/hard-locale-tests (Files): Add it. diff --git a/doc/posix-functions/iswdigit.texi b/doc/posix-functions/iswdigit.texi index c4b80c2..3bf89e2 100644 --- a/doc/posix-functions/iswdigit.texi +++ b/doc/posix-functions/iswdigit.texi @@ -15,6 +15,9 @@ Minix 3.1.8. This function cannot be called from plain inline or extern inline functions on some platforms: OS X 10.8. +@item +This function is not ISO C 99 compliant on some platforms: +FreeBSD 12, NetBSD 8.0, Solaris 11.4, mingw, MSVC 14. @end itemize Portability problems not fixed by Gnulib: diff --git a/lib/iswdigit.c b/lib/iswdigit.c new file mode 100644 index 0000000..4fd27e3 --- /dev/null +++ b/lib/iswdigit.c @@ -0,0 +1,26 @@ +/* Test wide character for being a digit. + Copyright (C) 2020 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, see . */ + +#include + +/* Specification. */ +#include + +int +iswdigit (wint_t wc) +{ + return wc >= '0' && wc <= '9'; +} diff --git a/lib/wctype.in.h b/lib/wctype.in.h index 7e7726f..d9a4379 100644 --- a/lib/wctype.in.h +++ b/lib/wctype.in.h @@ -348,7 +348,7 @@ iswcntrl } _GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ +# if @REPLACE_ISWDIGIT@ rpl_iswdigit # else iswdigit @@ -463,16 +463,29 @@ towupper # endif -# elif @GNULIB_ISWBLANK@ && (! @HAVE_ISWBLANK@ || @REPLACE_ISWBLANK@) -/* Only the iswblank function is missing. */ +# else +/* Only some of the functions are missing or broken. */ -# if @REPLACE_ISWBLANK@ -# if !(defined __cplusplus && defined GNULIB_NAMESPACE) -# define iswblank rpl_iswblank -# endif +# if @GNULIB_ISWBLANK@ && (! @HAVE_ISWBLANK@ || @REPLACE_ISWBLANK@) +/* Only the iswblank function is missing. */ +# if @REPLACE_ISWBLANK@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define iswblank rpl_iswblank +# endif _GL_FUNCDECL_RPL (iswblank, int, (wint_t wc)); -# else +# else _GL_FUNCDECL_SYS (iswblank, int, (wint_t wc)); +# endif +# endif + +# if @GNULIB_ISWDIGIT@ +# if @REPLACE_ISWDIGIT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef iswdigit +# define iswdigit rpl_iswdigit +# endif +_GL_FUNCDECL_RPL (iswdigit, int, (wint_t wc)); +# endif # endif # endif @@ -517,27 +530,57 @@ rpl_towupper (wint_t wc) #if @REPLACE_ISWCNTRL@ _GL_CXXALIAS_RPL (iswalnum, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswalpha, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswcntrl, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswdigit, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswgraph, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswlower, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswprint, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswpunct, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswspace, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswupper, int, (wint_t wc)); -_GL_CXXALIAS_RPL (iswxdigit, int, (wint_t wc)); #else _GL_CXXALIAS_SYS (iswalnum, int, (wint_t wc)); +#endif +#if @REPLACE_ISWCNTRL@ +_GL_CXXALIAS_RPL (iswalpha, int, (wint_t wc)); +#else _GL_CXXALIAS_SYS (iswalpha, int, (wint_t wc)); +#endif +#if @REPLACE_ISWCNTRL@ +_GL_CXXALIAS_RPL (iswcntrl, int, (wint_t wc)); +#else _GL_CXXALIAS_SYS (iswcntrl, int, (wint_t wc)); +#endif +#if @REPLACE_ISWDIGIT@ +_GL_CXXALIAS_RPL (iswdigit, int, (wint_t wc)); +#else _GL_CXXALIAS_SYS (iswdigit, int, (wint_t wc)); +#endif +#if @REPLACE_ISWCNTRL@ +_GL_CXXALIAS_RPL (iswgraph, int, (wint_t wc)); +#else _GL_CXXALIAS_SYS (iswgraph, int, (wint_t wc)); +#endif +#if @REPLACE_ISWCNTRL@ +_GL_CXXALIAS_RPL (iswlower, int, (wint_t wc)); +#else _GL_CXXALIAS_SYS (iswlower, int, (wint_t wc)); +#endif +#if @REPLACE_ISWCNTRL@ +_GL_CXXALIAS_RPL (iswprint, int, (wint_t wc)); +#else _GL_CXXALIAS_SYS (iswprint, int, (wint_t wc)); +#endif +#if @REPLACE_ISWCNTRL@ +_GL_CXXALIAS_RPL (iswpunct, int, (wint_t wc)); +#else _GL_CXXALIAS_SYS (iswpunct, int, (wint_t wc)); +#endif +#if @REPLACE_ISWCNTRL@ +_GL_CXXALIAS_RPL (iswspace, int, (wint_t wc)); +#else _GL_CXXALIAS_SYS (iswspace, int, (wint_t wc)); +#endif +#if @REPLACE_ISWCNTRL@ +_GL_CXXALIAS_RPL (iswupper, int, (wint_t wc)); +#else _GL_CXXALIAS_SYS (iswupper, int, (wint_t wc)); +#endif +#if @REPLACE_ISWCNTRL@ +_GL_CXXALIAS_RPL (iswxdigit, int, (wint_t wc)); +#else _GL_CXXALIAS_SYS (iswxdigit, int, (wint_t wc)); #endif #if __GLIBC__ >= 2 diff --git a/m4/iswdigit.m4 b/m4/iswdigit.m4 new file mode 100644 index 0000000..5f15c39 --- /dev/null +++ b/m4/iswdigit.m4 @@ -0,0 +1,122 @@ +# iswdigit.m4 serial 1 +dnl Copyright (C) 2020 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_ISWDIGIT], +[ + AC_REQUIRE([gl_WCTYPE_H_DEFAULTS]) + AC_REQUIRE([gl_WCTYPE_H]) + AC_REQUIRE([gt_LOCALE_FR]) + AC_REQUIRE([gt_LOCALE_JA]) + AC_REQUIRE([gt_LOCALE_FR_UTF8]) + AC_REQUIRE([gt_LOCALE_ZH_CN]) + + if test $HAVE_ISWCNTRL = 0 || test $REPLACE_ISWCNTRL = 1; then + dnl redefines iswdigit already. + REPLACE_ISWDIGIT="$REPLACE_ISWCNTRL" + else + AC_CACHE_CHECK([whether iswdigit is ISO C compliant], + [gl_cv_func_iswdigit_works], + [ + dnl Initial guess, used when cross-compiling or when no suitable locale + dnl is present. +changequote(,)dnl + case "$host_os" in + # Guess no on FreeBSD, NetBSD, Solaris, native Windows. + freebsd* | dragonfly* | netbsd* | solaris* | mingw*) + gl_cv_func_iswdigit_works="guessing no" ;; + # Guess yes otherwise. + *) gl_cv_func_iswdigit_works="guessing yes" ;; + esac +changequote([,])dnl + if test $LOCALE_FR != none || test $LOCALE_JA != none || test $LOCALE_FR_UTF8 != none || test $LOCALE_ZH_CN != none; then + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +#include +/* Tru64 with Desktop Toolkit C has a bug: must be included before + . + BSD/OS 4.0.1 has a bug: , and must be + included before . */ +#include +#include +#include +#include +#include + +/* Returns the value of iswdigit for the multibyte character s[0..n-1]. */ +static int +for_character (const char *s, size_t n) +{ + mbstate_t state; + wchar_t wc; + size_t ret; + + memset (&state, '\0', sizeof (mbstate_t)); + wc = (wchar_t) 0xBADFACE; + ret = mbrtowc (&wc, s, n, &state); + if (ret != n) + abort (); + + return iswdigit (wc); +} + +int +main (int argc, char *argv[]) +{ + int is; + int result = 0; + + if (setlocale (LC_ALL, "$LOCALE_FR") != NULL) + { + /* This fails on mingw, MSVC 14. */ + /* U+00B2 SUPERSCRIPT TWO */ + is = for_character ("\262", 1); + if (!(is == 0)) + result |= 1; + } + if (setlocale (LC_ALL, "$LOCALE_JA") != NULL) + { + /* This fails on NetBSD 8.0. */ + /* U+FF11 FULLWIDTH DIGIT ONE */ + is = for_character ("\243\261", 2); + if (!(is == 0)) + result |= 2; + } + if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) + { + /* This fails on FreeBSD 12, NetBSD 8.0, MSVC 14. */ + /* U+0663 ARABIC-INDIC DIGIT THREE */ + is = for_character ("\331\243", 2); + if (!(is == 0)) + result |= 4; + /* This fails on FreeBSD 12, NetBSD 8.0, MSVC 14. */ + /* U+FF11 FULLWIDTH DIGIT ONE */ + is = for_character ("\357\274\221", 3); + if (!(is == 0)) + result |= 8; + } + if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL) + { + /* This fails on NetBSD 8.0, Solaris 10, Solaris 11.4. */ + /* U+FF11 FULLWIDTH DIGIT ONE */ + is = for_character ("\243\261", 2); + if (!(is == 0)) + result |= 16; + } + return result; +}]])], + [gl_cv_func_iswdigit_works=yes], + [gl_cv_func_iswdigit_works=no], + [:]) + fi + ]) + case "$gl_cv_func_iswdigit_works" in + *yes) ;; + *) REPLACE_ISWDIGIT=1 ;; + esac + fi +]) diff --git a/m4/wctype_h.m4 b/m4/wctype_h.m4 index dc854e6..24bad38 100644 --- a/m4/wctype_h.m4 +++ b/m4/wctype_h.m4 @@ -1,4 +1,4 @@ -# wctype_h.m4 serial 22 +# wctype_h.m4 serial 23 dnl A placeholder for ISO C99 , for platforms that lack it. @@ -204,6 +204,7 @@ AC_DEFUN([gl_WCTYPE_MODULE_INDICATOR], AC_DEFUN([gl_WCTYPE_H_DEFAULTS], [ GNULIB_ISWBLANK=0; AC_SUBST([GNULIB_ISWBLANK]) + GNULIB_ISWDIGIT=0; AC_SUBST([GNULIB_ISWDIGIT]) GNULIB_WCTYPE=0; AC_SUBST([GNULIB_WCTYPE]) GNULIB_ISWCTYPE=0; AC_SUBST([GNULIB_ISWCTYPE]) GNULIB_WCTRANS=0; AC_SUBST([GNULIB_WCTRANS]) @@ -213,4 +214,5 @@ AC_DEFUN([gl_WCTYPE_H_DEFAULTS], HAVE_WCTYPE_T=1; AC_SUBST([HAVE_WCTYPE_T]) HAVE_WCTRANS_T=1; AC_SUBST([HAVE_WCTRANS_T]) REPLACE_ISWBLANK=0; AC_SUBST([REPLACE_ISWBLANK]) + REPLACE_ISWDIGIT=0; AC_SUBST([REPLACE_ISWDIGIT]) ]) diff --git a/modules/iswdigit b/modules/iswdigit new file mode 100644 index 0000000..2098870 --- /dev/null +++ b/modules/iswdigit @@ -0,0 +1,31 @@ +Description: +iswdigit() function: test wide character for being a digit. + +Files: +lib/iswdigit.c +m4/iswdigit.m4 + +Depends-on: +wctype-h + +configure.ac: +gl_FUNC_ISWDIGIT +if test $HAVE_ISWCNTRL = 0 || test $REPLACE_ISWCNTRL = 1; then + : +else + if test $REPLACE_ISWDIGIT = 1; then + AC_LIBOBJ([iswdigit]) + fi +fi +gl_WCTYPE_MODULE_INDICATOR([iswdigit]) + +Makefile.am: + +Include: + + +License: +LGPLv2+ + +Maintainer: +Bruno Haible diff --git a/modules/wctype-h b/modules/wctype-h index 37bccce..58f4e51 100644 --- a/modules/wctype-h +++ b/modules/wctype-h @@ -34,6 +34,7 @@ wctype.h: wctype.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H -e 's/@''HAVE_CRTDEFS_H''@/$(HAVE_CRTDEFS_H)/g' \ -e 's/@''GNULIB_OVERRIDES_WINT_T''@/$(GNULIB_OVERRIDES_WINT_T)/g' \ -e 's/@''GNULIB_ISWBLANK''@/$(GNULIB_ISWBLANK)/g' \ + -e 's/@''GNULIB_ISWDIGIT''@/$(GNULIB_ISWDIGIT)/g' \ -e 's/@''GNULIB_WCTYPE''@/$(GNULIB_WCTYPE)/g' \ -e 's/@''GNULIB_ISWCTYPE''@/$(GNULIB_ISWCTYPE)/g' \ -e 's/@''GNULIB_WCTRANS''@/$(GNULIB_WCTRANS)/g' \ @@ -44,6 +45,7 @@ wctype.h: wctype.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H -e 's/@''HAVE_WCTRANS_T''@/$(HAVE_WCTRANS_T)/g' \ -e 's/@''HAVE_WINT_T''@/$(HAVE_WINT_T)/g' \ -e 's/@''REPLACE_ISWBLANK''@/$(REPLACE_ISWBLANK)/g' \ + -e 's/@''REPLACE_ISWDIGIT''@/$(REPLACE_ISWDIGIT)/g' \ -e 's/@''REPLACE_ISWCNTRL''@/$(REPLACE_ISWCNTRL)/g' \ -e 's/@''REPLACE_TOWLOWER''@/$(REPLACE_TOWLOWER)/g' \ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ -- 2.7.4