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