wctype: allow C++ use
[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 /* Define wint_t.  (Also done in wchar.in.h.)  */
58 #if !@HAVE_WINT_T@ && !defined wint_t
59 # define wint_t int
60 # ifndef WEOF
61 #  define WEOF -1
62 # endif
63 #endif
64
65 #ifdef __cplusplus
66 extern "C" {
67 #endif
68
69 /* FreeBSD 4.4 to 4.11 has <wctype.h> but lacks the functions.
70    Linux libc5 has <wctype.h> and the functions but they are broken.
71    Assume all 12 functions are implemented the same way, or not at all.  */
72 #if ! @HAVE_ISWCNTRL@ || @REPLACE_ISWCNTRL@
73
74 /* IRIX 5.3 has macros but no functions, its isw* macros refer to an
75    undefined variable _ctmp_ and to <ctype.h> macros like _P, and they
76    refer to system functions like _iswctype that are not in the
77    standard C library.  Rather than try to get ancient buggy
78    implementations like this to work, just disable them.  */
79 #  undef iswalnum
80 #  undef iswalpha
81 #  undef iswblank
82 #  undef iswcntrl
83 #  undef iswdigit
84 #  undef iswgraph
85 #  undef iswlower
86 #  undef iswprint
87 #  undef iswpunct
88 #  undef iswspace
89 #  undef iswupper
90 #  undef iswxdigit
91 #  undef towlower
92 #  undef towupper
93
94 /* Linux libc5 has <wctype.h> and the functions but they are broken.  */
95 #  if @REPLACE_ISWCNTRL@
96 #   define iswalnum rpl_iswalnum
97 #   define iswalpha rpl_iswalpha
98 #   define iswblank rpl_iswblank
99 #   define iswcntrl rpl_iswcntrl
100 #   define iswdigit rpl_iswdigit
101 #   define iswgraph rpl_iswgraph
102 #   define iswlower rpl_iswlower
103 #   define iswprint rpl_iswprint
104 #   define iswpunct rpl_iswpunct
105 #   define iswspace rpl_iswspace
106 #   define iswupper rpl_iswupper
107 #   define iswxdigit rpl_iswxdigit
108 #   define towlower rpl_towlower
109 #   define towupper rpl_towupper
110 #  endif
111
112 static inline int
113 iswalnum (wint_t wc)
114 {
115   return ((wc >= '0' && wc <= '9')
116           || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'));
117 }
118
119 static inline int
120 iswalpha (wint_t wc)
121 {
122   return (wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z';
123 }
124
125 static inline int
126 iswblank (wint_t wc)
127 {
128   return wc == ' ' || wc == '\t';
129 }
130
131 static inline int
132 iswcntrl (wint_t wc)
133 {
134   return (wc & ~0x1f) == 0 || wc == 0x7f;
135 }
136
137 static inline int
138 iswdigit (wint_t wc)
139 {
140   return wc >= '0' && wc <= '9';
141 }
142
143 static inline int
144 iswgraph (wint_t wc)
145 {
146   return wc >= '!' && wc <= '~';
147 }
148
149 static inline int
150 iswlower (wint_t wc)
151 {
152   return wc >= 'a' && wc <= 'z';
153 }
154
155 static inline int
156 iswprint (wint_t wc)
157 {
158   return wc >= ' ' && wc <= '~';
159 }
160
161 static inline int
162 iswpunct (wint_t wc)
163 {
164   return (wc >= '!' && wc <= '~'
165           && !((wc >= '0' && wc <= '9')
166                || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z')));
167 }
168
169 static inline int
170 iswspace (wint_t wc)
171 {
172   return (wc == ' ' || wc == '\t'
173           || wc == '\n' || wc == '\v' || wc == '\f' || wc == '\r');
174 }
175
176 static inline int
177 iswupper (wint_t wc)
178 {
179   return wc >= 'A' && wc <= 'Z';
180 }
181
182 static inline int
183 iswxdigit (wint_t wc)
184 {
185   return ((wc >= '0' && wc <= '9')
186           || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'F'));
187 }
188
189 static inline wint_t
190 towlower (wint_t wc)
191 {
192   return (wc >= 'A' && wc <= 'Z' ? wc - 'A' + 'a' : wc);
193 }
194
195 static inline wint_t
196 towupper (wint_t wc)
197 {
198   return (wc >= 'a' && wc <= 'z' ? wc - 'a' + 'A' : wc);
199 }
200
201 # endif /* ! HAVE_ISWCNTRL */
202
203 # if defined __MINGW32__
204
205 /* On native Windows, wchar_t is uint16_t, and wint_t is uint32_t.
206    The functions towlower and towupper are implemented in the MSVCRT library
207    to take a wchar_t argument and return a wchar_t result.  mingw declares
208    these functions to take a wint_t argument and return a wint_t result.
209    This means that:
210    1. When the user passes an argument outside the range 0x0000..0xFFFF, the
211       function will look only at the lower 16 bits.  This is allowed according
212       to POSIX.
213    2. The return value is returned in the lower 16 bits of the result register.
214       The upper 16 bits are random: whatever happened to be in that part of the
215       result register.  We need to fix this by adding a zero-extend from
216       wchar_t to wint_t after the call.  */
217
218 static inline wint_t
219 rpl_towlower (wint_t wc)
220 {
221   return (wint_t) (wchar_t) towlower (wc);
222 }
223 #  define towlower rpl_towlower
224
225 static inline wint_t
226 rpl_towupper (wint_t wc)
227 {
228   return (wint_t) (wchar_t) towupper (wc);
229 }
230 #  define towupper rpl_towupper
231
232 # endif
233
234 #ifdef __cplusplus
235 }
236 #endif
237
238 #endif /* _GL_WCTYPE_H */
239 #endif /* _GL_WCTYPE_H */