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@
rpl_iswalnum(wint_t wc)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@
rpl_iswalpha(wint_t wc)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@
rpl_iswblank(wint_t wc)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@
rpl_iswcntrl(wint_t wc)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@
rpl_iswdigit(wint_t wc)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@
rpl_iswgraph(wint_t wc)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@
rpl_iswlower(wint_t wc)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@
rpl_iswprint(wint_t wc)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@
rpl_iswpunct(wint_t wc)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@
rpl_iswspace(wint_t wc)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@
rpl_iswupper(wint_t wc)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@
rpl_iswxdigit(wint_t wc)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@
rpl_towlower(wint_t wc)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@
rpl_towupper(wint_t wc)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
rpl_towlower(wint_t wc)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
rpl_towupper(wint_t wc)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