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