Remove #include <stdio.h>. Add #include <string.h>.
[bpt/guile.git] / libguile / chars.c
CommitLineData
f2c9fcb0 1/* Copyright (C) 1995,1996,1998, 2000 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
0f2d19dd 47#include <ctype.h>
a0599745
MD
48#include "libguile/_scm.h"
49#include "libguile/validate.h"
0f2d19dd 50
a0599745 51#include "libguile/chars.h"
0f2d19dd
JB
52\f
53
a1ec6916 54SCM_DEFINE (scm_char_p, "char?", 1, 0, 0,
1bbd0b84 55 (SCM x),
cdbc7418 56 "Return @code{#t} iff @var{x} is a character, else @code{#f}.")
1bbd0b84 57#define FUNC_NAME s_scm_char_p
0f2d19dd 58{
7866a09b 59 return SCM_BOOL(SCM_CHARP(x));
0f2d19dd 60}
1bbd0b84 61#undef FUNC_NAME
0f2d19dd 62
c3ee7520 63SCM_DEFINE1 (scm_char_eq_p, "char=?", scm_tc7_rpsubr,
1bbd0b84 64 (SCM x, SCM y),
cdbc7418 65 "Return @code{#t} iff @var{x} is the same character as @var{y}, else @code{#f}.")
1bbd0b84 66#define FUNC_NAME s_scm_char_eq_p
0f2d19dd 67{
362306b9
DH
68 SCM_VALIDATE_CHAR (1, x);
69 SCM_VALIDATE_CHAR (2, y);
70 return SCM_BOOL (SCM_EQ_P (x, y));
0f2d19dd 71}
1bbd0b84 72#undef FUNC_NAME
0f2d19dd
JB
73
74
c3ee7520 75SCM_DEFINE1 (scm_char_less_p, "char<?", scm_tc7_rpsubr,
1bbd0b84 76 (SCM x, SCM y),
cdbc7418
NJ
77 "Return @code{#t} iff @var{x} is less than @var{y} in the ASCII sequence,\n"
78 "else @code{#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),
cdbc7418
NJ
89 "Return @code{#t} iff @var{x} is less than or equal to @var{y} in the\n"
90 "ASCII sequence, else @code{#f}.")
1bbd0b84 91#define FUNC_NAME s_scm_char_leq_p
0f2d19dd 92{
7866a09b
GB
93 SCM_VALIDATE_CHAR (1,x);
94 SCM_VALIDATE_CHAR (2,y);
95 return SCM_BOOL(SCM_CHAR(x) <= SCM_CHAR(y));
0f2d19dd 96}
1bbd0b84 97#undef FUNC_NAME
0f2d19dd 98
c3ee7520 99SCM_DEFINE1 (scm_char_gr_p, "char>?", scm_tc7_rpsubr,
1bbd0b84 100 (SCM x, SCM y),
cdbc7418
NJ
101 "Return @code{#t} iff @var{x} is greater than @var{y} in the ASCII\n"
102 "sequence, else @code{#f}.")
1bbd0b84 103#define FUNC_NAME s_scm_char_gr_p
0f2d19dd 104{
7866a09b
GB
105 SCM_VALIDATE_CHAR (1,x);
106 SCM_VALIDATE_CHAR (2,y);
107 return SCM_BOOL(SCM_CHAR(x) > SCM_CHAR(y));
0f2d19dd 108}
1bbd0b84 109#undef FUNC_NAME
0f2d19dd 110
c3ee7520 111SCM_DEFINE1 (scm_char_geq_p, "char>=?", scm_tc7_rpsubr,
1bbd0b84 112 (SCM x, SCM y),
cdbc7418
NJ
113 "Return @code{#t} iff @var{x} is greater than or equal to @var{y} in the\n"
114 "ASCII sequence, else @code{#f}.")
1bbd0b84 115#define FUNC_NAME s_scm_char_geq_p
0f2d19dd 116{
7866a09b
GB
117 SCM_VALIDATE_CHAR (1,x);
118 SCM_VALIDATE_CHAR (2,y);
119 return SCM_BOOL(SCM_CHAR(x) >= SCM_CHAR(y));
0f2d19dd 120}
1bbd0b84 121#undef FUNC_NAME
0f2d19dd 122
c3ee7520 123SCM_DEFINE1 (scm_char_ci_eq_p, "char-ci=?", scm_tc7_rpsubr,
1bbd0b84 124 (SCM x, SCM y),
cdbc7418
NJ
125 "Return @code{#t} iff @var{x} is the same character as @var{y} ignoring\n"
126 "case, else @code{#f}.")
1bbd0b84 127#define FUNC_NAME s_scm_char_ci_eq_p
0f2d19dd 128{
7866a09b
GB
129 SCM_VALIDATE_CHAR (1,x);
130 SCM_VALIDATE_CHAR (2,y);
131 return SCM_BOOL(scm_upcase(SCM_CHAR(x))==scm_upcase(SCM_CHAR(y)));
0f2d19dd 132}
1bbd0b84 133#undef FUNC_NAME
0f2d19dd 134
c3ee7520 135SCM_DEFINE1 (scm_char_ci_less_p, "char-ci<?", scm_tc7_rpsubr,
1bbd0b84 136 (SCM x, SCM y),
cdbc7418
NJ
137 "Return @code{#t} iff @var{x} is less than @var{y} in the ASCII sequence\n"
138 "ignoring case, else @code{#f}.")
1bbd0b84 139#define FUNC_NAME s_scm_char_ci_less_p
0f2d19dd 140{
7866a09b
GB
141 SCM_VALIDATE_CHAR (1,x);
142 SCM_VALIDATE_CHAR (2,y);
143 return SCM_BOOL((scm_upcase(SCM_CHAR(x))) < scm_upcase(SCM_CHAR(y)));
0f2d19dd 144}
1bbd0b84 145#undef FUNC_NAME
0f2d19dd 146
c3ee7520 147SCM_DEFINE1 (scm_char_ci_leq_p, "char-ci<=?", scm_tc7_rpsubr,
1bbd0b84 148 (SCM x, SCM y),
cdbc7418
NJ
149 "Return @code{#t} iff @var{x} is less than or equal to @var{y} in the\n"
150 "ASCII sequence ignoring case, else @code{#f}.")
1bbd0b84 151#define FUNC_NAME s_scm_char_ci_leq_p
0f2d19dd 152{
7866a09b
GB
153 SCM_VALIDATE_CHAR (1,x);
154 SCM_VALIDATE_CHAR (2,y);
155 return SCM_BOOL(scm_upcase(SCM_CHAR(x)) <= scm_upcase(SCM_CHAR(y)));
0f2d19dd 156}
1bbd0b84 157#undef FUNC_NAME
0f2d19dd 158
c3ee7520 159SCM_DEFINE1 (scm_char_ci_gr_p, "char-ci>?", scm_tc7_rpsubr,
1bbd0b84 160 (SCM x, SCM y),
cdbc7418
NJ
161 "Return @code{#t} iff @var{x} is greater than @var{y} in the ASCII\n"
162 "sequence ignoring case, else @code{#f}.")
1bbd0b84 163#define FUNC_NAME s_scm_char_ci_gr_p
0f2d19dd 164{
7866a09b
GB
165 SCM_VALIDATE_CHAR (1,x);
166 SCM_VALIDATE_CHAR (2,y);
167 return SCM_BOOL(scm_upcase(SCM_CHAR(x)) > scm_upcase(SCM_CHAR(y)));
0f2d19dd 168}
1bbd0b84 169#undef FUNC_NAME
0f2d19dd 170
c3ee7520 171SCM_DEFINE1 (scm_char_ci_geq_p, "char-ci>=?", scm_tc7_rpsubr,
1bbd0b84 172 (SCM x, SCM y),
cdbc7418
NJ
173 "Return @code{#t} iff @var{x} is greater than or equal to @var{y} in the\n"
174 "ASCII sequence ignoring case, else @code{#f}.")
1bbd0b84 175#define FUNC_NAME s_scm_char_ci_geq_p
0f2d19dd 176{
7866a09b
GB
177 SCM_VALIDATE_CHAR (1,x);
178 SCM_VALIDATE_CHAR (2,y);
179 return SCM_BOOL(scm_upcase(SCM_CHAR(x)) >= scm_upcase(SCM_CHAR(y)));
0f2d19dd 180}
1bbd0b84 181#undef FUNC_NAME
0f2d19dd
JB
182
183
3b3b36dd 184SCM_DEFINE (scm_char_alphabetic_p, "char-alphabetic?", 1, 0, 0,
1bbd0b84 185 (SCM chr),
cdbc7418 186 "Return @code{#t} iff @var{chr} is alphabetic, else @code{#f}.\n"
b380b885 187 "Alphabetic means the same thing as the isalpha C library function.")
1bbd0b84 188#define FUNC_NAME s_scm_char_alphabetic_p
0f2d19dd 189{
7866a09b
GB
190 SCM_VALIDATE_CHAR (1,chr);
191 return SCM_BOOL(isascii(SCM_CHAR(chr)) && isalpha(SCM_CHAR(chr)));
0f2d19dd 192}
1bbd0b84 193#undef FUNC_NAME
0f2d19dd 194
3b3b36dd 195SCM_DEFINE (scm_char_numeric_p, "char-numeric?", 1, 0, 0,
1bbd0b84 196 (SCM chr),
cdbc7418 197 "Return @code{#t} iff @var{chr} is numeric, else @code{#f}.\n"
b380b885 198 "Numeric means the same thing as the isdigit C library function.")
1bbd0b84 199#define FUNC_NAME s_scm_char_numeric_p
0f2d19dd 200{
7866a09b
GB
201 SCM_VALIDATE_CHAR (1,chr);
202 return SCM_BOOL(isascii(SCM_CHAR(chr)) && isdigit(SCM_CHAR(chr)));
0f2d19dd 203}
1bbd0b84 204#undef FUNC_NAME
0f2d19dd 205
3b3b36dd 206SCM_DEFINE (scm_char_whitespace_p, "char-whitespace?", 1, 0, 0,
1bbd0b84 207 (SCM chr),
cdbc7418 208 "Return @code{#t} iff @var{chr} is whitespace, else @code{#f}.\n"
b380b885 209 "Whitespace means the same thing as the isspace C library function.")
1bbd0b84 210#define FUNC_NAME s_scm_char_whitespace_p
0f2d19dd 211{
7866a09b
GB
212 SCM_VALIDATE_CHAR (1,chr);
213 return SCM_BOOL(isascii(SCM_CHAR(chr)) && isspace(SCM_CHAR(chr)));
0f2d19dd 214}
1bbd0b84 215#undef FUNC_NAME
0f2d19dd
JB
216
217
218
3b3b36dd 219SCM_DEFINE (scm_char_upper_case_p, "char-upper-case?", 1, 0, 0,
1bbd0b84 220 (SCM chr),
cdbc7418 221 "Return @code{#t} iff @var{chr} is uppercase, else @code{#f}.\n"
b380b885 222 "Uppercase means the same thing as the isupper C library function.")
1bbd0b84 223#define FUNC_NAME s_scm_char_upper_case_p
0f2d19dd 224{
7866a09b
GB
225 SCM_VALIDATE_CHAR (1,chr);
226 return SCM_BOOL(isascii(SCM_CHAR(chr)) && isupper(SCM_CHAR(chr)));
0f2d19dd 227}
1bbd0b84 228#undef FUNC_NAME
0f2d19dd
JB
229
230
3b3b36dd 231SCM_DEFINE (scm_char_lower_case_p, "char-lower-case?", 1, 0, 0,
1bbd0b84 232 (SCM chr),
cdbc7418 233 "Return @code{#t} iff @var{chr} is lowercase, else @code{#f}.\n"
b380b885 234 "Lowercase means the same thing as the islower C library function.")
1bbd0b84 235#define FUNC_NAME s_scm_char_lower_case_p
0f2d19dd 236{
7866a09b
GB
237 SCM_VALIDATE_CHAR (1,chr);
238 return SCM_BOOL(isascii(SCM_CHAR(chr)) && islower(SCM_CHAR(chr)));
0f2d19dd 239}
1bbd0b84 240#undef FUNC_NAME
0f2d19dd
JB
241
242
243
a1ec6916 244SCM_DEFINE (scm_char_is_both_p, "char-is-both?", 1, 0, 0,
1bbd0b84 245 (SCM chr),
cdbc7418 246 "Return @code{#t} iff @var{chr} is either uppercase or lowercase, else @code{#f}.\n"
b380b885
MD
247 "Uppercase and lowercase are as defined by the isupper and islower\n"
248 "C library functions.")
1bbd0b84 249#define FUNC_NAME s_scm_char_is_both_p
0f2d19dd 250{
7866a09b
GB
251 SCM_VALIDATE_CHAR (1,chr);
252 return SCM_BOOL(isascii(SCM_CHAR(chr)) && (isupper(SCM_CHAR(chr)) || islower(SCM_CHAR(chr))));
0f2d19dd 253}
1bbd0b84 254#undef FUNC_NAME
0f2d19dd
JB
255
256
257
258
a1ec6916 259SCM_DEFINE (scm_char_to_integer, "char->integer", 1, 0, 0,
1bbd0b84 260 (SCM chr),
cdbc7418
NJ
261 "Return the number corresponding to ordinal position of @var{chr} in the\n"
262 "ASCII sequence.")
1bbd0b84 263#define FUNC_NAME s_scm_char_to_integer
0f2d19dd 264{
7866a09b
GB
265 SCM_VALIDATE_CHAR (1,chr);
266 return scm_ulong2num((unsigned long)SCM_CHAR(chr));
0f2d19dd 267}
1bbd0b84 268#undef FUNC_NAME
0f2d19dd
JB
269
270
271
3b3b36dd 272SCM_DEFINE (scm_integer_to_char, "integer->char", 1, 0, 0,
1bbd0b84 273 (SCM n),
cdbc7418 274 "Return the character at position @var{n} in the ASCII sequence.")
1bbd0b84 275#define FUNC_NAME s_scm_integer_to_char
0f2d19dd 276{
90e49489 277 SCM_VALIDATE_INUM_RANGE (1, n, 0, 256);
7866a09b 278 return SCM_MAKE_CHAR (SCM_INUM (n));
0f2d19dd 279}
1bbd0b84 280#undef FUNC_NAME
0f2d19dd
JB
281
282
3b3b36dd 283SCM_DEFINE (scm_char_upcase, "char-upcase", 1, 0, 0,
1bbd0b84 284 (SCM chr),
cdbc7418 285 "Return the uppercase character version of @var{chr}.")
1bbd0b84 286#define FUNC_NAME s_scm_char_upcase
0f2d19dd 287{
7866a09b
GB
288 SCM_VALIDATE_CHAR (1,chr);
289 return SCM_MAKE_CHAR(scm_upcase(SCM_CHAR(chr)));
0f2d19dd 290}
1bbd0b84 291#undef FUNC_NAME
0f2d19dd
JB
292
293
3b3b36dd 294SCM_DEFINE (scm_char_downcase, "char-downcase", 1, 0, 0,
1bbd0b84 295 (SCM chr),
cdbc7418 296 "Return the lowercase character version of @var{chr}.")
1bbd0b84 297#define FUNC_NAME s_scm_char_downcase
0f2d19dd 298{
7866a09b
GB
299 SCM_VALIDATE_CHAR (1,chr);
300 return SCM_MAKE_CHAR(scm_downcase(SCM_CHAR(chr)));
0f2d19dd 301}
1bbd0b84 302#undef FUNC_NAME
0f2d19dd
JB
303
304\f
305
306
307
e2806c10
MD
308static unsigned char scm_upcase_table[SCM_CHAR_CODE_LIMIT];
309static unsigned char scm_downcase_table[SCM_CHAR_CODE_LIMIT];
57e3a543
JB
310static const unsigned char scm_lowers[] = "abcdefghijklmnopqrstuvwxyz";
311static const unsigned char scm_uppers[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
0f2d19dd 312
1cc91f1b 313
0f2d19dd
JB
314void
315scm_tables_prehistory ()
0f2d19dd
JB
316{
317 int i;
e2806c10 318 for (i = 0; i < SCM_CHAR_CODE_LIMIT; i++)
0f2d19dd 319 scm_upcase_table[i] = scm_downcase_table[i] = i;
77364130 320 for (i = 0; i < (int) (sizeof scm_lowers / sizeof (scm_lowers[0])); i++)
0f2d19dd
JB
321 {
322 scm_upcase_table[scm_lowers[i]] = scm_uppers[i];
323 scm_downcase_table[scm_uppers[i]] = scm_lowers[i];
324 }
325}
326
1cc91f1b 327
0f2d19dd 328int
6e8d25a6 329scm_upcase (unsigned int c)
0f2d19dd
JB
330{
331 if (c < sizeof (scm_upcase_table))
332 return scm_upcase_table[c];
333 else
334 return c;
335}
336
1cc91f1b 337
0f2d19dd 338int
6e8d25a6 339scm_downcase (unsigned int c)
0f2d19dd
JB
340{
341 if (c < sizeof (scm_downcase_table))
342 return scm_downcase_table[c];
343 else
344 return c;
345}
346
347
348#ifdef _DCC
349# define ASCII
350#else
351# if (('\n'=='\025') && (' '=='\100') && ('a'=='\201') && ('A'=='\301'))
352# define EBCDIC
353# endif /* (('\n'=='\025') && (' '=='\100') && ('a'=='\201') && ('A'=='\301')) */
354# if (('\n'=='\012') && (' '=='\040') && ('a'=='\141') && ('A'=='\101'))
355# define ASCII
356# endif /* (('\n'=='\012') && (' '=='\040') && ('a'=='\141') && ('A'=='\101')) */
357#endif /* def _DCC */
358
359
360#ifdef EBCDIC
57e3a543 361char *const scm_charnames[] =
0f2d19dd
JB
362{
363 "nul","soh","stx","etx", "pf", "ht", "lc","del",
364 0 , 0 ,"smm", "vt", "ff", "cr", "so", "si",
365 "dle","dc1","dc2","dc3","res", "nl", "bs", "il",
366 "can", "em", "cc", 0 ,"ifs","igs","irs","ius",
367 "ds","sos", "fs", 0 ,"byp", "lf","eob","pre",
368 0 , 0 , "sm", 0 , 0 ,"enq","ack","bel",
369 0 , 0 ,"syn", 0 , "pn", "rs", "uc","eot",
370 0 , 0 , 0 , 0 ,"dc4","nak", 0 ,"sub",
371 "space", scm_s_newline, "tab", "backspace", "return", "page", "null"};
372
57e3a543 373const char scm_charnums[] =
0f2d19dd
JB
374"\000\001\002\003\004\005\006\007\
375\010\011\012\013\014\015\016\017\
376\020\021\022\023\024\025\026\027\
377\030\031\032\033\034\035\036\037\
378\040\041\042\043\044\045\046\047\
379\050\051\052\053\054\055\056\057\
380\060\061\062\063\064\065\066\067\
381\070\071\072\073\074\075\076\077\
382 \n\t\b\r\f\0";
383#endif /* def EBCDIC */
384#ifdef ASCII
57e3a543 385char *const scm_charnames[] =
0f2d19dd
JB
386{
387 "nul","soh","stx","etx","eot","enq","ack","bel",
35fd4394 388 "bs", "ht", "newline", "vt", "np", "cr", "so", "si",
0f2d19dd
JB
389 "dle","dc1","dc2","dc3","dc4","nak","syn","etb",
390 "can", "em","sub","esc", "fs", "gs", "rs", "us",
35fd4394 391 "space", "nl", "tab", "backspace", "return", "page", "null", "del"};
57e3a543 392const char scm_charnums[] =
0f2d19dd
JB
393"\000\001\002\003\004\005\006\007\
394\010\011\012\013\014\015\016\017\
395\020\021\022\023\024\025\026\027\
396\030\031\032\033\034\035\036\037\
397 \n\t\b\r\f\0\177";
398#endif /* def ASCII */
399
400int scm_n_charnames = sizeof (scm_charnames) / sizeof (char *);
401
402
403\f
404
1cc91f1b 405
0f2d19dd
JB
406void
407scm_init_chars ()
0f2d19dd 408{
8dc9439f 409#ifndef SCM_MAGIC_SNARFER
a0599745 410#include "libguile/chars.x"
8dc9439f 411#endif
0f2d19dd
JB
412}
413
89e00824
ML
414
415/*
416 Local Variables:
417 c-file-style: "gnu"
418 End:
419*/