* lib/wctype.in.h (iswpunct): New declaration.
* lib/iswpunct.c: New file.
* m4/iswpunct.m4: New file.
* m4/wctype_h.m4 (gl_WCTYPE_H_REQUIRE_DEFAULTS): Initialize
GNULIB_ISWPUNCT.
(gl_WCTYPE_H_DEFAULTS): Initialize REPLACE_ISWPUNCT.
* modules/wctype-h (Makefile.am): Substitute GNULIB_ISWPUNCT,
REPLACE_ISWPUNCT.
* modules/iswpunct: New file.
* doc/posix-functions/iswpunct.texi: Mention the new module.
2023-08-29 Bruno Haible <bruno@clisp.org>
+ iswpunct: New module.
+ * lib/wctype.in.h (iswpunct): New declaration.
+ * lib/iswpunct.c: New file.
+ * m4/iswpunct.m4: New file.
+ * m4/wctype_h.m4 (gl_WCTYPE_H_REQUIRE_DEFAULTS): Initialize
+ GNULIB_ISWPUNCT.
+ (gl_WCTYPE_H_DEFAULTS): Initialize REPLACE_ISWPUNCT.
+ * modules/wctype-h (Makefile.am): Substitute GNULIB_ISWPUNCT,
+ REPLACE_ISWPUNCT.
+ * modules/iswpunct: New file.
+ * doc/posix-functions/iswpunct.texi: Mention the new module.
+
wctype-h tests: Add more tests.
* tests/test-wctype-h.c (main): Add a sanity check of iswpunct.
POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9699919799/functions/iswpunct.html}
-Gnulib module: wctype-h
+Gnulib module: iswpunct
Portability problems fixed by Gnulib:
@itemize
This function cannot be called from plain inline or extern inline functions
on some platforms:
OS X 10.8.
+@item
+This function is inconsistent with the @code{ispunct} function, because it
+returns false for the characters @code{'$'}, @code{'+'}, @code{'<'},
+@code{'='}, @code{'>'}, @code{'^'}, @code{'`'} , @code{'|'}, @code{'~'}
+on some platforms:
+Android 11.
@end itemize
Portability problems not fixed by Gnulib:
--- /dev/null
+/* Test wide character for being a punctuation or symbol character.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This file is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ This file 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <wctype.h>
+
+#include <ctype.h>
+
+int
+iswpunct (wint_t wc)
+#undef iswpunct
+{
+#if defined __ANDROID__
+ if ((unsigned int) wc < 128)
+ return ispunct ((unsigned int) wc);
+#endif
+ return iswpunct (wc);
+}
Linux libc5 has <wctype.h> and the functions but they are broken.
mingw and MSVC have <wctype.h> and the functions but they take a wchar_t
as argument, not an rpl_wint_t. Additionally, the mingw iswprint function
- is broken.
+ and the Android iswpunct function are broken.
Assume all 11 functions (all isw* except iswblank) are implemented the
same way, or not at all. */
# if ! @HAVE_ISWCNTRL@ || @REPLACE_ISWCNTRL@
# endif
# endif
+# if @GNULIB_ISWPUNCT@
+# if @REPLACE_ISWPUNCT@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# undef iswpunct
+# define iswpunct rpl_iswpunct
+# endif
+_GL_FUNCDECL_RPL (iswpunct, int, (wint_t wc));
+# endif
+# endif
+
# if @GNULIB_ISWXDIGIT@
# if @REPLACE_ISWXDIGIT@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
--- /dev/null
+# iswpunct.m4 serial 1
+dnl Copyright (C) 2023 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_ISWPUNCT],
+[
+ AC_REQUIRE([gl_WCTYPE_H_DEFAULTS])
+ AC_REQUIRE([gl_WCTYPE_H])
+
+ if test $HAVE_ISWCNTRL = 0 || test $REPLACE_ISWCNTRL = 1; then
+ dnl <wctype.h> redefines iswpunct already.
+ REPLACE_ISWPUNCT="$REPLACE_ISWCNTRL"
+ else
+ AC_CACHE_CHECK([whether iswpunct is consistent with ispunct],
+ [gl_cv_func_iswpunct_works],
+ [AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
+#include <ctype.h>
+#include <wchar.h>
+#include <wctype.h>
+int
+main (int argc, char *argv[])
+{
+ int result = 0;
+ /* This fails on Android 11. */
+ if ((! iswpunct ('\`')) != (! ispunct ('\`')))
+ result |= 1;
+ return result;
+}]])],
+ [gl_cv_func_iswpunct_works=yes],
+ [gl_cv_func_iswpunct_works=no],
+ [case "$host_os" in
+ # Guess no on Android.
+ android*) gl_cv_func_iswpunct_works="guessing no" ;;
+ # Guess yes otherwise.
+ *) gl_cv_func_iswpunct_works="guessing yes" ;;
+ esac
+ ])
+ ])
+ case "$gl_cv_func_iswpunct_works" in
+ *yes) ;;
+ *) REPLACE_ISWPUNCT=1 ;;
+ esac
+ fi
+])
-# wctype_h.m4 serial 32
+# wctype_h.m4 serial 33
dnl A placeholder for ISO C99 <wctype.h>, for platforms that lack it.
m4_defun(GL_MODULE_INDICATOR_PREFIX[_WCTYPE_H_MODULE_INDICATOR_DEFAULTS], [
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISWBLANK])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISWDIGIT])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISWPUNCT])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISWXDIGIT])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_WCTYPE])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISWCTYPE])
HAVE_WCTRANS_T=1; AC_SUBST([HAVE_WCTRANS_T])
REPLACE_ISWBLANK=0; AC_SUBST([REPLACE_ISWBLANK])
REPLACE_ISWDIGIT=0; AC_SUBST([REPLACE_ISWDIGIT])
+ REPLACE_ISWPUNCT=0; AC_SUBST([REPLACE_ISWPUNCT])
REPLACE_ISWXDIGIT=0; AC_SUBST([REPLACE_ISWXDIGIT])
REPLACE_WCTRANS=0; AC_SUBST([REPLACE_WCTRANS])
REPLACE_WCTYPE=0; AC_SUBST([REPLACE_WCTYPE])
--- /dev/null
+Description:
+iswpunct() function: test wide character for being a punctuation or symbol
+character.
+
+Files:
+lib/iswpunct.c
+m4/iswpunct.m4
+
+Depends-on:
+wctype-h
+
+configure.ac:
+gl_FUNC_ISWPUNCT
+gl_CONDITIONAL([GL_COND_OBJ_ISWPUNCT],
+ [! { test $HAVE_ISWCNTRL = 0 || test $REPLACE_ISWCNTRL = 1; } && test $REPLACE_ISWPUNCT = 1])
+gl_WCTYPE_MODULE_INDICATOR([iswpunct])
+
+Makefile.am:
+if GL_COND_OBJ_ISWPUNCT
+lib_SOURCES += iswpunct.c
+endif
+
+Include:
+<wctype.h>
+
+License:
+LGPLv2+
+
+Maintainer:
+Bruno Haible
-e 's/@''GNULIBHEADERS_OVERRIDE_WINT_T''@/$(GNULIBHEADERS_OVERRIDE_WINT_T)/g' \
-e 's/@''GNULIB_ISWBLANK''@/$(GNULIB_ISWBLANK)/g' \
-e 's/@''GNULIB_ISWDIGIT''@/$(GNULIB_ISWDIGIT)/g' \
+ -e 's/@''GNULIB_ISWPUNCT''@/$(GNULIB_ISWPUNCT)/g' \
-e 's/@''GNULIB_ISWXDIGIT''@/$(GNULIB_ISWXDIGIT)/g' \
-e 's/@''GNULIB_WCTYPE''@/$(GNULIB_WCTYPE)/g' \
-e 's/@''GNULIB_ISWCTYPE''@/$(GNULIB_ISWCTYPE)/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_ISWPUNCT''@/$(REPLACE_ISWPUNCT)/g' \
-e 's/@''REPLACE_ISWXDIGIT''@/$(REPLACE_ISWXDIGIT)/g' \
-e 's/@''REPLACE_ISWCNTRL''@/$(REPLACE_ISWCNTRL)/g' \
-e 's/@''REPLACE_TOWLOWER''@/$(REPLACE_TOWLOWER)/g' \