>From 756370637a184426d4834b47cd653fc7fee296f5 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sat, 25 Jan 2020 21:17:51 +0100 Subject: [PATCH 1/3] iswxdigit: New module. * m4/iswxdigit.m4: New file. * lib/wctype.in.h (iswxdigit): Potentially override. (iswxdigit, rpl_iswxdigit): Test REPLACE_ISWXDIGIT, not REPLACE_ISWCNTRL. Rely on ISO C compliant definition. * lib/iswxdigit.c: New file. * m4/wctype_h.m4 (gl_WCTYPE_H_DEFAULTS): Initialize GNULIB_ISWXDIGIT, REPLACE_ISWXDIGIT. * modules/wctype-h (Makefile.am): Substitute GNULIB_ISWXDIGIT, REPLACE_ISWXDIGIT. * modules/iswxdigit: New file. * doc/posix-functions/iswxdigit.texi: Mention the portability problem. --- ChangeLog | 15 +++++ doc/posix-functions/iswxdigit.texi | 3 + lib/iswxdigit.c | 33 +++++++++++ lib/wctype.in.h | 19 ++++++- m4/iswxdigit.m4 | 113 +++++++++++++++++++++++++++++++++++++ m4/wctype_h.m4 | 4 +- modules/iswxdigit | 35 ++++++++++++ modules/wctype-h | 2 + 8 files changed, 220 insertions(+), 4 deletions(-) create mode 100644 lib/iswxdigit.c create mode 100644 m4/iswxdigit.m4 create mode 100644 modules/iswxdigit diff --git a/ChangeLog b/ChangeLog index c70358c..e6c875b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,20 @@ 2020-01-25 Bruno Haible + iswxdigit: New module. + * m4/iswxdigit.m4: New file. + * lib/wctype.in.h (iswxdigit): Potentially override. + (iswxdigit, rpl_iswxdigit): Test REPLACE_ISWXDIGIT, not + REPLACE_ISWCNTRL. Rely on ISO C compliant definition. + * lib/iswxdigit.c: New file. + * m4/wctype_h.m4 (gl_WCTYPE_H_DEFAULTS): Initialize GNULIB_ISWXDIGIT, + REPLACE_ISWXDIGIT. + * modules/wctype-h (Makefile.am): Substitute GNULIB_ISWXDIGIT, + REPLACE_ISWXDIGIT. + * modules/iswxdigit: New file. + * doc/posix-functions/iswxdigit.texi: Mention the portability problem. + +2020-01-25 Bruno Haible + lseek: Fix the override to not undo the effects of AC_SYS_LARGEFILE. Reported by John Donoghue in . diff --git a/doc/posix-functions/iswxdigit.texi b/doc/posix-functions/iswxdigit.texi index bdce3b4..705c829 100644 --- a/doc/posix-functions/iswxdigit.texi +++ b/doc/posix-functions/iswxdigit.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, MSVC 14. @end itemize Portability problems not fixed by Gnulib: diff --git a/lib/iswxdigit.c b/lib/iswxdigit.c new file mode 100644 index 0000000..5c1c182 --- /dev/null +++ b/lib/iswxdigit.c @@ -0,0 +1,33 @@ +/* Test wide character for being a hexadecimal 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 +iswxdigit (wint_t wc) +{ + return ((wc >= '0' && wc <= '9') +#if 'A' == 0x41 && 'a' == 0x61 + /* Optimization, assuming ASCII */ + || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'F') +#else + || (wc >= 'A' && wc <= 'F') || (wc >= 'a' && wc <= 'f') +#endif + ); +} diff --git a/lib/wctype.in.h b/lib/wctype.in.h index 09dbb55..5d266d9 100644 --- a/lib/wctype.in.h +++ b/lib/wctype.in.h @@ -210,7 +210,10 @@ rpl_iswupper (wint_t wc) _GL_WCTYPE_INLINE int rpl_iswxdigit (wint_t wc) { - return ((wchar_t) wc == wc ? iswxdigit ((wchar_t) wc) : 0); + return ((wchar_t) wc == wc + ? (wc >= '0' && wc <= '9') + || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'F') + : 0); } _GL_WCTYPE_INLINE wint_t @@ -428,7 +431,7 @@ iswupper } _GL_WCTYPE_INLINE int -# if @REPLACE_ISWCNTRL@ +# if @REPLACE_ISWXDIGIT@ rpl_iswxdigit # else iswxdigit @@ -488,6 +491,16 @@ _GL_FUNCDECL_RPL (iswdigit, int, (wint_t wc)); # endif # endif +# if @GNULIB_ISWXDIGIT@ +# if @REPLACE_ISWXDIGIT@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef iswxdigit +# define iswxdigit rpl_iswxdigit +# endif +_GL_FUNCDECL_RPL (iswxdigit, int, (wint_t wc)); +# endif +# endif + # endif # if defined __MINGW32__ && !@GNULIB_OVERRIDES_WINT_T@ @@ -578,7 +591,7 @@ _GL_CXXALIAS_RPL (iswupper, int, (wint_t wc)); #else _GL_CXXALIAS_SYS (iswupper, int, (wint_t wc)); #endif -#if @REPLACE_ISWCNTRL@ +#if @REPLACE_ISWXDIGIT@ _GL_CXXALIAS_RPL (iswxdigit, int, (wint_t wc)); #else _GL_CXXALIAS_SYS (iswxdigit, int, (wint_t wc)); diff --git a/m4/iswxdigit.m4 b/m4/iswxdigit.m4 new file mode 100644 index 0000000..8219013 --- /dev/null +++ b/m4/iswxdigit.m4 @@ -0,0 +1,113 @@ +# iswxdigit.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_ISWXDIGIT], +[ + AC_REQUIRE([gl_WCTYPE_H_DEFAULTS]) + AC_REQUIRE([gl_WCTYPE_H]) + 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 iswxdigit already. + REPLACE_ISWXDIGIT="$REPLACE_ISWCNTRL" + else + AC_CACHE_CHECK([whether iswxdigit is ISO C compliant], + [gl_cv_func_iswxdigit_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_iswxdigit_works="guessing no" ;; + # Guess yes otherwise. + *) gl_cv_func_iswxdigit_works="guessing yes" ;; + esac +changequote([,])dnl + if 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 iswxdigit 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 iswxdigit (wc); +} + +int +main (int argc, char *argv[]) +{ + int is; + int result = 0; + + if (setlocale (LC_ALL, "$LOCALE_JA") != NULL) + { + /* This fails on NetBSD 8.0. */ + /* U+FF21 FULLWIDTH LATIN CAPITAL LETTER A */ + is = for_character ("\243\301", 2); + if (!(is == 0)) + result |= 1; + } + if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) + { + /* This fails on FreeBSD 12. */ + /* U+0663 ARABIC-INDIC DIGIT THREE */ + is = for_character ("\331\243", 2); + if (!(is == 0)) + result |= 2; + /* This fails on MSVC 14. */ + /* U+FF21 FULLWIDTH LATIN CAPITAL LETTER A */ + is = for_character ("\357\274\241", 3); + if (!(is == 0)) + result |= 4; + } + if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL) + { + /* This fails on Solaris 10, Solaris 11.4. */ + /* U+FF11 FULLWIDTH DIGIT ONE */ + is = for_character ("\243\261", 2); + if (!(is == 0)) + result |= 8; + } + return result; +}]])], + [gl_cv_func_iswxdigit_works=yes], + [gl_cv_func_iswxdigit_works=no], + [:]) + fi + ]) + case "$gl_cv_func_iswxdigit_works" in + *yes) ;; + *) REPLACE_ISWXDIGIT=1 ;; + esac + fi +]) diff --git a/m4/wctype_h.m4 b/m4/wctype_h.m4 index 24bad38..5c844b6 100644 --- a/m4/wctype_h.m4 +++ b/m4/wctype_h.m4 @@ -1,4 +1,4 @@ -# wctype_h.m4 serial 23 +# wctype_h.m4 serial 24 dnl A placeholder for ISO C99 , for platforms that lack it. @@ -205,6 +205,7 @@ AC_DEFUN([gl_WCTYPE_H_DEFAULTS], [ GNULIB_ISWBLANK=0; AC_SUBST([GNULIB_ISWBLANK]) GNULIB_ISWDIGIT=0; AC_SUBST([GNULIB_ISWDIGIT]) + GNULIB_ISWXDIGIT=0; AC_SUBST([GNULIB_ISWXDIGIT]) GNULIB_WCTYPE=0; AC_SUBST([GNULIB_WCTYPE]) GNULIB_ISWCTYPE=0; AC_SUBST([GNULIB_ISWCTYPE]) GNULIB_WCTRANS=0; AC_SUBST([GNULIB_WCTRANS]) @@ -215,4 +216,5 @@ AC_DEFUN([gl_WCTYPE_H_DEFAULTS], HAVE_WCTRANS_T=1; AC_SUBST([HAVE_WCTRANS_T]) REPLACE_ISWBLANK=0; AC_SUBST([REPLACE_ISWBLANK]) REPLACE_ISWDIGIT=0; AC_SUBST([REPLACE_ISWDIGIT]) + REPLACE_ISWXDIGIT=0; AC_SUBST([REPLACE_ISWXDIGIT]) ]) diff --git a/modules/iswxdigit b/modules/iswxdigit new file mode 100644 index 0000000..b25b31d --- /dev/null +++ b/modules/iswxdigit @@ -0,0 +1,35 @@ +Description: +iswxdigit() function: test wide character for being a hexadecimal digit. + +Files: +lib/iswxdigit.c +m4/iswxdigit.m4 +m4/locale-fr.m4 +m4/locale-ja.m4 +m4/locale-zh.m4 +m4/codeset.m4 + +Depends-on: +wctype-h + +configure.ac: +gl_FUNC_ISWXDIGIT +if test $HAVE_ISWCNTRL = 0 || test $REPLACE_ISWCNTRL = 1; then + : +else + if test $REPLACE_ISWXDIGIT = 1; then + AC_LIBOBJ([iswxdigit]) + fi +fi +gl_WCTYPE_MODULE_INDICATOR([iswxdigit]) + +Makefile.am: + +Include: + + +License: +LGPLv2+ + +Maintainer: +Bruno Haible diff --git a/modules/wctype-h b/modules/wctype-h index 58f4e51..b7aef46 100644 --- a/modules/wctype-h +++ b/modules/wctype-h @@ -35,6 +35,7 @@ wctype.h: wctype.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H -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_ISWXDIGIT''@/$(GNULIB_ISWXDIGIT)/g' \ -e 's/@''GNULIB_WCTYPE''@/$(GNULIB_WCTYPE)/g' \ -e 's/@''GNULIB_ISWCTYPE''@/$(GNULIB_ISWCTYPE)/g' \ -e 's/@''GNULIB_WCTRANS''@/$(GNULIB_WCTRANS)/g' \ @@ -46,6 +47,7 @@ wctype.h: wctype.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H -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_ISWXDIGIT''@/$(REPLACE_ISWXDIGIT)/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