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