Home | History | Annotate | Download | only in lib
      1 /* A substitute for ISO C99 <wctype.h>, for platforms that lack it.
      2 
      3    Copyright (C) 2006-2012 Free Software Foundation, Inc.
      4 
      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 3, or (at your option)
      8    any later version.
      9 
     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.
     14 
     15    You should have received a copy of the GNU General Public License
     16    along with this program; if not, see <http://www.gnu.org/licenses/>.  */
     17 
     18 /* Written by Bruno Haible and Paul Eggert.  */
     19 
     20 /*
     21  * ISO C 99 <wctype.h> for platforms that lack it.
     22  * <http://www.opengroup.org/susv3xbd/wctype.h.html>
     23  *
     24  * iswctype, towctrans, towlower, towupper, wctrans, wctype,
     25  * wctrans_t, and wctype_t are not yet implemented.
     26  */
     27 
     28 #ifndef _@GUARD_PREFIX@_WCTYPE_H
     29 
     30 #if __GNUC__ >= 3
     31 @PRAGMA_SYSTEM_HEADER@
     32 #endif
     33 @PRAGMA_COLUMNS@
     34 
     35 #if @HAVE_WINT_T@
     36 /* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>.
     37    Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
     38    <wchar.h>.
     39    BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
     40    included before <wchar.h>.  */
     41 # include <stddef.h>
     42 # include <stdio.h>
     43 # include <time.h>
     44 # include <wchar.h>
     45 #endif
     46 
     47 /* Include the original <wctype.h> if it exists.
     48    BeOS 5 has the functions but no <wctype.h>.  */
     49 /* The include_next requires a split double-inclusion guard.  */
     50 #if @HAVE_WCTYPE_H@
     51 # @INCLUDE_NEXT@ @NEXT_WCTYPE_H@
     52 #endif
     53 
     54 #ifndef _@GUARD_PREFIX@_WCTYPE_H
     55 #define _@GUARD_PREFIX@_WCTYPE_H
     56 
     57 _GL_INLINE_HEADER_BEGIN
     58 #ifndef _GL_WCTYPE_INLINE
     59 # define _GL_WCTYPE_INLINE _GL_INLINE
     60 #endif
     61 
     62 /* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
     63 
     64 /* The definition of _GL_WARN_ON_USE is copied here.  */
     65 
     66 /* Solaris 2.6 <wctype.h> includes <widec.h> which includes <euc.h> which
     67    #defines a number of identifiers in the application namespace.  Revert
     68    these #defines.  */
     69 #ifdef __sun
     70 # undef multibyte
     71 # undef eucw1
     72 # undef eucw2
     73 # undef eucw3
     74 # undef scrw1
     75 # undef scrw2
     76 # undef scrw3
     77 #endif
     78 
     79 /* Define wint_t and WEOF.  (Also done in wchar.in.h.)  */
     80 #if !@HAVE_WINT_T@ && !defined wint_t
     81 # define wint_t int
     82 # ifndef WEOF
     83 #  define WEOF -1
     84 # endif
     85 #else
     86 /* MSVC defines wint_t as 'unsigned short' in <crtdefs.h>.
     87    This is too small: ISO C 99 section 7.24.1.(2) says that wint_t must be
     88    "unchanged by default argument promotions".  Override it.  */
     89 # if defined _MSC_VER
     90 #  if !GNULIB_defined_wint_t
     91 #   include <crtdefs.h>
     92 typedef unsigned int rpl_wint_t;
     93 #   undef wint_t
     94 #   define wint_t rpl_wint_t
     95 #   define GNULIB_defined_wint_t 1
     96 #  endif
     97 # endif
     98 # ifndef WEOF
     99 #  define WEOF ((wint_t) -1)
    100 # endif
    101 #endif
    102 
    103 
    104 #if !GNULIB_defined_wctype_functions
    105 
    106 /* FreeBSD 4.4 to 4.11 has <wctype.h> but lacks the functions.
    107    Linux libc5 has <wctype.h> and the functions but they are broken.
    108    Assume all 11 functions (all isw* except iswblank) are implemented the
    109    same way, or not at all.  */
    110 # if ! @HAVE_ISWCNTRL@ || @REPLACE_ISWCNTRL@
    111 
    112 /* IRIX 5.3 has macros but no functions, its isw* macros refer to an
    113    undefined variable _ctmp_ and to <ctype.h> macros like _P, and they
    114    refer to system functions like _iswctype that are not in the
    115    standard C library.  Rather than try to get ancient buggy
    116    implementations like this to work, just disable them.  */
    117 #  undef iswalnum
    118 #  undef iswalpha
    119 #  undef iswblank
    120 #  undef iswcntrl
    121 #  undef iswdigit
    122 #  undef iswgraph
    123 #  undef iswlower
    124 #  undef iswprint
    125 #  undef iswpunct
    126 #  undef iswspace
    127 #  undef iswupper
    128 #  undef iswxdigit
    129 #  undef towlower
    130 #  undef towupper
    131 
    132 /* Linux libc5 has <wctype.h> and the functions but they are broken.  */
    133 #  if @REPLACE_ISWCNTRL@
    134 #   if !(defined __cplusplus && defined GNULIB_NAMESPACE)
    135 #    define iswalnum rpl_iswalnum
    136 #    define iswalpha rpl_iswalpha
    137 #    define iswblank rpl_iswblank
    138 #    define iswcntrl rpl_iswcntrl
    139 #    define iswdigit rpl_iswdigit
    140 #    define iswgraph rpl_iswgraph
    141 #    define iswlower rpl_iswlower
    142 #    define iswprint rpl_iswprint
    143 #    define iswpunct rpl_iswpunct
    144 #    define iswspace rpl_iswspace
    145 #    define iswupper rpl_iswupper
    146 #    define iswxdigit rpl_iswxdigit
    147 #   endif
    148 #  endif
    149 #  if @REPLACE_TOWLOWER@
    150 #   if !(defined __cplusplus && defined GNULIB_NAMESPACE)
    151 #    define towlower rpl_towlower
    152 #    define towupper rpl_towupper
    153 #   endif
    154 #  endif
    155 
    156 _GL_WCTYPE_INLINE int
    157 #  if @REPLACE_ISWCNTRL@
    158 rpl_iswalnum
    159 #  else
    160 iswalnum
    161 #  endif
    162          (wint_t wc)
    163 {
    164   return ((wc >= '0' && wc <= '9')
    165           || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'));
    166 }
    167 
    168 _GL_WCTYPE_INLINE int
    169 #  if @REPLACE_ISWCNTRL@
    170 rpl_iswalpha
    171 #  else
    172 iswalpha
    173 #  endif
    174          (wint_t wc)
    175 {
    176   return (wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z';
    177 }
    178 
    179 _GL_WCTYPE_INLINE int
    180 #  if @REPLACE_ISWCNTRL@
    181 rpl_iswblank
    182 #  else
    183 iswblank
    184 #  endif
    185          (wint_t wc)
    186 {
    187   return wc == ' ' || wc == '\t';
    188 }
    189 
    190 _GL_WCTYPE_INLINE int
    191 #  if @REPLACE_ISWCNTRL@
    192 rpl_iswcntrl
    193 #  else
    194 iswcntrl
    195 #  endif
    196         (wint_t wc)
    197 {
    198   return (wc & ~0x1f) == 0 || wc == 0x7f;
    199 }
    200 
    201 _GL_WCTYPE_INLINE int
    202 #  if @REPLACE_ISWCNTRL@
    203 rpl_iswdigit
    204 #  else
    205 iswdigit
    206 #  endif
    207          (wint_t wc)
    208 {
    209   return wc >= '0' && wc <= '9';
    210 }
    211 
    212 _GL_WCTYPE_INLINE int
    213 #  if @REPLACE_ISWCNTRL@
    214 rpl_iswgraph
    215 #  else
    216 iswgraph
    217 #  endif
    218          (wint_t wc)
    219 {
    220   return wc >= '!' && wc <= '~';
    221 }
    222 
    223 _GL_WCTYPE_INLINE int
    224 #  if @REPLACE_ISWCNTRL@
    225 rpl_iswlower
    226 #  else
    227 iswlower
    228 #  endif
    229          (wint_t wc)
    230 {
    231   return wc >= 'a' && wc <= 'z';
    232 }
    233 
    234 _GL_WCTYPE_INLINE int
    235 #  if @REPLACE_ISWCNTRL@
    236 rpl_iswprint
    237 #  else
    238 iswprint
    239 #  endif
    240          (wint_t wc)
    241 {
    242   return wc >= ' ' && wc <= '~';
    243 }
    244 
    245 _GL_WCTYPE_INLINE int
    246 #  if @REPLACE_ISWCNTRL@
    247 rpl_iswpunct
    248 #  else
    249 iswpunct
    250 #  endif
    251          (wint_t wc)
    252 {
    253   return (wc >= '!' && wc <= '~'
    254           && !((wc >= '0' && wc <= '9')
    255                || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z')));
    256 }
    257 
    258 _GL_WCTYPE_INLINE int
    259 #  if @REPLACE_ISWCNTRL@
    260 rpl_iswspace
    261 #  else
    262 iswspace
    263 #  endif
    264          (wint_t wc)
    265 {
    266   return (wc == ' ' || wc == '\t'
    267           || wc == '\n' || wc == '\v' || wc == '\f' || wc == '\r');
    268 }
    269 
    270 _GL_WCTYPE_INLINE int
    271 #  if @REPLACE_ISWCNTRL@
    272 rpl_iswupper
    273 #  else
    274 iswupper
    275 #  endif
    276          (wint_t wc)
    277 {
    278   return wc >= 'A' && wc <= 'Z';
    279 }
    280 
    281 _GL_WCTYPE_INLINE int
    282 #  if @REPLACE_ISWCNTRL@
    283 rpl_iswxdigit
    284 #  else
    285 iswxdigit
    286 #  endif
    287           (wint_t wc)
    288 {
    289   return ((wc >= '0' && wc <= '9')
    290           || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'F'));
    291 }
    292 
    293 _GL_WCTYPE_INLINE wint_t
    294 #  if @REPLACE_TOWLOWER@
    295 rpl_towlower
    296 #  else
    297 towlower
    298 #  endif
    299          (wint_t wc)
    300 {
    301   return (wc >= 'A' && wc <= 'Z' ? wc - 'A' + 'a' : wc);
    302 }
    303 
    304 _GL_WCTYPE_INLINE wint_t
    305 #  if @REPLACE_TOWLOWER@
    306 rpl_towupper
    307 #  else
    308 towupper
    309 #  endif
    310          (wint_t wc)
    311 {
    312   return (wc >= 'a' && wc <= 'z' ? wc - 'a' + 'A' : wc);
    313 }
    314 
    315 # elif @GNULIB_ISWBLANK@ && (! @HAVE_ISWBLANK@ || @REPLACE_ISWBLANK@)
    316 /* Only the iswblank function is missing.  */
    317 
    318 #  if @REPLACE_ISWBLANK@
    319 #   if !(defined __cplusplus && defined GNULIB_NAMESPACE)
    320 #    define iswblank rpl_iswblank
    321 #   endif
    322 _GL_FUNCDECL_RPL (iswblank, int, (wint_t wc));
    323 #  else
    324 _GL_FUNCDECL_SYS (iswblank, int, (wint_t wc));
    325 #  endif
    326 
    327 # endif
    328 
    329 # if defined __MINGW32__
    330 
    331 /* On native Windows, wchar_t is uint16_t, and wint_t is uint32_t.
    332    The functions towlower and towupper are implemented in the MSVCRT library
    333    to take a wchar_t argument and return a wchar_t result.  mingw declares
    334    these functions to take a wint_t argument and return a wint_t result.
    335    This means that:
    336    1. When the user passes an argument outside the range 0x0000..0xFFFF, the
    337       function will look only at the lower 16 bits.  This is allowed according
    338       to POSIX.
    339    2. The return value is returned in the lower 16 bits of the result register.
    340       The upper 16 bits are random: whatever happened to be in that part of the
    341       result register.  We need to fix this by adding a zero-extend from
    342       wchar_t to wint_t after the call.  */
    343 
    344 _GL_WCTYPE_INLINE wint_t
    345 rpl_towlower (wint_t wc)
    346 {
    347   return (wint_t) (wchar_t) towlower (wc);
    348 }
    349 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
    350 #   define towlower rpl_towlower
    351 #  endif
    352 
    353 _GL_WCTYPE_INLINE wint_t
    354 rpl_towupper (wint_t wc)
    355 {
    356   return (wint_t) (wchar_t) towupper (wc);
    357 }
    358 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
    359 #   define towupper rpl_towupper
    360 #  endif
    361 
    362 # endif /* __MINGW32__ */
    363 
    364 # define GNULIB_defined_wctype_functions 1
    365 #endif
    366 
    367 #if @REPLACE_ISWCNTRL@
    368 _GL_CXXALIAS_RPL (iswalnum, int, (wint_t wc));
    369 _GL_CXXALIAS_RPL (iswalpha, int, (wint_t wc));
    370 _GL_CXXALIAS_RPL (iswcntrl, int, (wint_t wc));
    371 _GL_CXXALIAS_RPL (iswdigit, int, (wint_t wc));
    372 _GL_CXXALIAS_RPL (iswgraph, int, (wint_t wc));
    373 _GL_CXXALIAS_RPL (iswlower, int, (wint_t wc));
    374 _GL_CXXALIAS_RPL (iswprint, int, (wint_t wc));
    375 _GL_CXXALIAS_RPL (iswpunct, int, (wint_t wc));
    376 _GL_CXXALIAS_RPL (iswspace, int, (wint_t wc));
    377 _GL_CXXALIAS_RPL (iswupper, int, (wint_t wc));
    378 _GL_CXXALIAS_RPL (iswxdigit, int, (wint_t wc));
    379 #else
    380 _GL_CXXALIAS_SYS (iswalnum, int, (wint_t wc));
    381 _GL_CXXALIAS_SYS (iswalpha, int, (wint_t wc));
    382 _GL_CXXALIAS_SYS (iswcntrl, int, (wint_t wc));
    383 _GL_CXXALIAS_SYS (iswdigit, int, (wint_t wc));
    384 _GL_CXXALIAS_SYS (iswgraph, int, (wint_t wc));
    385 _GL_CXXALIAS_SYS (iswlower, int, (wint_t wc));
    386 _GL_CXXALIAS_SYS (iswprint, int, (wint_t wc));
    387 _GL_CXXALIAS_SYS (iswpunct, int, (wint_t wc));
    388 _GL_CXXALIAS_SYS (iswspace, int, (wint_t wc));
    389 _GL_CXXALIAS_SYS (iswupper, int, (wint_t wc));
    390 _GL_CXXALIAS_SYS (iswxdigit, int, (wint_t wc));
    391 #endif
    392 _GL_CXXALIASWARN (iswalnum);
    393 _GL_CXXALIASWARN (iswalpha);
    394 _GL_CXXALIASWARN (iswcntrl);
    395 _GL_CXXALIASWARN (iswdigit);
    396 _GL_CXXALIASWARN (iswgraph);
    397 _GL_CXXALIASWARN (iswlower);
    398 _GL_CXXALIASWARN (iswprint);
    399 _GL_CXXALIASWARN (iswpunct);
    400 _GL_CXXALIASWARN (iswspace);
    401 _GL_CXXALIASWARN (iswupper);
    402 _GL_CXXALIASWARN (iswxdigit);
    403 
    404 #if @GNULIB_ISWBLANK@
    405 # if @REPLACE_ISWCNTRL@ || @REPLACE_ISWBLANK@
    406 _GL_CXXALIAS_RPL (iswblank, int, (wint_t wc));
    407 # else
    408 _GL_CXXALIAS_SYS (iswblank, int, (wint_t wc));
    409 # endif
    410 _GL_CXXALIASWARN (iswblank);
    411 #endif
    412 
    413 #if !@HAVE_WCTYPE_T@
    414 # if !GNULIB_defined_wctype_t
    415 typedef void * wctype_t;
    416 #  define GNULIB_defined_wctype_t 1
    417 # endif
    418 #endif
    419 
    420 /* Get a descriptor for a wide character property.  */
    421 #if @GNULIB_WCTYPE@
    422 # if !@HAVE_WCTYPE_T@
    423 _GL_FUNCDECL_SYS (wctype, wctype_t, (const char *name));
    424 # endif
    425 _GL_CXXALIAS_SYS (wctype, wctype_t, (const char *name));
    426 _GL_CXXALIASWARN (wctype);
    427 #elif defined GNULIB_POSIXCHECK
    428 # undef wctype
    429 # if HAVE_RAW_DECL_WCTYPE
    430 _GL_WARN_ON_USE (wctype, "wctype is unportable - "
    431                  "use gnulib module wctype for portability");
    432 # endif
    433 #endif
    434 
    435 /* Test whether a wide character has a given property.
    436    The argument WC must be either a wchar_t value or WEOF.
    437    The argument DESC must have been returned by the wctype() function.  */
    438 #if @GNULIB_ISWCTYPE@
    439 # if !@HAVE_WCTYPE_T@
    440 _GL_FUNCDECL_SYS (iswctype, int, (wint_t wc, wctype_t desc));
    441 # endif
    442 _GL_CXXALIAS_SYS (iswctype, int, (wint_t wc, wctype_t desc));
    443 _GL_CXXALIASWARN (iswctype);
    444 #elif defined GNULIB_POSIXCHECK
    445 # undef iswctype
    446 # if HAVE_RAW_DECL_ISWCTYPE
    447 _GL_WARN_ON_USE (iswctype, "iswctype is unportable - "
    448                  "use gnulib module iswctype for portability");
    449 # endif
    450 #endif
    451 
    452 #if @REPLACE_TOWLOWER@ || defined __MINGW32__
    453 _GL_CXXALIAS_RPL (towlower, wint_t, (wint_t wc));
    454 _GL_CXXALIAS_RPL (towupper, wint_t, (wint_t wc));
    455 #else
    456 _GL_CXXALIAS_SYS (towlower, wint_t, (wint_t wc));
    457 _GL_CXXALIAS_SYS (towupper, wint_t, (wint_t wc));
    458 #endif
    459 _GL_CXXALIASWARN (towlower);
    460 _GL_CXXALIASWARN (towupper);
    461 
    462 #if !@HAVE_WCTRANS_T@
    463 # if !GNULIB_defined_wctrans_t
    464 typedef void * wctrans_t;
    465 #  define GNULIB_defined_wctrans_t 1
    466 # endif
    467 #endif
    468 
    469 /* Get a descriptor for a wide character case conversion.  */
    470 #if @GNULIB_WCTRANS@
    471 # if !@HAVE_WCTRANS_T@
    472 _GL_FUNCDECL_SYS (wctrans, wctrans_t, (const char *name));
    473 # endif
    474 _GL_CXXALIAS_SYS (wctrans, wctrans_t, (const char *name));
    475 _GL_CXXALIASWARN (wctrans);
    476 #elif defined GNULIB_POSIXCHECK
    477 # undef wctrans
    478 # if HAVE_RAW_DECL_WCTRANS
    479 _GL_WARN_ON_USE (wctrans, "wctrans is unportable - "
    480                  "use gnulib module wctrans for portability");
    481 # endif
    482 #endif
    483 
    484 /* Perform a given case conversion on a wide character.
    485    The argument WC must be either a wchar_t value or WEOF.
    486    The argument DESC must have been returned by the wctrans() function.  */
    487 #if @GNULIB_TOWCTRANS@
    488 # if !@HAVE_WCTRANS_T@
    489 _GL_FUNCDECL_SYS (towctrans, wint_t, (wint_t wc, wctrans_t desc));
    490 # endif
    491 _GL_CXXALIAS_SYS (towctrans, wint_t, (wint_t wc, wctrans_t desc));
    492 _GL_CXXALIASWARN (towctrans);
    493 #elif defined GNULIB_POSIXCHECK
    494 # undef towctrans
    495 # if HAVE_RAW_DECL_TOWCTRANS
    496 _GL_WARN_ON_USE (towctrans, "towctrans is unportable - "
    497                  "use gnulib module towctrans for portability");
    498 # endif
    499 #endif
    500 
    501 _GL_INLINE_HEADER_END
    502 
    503 #endif /* _@GUARD_PREFIX@_WCTYPE_H */
    504 #endif /* _@GUARD_PREFIX@_WCTYPE_H */
    505