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