wctype: Make it work in C++ mode on OSF/1 5.1.
[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 extern int rpl_iswblank (wint_t wc);
288 # else
289 extern int iswblank (wint_t wc);
290 # endif
291
292 #endif
293
294 #if defined __MINGW32__
295
296 /* On native Windows, wchar_t is uint16_t, and wint_t is uint32_t.
297    The functions towlower and towupper are implemented in the MSVCRT library
298    to take a wchar_t argument and return a wchar_t result.  mingw declares
299    these functions to take a wint_t argument and return a wint_t result.
300    This means that:
301    1. When the user passes an argument outside the range 0x0000..0xFFFF, the
302       function will look only at the lower 16 bits.  This is allowed according
303       to POSIX.
304    2. The return value is returned in the lower 16 bits of the result register.
305       The upper 16 bits are random: whatever happened to be in that part of the
306       result register.  We need to fix this by adding a zero-extend from
307       wchar_t to wint_t after the call.  */
308
309 static inline wint_t
310 rpl_towlower (wint_t wc)
311 {
312   return (wint_t) (wchar_t) towlower (wc);
313 }
314 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
315 #  define towlower rpl_towlower
316 # endif
317
318 static inline wint_t
319 rpl_towupper (wint_t wc)
320 {
321   return (wint_t) (wchar_t) towupper (wc);
322 }
323 # if !(defined __cplusplus && defined GNULIB_NAMESPACE)
324 #  define towupper rpl_towupper
325 # endif
326
327 #endif /* __MINGW32__ */
328
329 #if @REPLACE_ISWCNTRL@
330 _GL_CXXALIAS_RPL (iswalnum, int, (wint_t wc));
331 _GL_CXXALIAS_RPL (iswalpha, int, (wint_t wc));
332 _GL_CXXALIAS_RPL (iswblank, int, (wint_t wc));
333 _GL_CXXALIAS_RPL (iswcntrl, int, (wint_t wc));
334 _GL_CXXALIAS_RPL (iswdigit, int, (wint_t wc));
335 _GL_CXXALIAS_RPL (iswgraph, int, (wint_t wc));
336 _GL_CXXALIAS_RPL (iswlower, int, (wint_t wc));
337 _GL_CXXALIAS_RPL (iswprint, int, (wint_t wc));
338 _GL_CXXALIAS_RPL (iswpunct, int, (wint_t wc));
339 _GL_CXXALIAS_RPL (iswspace, int, (wint_t wc));
340 _GL_CXXALIAS_RPL (iswupper, int, (wint_t wc));
341 _GL_CXXALIAS_RPL (iswxdigit, int, (wint_t wc));
342 #else
343 _GL_CXXALIAS_SYS (iswalnum, int, (wint_t wc));
344 _GL_CXXALIAS_SYS (iswalpha, int, (wint_t wc));
345 # if @REPLACE_ISWBLANK@
346 _GL_CXXALIAS_RPL (iswblank, int, (wint_t wc));
347 # else
348 _GL_CXXALIAS_SYS (iswblank, int, (wint_t wc));
349 # endif
350 _GL_CXXALIAS_SYS (iswcntrl, int, (wint_t wc));
351 _GL_CXXALIAS_SYS (iswdigit, int, (wint_t wc));
352 _GL_CXXALIAS_SYS (iswgraph, int, (wint_t wc));
353 _GL_CXXALIAS_SYS (iswlower, int, (wint_t wc));
354 _GL_CXXALIAS_SYS (iswprint, int, (wint_t wc));
355 _GL_CXXALIAS_SYS (iswpunct, int, (wint_t wc));
356 _GL_CXXALIAS_SYS (iswspace, int, (wint_t wc));
357 _GL_CXXALIAS_SYS (iswupper, int, (wint_t wc));
358 _GL_CXXALIAS_SYS (iswxdigit, int, (wint_t wc));
359 #endif
360 _GL_CXXALIASWARN (iswalnum);
361 _GL_CXXALIASWARN (iswalpha);
362 _GL_CXXALIASWARN (iswblank);
363 _GL_CXXALIASWARN (iswcntrl);
364 _GL_CXXALIASWARN (iswdigit);
365 _GL_CXXALIASWARN (iswgraph);
366 _GL_CXXALIASWARN (iswlower);
367 _GL_CXXALIASWARN (iswprint);
368 _GL_CXXALIASWARN (iswpunct);
369 _GL_CXXALIASWARN (iswspace);
370 _GL_CXXALIASWARN (iswupper);
371 _GL_CXXALIASWARN (iswxdigit);
372
373 #if @REPLACE_ISWCNTRL@ || defined __MINGW32__
374 _GL_CXXALIAS_RPL (towlower, wint_t, (wint_t wc));
375 _GL_CXXALIAS_RPL (towupper, wint_t, (wint_t wc));
376 #else
377 _GL_CXXALIAS_SYS (towlower, wint_t, (wint_t wc));
378 _GL_CXXALIAS_SYS (towupper, wint_t, (wint_t wc));
379 #endif
380 _GL_CXXALIASWARN (towlower);
381 _GL_CXXALIASWARN (towupper);
382
383
384 #endif /* _GL_WCTYPE_H */
385 #endif /* _GL_WCTYPE_H */