1/* A substitute for ISO C99 <wctype.h>, for platforms that lack it. 2 3 Copyright (C) 2006-2010 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 Lesser General Public License as published by 7 the Free Software Foundation; either version 2, 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 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public License 16 along with this program; if not, write to the Free Software Foundation, 17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 18 19/* Written by Bruno Haible and Paul Eggert. */ 20 21/* 22 * ISO C 99 <wctype.h> for platforms that lack it. 23 * <http://www.opengroup.org/susv3xbd/wctype.h.html> 24 * 25 * iswctype, towctrans, towlower, towupper, wctrans, wctype, 26 * wctrans_t, and wctype_t are not yet implemented. 27 */ 28 29#ifndef _GL_WCTYPE_H 30 31#if __GNUC__ >= 3 32@PRAGMA_SYSTEM_HEADER@ 33#endif 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 _GL_WCTYPE_H 55#define _GL_WCTYPE_H 56 57/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ 58 59/* The definition of _GL_WARN_ON_USE is copied here. */ 60 61/* Define wint_t and WEOF. (Also done in wchar.in.h.) */ 62#if !@HAVE_WINT_T@ && !defined wint_t 63# define wint_t int 64# ifndef WEOF 65# define WEOF -1 66# endif 67#else 68# ifndef WEOF 69# define WEOF ((wint_t) -1) 70# endif 71#endif 72 73 74/* FreeBSD 4.4 to 4.11 has <wctype.h> but lacks the functions. 75 Linux libc5 has <wctype.h> and the functions but they are broken. 76 Assume all 11 functions (all isw* except iswblank) are implemented the 77 same way, or not at all. */ 78#if ! @HAVE_ISWCNTRL@ || @REPLACE_ISWCNTRL@ 79 80/* IRIX 5.3 has macros but no functions, its isw* macros refer to an 81 undefined variable _ctmp_ and to <ctype.h> macros like _P, and they 82 refer to system functions like _iswctype that are not in the 83 standard C library. Rather than try to get ancient buggy 84 implementations like this to work, just disable them. */ 85# undef iswalnum 86# undef iswalpha 87# undef iswblank 88# undef iswcntrl 89# undef iswdigit 90# undef iswgraph 91# undef iswlower 92# undef iswprint 93# undef iswpunct 94# undef iswspace 95# undef iswupper 96# undef iswxdigit 97# undef towlower 98# undef towupper 99 100/* Linux libc5 has <wctype.h> and the functions but they are broken. */ 101# if @REPLACE_ISWCNTRL@ 102# if !(defined __cplusplus && defined GNULIB_NAMESPACE) 103# define iswalnum rpl_iswalnum 104# define iswalpha rpl_iswalpha 105# define iswblank rpl_iswblank 106# define iswcntrl rpl_iswcntrl 107# define iswdigit rpl_iswdigit 108# define iswgraph rpl_iswgraph 109# define iswlower rpl_iswlower 110# define iswprint rpl_iswprint 111# define iswpunct rpl_iswpunct 112# define iswspace rpl_iswspace 113# define iswupper rpl_iswupper 114# define iswxdigit rpl_iswxdigit 115# define towlower rpl_towlower 116# define towupper rpl_towupper 117# endif 118# endif 119 120static inline int 121# if @REPLACE_ISWCNTRL@ 122rpl_iswalnum 123# else 124iswalnum 125# endif 126 (wint_t wc) 127{ 128 return ((wc >= '0' && wc <= '9') 129 || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z')); 130} 131 132static inline int 133# if @REPLACE_ISWCNTRL@ 134rpl_iswalpha 135# else 136iswalpha 137# endif 138 (wint_t wc) 139{ 140 return (wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'; 141} 142 143static inline int 144# if @REPLACE_ISWCNTRL@ 145rpl_iswblank 146# else 147iswblank 148# endif 149 (wint_t wc) 150{ 151 return wc == ' ' || wc == '\t'; 152} 153 154static inline int 155# if @REPLACE_ISWCNTRL@ 156rpl_iswcntrl 157# else 158iswcntrl 159# endif 160 (wint_t wc) 161{ 162 return (wc & ~0x1f) == 0 || wc == 0x7f; 163} 164 165static inline int 166# if @REPLACE_ISWCNTRL@ 167rpl_iswdigit 168# else 169iswdigit 170# endif 171 (wint_t wc) 172{ 173 return wc >= '0' && wc <= '9'; 174} 175 176static inline int 177# if @REPLACE_ISWCNTRL@ 178rpl_iswgraph 179# else 180iswgraph 181# endif 182 (wint_t wc) 183{ 184 return wc >= '!' && wc <= '~'; 185} 186 187static inline int 188# if @REPLACE_ISWCNTRL@ 189rpl_iswlower 190# else 191iswlower 192# endif 193 (wint_t wc) 194{ 195 return wc >= 'a' && wc <= 'z'; 196} 197 198static inline int 199# if @REPLACE_ISWCNTRL@ 200rpl_iswprint 201# else 202iswprint 203# endif 204 (wint_t wc) 205{ 206 return wc >= ' ' && wc <= '~'; 207} 208 209static inline int 210# if @REPLACE_ISWCNTRL@ 211rpl_iswpunct 212# else 213iswpunct 214# endif 215 (wint_t wc) 216{ 217 return (wc >= '!' && wc <= '~' 218 && !((wc >= '0' && wc <= '9') 219 || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'))); 220} 221 222static inline int 223# if @REPLACE_ISWCNTRL@ 224rpl_iswspace 225# else 226iswspace 227# endif 228 (wint_t wc) 229{ 230 return (wc == ' ' || wc == '\t' 231 || wc == '\n' || wc == '\v' || wc == '\f' || wc == '\r'); 232} 233 234static inline int 235# if @REPLACE_ISWCNTRL@ 236rpl_iswupper 237# else 238iswupper 239# endif 240 (wint_t wc) 241{ 242 return wc >= 'A' && wc <= 'Z'; 243} 244 245static inline int 246# if @REPLACE_ISWCNTRL@ 247rpl_iswxdigit 248# else 249iswxdigit 250# endif 251 (wint_t wc) 252{ 253 return ((wc >= '0' && wc <= '9') 254 || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'F')); 255} 256 257static inline wint_t 258# if @REPLACE_ISWCNTRL@ 259rpl_towlower 260# else 261towlower 262# endif 263 (wint_t wc) 264{ 265 return (wc >= 'A' && wc <= 'Z' ? wc - 'A' + 'a' : wc); 266} 267 268static inline wint_t 269# if @REPLACE_ISWCNTRL@ 270rpl_towupper 271# else 272towupper 273# endif 274 (wint_t wc) 275{ 276 return (wc >= 'a' && wc <= 'z' ? wc - 'a' + 'A' : wc); 277} 278 279#elif ! @HAVE_ISWBLANK@ 280/* Only the iswblank function is missing. */ 281 282static inline int 283iswblank (wint_t wc) 284{ 285 return wc == ' ' || wc == '\t'; 286} 287 288#endif 289 290#if defined __MINGW32__ 291 292/* On native Windows, wchar_t is uint16_t, and wint_t is uint32_t. 293 The functions towlower and towupper are implemented in the MSVCRT library 294 to take a wchar_t argument and return a wchar_t result. mingw declares 295 these functions to take a wint_t argument and return a wint_t result. 296 This means that: 297 1. When the user passes an argument outside the range 0x0000..0xFFFF, the 298 function will look only at the lower 16 bits. This is allowed according 299 to POSIX. 300 2. The return value is returned in the lower 16 bits of the result register. 301 The upper 16 bits are random: whatever happened to be in that part of the 302 result register. We need to fix this by adding a zero-extend from 303 wchar_t to wint_t after the call. */ 304 305static inline wint_t 306rpl_towlower (wint_t wc) 307{ 308 return (wint_t) (wchar_t) towlower (wc); 309} 310# if !(defined __cplusplus && defined GNULIB_NAMESPACE) 311# define towlower rpl_towlower 312# endif 313 314static inline wint_t 315rpl_towupper (wint_t wc) 316{ 317 return (wint_t) (wchar_t) towupper (wc); 318} 319# if !(defined __cplusplus && defined GNULIB_NAMESPACE) 320# define towupper rpl_towupper 321# endif 322 323#endif /* __MINGW32__ */ 324 325#if @REPLACE_ISWCNTRL@ 326_GL_CXXALIAS_RPL (iswalnum, int, (wint_t wc)); 327_GL_CXXALIAS_RPL (iswalpha, int, (wint_t wc)); 328_GL_CXXALIAS_RPL (iswblank, int, (wint_t wc)); 329_GL_CXXALIAS_RPL (iswcntrl, int, (wint_t wc)); 330_GL_CXXALIAS_RPL (iswdigit, int, (wint_t wc)); 331_GL_CXXALIAS_RPL (iswgraph, int, (wint_t wc)); 332_GL_CXXALIAS_RPL (iswlower, int, (wint_t wc)); 333_GL_CXXALIAS_RPL (iswprint, int, (wint_t wc)); 334_GL_CXXALIAS_RPL (iswpunct, int, (wint_t wc)); 335_GL_CXXALIAS_RPL (iswspace, int, (wint_t wc)); 336_GL_CXXALIAS_RPL (iswupper, int, (wint_t wc)); 337_GL_CXXALIAS_RPL (iswxdigit, int, (wint_t wc)); 338#else 339_GL_CXXALIAS_SYS (iswalnum, int, (wint_t wc)); 340_GL_CXXALIAS_SYS (iswalpha, int, (wint_t wc)); 341_GL_CXXALIAS_SYS (iswblank, int, (wint_t wc)); 342_GL_CXXALIAS_SYS (iswcntrl, int, (wint_t wc)); 343_GL_CXXALIAS_SYS (iswdigit, int, (wint_t wc)); 344_GL_CXXALIAS_SYS (iswgraph, int, (wint_t wc)); 345_GL_CXXALIAS_SYS (iswlower, int, (wint_t wc)); 346_GL_CXXALIAS_SYS (iswprint, int, (wint_t wc)); 347_GL_CXXALIAS_SYS (iswpunct, int, (wint_t wc)); 348_GL_CXXALIAS_SYS (iswspace, int, (wint_t wc)); 349_GL_CXXALIAS_SYS (iswupper, int, (wint_t wc)); 350_GL_CXXALIAS_SYS (iswxdigit, int, (wint_t wc)); 351#endif 352_GL_CXXALIASWARN (iswalnum); 353_GL_CXXALIASWARN (iswalpha); 354_GL_CXXALIASWARN (iswblank); 355_GL_CXXALIASWARN (iswcntrl); 356_GL_CXXALIASWARN (iswdigit); 357_GL_CXXALIASWARN (iswgraph); 358_GL_CXXALIASWARN (iswlower); 359_GL_CXXALIASWARN (iswprint); 360_GL_CXXALIASWARN (iswpunct); 361_GL_CXXALIASWARN (iswspace); 362_GL_CXXALIASWARN (iswupper); 363_GL_CXXALIASWARN (iswxdigit); 364 365#if @REPLACE_ISWCNTRL@ || defined __MINGW32__ 366_GL_CXXALIAS_RPL (towlower, wint_t, (wint_t wc)); 367_GL_CXXALIAS_RPL (towupper, wint_t, (wint_t wc)); 368#else 369_GL_CXXALIAS_SYS (towlower, wint_t, (wint_t wc)); 370_GL_CXXALIAS_SYS (towupper, wint_t, (wint_t wc)); 371#endif 372_GL_CXXALIASWARN (towlower); 373_GL_CXXALIASWARN (towupper); 374 375 376#endif /* _GL_WCTYPE_H */ 377#endif /* _GL_WCTYPE_H */ 378