1 /* A substitute for ISO C99 <wctype.h>, for platforms that lack it.
3 Copyright (C) 2006-2018 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 * <http://www.opengroup.org/susv3xbd/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 Assume all 11 functions (all isw* except iswblank) are implemented the
137 same way, or not at all. */
138 # if ! @HAVE_ISWCNTRL@ || @REPLACE_ISWCNTRL@
140 /* IRIX 5.3 has macros but no functions, its isw* macros refer to an
141 undefined variable _ctmp_ and to <ctype.h> macros like _P, and they
142 refer to system functions like _iswctype that are not in the
143 standard C library. Rather than try to get ancient buggy
144 implementations like this to work, just disable them. */
160 /* Linux libc5 has <wctype.h> and the functions but they are broken. */
161 # if @REPLACE_ISWCNTRL@
162 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
163 # define iswalnum rpl_iswalnum
164 # define iswalpha rpl_iswalpha
165 # define iswblank rpl_iswblank
166 # define iswcntrl rpl_iswcntrl
167 # define iswdigit rpl_iswdigit
168 # define iswgraph rpl_iswgraph
169 # define iswlower rpl_iswlower
170 # define iswprint rpl_iswprint
171 # define iswpunct rpl_iswpunct
172 # define iswspace rpl_iswspace
173 # define iswupper rpl_iswupper
174 # define iswxdigit rpl_iswxdigit
177 # if @REPLACE_TOWLOWER@
178 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
179 # define towlower rpl_towlower
180 # define towupper rpl_towupper
184 _GL_WCTYPE_INLINE
int
185 # if @REPLACE_ISWCNTRL@
192 return ((wc
>= '0' && wc
<= '9')
193 || ((wc
& ~0x20) >= 'A' && (wc
& ~0x20) <= 'Z'));
196 _GL_WCTYPE_INLINE
int
197 # if @REPLACE_ISWCNTRL@
204 return (wc
& ~0x20) >= 'A' && (wc
& ~0x20) <= 'Z';
207 _GL_WCTYPE_INLINE
int
208 # if @REPLACE_ISWCNTRL@
215 return wc
== ' ' || wc
== '\t';
218 _GL_WCTYPE_INLINE
int
219 # if @REPLACE_ISWCNTRL@
226 return (wc
& ~0x1f) == 0 || wc
== 0x7f;
229 _GL_WCTYPE_INLINE
int
230 # if @REPLACE_ISWCNTRL@
237 return wc
>= '0' && wc
<= '9';
240 _GL_WCTYPE_INLINE
int
241 # if @REPLACE_ISWCNTRL@
248 return wc
>= '!' && wc
<= '~';
251 _GL_WCTYPE_INLINE
int
252 # if @REPLACE_ISWCNTRL@
259 return wc
>= 'a' && wc
<= 'z';
262 _GL_WCTYPE_INLINE
int
263 # if @REPLACE_ISWCNTRL@
270 return wc
>= ' ' && wc
<= '~';
273 _GL_WCTYPE_INLINE
int
274 # if @REPLACE_ISWCNTRL@
281 return (wc
>= '!' && wc
<= '~'
282 && !((wc
>= '0' && wc
<= '9')
283 || ((wc
& ~0x20) >= 'A' && (wc
& ~0x20) <= 'Z')));
286 _GL_WCTYPE_INLINE
int
287 # if @REPLACE_ISWCNTRL@
294 return (wc
== ' ' || wc
== '\t'
295 || wc
== '\n' || wc
== '\v' || wc
== '\f' || wc
== '\r');
298 _GL_WCTYPE_INLINE
int
299 # if @REPLACE_ISWCNTRL@
306 return wc
>= 'A' && wc
<= 'Z';
309 _GL_WCTYPE_INLINE
int
310 # if @REPLACE_ISWCNTRL@
317 return ((wc
>= '0' && wc
<= '9')
318 || ((wc
& ~0x20) >= 'A' && (wc
& ~0x20) <= 'F'));
321 _GL_WCTYPE_INLINE
wint_t
322 # if @REPLACE_TOWLOWER@
329 return (wc
>= 'A' && wc
<= 'Z' ? wc
- 'A' + 'a' : wc
);
332 _GL_WCTYPE_INLINE
wint_t
333 # if @REPLACE_TOWLOWER@
340 return (wc
>= 'a' && wc
<= 'z' ? wc
- 'a' + 'A' : wc
);
343 # elif @GNULIB_ISWBLANK@ && (! @HAVE_ISWBLANK@ || @REPLACE_ISWBLANK@)
344 /* Only the iswblank function is missing. */
346 # if @REPLACE_ISWBLANK@
347 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
348 # define iswblank rpl_iswblank
350 _GL_FUNCDECL_RPL (iswblank
, int, (wint_t wc
));
352 _GL_FUNCDECL_SYS (iswblank
, int, (wint_t wc
));
357 # if defined __MINGW32__
359 /* On native Windows, wchar_t is uint16_t, and wint_t is uint32_t.
360 The functions towlower and towupper are implemented in the MSVCRT library
361 to take a wchar_t argument and return a wchar_t result. mingw declares
362 these functions to take a wint_t argument and return a wint_t result.
364 1. When the user passes an argument outside the range 0x0000..0xFFFF, the
365 function will look only at the lower 16 bits. This is allowed according
367 2. The return value is returned in the lower 16 bits of the result register.
368 The upper 16 bits are random: whatever happened to be in that part of the
369 result register. We need to fix this by adding a zero-extend from
370 wchar_t to wint_t after the call. */
372 _GL_WCTYPE_INLINE
wint_t
373 rpl_towlower (wint_t wc
)
375 return (wint_t) (wchar_t) towlower (wc
);
377 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
378 # define towlower rpl_towlower
381 _GL_WCTYPE_INLINE
wint_t
382 rpl_towupper (wint_t wc
)
384 return (wint_t) (wchar_t) towupper (wc
);
386 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
387 # define towupper rpl_towupper
390 # endif /* __MINGW32__ */
392 # define GNULIB_defined_wctype_functions 1
395 #if @REPLACE_ISWCNTRL@
396 _GL_CXXALIAS_RPL (iswalnum
, int, (wint_t wc
));
397 _GL_CXXALIAS_RPL (iswalpha
, int, (wint_t wc
));
398 _GL_CXXALIAS_RPL (iswcntrl
, int, (wint_t wc
));
399 _GL_CXXALIAS_RPL (iswdigit
, int, (wint_t wc
));
400 _GL_CXXALIAS_RPL (iswgraph
, int, (wint_t wc
));
401 _GL_CXXALIAS_RPL (iswlower
, int, (wint_t wc
));
402 _GL_CXXALIAS_RPL (iswprint
, int, (wint_t wc
));
403 _GL_CXXALIAS_RPL (iswpunct
, int, (wint_t wc
));
404 _GL_CXXALIAS_RPL (iswspace
, int, (wint_t wc
));
405 _GL_CXXALIAS_RPL (iswupper
, int, (wint_t wc
));
406 _GL_CXXALIAS_RPL (iswxdigit
, int, (wint_t wc
));
408 _GL_CXXALIAS_SYS (iswalnum
, int, (wint_t wc
));
409 _GL_CXXALIAS_SYS (iswalpha
, int, (wint_t wc
));
410 _GL_CXXALIAS_SYS (iswcntrl
, int, (wint_t wc
));
411 _GL_CXXALIAS_SYS (iswdigit
, int, (wint_t wc
));
412 _GL_CXXALIAS_SYS (iswgraph
, int, (wint_t wc
));
413 _GL_CXXALIAS_SYS (iswlower
, int, (wint_t wc
));
414 _GL_CXXALIAS_SYS (iswprint
, int, (wint_t wc
));
415 _GL_CXXALIAS_SYS (iswpunct
, int, (wint_t wc
));
416 _GL_CXXALIAS_SYS (iswspace
, int, (wint_t wc
));
417 _GL_CXXALIAS_SYS (iswupper
, int, (wint_t wc
));
418 _GL_CXXALIAS_SYS (iswxdigit
, int, (wint_t wc
));
420 _GL_CXXALIASWARN (iswalnum
);
421 _GL_CXXALIASWARN (iswalpha
);
422 _GL_CXXALIASWARN (iswcntrl
);
423 _GL_CXXALIASWARN (iswdigit
);
424 _GL_CXXALIASWARN (iswgraph
);
425 _GL_CXXALIASWARN (iswlower
);
426 _GL_CXXALIASWARN (iswprint
);
427 _GL_CXXALIASWARN (iswpunct
);
428 _GL_CXXALIASWARN (iswspace
);
429 _GL_CXXALIASWARN (iswupper
);
430 _GL_CXXALIASWARN (iswxdigit
);
432 #if @GNULIB_ISWBLANK@
433 # if @REPLACE_ISWCNTRL@ || @REPLACE_ISWBLANK@
434 _GL_CXXALIAS_RPL (iswblank
, int, (wint_t wc
));
436 _GL_CXXALIAS_SYS (iswblank
, int, (wint_t wc
));
438 _GL_CXXALIASWARN (iswblank
);
442 # if !GNULIB_defined_wctype_t
443 typedef void * wctype_t;
444 # define GNULIB_defined_wctype_t 1
448 /* Get a descriptor for a wide character property. */
450 # if !@HAVE_WCTYPE_T@
451 _GL_FUNCDECL_SYS (wctype
, wctype_t, (const char *name
));
453 _GL_CXXALIAS_SYS (wctype
, wctype_t, (const char *name
));
454 _GL_CXXALIASWARN (wctype
);
455 #elif defined GNULIB_POSIXCHECK
457 # if HAVE_RAW_DECL_WCTYPE
458 _GL_WARN_ON_USE (wctype
, "wctype is unportable - "
459 "use gnulib module wctype for portability");
463 /* Test whether a wide character has a given property.
464 The argument WC must be either a wchar_t value or WEOF.
465 The argument DESC must have been returned by the wctype() function. */
466 #if @GNULIB_ISWCTYPE@
467 # if !@HAVE_WCTYPE_T@
468 _GL_FUNCDECL_SYS (iswctype
, int, (wint_t wc
, wctype_t desc
));
470 _GL_CXXALIAS_SYS (iswctype
, int, (wint_t wc
, wctype_t desc
));
471 _GL_CXXALIASWARN (iswctype
);
472 #elif defined GNULIB_POSIXCHECK
474 # if HAVE_RAW_DECL_ISWCTYPE
475 _GL_WARN_ON_USE (iswctype
, "iswctype is unportable - "
476 "use gnulib module iswctype for portability");
480 #if @REPLACE_TOWLOWER@ || defined __MINGW32__
481 _GL_CXXALIAS_RPL (towlower
, wint_t, (wint_t wc
));
482 _GL_CXXALIAS_RPL (towupper
, wint_t, (wint_t wc
));
484 _GL_CXXALIAS_SYS (towlower
, wint_t, (wint_t wc
));
485 _GL_CXXALIAS_SYS (towupper
, wint_t, (wint_t wc
));
487 _GL_CXXALIASWARN (towlower
);
488 _GL_CXXALIASWARN (towupper
);
490 #if !@HAVE_WCTRANS_T@
491 # if !GNULIB_defined_wctrans_t
492 typedef void * wctrans_t;
493 # define GNULIB_defined_wctrans_t 1
497 /* Get a descriptor for a wide character case conversion. */
499 # if !@HAVE_WCTRANS_T@
500 _GL_FUNCDECL_SYS (wctrans
, wctrans_t, (const char *name
));
502 _GL_CXXALIAS_SYS (wctrans
, wctrans_t, (const char *name
));
503 _GL_CXXALIASWARN (wctrans
);
504 #elif defined GNULIB_POSIXCHECK
506 # if HAVE_RAW_DECL_WCTRANS
507 _GL_WARN_ON_USE (wctrans
, "wctrans is unportable - "
508 "use gnulib module wctrans for portability");
512 /* Perform a given case conversion on a wide character.
513 The argument WC must be either a wchar_t value or WEOF.
514 The argument DESC must have been returned by the wctrans() function. */
515 #if @GNULIB_TOWCTRANS@
516 # if !@HAVE_WCTRANS_T@
517 _GL_FUNCDECL_SYS (towctrans
, wint_t, (wint_t wc
, wctrans_t desc
));
519 _GL_CXXALIAS_SYS (towctrans
, wint_t, (wint_t wc
, wctrans_t desc
));
520 _GL_CXXALIASWARN (towctrans
);
521 #elif defined GNULIB_POSIXCHECK
523 # if HAVE_RAW_DECL_TOWCTRANS
524 _GL_WARN_ON_USE (towctrans
, "towctrans is unportable - "
525 "use gnulib module towctrans for portability");
529 _GL_INLINE_HEADER_END
531 #endif /* _@GUARD_PREFIX@_WCTYPE_H */
532 #endif /* _@GUARD_PREFIX@_WCTYPE_H */