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