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