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