diff options
author | Bruno Haible <bruno@clisp.org> | 2023-05-04 23:27:12 +0200 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2023-05-04 23:29:34 +0200 |
commit | 15880a3da91a0403eb287a84db90b54713ac4a09 (patch) | |
tree | 073cbfb1f015142cf598c710012db0243da45f10 /lib | |
parent | 59f878fa3d175b2d085a01a8df786c9e40be14b9 (diff) | |
download | gnulib-15880a3da91a0403eb287a84db90b54713ac4a09.tar.gz |
c32swidth: New module.
* lib/uchar.in.h (c32swidth): New declaration.
* lib/wcswidth-impl.h: Use macros FUNC, UNIT, CHARACTER_WIDTH.
* lib/wcswidth.c: Define FUNC, UNIT, CHARACTER_WIDTH before including
wcswidth-impl.h.
* lib/c32swidth.c: New file.
* modules/c32swidth: New file.
* m4/uchar_h.m4 (gl_UCHAR_H_REQUIRE_DEFAULTS): Initialize
GNULIB_C32SWIDTH.
* modules/uchar (Makefile.am): Substitute GNULIB_C32SWIDTH.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/c32swidth.c | 43 | ||||
-rw-r--r-- | lib/uchar.in.h | 19 | ||||
-rw-r--r-- | lib/wcswidth-impl.h | 14 | ||||
-rw-r--r-- | lib/wcswidth.c | 3 |
4 files changed, 72 insertions, 7 deletions
diff --git a/lib/c32swidth.c b/lib/c32swidth.c new file mode 100644 index 0000000000..2f7adcf74c --- /dev/null +++ b/lib/c32swidth.c @@ -0,0 +1,43 @@ +/* Determine number of screen columns needed for a size-bounded 32-bit wide string. + 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> + +#define IN_C32SWIDTH +/* Specification. */ +#include <uchar.h> + +#if _GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t + +# include <wchar.h> + +_GL_EXTERN_INLINE +int +c32swidth (const char32_t *s, size_t n) +{ + return wcswidth ((const wchar_t *) s, n); +} + +#else + +# include <limits.h> + +# define FUNC c32swidth +# define UNIT char32_t +# define CHARACTER_WIDTH c32width +# include "wcswidth-impl.h" + +#endif diff --git a/lib/uchar.in.h b/lib/uchar.in.h index 3815af4c26..8bf6176b8c 100644 --- a/lib/uchar.in.h +++ b/lib/uchar.in.h @@ -494,6 +494,25 @@ _GL_CXXALIASWARN (c32stombs); #endif +/* Number of screen columns needed for a size-bounded 32-bit wide string. */ +#if @GNULIB_C32SWIDTH@ +# if (_GL_WCHAR_T_IS_UCS4 && !GNULIB_defined_mbstate_t) && !defined IN_C32SWIDTH +_GL_BEGIN_C_LINKAGE +_GL_INLINE _GL_ARG_NONNULL ((1)) int +c32swidth (const char32_t *s, size_t n) +{ + return wcswidth ((const wchar_t *) s, n); +} +_GL_END_C_LINKAGE +# else +_GL_FUNCDECL_SYS (c32swidth, int, (const char32_t *s, size_t n) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (c32swidth, int, (const char32_t *s, size_t n)); +_GL_CXXALIASWARN (c32swidth); +#endif + + /* Converts a 32-bit wide character to unibyte character. Returns the single-byte representation of WC if it exists, or EOF otherwise. */ diff --git a/lib/wcswidth-impl.h b/lib/wcswidth-impl.h index a879bfdd93..34cb0b9814 100644 --- a/lib/wcswidth-impl.h +++ b/lib/wcswidth-impl.h @@ -16,16 +16,16 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */ int -wcswidth (const wchar_t *s, size_t n) +FUNC (const UNIT *s, size_t n) { int count = 0; for (; n > 0; s++, n--) { - wchar_t c = *s; - if (c == (wchar_t)'\0') + UNIT c = *s; + if (c == (UNIT)'\0') break; { - int width = wcwidth (c); + int width = CHARACTER_WIDTH (c); if (width < 0) goto found_nonprinting; if (width > INT_MAX - count) @@ -39,11 +39,11 @@ wcswidth (const wchar_t *s, size_t n) Continue searching for a non-printing wide character. */ for (; n > 0; s++, n--) { - wchar_t c = *s; - if (c == (wchar_t)'\0') + UNIT c = *s; + if (c == (UNIT)'\0') break; { - int width = wcwidth (c); + int width = CHARACTER_WIDTH (c); if (width < 0) goto found_nonprinting; } diff --git a/lib/wcswidth.c b/lib/wcswidth.c index 8188e380fd..408b826c62 100644 --- a/lib/wcswidth.c +++ b/lib/wcswidth.c @@ -22,4 +22,7 @@ #include <limits.h> +#define FUNC wcswidth +#define UNIT wchar_t +#define CHARACTER_WIDTH wcwidth #include "wcswidth-impl.h" |