1 /* A substitute for ISO C99 <wctype.h>, for platforms that lack it.
3 Copyright (C) 2006-2011 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, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
19 /* Written by Bruno Haible and Paul Eggert. */
22 * ISO C 99 <wctype.h> for platforms that lack it.
23 * <http://www.opengroup.org/susv3xbd/wctype.h.html>
25 * iswctype, towctrans, towlower, towupper, wctrans, wctype,
26 * wctrans_t, and wctype_t are not yet implemented.
32 @PRAGMA_SYSTEM_HEADER@
37 /* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>.
38 Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
40 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
41 included before <wchar.h>. */
48 /* Include the original <wctype.h> if it exists.
49 BeOS 5 has the functions but no <wctype.h>. */
50 /* The include_next requires a split double-inclusion guard. */
52 # @INCLUDE_NEXT@ @NEXT_WCTYPE_H@
58 /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
60 /* The definition of _GL_WARN_ON_USE is copied here. */
62 /* Define wint_t and WEOF. (Also done in wchar.in.h.) */
63 #if !@HAVE_WINT_T@ && !defined wint_t
70 # define WEOF ((wint_t) -1)
75 #if !GNULIB_defined_wctype_functions
77 /* FreeBSD 4.4 to 4.11 has <wctype.h> but lacks the functions.
78 Linux libc5 has <wctype.h> and the functions but they are broken.
79 Assume all 11 functions (all isw* except iswblank) are implemented the
80 same way, or not at all. */
81 # if ! @HAVE_ISWCNTRL@ || @REPLACE_ISWCNTRL@
83 /* IRIX 5.3 has macros but no functions, its isw* macros refer to an
84 undefined variable _ctmp_ and to <ctype.h> macros like _P, and they
85 refer to system functions like _iswctype that are not in the
86 standard C library. Rather than try to get ancient buggy
87 implementations like this to work, just disable them. */
103 /* Linux libc5 has <wctype.h> and the functions but they are broken. */
104 # if @REPLACE_ISWCNTRL@
105 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
106 # define iswalnum rpl_iswalnum
107 # define iswalpha rpl_iswalpha
108 # define iswblank rpl_iswblank
109 # define iswcntrl rpl_iswcntrl
110 # define iswdigit rpl_iswdigit
111 # define iswgraph rpl_iswgraph
112 # define iswlower rpl_iswlower
113 # define iswprint rpl_iswprint
114 # define iswpunct rpl_iswpunct
115 # define iswspace rpl_iswspace
116 # define iswupper rpl_iswupper
117 # define iswxdigit rpl_iswxdigit
118 # define towlower rpl_towlower
119 # define towupper rpl_towupper
124 # if @REPLACE_ISWCNTRL@
131 return ((wc >= '0' && wc <= '9')
132 || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'));
136 # if @REPLACE_ISWCNTRL@
143 return (wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z';
147 # if @REPLACE_ISWCNTRL@
154 return wc == ' ' || wc == '\t';
158 # if @REPLACE_ISWCNTRL@
165 return (wc & ~0x1f) == 0 || wc == 0x7f;
169 # if @REPLACE_ISWCNTRL@
176 return wc >= '0' && wc <= '9';
180 # if @REPLACE_ISWCNTRL@
187 return wc >= '!' && wc <= '~';
191 # if @REPLACE_ISWCNTRL@
198 return wc >= 'a' && wc <= 'z';
202 # if @REPLACE_ISWCNTRL@
209 return wc >= ' ' && wc <= '~';
213 # if @REPLACE_ISWCNTRL@
220 return (wc >= '!' && wc <= '~'
221 && !((wc >= '0' && wc <= '9')
222 || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z')));
226 # if @REPLACE_ISWCNTRL@
233 return (wc == ' ' || wc == '\t'
234 || wc == '\n' || wc == '\v' || wc == '\f' || wc == '\r');
238 # if @REPLACE_ISWCNTRL@
245 return wc >= 'A' && wc <= 'Z';
249 # if @REPLACE_ISWCNTRL@
256 return ((wc >= '0' && wc <= '9')
257 || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'F'));
261 # if @REPLACE_ISWCNTRL@
268 return (wc >= 'A' && wc <= 'Z' ? wc - 'A' + 'a' : wc);
272 # if @REPLACE_ISWCNTRL@
279 return (wc >= 'a' && wc <= 'z' ? wc - 'a' + 'A' : wc);
282 # elif @GNULIB_ISWBLANK@ && (! @HAVE_ISWBLANK@ || @REPLACE_ISWBLANK@)
283 /* Only the iswblank function is missing. */
285 # if @REPLACE_ISWBLANK@
286 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
287 # define iswblank rpl_iswblank
289 _GL_FUNCDECL_RPL (iswblank, int, (wint_t wc));
291 _GL_FUNCDECL_SYS (iswblank, int, (wint_t wc));
296 # if defined __MINGW32__
298 /* On native Windows, wchar_t is uint16_t, and wint_t is uint32_t.
299 The functions towlower and towupper are implemented in the MSVCRT library
300 to take a wchar_t argument and return a wchar_t result. mingw declares
301 these functions to take a wint_t argument and return a wint_t result.
303 1. When the user passes an argument outside the range 0x0000..0xFFFF, the
304 function will look only at the lower 16 bits. This is allowed according
306 2. The return value is returned in the lower 16 bits of the result register.
307 The upper 16 bits are random: whatever happened to be in that part of the
308 result register. We need to fix this by adding a zero-extend from
309 wchar_t to wint_t after the call. */
312 rpl_towlower (wint_t wc)
314 return (wint_t) (wchar_t) towlower (wc);
316 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
317 # define towlower rpl_towlower
321 rpl_towupper (wint_t wc)
323 return (wint_t) (wchar_t) towupper (wc);
325 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
326 # define towupper rpl_towupper
329 # endif /* __MINGW32__ */
331 # define GNULIB_defined_wctype_functions 1
334 #if @REPLACE_ISWCNTRL@
335 _GL_CXXALIAS_RPL (iswalnum, int, (wint_t wc));
336 _GL_CXXALIAS_RPL (iswalpha, int, (wint_t wc));
337 _GL_CXXALIAS_RPL (iswcntrl, int, (wint_t wc));
338 _GL_CXXALIAS_RPL (iswdigit, int, (wint_t wc));
339 _GL_CXXALIAS_RPL (iswgraph, int, (wint_t wc));
340 _GL_CXXALIAS_RPL (iswlower, int, (wint_t wc));
341 _GL_CXXALIAS_RPL (iswprint, int, (wint_t wc));
342 _GL_CXXALIAS_RPL (iswpunct, int, (wint_t wc));
343 _GL_CXXALIAS_RPL (iswspace, int, (wint_t wc));
344 _GL_CXXALIAS_RPL (iswupper, int, (wint_t wc));
345 _GL_CXXALIAS_RPL (iswxdigit, int, (wint_t wc));
347 _GL_CXXALIAS_SYS (iswalnum, int, (wint_t wc));
348 _GL_CXXALIAS_SYS (iswalpha, int, (wint_t wc));
349 _GL_CXXALIAS_SYS (iswcntrl, int, (wint_t wc));
350 _GL_CXXALIAS_SYS (iswdigit, int, (wint_t wc));
351 _GL_CXXALIAS_SYS (iswgraph, int, (wint_t wc));
352 _GL_CXXALIAS_SYS (iswlower, int, (wint_t wc));
353 _GL_CXXALIAS_SYS (iswprint, int, (wint_t wc));
354 _GL_CXXALIAS_SYS (iswpunct, int, (wint_t wc));
355 _GL_CXXALIAS_SYS (iswspace, int, (wint_t wc));
356 _GL_CXXALIAS_SYS (iswupper, int, (wint_t wc));
357 _GL_CXXALIAS_SYS (iswxdigit, int, (wint_t wc));
359 _GL_CXXALIASWARN (iswalnum);
360 _GL_CXXALIASWARN (iswalpha);
361 _GL_CXXALIASWARN (iswcntrl);
362 _GL_CXXALIASWARN (iswdigit);
363 _GL_CXXALIASWARN (iswgraph);
364 _GL_CXXALIASWARN (iswlower);
365 _GL_CXXALIASWARN (iswprint);
366 _GL_CXXALIASWARN (iswpunct);
367 _GL_CXXALIASWARN (iswspace);
368 _GL_CXXALIASWARN (iswupper);
369 _GL_CXXALIASWARN (iswxdigit);
371 #if @GNULIB_ISWBLANK@
372 # if @REPLACE_ISWCNTRL@ || @REPLACE_ISWBLANK@
373 _GL_CXXALIAS_RPL (iswblank, int, (wint_t wc));
375 _GL_CXXALIAS_SYS (iswblank, int, (wint_t wc));
377 _GL_CXXALIASWARN (iswblank);
381 # if !GNULIB_defined_wctype_t
382 typedef void * wctype_t;
383 # define GNULIB_defined_wctype_t 1
387 /* Get a descriptor for a wide character property. */
389 # if !@HAVE_WCTYPE_T@
390 _GL_FUNCDECL_SYS (wctype, wctype_t, (const char *name));
392 _GL_CXXALIAS_SYS (wctype, wctype_t, (const char *name));
393 _GL_CXXALIASWARN (wctype);
394 #elif defined GNULIB_POSIXCHECK
396 # if HAVE_RAW_DECL_WCTYPE
397 _GL_WARN_ON_USE (wctype, "wctype is unportable - "
398 "use gnulib module wctype for portability");
402 /* Test whether a wide character has a given property.
403 The argument WC must be either a wchar_t value or WEOF.
404 The argument DESC must have been returned by the wctype() function. */
405 #if @GNULIB_ISWCTYPE@
406 # if !@HAVE_WCTYPE_T@
407 _GL_FUNCDECL_SYS (iswctype, int, (wint_t wc, wctype_t desc));
409 _GL_CXXALIAS_SYS (iswctype, int, (wint_t wc, wctype_t desc));
410 _GL_CXXALIASWARN (iswctype);
411 #elif defined GNULIB_POSIXCHECK
413 # if HAVE_RAW_DECL_ISWCTYPE
414 _GL_WARN_ON_USE (iswctype, "iswctype is unportable - "
415 "use gnulib module iswctype for portability");
419 #if @REPLACE_ISWCNTRL@ || defined __MINGW32__
420 _GL_CXXALIAS_RPL (towlower, wint_t, (wint_t wc));
421 _GL_CXXALIAS_RPL (towupper, wint_t, (wint_t wc));
423 _GL_CXXALIAS_SYS (towlower, wint_t, (wint_t wc));
424 _GL_CXXALIAS_SYS (towupper, wint_t, (wint_t wc));
426 _GL_CXXALIASWARN (towlower);
427 _GL_CXXALIASWARN (towupper);
429 #if !@HAVE_WCTRANS_T@
430 # if !GNULIB_defined_wctrans_t
431 typedef void * wctrans_t;
432 # define GNULIB_defined_wctrans_t 1
436 /* Get a descriptor for a wide character case conversion. */
438 # if !@HAVE_WCTRANS_T@
439 _GL_FUNCDECL_SYS (wctrans, wctrans_t, (const char *name));
441 _GL_CXXALIAS_SYS (wctrans, wctrans_t, (const char *name));
442 _GL_CXXALIASWARN (wctrans);
443 #elif defined GNULIB_POSIXCHECK
445 # if HAVE_RAW_DECL_WCTRANS
446 _GL_WARN_ON_USE (wctrans, "wctrans is unportable - "
447 "use gnulib module wctrans for portability");
451 /* Perform a given case conversion on a wide character.
452 The argument WC must be either a wchar_t value or WEOF.
453 The argument DESC must have been returned by the wctrans() function. */
454 #if @GNULIB_TOWCTRANS@
455 # if !@HAVE_WCTRANS_T@
456 _GL_FUNCDECL_SYS (towctrans, wint_t, (wint_t wc, wctrans_t desc));
458 _GL_CXXALIAS_SYS (towctrans, wint_t, (wint_t wc, wctrans_t desc));
459 _GL_CXXALIASWARN (towctrans);
460 #elif defined GNULIB_POSIXCHECK
462 # if HAVE_RAW_DECL_TOWCTRANS
463 _GL_WARN_ON_USE (towctrans, "towctrans is unportable - "
464 "use gnulib module towctrans for portability");
469 #endif /* _GL_WCTYPE_H */
470 #endif /* _GL_WCTYPE_H */