1 /* A substitute for ISO C99 <wctype.h>, for platforms that lack it.
3 Copyright (C) 2006-2020 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, see <https://www.gnu.org/licenses/>. */
18 /* Written by Bruno Haible and Paul Eggert. */
21 * ISO C 99 <wctype.h> for platforms that lack it.
22 * <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/wctype.h.html>
24 * iswctype, towctrans, towlower, towupper, wctrans, wctype,
25 * wctrans_t, and wctype_t are not yet implemented.
29 @PRAGMA_SYSTEM_HEADER@
33 #if (defined __MINGW32__ && defined __CTYPE_H_SOURCED__)
35 /* Special invocation convention:
36 - With MinGW 3.22, when <ctype.h> includes <wctype.h>, only some part of
37 <wctype.h> is being processed, which doesn't include the idempotency
40 #@INCLUDE_NEXT@ @NEXT_WCTYPE_H@
43 /* Normal invocation convention. */
45 #ifndef _@GUARD_PREFIX@_WCTYPE_H
48 /* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>.
49 Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
51 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
52 included before <wchar.h>. */
59 /* Native Windows (mingw, MSVC) have declarations of towupper, towlower, and
60 isw* functions in <ctype.h>, <wchar.h> as well as in <wctype.h>. Include
61 <ctype.h>, <wchar.h> in advance to avoid rpl_ prefix being added to the
63 #if defined _WIN32 && ! defined __CYGWIN__
68 /* Include the original <wctype.h> if it exists.
69 BeOS 5 has the functions but no <wctype.h>. */
70 /* The include_next requires a split double-inclusion guard. */
72 # @INCLUDE_NEXT@ @NEXT_WCTYPE_H@
75 #ifndef _@GUARD_PREFIX@_WCTYPE_H
76 #define _@GUARD_PREFIX@_WCTYPE_H
78 #ifndef _GL_INLINE_HEADER_BEGIN
79 #error "Please include config.h first."
81 _GL_INLINE_HEADER_BEGIN
82 #ifndef _GL_WCTYPE_INLINE
83 # define _GL_WCTYPE_INLINE _GL_INLINE
86 /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
88 /* The definition of _GL_WARN_ON_USE is copied here. */
90 /* Solaris 2.6 <wctype.h> includes <widec.h> which includes <euc.h> which
91 #defines a number of identifiers in the application namespace. Revert
103 /* Define wint_t and WEOF. (Also done in wchar.in.h.) */
104 #if !@HAVE_WINT_T@ && !defined wint_t
110 /* mingw and MSVC define wint_t as 'unsigned short' in <crtdefs.h> or
111 <stddef.h>. This is too small: ISO C 99 section 7.24.1.(2) says that
112 wint_t must be "unchanged by default argument promotions". Override it. */
113 # if @GNULIB_OVERRIDES_WINT_T@
114 # if !GNULIB_defined_wint_t
115 # if @HAVE_CRTDEFS_H@
116 # include <crtdefs.h>
120 typedef unsigned int rpl_wint_t
;
122 # define wint_t rpl_wint_t
123 # define GNULIB_defined_wint_t 1
127 # define WEOF ((wint_t) -1)
132 #if !GNULIB_defined_wctype_functions
134 /* FreeBSD 4.4 to 4.11 has <wctype.h> but lacks the functions.
135 Linux libc5 has <wctype.h> and the functions but they are broken.
136 mingw and MSVC have <wctype.h> and the functions but they take a wchar_t
137 as argument, not an rpl_wint_t.
138 Assume all 11 functions (all isw* except iswblank) are implemented the
139 same way, or not at all. */
140 # if ! @HAVE_ISWCNTRL@ || @REPLACE_ISWCNTRL@
142 # if @GNULIB_OVERRIDES_WINT_T@ /* implies @REPLACE_ISWCNTRL@ */
144 _GL_WCTYPE_INLINE
int
145 rpl_iswalnum (wint_t wc
)
147 return ((wchar_t) wc
== wc
? iswalnum ((wchar_t) wc
) : 0);
150 _GL_WCTYPE_INLINE
int
151 rpl_iswalpha (wint_t wc
)
153 return ((wchar_t) wc
== wc
? iswalpha ((wchar_t) wc
) : 0);
156 _GL_WCTYPE_INLINE
int
157 rpl_iswblank (wint_t wc
)
159 return ((wchar_t) wc
== wc
? iswblank ((wchar_t) wc
) : 0);
162 _GL_WCTYPE_INLINE
int
163 rpl_iswcntrl (wint_t wc
)
165 return ((wchar_t) wc
== wc
? iswcntrl ((wchar_t) wc
) : 0);
168 _GL_WCTYPE_INLINE
int
169 rpl_iswdigit (wint_t wc
)
171 return ((wchar_t) wc
== wc
? iswdigit ((wchar_t) wc
) : 0);
174 _GL_WCTYPE_INLINE
int
175 rpl_iswgraph (wint_t wc
)
177 return ((wchar_t) wc
== wc
? iswgraph ((wchar_t) wc
) : 0);
180 _GL_WCTYPE_INLINE
int
181 rpl_iswlower (wint_t wc
)
183 return ((wchar_t) wc
== wc
? iswlower ((wchar_t) wc
) : 0);
186 _GL_WCTYPE_INLINE
int
187 rpl_iswprint (wint_t wc
)
189 return ((wchar_t) wc
== wc
? iswprint ((wchar_t) wc
) : 0);
192 _GL_WCTYPE_INLINE
int
193 rpl_iswpunct (wint_t wc
)
195 return ((wchar_t) wc
== wc
? iswpunct ((wchar_t) wc
) : 0);
198 _GL_WCTYPE_INLINE
int
199 rpl_iswspace (wint_t wc
)
201 return ((wchar_t) wc
== wc
? iswspace ((wchar_t) wc
) : 0);
204 _GL_WCTYPE_INLINE
int
205 rpl_iswupper (wint_t wc
)
207 return ((wchar_t) wc
== wc
? iswupper ((wchar_t) wc
) : 0);
210 _GL_WCTYPE_INLINE
int
211 rpl_iswxdigit (wint_t wc
)
213 return ((wchar_t) wc
== wc
? iswxdigit ((wchar_t) wc
) : 0);
216 _GL_WCTYPE_INLINE
wint_t
217 rpl_towlower (wint_t wc
)
219 return ((wchar_t) wc
== wc
? (wchar_t) towlower ((wchar_t) wc
) : wc
);
222 _GL_WCTYPE_INLINE
wint_t
223 rpl_towupper (wint_t wc
)
225 return ((wchar_t) wc
== wc
? (wchar_t) towupper ((wchar_t) wc
) : wc
);
228 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
243 # define iswalnum rpl_iswalnum
244 # define iswalpha rpl_iswalpha
245 # define iswblank rpl_iswblank
246 # define iswcntrl rpl_iswcntrl
247 # define iswdigit rpl_iswdigit
248 # define iswgraph rpl_iswgraph
249 # define iswlower rpl_iswlower
250 # define iswprint rpl_iswprint
251 # define iswpunct rpl_iswpunct
252 # define iswspace rpl_iswspace
253 # define iswupper rpl_iswupper
254 # define iswxdigit rpl_iswxdigit
255 # define towlower rpl_towlower
256 # define towupper rpl_towupper
261 /* IRIX 5.3 has macros but no functions, its isw* macros refer to an
262 undefined variable _ctmp_ and to <ctype.h> macros like _P, and they
263 refer to system functions like _iswctype that are not in the
264 standard C library. Rather than try to get ancient buggy
265 implementations like this to work, just disable them. */
281 /* Linux libc5 has <wctype.h> and the functions but they are broken. */
282 # if @REPLACE_ISWCNTRL@
283 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
284 # define iswalnum rpl_iswalnum
285 # define iswalpha rpl_iswalpha
286 # define iswblank rpl_iswblank
287 # define iswcntrl rpl_iswcntrl
288 # define iswdigit rpl_iswdigit
289 # define iswgraph rpl_iswgraph
290 # define iswlower rpl_iswlower
291 # define iswprint rpl_iswprint
292 # define iswpunct rpl_iswpunct
293 # define iswspace rpl_iswspace
294 # define iswupper rpl_iswupper
295 # define iswxdigit rpl_iswxdigit
298 # if @REPLACE_TOWLOWER@
299 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
300 # define towlower rpl_towlower
301 # define towupper rpl_towupper
305 _GL_WCTYPE_INLINE
int
306 # if @REPLACE_ISWCNTRL@
313 return ((wc
>= '0' && wc
<= '9')
314 || ((wc
& ~0x20) >= 'A' && (wc
& ~0x20) <= 'Z'));
317 _GL_WCTYPE_INLINE
int
318 # if @REPLACE_ISWCNTRL@
325 return (wc
& ~0x20) >= 'A' && (wc
& ~0x20) <= 'Z';
328 _GL_WCTYPE_INLINE
int
329 # if @REPLACE_ISWCNTRL@
336 return wc
== ' ' || wc
== '\t';
339 _GL_WCTYPE_INLINE
int
340 # if @REPLACE_ISWCNTRL@
347 return (wc
& ~0x1f) == 0 || wc
== 0x7f;
350 _GL_WCTYPE_INLINE
int
351 # if @REPLACE_ISWCNTRL@
358 return wc
>= '0' && wc
<= '9';
361 _GL_WCTYPE_INLINE
int
362 # if @REPLACE_ISWCNTRL@
369 return wc
>= '!' && wc
<= '~';
372 _GL_WCTYPE_INLINE
int
373 # if @REPLACE_ISWCNTRL@
380 return wc
>= 'a' && wc
<= 'z';
383 _GL_WCTYPE_INLINE
int
384 # if @REPLACE_ISWCNTRL@
391 return wc
>= ' ' && wc
<= '~';
394 _GL_WCTYPE_INLINE
int
395 # if @REPLACE_ISWCNTRL@
402 return (wc
>= '!' && wc
<= '~'
403 && !((wc
>= '0' && wc
<= '9')
404 || ((wc
& ~0x20) >= 'A' && (wc
& ~0x20) <= 'Z')));
407 _GL_WCTYPE_INLINE
int
408 # if @REPLACE_ISWCNTRL@
415 return (wc
== ' ' || wc
== '\t'
416 || wc
== '\n' || wc
== '\v' || wc
== '\f' || wc
== '\r');
419 _GL_WCTYPE_INLINE
int
420 # if @REPLACE_ISWCNTRL@
427 return wc
>= 'A' && wc
<= 'Z';
430 _GL_WCTYPE_INLINE
int
431 # if @REPLACE_ISWCNTRL@
438 return ((wc
>= '0' && wc
<= '9')
439 || ((wc
& ~0x20) >= 'A' && (wc
& ~0x20) <= 'F'));
442 _GL_WCTYPE_INLINE
wint_t
443 # if @REPLACE_TOWLOWER@
450 return (wc
>= 'A' && wc
<= 'Z' ? wc
- 'A' + 'a' : wc
);
453 _GL_WCTYPE_INLINE
wint_t
454 # if @REPLACE_TOWLOWER@
461 return (wc
>= 'a' && wc
<= 'z' ? wc
- 'a' + 'A' : wc
);
466 # elif @GNULIB_ISWBLANK@ && (! @HAVE_ISWBLANK@ || @REPLACE_ISWBLANK@)
467 /* Only the iswblank function is missing. */
469 # if @REPLACE_ISWBLANK@
470 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
471 # define iswblank rpl_iswblank
473 _GL_FUNCDECL_RPL (iswblank
, int, (wint_t wc
));
475 _GL_FUNCDECL_SYS (iswblank
, int, (wint_t wc
));
480 # if defined __MINGW32__ && !@GNULIB_OVERRIDES_WINT_T@
482 /* On native Windows, wchar_t is uint16_t, and wint_t is uint32_t.
483 The functions towlower and towupper are implemented in the MSVCRT library
484 to take a wchar_t argument and return a wchar_t result. mingw declares
485 these functions to take a wint_t argument and return a wint_t result.
487 1. When the user passes an argument outside the range 0x0000..0xFFFF, the
488 function will look only at the lower 16 bits. This is allowed according
490 2. The return value is returned in the lower 16 bits of the result register.
491 The upper 16 bits are random: whatever happened to be in that part of the
492 result register. We need to fix this by adding a zero-extend from
493 wchar_t to wint_t after the call. */
495 _GL_WCTYPE_INLINE
wint_t
496 rpl_towlower (wint_t wc
)
498 return (wint_t) (wchar_t) towlower (wc
);
500 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
501 # define towlower rpl_towlower
504 _GL_WCTYPE_INLINE
wint_t
505 rpl_towupper (wint_t wc
)
507 return (wint_t) (wchar_t) towupper (wc
);
509 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
510 # define towupper rpl_towupper
513 # endif /* __MINGW32__ && !@GNULIB_OVERRIDES_WINT_T@ */
515 # define GNULIB_defined_wctype_functions 1
518 #if @REPLACE_ISWCNTRL@
519 _GL_CXXALIAS_RPL (iswalnum
, int, (wint_t wc
));
520 _GL_CXXALIAS_RPL (iswalpha
, int, (wint_t wc
));
521 _GL_CXXALIAS_RPL (iswcntrl
, int, (wint_t wc
));
522 _GL_CXXALIAS_RPL (iswdigit
, int, (wint_t wc
));
523 _GL_CXXALIAS_RPL (iswgraph
, int, (wint_t wc
));
524 _GL_CXXALIAS_RPL (iswlower
, int, (wint_t wc
));
525 _GL_CXXALIAS_RPL (iswprint
, int, (wint_t wc
));
526 _GL_CXXALIAS_RPL (iswpunct
, int, (wint_t wc
));
527 _GL_CXXALIAS_RPL (iswspace
, int, (wint_t wc
));
528 _GL_CXXALIAS_RPL (iswupper
, int, (wint_t wc
));
529 _GL_CXXALIAS_RPL (iswxdigit
, int, (wint_t wc
));
531 _GL_CXXALIAS_SYS (iswalnum
, int, (wint_t wc
));
532 _GL_CXXALIAS_SYS (iswalpha
, int, (wint_t wc
));
533 _GL_CXXALIAS_SYS (iswcntrl
, int, (wint_t wc
));
534 _GL_CXXALIAS_SYS (iswdigit
, int, (wint_t wc
));
535 _GL_CXXALIAS_SYS (iswgraph
, int, (wint_t wc
));
536 _GL_CXXALIAS_SYS (iswlower
, int, (wint_t wc
));
537 _GL_CXXALIAS_SYS (iswprint
, int, (wint_t wc
));
538 _GL_CXXALIAS_SYS (iswpunct
, int, (wint_t wc
));
539 _GL_CXXALIAS_SYS (iswspace
, int, (wint_t wc
));
540 _GL_CXXALIAS_SYS (iswupper
, int, (wint_t wc
));
541 _GL_CXXALIAS_SYS (iswxdigit
, int, (wint_t wc
));
544 _GL_CXXALIASWARN (iswalnum
);
545 _GL_CXXALIASWARN (iswalpha
);
546 _GL_CXXALIASWARN (iswcntrl
);
547 _GL_CXXALIASWARN (iswdigit
);
548 _GL_CXXALIASWARN (iswgraph
);
549 _GL_CXXALIASWARN (iswlower
);
550 _GL_CXXALIASWARN (iswprint
);
551 _GL_CXXALIASWARN (iswpunct
);
552 _GL_CXXALIASWARN (iswspace
);
553 _GL_CXXALIASWARN (iswupper
);
554 _GL_CXXALIASWARN (iswxdigit
);
557 #if @GNULIB_ISWBLANK@
558 # if @REPLACE_ISWCNTRL@ || @REPLACE_ISWBLANK@
559 _GL_CXXALIAS_RPL (iswblank
, int, (wint_t wc
));
561 _GL_CXXALIAS_SYS (iswblank
, int, (wint_t wc
));
564 _GL_CXXALIASWARN (iswblank
);
569 # if !GNULIB_defined_wctype_t
570 typedef void * wctype_t;
571 # define GNULIB_defined_wctype_t 1
575 /* Get a descriptor for a wide character property. */
577 # if !@HAVE_WCTYPE_T@
578 _GL_FUNCDECL_SYS (wctype
, wctype_t, (const char *name
));
580 _GL_CXXALIAS_SYS (wctype
, wctype_t, (const char *name
));
582 _GL_CXXALIASWARN (wctype
);
584 #elif defined GNULIB_POSIXCHECK
586 # if HAVE_RAW_DECL_WCTYPE
587 _GL_WARN_ON_USE (wctype
, "wctype is unportable - "
588 "use gnulib module wctype for portability");
592 /* Test whether a wide character has a given property.
593 The argument WC must be either a wchar_t value or WEOF.
594 The argument DESC must have been returned by the wctype() function. */
595 #if @GNULIB_ISWCTYPE@
596 # if @GNULIB_OVERRIDES_WINT_T@
597 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
599 # define iswctype rpl_iswctype
601 _GL_FUNCDECL_RPL (iswctype
, int, (wint_t wc
, wctype_t desc
));
602 _GL_CXXALIAS_RPL (iswctype
, int, (wint_t wc
, wctype_t desc
));
604 # if !@HAVE_WCTYPE_T@
605 _GL_FUNCDECL_SYS (iswctype
, int, (wint_t wc
, wctype_t desc
));
607 _GL_CXXALIAS_SYS (iswctype
, int, (wint_t wc
, wctype_t desc
));
610 _GL_CXXALIASWARN (iswctype
);
612 #elif defined GNULIB_POSIXCHECK
614 # if HAVE_RAW_DECL_ISWCTYPE
615 _GL_WARN_ON_USE (iswctype
, "iswctype is unportable - "
616 "use gnulib module iswctype for portability");
620 #if @REPLACE_TOWLOWER@ || defined __MINGW32__
621 _GL_CXXALIAS_RPL (towlower
, wint_t, (wint_t wc
));
622 _GL_CXXALIAS_RPL (towupper
, wint_t, (wint_t wc
));
624 _GL_CXXALIAS_SYS (towlower
, wint_t, (wint_t wc
));
625 _GL_CXXALIAS_SYS (towupper
, wint_t, (wint_t wc
));
628 _GL_CXXALIASWARN (towlower
);
629 _GL_CXXALIASWARN (towupper
);
632 #if !@HAVE_WCTRANS_T@
633 # if !GNULIB_defined_wctrans_t
634 typedef void * wctrans_t;
635 # define GNULIB_defined_wctrans_t 1
639 /* Get a descriptor for a wide character case conversion. */
641 # if !@HAVE_WCTRANS_T@
642 _GL_FUNCDECL_SYS (wctrans
, wctrans_t, (const char *name
));
644 _GL_CXXALIAS_SYS (wctrans
, wctrans_t, (const char *name
));
646 _GL_CXXALIASWARN (wctrans
);
648 #elif defined GNULIB_POSIXCHECK
650 # if HAVE_RAW_DECL_WCTRANS
651 _GL_WARN_ON_USE (wctrans
, "wctrans is unportable - "
652 "use gnulib module wctrans for portability");
656 /* Perform a given case conversion on a wide character.
657 The argument WC must be either a wchar_t value or WEOF.
658 The argument DESC must have been returned by the wctrans() function. */
659 #if @GNULIB_TOWCTRANS@
660 # if !@HAVE_WCTRANS_T@
661 _GL_FUNCDECL_SYS (towctrans
, wint_t, (wint_t wc
, wctrans_t desc
));
663 _GL_CXXALIAS_SYS (towctrans
, wint_t, (wint_t wc
, wctrans_t desc
));
665 _GL_CXXALIASWARN (towctrans
);
667 #elif defined GNULIB_POSIXCHECK
669 # if HAVE_RAW_DECL_TOWCTRANS
670 _GL_WARN_ON_USE (towctrans
, "towctrans is unportable - "
671 "use gnulib module towctrans for portability");
675 _GL_INLINE_HEADER_END
677 #endif /* _@GUARD_PREFIX@_WCTYPE_H */
678 #endif /* _@GUARD_PREFIX@_WCTYPE_H */