Merge branch 'upstream' into stable
[gnulib.git] / lib / wctype.in.h
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 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 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, 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 @PRAGMA_COLUMNS@
35
36 #if @HAVE_WINT_T@
37 /* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>.
38    Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
39    <wchar.h>.
40    BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
41    included before <wchar.h>.  */
42 # include <stddef.h>
43 # include <stdio.h>
44 # include <time.h>
45 # include <wchar.h>
46 #endif
47
48 /* Include the original <wctype.h> if it exists.
49    BeOS 5 has the functions but no <wctype.h>.  */
50 /* The include_next requires a split double-inclusion guard.  */
51 #if @HAVE_WCTYPE_H@
52 # @INCLUDE_NEXT@ @NEXT_WCTYPE_H@
53 #endif
54
55 #ifndef _GL_WCTYPE_H
56 #define _GL_WCTYPE_H
57
58 /* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
59
60 /* The definition of _GL_WARN_ON_USE is copied here.  */
61
62 /* Define wint_t and WEOF.  (Also done in wchar.in.h.)  */
63 #if !@HAVE_WINT_T@ && !defined wint_t
64 # define wint_t int
65 # ifndef WEOF
66 #  define WEOF -1
67 # endif
68 #else
69 # ifndef WEOF
70 #  define WEOF ((wint_t) -1)
71 # endif
72 #endif
73
74
75 /* FreeBSD 4.4 to 4.11 has <wctype.h> but lacks the functions.
76    Linux libc5 has <wctype.h> and the functions but they are broken.
77    Assume all 11 functions (all isw* except iswblank) are implemented the
78    same way, or not at all.  */
79 #if ! @HAVE_ISWCNTRL@ || @REPLACE_ISWCNTRL@
80
81 /* IRIX 5.3 has macros but no functions, its isw* macros refer to an
82    undefined variable _ctmp_ and to <ctype.h> macros like _P, and they
83    refer to system functions like _iswctype that are not in the
84    standard C library.  Rather than try to get ancient buggy
85    implementations like this to work, just disable them.  */
86 # undef iswalnum
87 # undef iswalpha
88 # undef iswblank
89 # undef iswcntrl
90 # undef iswdigit
91 # undef iswgraph
92 # undef iswlower
93 # undef iswprint
94 # undef iswpunct
95 # undef iswspace
96 # undef iswupper
97 # undef iswxdigit
98 # undef towlower
99 # undef towupper
100
101 /* Linux libc5 has <wctype.h> and the functions but they are broken.  */
102 # if @REPLACE_ISWCNTRL@
103 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
104 #   define iswalnum rpl_iswalnum
105 #   define iswalpha rpl_iswalpha
106 #   define iswblank rpl_iswblank
107 #   define iswcntrl rpl_iswcntrl
108 #   define iswdigit rpl_iswdigit
109 #   define iswgraph rpl_iswgraph
110 #   define iswlower rpl_iswlower
111 #   define iswprint rpl_iswprint
112 #   define iswpunct rpl_iswpunct
113 #   define iswspace rpl_iswspace
114 #   define iswupper rpl_iswupper
115 #   define iswxdigit rpl_iswxdigit
116 #   define towlower rpl_towlower
117 #   define towupper rpl_towupper
118 #  endif
119 # endif
120
121 static inline int
122 # if @REPLACE_ISWCNTRL@
123 rpl_iswalnum
124 # else
125 iswalnum
126 # endif
127          (wint_t wc)
128 {
129   return ((wc >= '0' && wc <= '9')
130           || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'));
131 }
132
133 static inline int
134 # if @REPLACE_ISWCNTRL@
135 rpl_iswalpha
136 # else
137 iswalpha
138 # endif
139          (wint_t wc)
140 {
141   return (wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z';
142 }
143
144 static inline int
145 # if @REPLACE_ISWCNTRL@
146 rpl_iswblank
147 # else
148 iswblank
149 # endif
150          (wint_t wc)
151 {
152   return wc == ' ' || wc == '\t';
153 }
154
155 static inline int
156 # if @REPLACE_ISWCNTRL@
157 rpl_iswcntrl
158 # else
159 iswcntrl
160 # endif
161         (wint_t wc)
162 {
163   return (wc & ~0x1f) == 0 || wc == 0x7f;
164 }
165
166 static inline int
167 # if @REPLACE_ISWCNTRL@
168 rpl_iswdigit
169 # else
170 iswdigit
171 # endif
172          (wint_t wc)
173 {
174   return wc >= '0' && wc <= '9';
175 }
176
177 static inline int
178 # if @REPLACE_ISWCNTRL@
179 rpl_iswgraph
180 # else
181 iswgraph
182 # endif
183          (wint_t wc)
184 {
185   return wc >= '!' && wc <= '~';
186 }
187
188 static inline int
189 # if @REPLACE_ISWCNTRL@
190 rpl_iswlower
191 # else
192 iswlower
193 # endif
194          (wint_t wc)
195 {
196   return wc >= 'a' && wc <= 'z';
197 }
198
199 static inline int
200 # if @REPLACE_ISWCNTRL@
201 rpl_iswprint
202 # else
203 iswprint
204 # endif
205          (wint_t wc)
206 {
207   return wc >= ' ' && wc <= '~';
208 }
209
210 static inline int
211 # if @REPLACE_ISWCNTRL@
212 rpl_iswpunct
213 # else
214 iswpunct
215 # endif
216          (wint_t wc)
217 {
218   return (wc >= '!' && wc <= '~'
219           && !((wc >= '0' && wc <= '9')
220                || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z')));
221 }
222
223 static inline int
224 # if @REPLACE_ISWCNTRL@
225 rpl_iswspace
226 # else
227 iswspace
228 # endif
229          (wint_t wc)
230 {
231   return (wc == ' ' || wc == '\t'
232           || wc == '\n' || wc == '\v' || wc == '\f' || wc == '\r');
233 }
234
235 static inline int
236 # if @REPLACE_ISWCNTRL@
237 rpl_iswupper
238 # else
239 iswupper
240 # endif
241          (wint_t wc)
242 {
243   return wc >= 'A' && wc <= 'Z';
244 }
245
246 static inline int
247 # if @REPLACE_ISWCNTRL@
248 rpl_iswxdigit
249 # else
250 iswxdigit
251 # endif
252           (wint_t wc)
253 {
254   return ((wc >= '0' && wc <= '9')
255           || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'F'));
256 }
257
258 static inline wint_t
259 # if @REPLACE_ISWCNTRL@
260 rpl_towlower
261 # else
262 towlower
263 # endif
264          (wint_t wc)
265 {
266   return (wc >= 'A' && wc <= 'Z' ? wc - 'A' + 'a' : wc);
267 }
268
269 static inline wint_t
270 # if @REPLACE_ISWCNTRL@
271 rpl_towupper
272 # else
273 towupper
274 # endif
275          (wint_t wc)
276 {
277   return (wc >= 'a' && wc <= 'z' ? wc - 'a' + 'A' : wc);
278 }
279
280 #elif ! @HAVE_ISWBLANK@ || @REPLACE_ISWBLANK@
281 /* Only the iswblank function is missing.  */
282
283 # if @REPLACE_ISWBLANK@
284 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
285 #   define iswblank rpl_iswblank
286 #  endif
287 # endif
288
289 static inline int
290 # if @REPLACE_ISWBLANK@
291 rpl_iswblank
292 # else
293 iswblank
294 # endif
295          (wint_t wc)
296 {
297   return wc == ' ' || wc == '\t';
298 }
299
300 #endif
301
302 #if defined __MINGW32__
303
304 /* On native Windows, wchar_t is uint16_t, and wint_t is uint32_t.
305    The functions towlower and towupper are implemented in the MSVCRT library
306    to take a wchar_t argument and return a wchar_t result.  mingw declares
307    these functions to take a wint_t argument and return a wint_t result.
308    This means that:
309    1. When the user passes an argument outside the range 0x0000..0xFFFF, the
310       function will look only at the lower 16 bits.  This is allowed according
311       to POSIX.
312    2. The return value is returned in the lower 16 bits of the result register.
313       The upper 16 bits are random: whatever happened to be in that part of the
314       result register.  We need to fix this by adding a zero-extend from
315       wchar_t to wint_t after the call.  */
316
317 static inline wint_t
318 rpl_towlower (wint_t wc)
319 {
320   return (wint_t) (wchar_t) towlower (wc);
321 }
322 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
323 #  define towlower rpl_towlower
324 # endif
325
326 static inline wint_t
327 rpl_towupper (wint_t wc)
328 {
329   return (wint_t) (wchar_t) towupper (wc);
330 }
331 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
332 #  define towupper rpl_towupper
333 # endif
334
335 #endif /* __MINGW32__ */
336
337 #if @REPLACE_ISWCNTRL@
338 _GL_CXXALIAS_RPL (iswalnum, int, (wint_t wc));
339 _GL_CXXALIAS_RPL (iswalpha, int, (wint_t wc));
340 _GL_CXXALIAS_RPL (iswblank, int, (wint_t wc));
341 _GL_CXXALIAS_RPL (iswcntrl, int, (wint_t wc));
342 _GL_CXXALIAS_RPL (iswdigit, int, (wint_t wc));
343 _GL_CXXALIAS_RPL (iswgraph, int, (wint_t wc));
344 _GL_CXXALIAS_RPL (iswlower, int, (wint_t wc));
345 _GL_CXXALIAS_RPL (iswprint, int, (wint_t wc));
346 _GL_CXXALIAS_RPL (iswpunct, int, (wint_t wc));
347 _GL_CXXALIAS_RPL (iswspace, int, (wint_t wc));
348 _GL_CXXALIAS_RPL (iswupper, int, (wint_t wc));
349 _GL_CXXALIAS_RPL (iswxdigit, int, (wint_t wc));
350 #else
351 _GL_CXXALIAS_SYS (iswalnum, int, (wint_t wc));
352 _GL_CXXALIAS_SYS (iswalpha, int, (wint_t wc));
353 # if @REPLACE_ISWBLANK@
354 _GL_CXXALIAS_RPL (iswblank, int, (wint_t wc));
355 # else
356 _GL_CXXALIAS_SYS (iswblank, int, (wint_t wc));
357 # endif
358 _GL_CXXALIAS_SYS (iswcntrl, int, (wint_t wc));
359 _GL_CXXALIAS_SYS (iswdigit, int, (wint_t wc));
360 _GL_CXXALIAS_SYS (iswgraph, int, (wint_t wc));
361 _GL_CXXALIAS_SYS (iswlower, int, (wint_t wc));
362 _GL_CXXALIAS_SYS (iswprint, int, (wint_t wc));
363 _GL_CXXALIAS_SYS (iswpunct, int, (wint_t wc));
364 _GL_CXXALIAS_SYS (iswspace, int, (wint_t wc));
365 _GL_CXXALIAS_SYS (iswupper, int, (wint_t wc));
366 _GL_CXXALIAS_SYS (iswxdigit, int, (wint_t wc));
367 #endif
368 _GL_CXXALIASWARN (iswalnum);
369 _GL_CXXALIASWARN (iswalpha);
370 _GL_CXXALIASWARN (iswblank);
371 _GL_CXXALIASWARN (iswcntrl);
372 _GL_CXXALIASWARN (iswdigit);
373 _GL_CXXALIASWARN (iswgraph);
374 _GL_CXXALIASWARN (iswlower);
375 _GL_CXXALIASWARN (iswprint);
376 _GL_CXXALIASWARN (iswpunct);
377 _GL_CXXALIASWARN (iswspace);
378 _GL_CXXALIASWARN (iswupper);
379 _GL_CXXALIASWARN (iswxdigit);
380
381 #if @REPLACE_ISWCNTRL@ || defined __MINGW32__
382 _GL_CXXALIAS_RPL (towlower, wint_t, (wint_t wc));
383 _GL_CXXALIAS_RPL (towupper, wint_t, (wint_t wc));
384 #else
385 _GL_CXXALIAS_SYS (towlower, wint_t, (wint_t wc));
386 _GL_CXXALIAS_SYS (towupper, wint_t, (wint_t wc));
387 #endif
388 _GL_CXXALIASWARN (towlower);
389 _GL_CXXALIASWARN (towupper);
390
391
392 #endif /* _GL_WCTYPE_H */
393 #endif /* _GL_WCTYPE_H */