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