Changed license terms to the plain LGPL thru-out.
[bpt/guile.git] / libguile / chars.c
1 /* Copyright (C) 1995,1996,1998, 2000, 2001 Free Software Foundation, Inc.
2 *
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17
18
19 \f
20
21 #include <ctype.h>
22 #include "libguile/_scm.h"
23 #include "libguile/validate.h"
24
25 #include "libguile/chars.h"
26 \f
27
28 SCM_DEFINE (scm_char_p, "char?", 1, 0, 0,
29 (SCM x),
30 "Return @code{#t} iff @var{x} is a character, else @code{#f}.")
31 #define FUNC_NAME s_scm_char_p
32 {
33 return SCM_BOOL(SCM_CHARP(x));
34 }
35 #undef FUNC_NAME
36
37 SCM_DEFINE1 (scm_char_eq_p, "char=?", scm_tc7_rpsubr,
38 (SCM x, SCM y),
39 "Return @code{#t} iff @var{x} is the same character as @var{y}, else @code{#f}.")
40 #define FUNC_NAME s_scm_char_eq_p
41 {
42 SCM_VALIDATE_CHAR (1, x);
43 SCM_VALIDATE_CHAR (2, y);
44 return SCM_BOOL (SCM_EQ_P (x, y));
45 }
46 #undef FUNC_NAME
47
48
49 SCM_DEFINE1 (scm_char_less_p, "char<?", scm_tc7_rpsubr,
50 (SCM x, SCM y),
51 "Return @code{#t} iff @var{x} is less than @var{y} in the ASCII sequence,\n"
52 "else @code{#f}.")
53 #define FUNC_NAME s_scm_char_less_p
54 {
55 SCM_VALIDATE_CHAR (1, x);
56 SCM_VALIDATE_CHAR (2, y);
57 return SCM_BOOL(SCM_CHAR(x) < SCM_CHAR(y));
58 }
59 #undef FUNC_NAME
60
61 SCM_DEFINE1 (scm_char_leq_p, "char<=?", scm_tc7_rpsubr,
62 (SCM x, SCM y),
63 "Return @code{#t} iff @var{x} is less than or equal to @var{y} in the\n"
64 "ASCII sequence, else @code{#f}.")
65 #define FUNC_NAME s_scm_char_leq_p
66 {
67 SCM_VALIDATE_CHAR (1, x);
68 SCM_VALIDATE_CHAR (2, y);
69 return SCM_BOOL(SCM_CHAR(x) <= SCM_CHAR(y));
70 }
71 #undef FUNC_NAME
72
73 SCM_DEFINE1 (scm_char_gr_p, "char>?", scm_tc7_rpsubr,
74 (SCM x, SCM y),
75 "Return @code{#t} iff @var{x} is greater than @var{y} in the ASCII\n"
76 "sequence, else @code{#f}.")
77 #define FUNC_NAME s_scm_char_gr_p
78 {
79 SCM_VALIDATE_CHAR (1, x);
80 SCM_VALIDATE_CHAR (2, y);
81 return SCM_BOOL(SCM_CHAR(x) > SCM_CHAR(y));
82 }
83 #undef FUNC_NAME
84
85 SCM_DEFINE1 (scm_char_geq_p, "char>=?", scm_tc7_rpsubr,
86 (SCM x, SCM y),
87 "Return @code{#t} iff @var{x} is greater than or equal to @var{y} in the\n"
88 "ASCII sequence, else @code{#f}.")
89 #define FUNC_NAME s_scm_char_geq_p
90 {
91 SCM_VALIDATE_CHAR (1, x);
92 SCM_VALIDATE_CHAR (2, y);
93 return SCM_BOOL(SCM_CHAR(x) >= SCM_CHAR(y));
94 }
95 #undef FUNC_NAME
96
97 SCM_DEFINE1 (scm_char_ci_eq_p, "char-ci=?", scm_tc7_rpsubr,
98 (SCM x, SCM y),
99 "Return @code{#t} iff @var{x} is the same character as @var{y} ignoring\n"
100 "case, else @code{#f}.")
101 #define FUNC_NAME s_scm_char_ci_eq_p
102 {
103 SCM_VALIDATE_CHAR (1, x);
104 SCM_VALIDATE_CHAR (2, y);
105 return SCM_BOOL(scm_upcase(SCM_CHAR(x))==scm_upcase(SCM_CHAR(y)));
106 }
107 #undef FUNC_NAME
108
109 SCM_DEFINE1 (scm_char_ci_less_p, "char-ci<?", scm_tc7_rpsubr,
110 (SCM x, SCM y),
111 "Return @code{#t} iff @var{x} is less than @var{y} in the ASCII sequence\n"
112 "ignoring case, else @code{#f}.")
113 #define FUNC_NAME s_scm_char_ci_less_p
114 {
115 SCM_VALIDATE_CHAR (1, x);
116 SCM_VALIDATE_CHAR (2, y);
117 return SCM_BOOL((scm_upcase(SCM_CHAR(x))) < scm_upcase(SCM_CHAR(y)));
118 }
119 #undef FUNC_NAME
120
121 SCM_DEFINE1 (scm_char_ci_leq_p, "char-ci<=?", scm_tc7_rpsubr,
122 (SCM x, SCM y),
123 "Return @code{#t} iff @var{x} is less than or equal to @var{y} in the\n"
124 "ASCII sequence ignoring case, else @code{#f}.")
125 #define FUNC_NAME s_scm_char_ci_leq_p
126 {
127 SCM_VALIDATE_CHAR (1, x);
128 SCM_VALIDATE_CHAR (2, y);
129 return SCM_BOOL(scm_upcase(SCM_CHAR(x)) <= scm_upcase(SCM_CHAR(y)));
130 }
131 #undef FUNC_NAME
132
133 SCM_DEFINE1 (scm_char_ci_gr_p, "char-ci>?", scm_tc7_rpsubr,
134 (SCM x, SCM y),
135 "Return @code{#t} iff @var{x} is greater than @var{y} in the ASCII\n"
136 "sequence ignoring case, else @code{#f}.")
137 #define FUNC_NAME s_scm_char_ci_gr_p
138 {
139 SCM_VALIDATE_CHAR (1, x);
140 SCM_VALIDATE_CHAR (2, y);
141 return SCM_BOOL(scm_upcase(SCM_CHAR(x)) > scm_upcase(SCM_CHAR(y)));
142 }
143 #undef FUNC_NAME
144
145 SCM_DEFINE1 (scm_char_ci_geq_p, "char-ci>=?", scm_tc7_rpsubr,
146 (SCM x, SCM y),
147 "Return @code{#t} iff @var{x} is greater than or equal to @var{y} in the\n"
148 "ASCII sequence ignoring case, else @code{#f}.")
149 #define FUNC_NAME s_scm_char_ci_geq_p
150 {
151 SCM_VALIDATE_CHAR (1, x);
152 SCM_VALIDATE_CHAR (2, y);
153 return SCM_BOOL(scm_upcase(SCM_CHAR(x)) >= scm_upcase(SCM_CHAR(y)));
154 }
155 #undef FUNC_NAME
156
157
158 SCM_DEFINE (scm_char_alphabetic_p, "char-alphabetic?", 1, 0, 0,
159 (SCM chr),
160 "Return @code{#t} iff @var{chr} is alphabetic, else @code{#f}.\n"
161 "Alphabetic means the same thing as the isalpha C library function.")
162 #define FUNC_NAME s_scm_char_alphabetic_p
163 {
164 SCM_VALIDATE_CHAR (1, chr);
165 return SCM_BOOL(isalpha(SCM_CHAR(chr)));
166 }
167 #undef FUNC_NAME
168
169 SCM_DEFINE (scm_char_numeric_p, "char-numeric?", 1, 0, 0,
170 (SCM chr),
171 "Return @code{#t} iff @var{chr} is numeric, else @code{#f}.\n"
172 "Numeric means the same thing as the isdigit C library function.")
173 #define FUNC_NAME s_scm_char_numeric_p
174 {
175 SCM_VALIDATE_CHAR (1, chr);
176 return SCM_BOOL(isdigit(SCM_CHAR(chr)));
177 }
178 #undef FUNC_NAME
179
180 SCM_DEFINE (scm_char_whitespace_p, "char-whitespace?", 1, 0, 0,
181 (SCM chr),
182 "Return @code{#t} iff @var{chr} is whitespace, else @code{#f}.\n"
183 "Whitespace means the same thing as the isspace C library function.")
184 #define FUNC_NAME s_scm_char_whitespace_p
185 {
186 SCM_VALIDATE_CHAR (1, chr);
187 return SCM_BOOL(isspace(SCM_CHAR(chr)));
188 }
189 #undef FUNC_NAME
190
191
192
193 SCM_DEFINE (scm_char_upper_case_p, "char-upper-case?", 1, 0, 0,
194 (SCM chr),
195 "Return @code{#t} iff @var{chr} is uppercase, else @code{#f}.\n"
196 "Uppercase means the same thing as the isupper C library function.")
197 #define FUNC_NAME s_scm_char_upper_case_p
198 {
199 SCM_VALIDATE_CHAR (1, chr);
200 return SCM_BOOL(isupper(SCM_CHAR(chr)));
201 }
202 #undef FUNC_NAME
203
204
205 SCM_DEFINE (scm_char_lower_case_p, "char-lower-case?", 1, 0, 0,
206 (SCM chr),
207 "Return @code{#t} iff @var{chr} is lowercase, else @code{#f}.\n"
208 "Lowercase means the same thing as the islower C library function.")
209 #define FUNC_NAME s_scm_char_lower_case_p
210 {
211 SCM_VALIDATE_CHAR (1, chr);
212 return SCM_BOOL(islower(SCM_CHAR(chr)));
213 }
214 #undef FUNC_NAME
215
216
217
218 SCM_DEFINE (scm_char_is_both_p, "char-is-both?", 1, 0, 0,
219 (SCM chr),
220 "Return @code{#t} iff @var{chr} is either uppercase or lowercase, else @code{#f}.\n"
221 "Uppercase and lowercase are as defined by the isupper and islower\n"
222 "C library functions.")
223 #define FUNC_NAME s_scm_char_is_both_p
224 {
225 SCM_VALIDATE_CHAR (1, chr);
226 return SCM_BOOL((isupper(SCM_CHAR(chr)) || islower(SCM_CHAR(chr))));
227 }
228 #undef FUNC_NAME
229
230
231
232
233 SCM_DEFINE (scm_char_to_integer, "char->integer", 1, 0, 0,
234 (SCM chr),
235 "Return the number corresponding to ordinal position of @var{chr} in the\n"
236 "ASCII sequence.")
237 #define FUNC_NAME s_scm_char_to_integer
238 {
239 SCM_VALIDATE_CHAR (1, chr);
240 return scm_ulong2num((unsigned long)SCM_CHAR(chr));
241 }
242 #undef FUNC_NAME
243
244
245
246 SCM_DEFINE (scm_integer_to_char, "integer->char", 1, 0, 0,
247 (SCM n),
248 "Return the character at position @var{n} in the ASCII sequence.")
249 #define FUNC_NAME s_scm_integer_to_char
250 {
251 SCM_VALIDATE_INUM_RANGE (1, n, 0, 256);
252 return SCM_MAKE_CHAR (SCM_INUM (n));
253 }
254 #undef FUNC_NAME
255
256
257 SCM_DEFINE (scm_char_upcase, "char-upcase", 1, 0, 0,
258 (SCM chr),
259 "Return the uppercase character version of @var{chr}.")
260 #define FUNC_NAME s_scm_char_upcase
261 {
262 SCM_VALIDATE_CHAR (1, chr);
263 return SCM_MAKE_CHAR(scm_upcase(SCM_CHAR(chr)));
264 }
265 #undef FUNC_NAME
266
267
268 SCM_DEFINE (scm_char_downcase, "char-downcase", 1, 0, 0,
269 (SCM chr),
270 "Return the lowercase character version of @var{chr}.")
271 #define FUNC_NAME s_scm_char_downcase
272 {
273 SCM_VALIDATE_CHAR (1, chr);
274 return SCM_MAKE_CHAR(scm_downcase(SCM_CHAR(chr)));
275 }
276 #undef FUNC_NAME
277
278 \f
279
280
281
282 static unsigned char scm_upcase_table[SCM_CHAR_CODE_LIMIT];
283 static unsigned char scm_downcase_table[SCM_CHAR_CODE_LIMIT];
284 static const unsigned char scm_lowers[] = "abcdefghijklmnopqrstuvwxyz";
285 static const unsigned char scm_uppers[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
286
287
288 void
289 scm_tables_prehistory ()
290 {
291 int i;
292 for (i = 0; i < SCM_CHAR_CODE_LIMIT; i++)
293 scm_upcase_table[i] = scm_downcase_table[i] = i;
294 for (i = 0; i < (int) (sizeof scm_lowers / sizeof (scm_lowers[0])); i++)
295 {
296 scm_upcase_table[scm_lowers[i]] = scm_uppers[i];
297 scm_downcase_table[scm_uppers[i]] = scm_lowers[i];
298 }
299 }
300
301
302 int
303 scm_upcase (unsigned int c)
304 {
305 if (c < sizeof (scm_upcase_table))
306 return scm_upcase_table[c];
307 else
308 return c;
309 }
310
311
312 int
313 scm_downcase (unsigned int c)
314 {
315 if (c < sizeof (scm_downcase_table))
316 return scm_downcase_table[c];
317 else
318 return c;
319 }
320
321
322 #ifdef _DCC
323 # define ASCII
324 #else
325 # if (('\n'=='\025') && (' '=='\100') && ('a'=='\201') && ('A'=='\301'))
326 # define EBCDIC
327 # endif /* (('\n'=='\025') && (' '=='\100') && ('a'=='\201') && ('A'=='\301')) */
328 # if (('\n'=='\012') && (' '=='\040') && ('a'=='\141') && ('A'=='\101'))
329 # define ASCII
330 # endif /* (('\n'=='\012') && (' '=='\040') && ('a'=='\141') && ('A'=='\101')) */
331 #endif /* def _DCC */
332
333
334 #ifdef EBCDIC
335 char *const scm_charnames[] =
336 {
337 "nul", "soh", "stx", "etx", "pf", "ht", "lc", "del",
338 0 , 0 , "smm", "vt", "ff", "cr", "so", "si",
339 "dle", "dc1", "dc2", "dc3", "res", "nl", "bs", "il",
340 "can", "em", "cc", 0 , "ifs", "igs", "irs", "ius",
341 "ds", "sos", "fs", 0 , "byp", "lf", "eob", "pre",
342 0 , 0 , "sm", 0 , 0 , "enq", "ack", "bel",
343 0 , 0 , "syn", 0 , "pn", "rs", "uc", "eot",
344 0 , 0 , 0 , 0 , "dc4", "nak", 0 , "sub",
345 "space", scm_s_newline, "tab", "backspace", "return", "page", "null"};
346
347 const char scm_charnums[] =
348 "\000\001\002\003\004\005\006\007\
349 \010\011\012\013\014\015\016\017\
350 \020\021\022\023\024\025\026\027\
351 \030\031\032\033\034\035\036\037\
352 \040\041\042\043\044\045\046\047\
353 \050\051\052\053\054\055\056\057\
354 \060\061\062\063\064\065\066\067\
355 \070\071\072\073\074\075\076\077\
356 \n\t\b\r\f\0";
357 #endif /* def EBCDIC */
358 #ifdef ASCII
359 char *const scm_charnames[] =
360 {
361 "nul","soh","stx","etx","eot","enq","ack","bel",
362 "bs", "ht", "newline", "vt", "np", "cr", "so", "si",
363 "dle","dc1","dc2","dc3","dc4","nak","syn","etb",
364 "can", "em","sub","esc", "fs", "gs", "rs", "us",
365 "space", "nl", "tab", "backspace", "return", "page", "null", "del"};
366 const char scm_charnums[] =
367 "\000\001\002\003\004\005\006\007\
368 \010\011\012\013\014\015\016\017\
369 \020\021\022\023\024\025\026\027\
370 \030\031\032\033\034\035\036\037\
371 \n\t\b\r\f\0\177";
372 #endif /* def ASCII */
373
374 int scm_n_charnames = sizeof (scm_charnames) / sizeof (char *);
375
376
377 \f
378
379
380 void
381 scm_init_chars ()
382 {
383 #include "libguile/chars.x"
384 }
385
386
387 /*
388 Local Variables:
389 c-file-style: "gnu"
390 End:
391 */