1/* Character handling in C locale.
2
3   Copyright 2000, 2001, 2002, 2003, 2006, 2009 Free Software
4   Foundation, Inc.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 3 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software Foundation,
18Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
19
20#include <config.h>
21
22/* Specification.  */
23#define NO_C_CTYPE_MACROS
24#include "c-ctype.h"
25
26/* The function isascii is not locale dependent. Its use in EBCDIC is
27   questionable. */
28bool
29c_isascii (int c)
30{
31  return (c >= 0x00 && c <= 0x7f);
32}
33
34bool
35c_isalnum (int c)
36{
37#if C_CTYPE_CONSECUTIVE_DIGITS \
38    && C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
39#if C_CTYPE_ASCII
40  return ((c >= '0' && c <= '9')
41          || ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'Z'));
42#else
43  return ((c >= '0' && c <= '9')
44          || (c >= 'A' && c <= 'Z')
45          || (c >= 'a' && c <= 'z'));
46#endif
47#else
48  switch (c)
49    {
50    case '0': case '1': case '2': case '3': case '4': case '5':
51    case '6': case '7': case '8': case '9':
52    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
53    case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
54    case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
55    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
56    case 'Y': case 'Z':
57    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
58    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
59    case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
60    case 's': case 't': case 'u': case 'v': case 'w': case 'x':
61    case 'y': case 'z':
62      return 1;
63    default:
64      return 0;
65    }
66#endif
67}
68
69bool
70c_isalpha (int c)
71{
72#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
73#if C_CTYPE_ASCII
74  return ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'Z');
75#else
76  return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
77#endif
78#else
79  switch (c)
80    {
81    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
82    case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
83    case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
84    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
85    case 'Y': case 'Z':
86    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
87    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
88    case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
89    case 's': case 't': case 'u': case 'v': case 'w': case 'x':
90    case 'y': case 'z':
91      return 1;
92    default:
93      return 0;
94    }
95#endif
96}
97
98bool
99c_isblank (int c)
100{
101  return (c == ' ' || c == '\t');
102}
103
104bool
105c_iscntrl (int c)
106{
107#if C_CTYPE_ASCII
108  return ((c & ~0x1f) == 0 || c == 0x7f);
109#else
110  switch (c)
111    {
112    case ' ': case '!': case '"': case '#': case '$': case '%':
113    case '&': case '\'': case '(': case ')': case '*': case '+':
114    case ',': case '-': case '.': case '/':
115    case '0': case '1': case '2': case '3': case '4': case '5':
116    case '6': case '7': case '8': case '9':
117    case ':': case ';': case '<': case '=': case '>': case '?':
118    case '@':
119    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
120    case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
121    case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
122    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
123    case 'Y': case 'Z':
124    case '[': case '\\': case ']': case '^': case '_': case '`':
125    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
126    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
127    case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
128    case 's': case 't': case 'u': case 'v': case 'w': case 'x':
129    case 'y': case 'z':
130    case '{': case '|': case '}': case '~':
131      return 0;
132    default:
133      return 1;
134    }
135#endif
136}
137
138bool
139c_isdigit (int c)
140{
141#if C_CTYPE_CONSECUTIVE_DIGITS
142  return (c >= '0' && c <= '9');
143#else
144  switch (c)
145    {
146    case '0': case '1': case '2': case '3': case '4': case '5':
147    case '6': case '7': case '8': case '9':
148      return 1;
149    default:
150      return 0;
151    }
152#endif
153}
154
155bool
156c_islower (int c)
157{
158#if C_CTYPE_CONSECUTIVE_LOWERCASE
159  return (c >= 'a' && c <= 'z');
160#else
161  switch (c)
162    {
163    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
164    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
165    case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
166    case 's': case 't': case 'u': case 'v': case 'w': case 'x':
167    case 'y': case 'z':
168      return 1;
169    default:
170      return 0;
171    }
172#endif
173}
174
175bool
176c_isgraph (int c)
177{
178#if C_CTYPE_ASCII
179  return (c >= '!' && c <= '~');
180#else
181  switch (c)
182    {
183    case '!': case '"': case '#': case '$': case '%': case '&':
184    case '\'': case '(': case ')': case '*': case '+': case ',':
185    case '-': case '.': case '/':
186    case '0': case '1': case '2': case '3': case '4': case '5':
187    case '6': case '7': case '8': case '9':
188    case ':': case ';': case '<': case '=': case '>': case '?':
189    case '@':
190    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
191    case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
192    case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
193    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
194    case 'Y': case 'Z':
195    case '[': case '\\': case ']': case '^': case '_': case '`':
196    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
197    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
198    case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
199    case 's': case 't': case 'u': case 'v': case 'w': case 'x':
200    case 'y': case 'z':
201    case '{': case '|': case '}': case '~':
202      return 1;
203    default:
204      return 0;
205    }
206#endif
207}
208
209bool
210c_isprint (int c)
211{
212#if C_CTYPE_ASCII
213  return (c >= ' ' && c <= '~');
214#else
215  switch (c)
216    {
217    case ' ': case '!': case '"': case '#': case '$': case '%':
218    case '&': case '\'': case '(': case ')': case '*': case '+':
219    case ',': case '-': case '.': case '/':
220    case '0': case '1': case '2': case '3': case '4': case '5':
221    case '6': case '7': case '8': case '9':
222    case ':': case ';': case '<': case '=': case '>': case '?':
223    case '@':
224    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
225    case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
226    case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
227    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
228    case 'Y': case 'Z':
229    case '[': case '\\': case ']': case '^': case '_': case '`':
230    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
231    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
232    case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
233    case 's': case 't': case 'u': case 'v': case 'w': case 'x':
234    case 'y': case 'z':
235    case '{': case '|': case '}': case '~':
236      return 1;
237    default:
238      return 0;
239    }
240#endif
241}
242
243bool
244c_ispunct (int c)
245{
246#if C_CTYPE_ASCII
247  return ((c >= '!' && c <= '~')
248          && !((c >= '0' && c <= '9')
249               || ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'Z')));
250#else
251  switch (c)
252    {
253    case '!': case '"': case '#': case '$': case '%': case '&':
254    case '\'': case '(': case ')': case '*': case '+': case ',':
255    case '-': case '.': case '/':
256    case ':': case ';': case '<': case '=': case '>': case '?':
257    case '@':
258    case '[': case '\\': case ']': case '^': case '_': case '`':
259    case '{': case '|': case '}': case '~':
260      return 1;
261    default:
262      return 0;
263    }
264#endif
265}
266
267bool
268c_isspace (int c)
269{
270  return (c == ' ' || c == '\t'
271          || c == '\n' || c == '\v' || c == '\f' || c == '\r');
272}
273
274bool
275c_isupper (int c)
276{
277#if C_CTYPE_CONSECUTIVE_UPPERCASE
278  return (c >= 'A' && c <= 'Z');
279#else
280  switch (c)
281    {
282    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
283    case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
284    case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
285    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
286    case 'Y': case 'Z':
287      return 1;
288    default:
289      return 0;
290    }
291#endif
292}
293
294bool
295c_isxdigit (int c)
296{
297#if C_CTYPE_CONSECUTIVE_DIGITS \
298    && C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
299#if C_CTYPE_ASCII
300  return ((c >= '0' && c <= '9')
301          || ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'F'));
302#else
303  return ((c >= '0' && c <= '9')
304          || (c >= 'A' && c <= 'F')
305          || (c >= 'a' && c <= 'f'));
306#endif
307#else
308  switch (c)
309    {
310    case '0': case '1': case '2': case '3': case '4': case '5':
311    case '6': case '7': case '8': case '9':
312    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
313    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
314      return 1;
315    default:
316      return 0;
317    }
318#endif
319}
320
321int
322c_tolower (int c)
323{
324#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
325  return (c >= 'A' && c <= 'Z' ? c - 'A' + 'a' : c);
326#else
327  switch (c)
328    {
329    case 'A': return 'a';
330    case 'B': return 'b';
331    case 'C': return 'c';
332    case 'D': return 'd';
333    case 'E': return 'e';
334    case 'F': return 'f';
335    case 'G': return 'g';
336    case 'H': return 'h';
337    case 'I': return 'i';
338    case 'J': return 'j';
339    case 'K': return 'k';
340    case 'L': return 'l';
341    case 'M': return 'm';
342    case 'N': return 'n';
343    case 'O': return 'o';
344    case 'P': return 'p';
345    case 'Q': return 'q';
346    case 'R': return 'r';
347    case 'S': return 's';
348    case 'T': return 't';
349    case 'U': return 'u';
350    case 'V': return 'v';
351    case 'W': return 'w';
352    case 'X': return 'x';
353    case 'Y': return 'y';
354    case 'Z': return 'z';
355    default: return c;
356    }
357#endif
358}
359
360int
361c_toupper (int c)
362{
363#if C_CTYPE_CONSECUTIVE_UPPERCASE && C_CTYPE_CONSECUTIVE_LOWERCASE
364  return (c >= 'a' && c <= 'z' ? c - 'a' + 'A' : c);
365#else
366  switch (c)
367    {
368    case 'a': return 'A';
369    case 'b': return 'B';
370    case 'c': return 'C';
371    case 'd': return 'D';
372    case 'e': return 'E';
373    case 'f': return 'F';
374    case 'g': return 'G';
375    case 'h': return 'H';
376    case 'i': return 'I';
377    case 'j': return 'J';
378    case 'k': return 'K';
379    case 'l': return 'L';
380    case 'm': return 'M';
381    case 'n': return 'N';
382    case 'o': return 'O';
383    case 'p': return 'P';
384    case 'q': return 'Q';
385    case 'r': return 'R';
386    case 's': return 'S';
387    case 't': return 'T';
388    case 'u': return 'U';
389    case 'v': return 'V';
390    case 'w': return 'W';
391    case 'x': return 'X';
392    case 'y': return 'Y';
393    case 'z': return 'Z';
394    default: return c;
395    }
396#endif
397}
398