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