Include <config.h> in all C files; use `#ifdef HAVE_CONFIG_H' rather than `#if'.
[bpt/guile.git] / libguile / chars.c
CommitLineData
dbb605f5 1/* Copyright (C) 1995,1996,1998, 2000, 2001, 2004, 2006, 2008 Free Software Foundation, Inc.
0f2d19dd 2 *
73be1d9e
MV
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.
0f2d19dd 7 *
73be1d9e
MV
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.
0f2d19dd 12 *
73be1d9e
MV
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
92205699 15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
73be1d9e 16 */
1bbd0b84 17
1bbd0b84 18
0f2d19dd 19\f
dbb605f5
LC
20#ifdef HAVE_CONFIG_H
21# include <config.h>
22#endif
0f2d19dd 23
0f2d19dd 24#include <ctype.h>
465380de 25#include <limits.h>
a0599745
MD
26#include "libguile/_scm.h"
27#include "libguile/validate.h"
0f2d19dd 28
a0599745 29#include "libguile/chars.h"
1fdbbd4c
MV
30#include "libguile/srfi-14.h"
31
0f2d19dd
JB
32\f
33
a1ec6916 34SCM_DEFINE (scm_char_p, "char?", 1, 0, 0,
1bbd0b84 35 (SCM x),
cdbc7418 36 "Return @code{#t} iff @var{x} is a character, else @code{#f}.")
1bbd0b84 37#define FUNC_NAME s_scm_char_p
0f2d19dd 38{
7888309b 39 return scm_from_bool (SCM_CHARP(x));
0f2d19dd 40}
1bbd0b84 41#undef FUNC_NAME
0f2d19dd 42
c3ee7520 43SCM_DEFINE1 (scm_char_eq_p, "char=?", scm_tc7_rpsubr,
1bbd0b84 44 (SCM x, SCM y),
cdbc7418 45 "Return @code{#t} iff @var{x} is the same character as @var{y}, else @code{#f}.")
1bbd0b84 46#define FUNC_NAME s_scm_char_eq_p
0f2d19dd 47{
362306b9
DH
48 SCM_VALIDATE_CHAR (1, x);
49 SCM_VALIDATE_CHAR (2, y);
bc36d050 50 return scm_from_bool (scm_is_eq (x, y));
0f2d19dd 51}
1bbd0b84 52#undef FUNC_NAME
0f2d19dd
JB
53
54
c3ee7520 55SCM_DEFINE1 (scm_char_less_p, "char<?", scm_tc7_rpsubr,
1bbd0b84 56 (SCM x, SCM y),
cdbc7418
NJ
57 "Return @code{#t} iff @var{x} is less than @var{y} in the ASCII sequence,\n"
58 "else @code{#f}.")
1bbd0b84 59#define FUNC_NAME s_scm_char_less_p
0f2d19dd 60{
34d19ef6
HWN
61 SCM_VALIDATE_CHAR (1, x);
62 SCM_VALIDATE_CHAR (2, y);
7888309b 63 return scm_from_bool (SCM_CHAR(x) < SCM_CHAR(y));
0f2d19dd 64}
1bbd0b84 65#undef FUNC_NAME
0f2d19dd 66
c3ee7520 67SCM_DEFINE1 (scm_char_leq_p, "char<=?", scm_tc7_rpsubr,
1bbd0b84 68 (SCM x, SCM y),
cdbc7418
NJ
69 "Return @code{#t} iff @var{x} is less than or equal to @var{y} in the\n"
70 "ASCII sequence, else @code{#f}.")
1bbd0b84 71#define FUNC_NAME s_scm_char_leq_p
0f2d19dd 72{
34d19ef6
HWN
73 SCM_VALIDATE_CHAR (1, x);
74 SCM_VALIDATE_CHAR (2, y);
7888309b 75 return scm_from_bool (SCM_CHAR(x) <= SCM_CHAR(y));
0f2d19dd 76}
1bbd0b84 77#undef FUNC_NAME
0f2d19dd 78
c3ee7520 79SCM_DEFINE1 (scm_char_gr_p, "char>?", scm_tc7_rpsubr,
1bbd0b84 80 (SCM x, SCM y),
cdbc7418
NJ
81 "Return @code{#t} iff @var{x} is greater than @var{y} in the ASCII\n"
82 "sequence, else @code{#f}.")
1bbd0b84 83#define FUNC_NAME s_scm_char_gr_p
0f2d19dd 84{
34d19ef6
HWN
85 SCM_VALIDATE_CHAR (1, x);
86 SCM_VALIDATE_CHAR (2, y);
7888309b 87 return scm_from_bool (SCM_CHAR(x) > SCM_CHAR(y));
0f2d19dd 88}
1bbd0b84 89#undef FUNC_NAME
0f2d19dd 90
c3ee7520 91SCM_DEFINE1 (scm_char_geq_p, "char>=?", scm_tc7_rpsubr,
1bbd0b84 92 (SCM x, SCM y),
cdbc7418
NJ
93 "Return @code{#t} iff @var{x} is greater than or equal to @var{y} in the\n"
94 "ASCII sequence, else @code{#f}.")
1bbd0b84 95#define FUNC_NAME s_scm_char_geq_p
0f2d19dd 96{
34d19ef6
HWN
97 SCM_VALIDATE_CHAR (1, x);
98 SCM_VALIDATE_CHAR (2, y);
7888309b 99 return scm_from_bool (SCM_CHAR(x) >= SCM_CHAR(y));
0f2d19dd 100}
1bbd0b84 101#undef FUNC_NAME
0f2d19dd 102
c3ee7520 103SCM_DEFINE1 (scm_char_ci_eq_p, "char-ci=?", scm_tc7_rpsubr,
1bbd0b84 104 (SCM x, SCM y),
cdbc7418
NJ
105 "Return @code{#t} iff @var{x} is the same character as @var{y} ignoring\n"
106 "case, else @code{#f}.")
1bbd0b84 107#define FUNC_NAME s_scm_char_ci_eq_p
0f2d19dd 108{
34d19ef6
HWN
109 SCM_VALIDATE_CHAR (1, x);
110 SCM_VALIDATE_CHAR (2, y);
7888309b 111 return scm_from_bool (scm_c_upcase(SCM_CHAR(x))==scm_c_upcase(SCM_CHAR(y)));
0f2d19dd 112}
1bbd0b84 113#undef FUNC_NAME
0f2d19dd 114
c3ee7520 115SCM_DEFINE1 (scm_char_ci_less_p, "char-ci<?", scm_tc7_rpsubr,
1bbd0b84 116 (SCM x, SCM y),
cdbc7418
NJ
117 "Return @code{#t} iff @var{x} is less than @var{y} in the ASCII sequence\n"
118 "ignoring case, else @code{#f}.")
1bbd0b84 119#define FUNC_NAME s_scm_char_ci_less_p
0f2d19dd 120{
34d19ef6
HWN
121 SCM_VALIDATE_CHAR (1, x);
122 SCM_VALIDATE_CHAR (2, y);
7888309b 123 return scm_from_bool ((scm_c_upcase(SCM_CHAR(x))) < scm_c_upcase(SCM_CHAR(y)));
0f2d19dd 124}
1bbd0b84 125#undef FUNC_NAME
0f2d19dd 126
c3ee7520 127SCM_DEFINE1 (scm_char_ci_leq_p, "char-ci<=?", scm_tc7_rpsubr,
1bbd0b84 128 (SCM x, SCM y),
cdbc7418
NJ
129 "Return @code{#t} iff @var{x} is less than or equal to @var{y} in the\n"
130 "ASCII sequence ignoring case, else @code{#f}.")
1bbd0b84 131#define FUNC_NAME s_scm_char_ci_leq_p
0f2d19dd 132{
34d19ef6
HWN
133 SCM_VALIDATE_CHAR (1, x);
134 SCM_VALIDATE_CHAR (2, y);
7888309b 135 return scm_from_bool (scm_c_upcase(SCM_CHAR(x)) <= scm_c_upcase(SCM_CHAR(y)));
0f2d19dd 136}
1bbd0b84 137#undef FUNC_NAME
0f2d19dd 138
c3ee7520 139SCM_DEFINE1 (scm_char_ci_gr_p, "char-ci>?", scm_tc7_rpsubr,
1bbd0b84 140 (SCM x, SCM y),
cdbc7418
NJ
141 "Return @code{#t} iff @var{x} is greater than @var{y} in the ASCII\n"
142 "sequence ignoring case, else @code{#f}.")
1bbd0b84 143#define FUNC_NAME s_scm_char_ci_gr_p
0f2d19dd 144{
34d19ef6
HWN
145 SCM_VALIDATE_CHAR (1, x);
146 SCM_VALIDATE_CHAR (2, y);
7888309b 147 return scm_from_bool (scm_c_upcase(SCM_CHAR(x)) > scm_c_upcase(SCM_CHAR(y)));
0f2d19dd 148}
1bbd0b84 149#undef FUNC_NAME
0f2d19dd 150
c3ee7520 151SCM_DEFINE1 (scm_char_ci_geq_p, "char-ci>=?", scm_tc7_rpsubr,
1bbd0b84 152 (SCM x, SCM y),
cdbc7418
NJ
153 "Return @code{#t} iff @var{x} is greater than or equal to @var{y} in the\n"
154 "ASCII sequence ignoring case, else @code{#f}.")
1bbd0b84 155#define FUNC_NAME s_scm_char_ci_geq_p
0f2d19dd 156{
34d19ef6
HWN
157 SCM_VALIDATE_CHAR (1, x);
158 SCM_VALIDATE_CHAR (2, y);
7888309b 159 return scm_from_bool (scm_c_upcase(SCM_CHAR(x)) >= scm_c_upcase(SCM_CHAR(y)));
0f2d19dd 160}
1bbd0b84 161#undef FUNC_NAME
0f2d19dd
JB
162
163
3b3b36dd 164SCM_DEFINE (scm_char_alphabetic_p, "char-alphabetic?", 1, 0, 0,
1bbd0b84 165 (SCM chr),
1fdbbd4c 166 "Return @code{#t} iff @var{chr} is alphabetic, else @code{#f}.\n")
1bbd0b84 167#define FUNC_NAME s_scm_char_alphabetic_p
0f2d19dd 168{
1fdbbd4c 169 return scm_char_set_contains_p (scm_char_set_letter, chr);
0f2d19dd 170}
1bbd0b84 171#undef FUNC_NAME
0f2d19dd 172
3b3b36dd 173SCM_DEFINE (scm_char_numeric_p, "char-numeric?", 1, 0, 0,
1bbd0b84 174 (SCM chr),
1fdbbd4c 175 "Return @code{#t} iff @var{chr} is numeric, else @code{#f}.\n")
1bbd0b84 176#define FUNC_NAME s_scm_char_numeric_p
0f2d19dd 177{
1fdbbd4c 178 return scm_char_set_contains_p (scm_char_set_digit, chr);
0f2d19dd 179}
1bbd0b84 180#undef FUNC_NAME
0f2d19dd 181
3b3b36dd 182SCM_DEFINE (scm_char_whitespace_p, "char-whitespace?", 1, 0, 0,
1bbd0b84 183 (SCM chr),
1fdbbd4c 184 "Return @code{#t} iff @var{chr} is whitespace, else @code{#f}.\n")
1bbd0b84 185#define FUNC_NAME s_scm_char_whitespace_p
0f2d19dd 186{
1fdbbd4c 187 return scm_char_set_contains_p (scm_char_set_whitespace, chr);
0f2d19dd 188}
1bbd0b84 189#undef FUNC_NAME
0f2d19dd
JB
190
191
192
3b3b36dd 193SCM_DEFINE (scm_char_upper_case_p, "char-upper-case?", 1, 0, 0,
1bbd0b84 194 (SCM chr),
1fdbbd4c 195 "Return @code{#t} iff @var{chr} is uppercase, else @code{#f}.\n")
1bbd0b84 196#define FUNC_NAME s_scm_char_upper_case_p
0f2d19dd 197{
1fdbbd4c 198 return scm_char_set_contains_p (scm_char_set_upper_case, chr);
0f2d19dd 199}
1bbd0b84 200#undef FUNC_NAME
0f2d19dd
JB
201
202
3b3b36dd 203SCM_DEFINE (scm_char_lower_case_p, "char-lower-case?", 1, 0, 0,
1bbd0b84 204 (SCM chr),
1fdbbd4c 205 "Return @code{#t} iff @var{chr} is lowercase, else @code{#f}.\n")
1bbd0b84 206#define FUNC_NAME s_scm_char_lower_case_p
0f2d19dd 207{
1fdbbd4c 208 return scm_char_set_contains_p (scm_char_set_lower_case, chr);
0f2d19dd 209}
1bbd0b84 210#undef FUNC_NAME
0f2d19dd
JB
211
212
213
a1ec6916 214SCM_DEFINE (scm_char_is_both_p, "char-is-both?", 1, 0, 0,
1bbd0b84 215 (SCM chr),
1fdbbd4c 216 "Return @code{#t} iff @var{chr} is either uppercase or lowercase, else @code{#f}.\n")
1bbd0b84 217#define FUNC_NAME s_scm_char_is_both_p
0f2d19dd 218{
1fdbbd4c
MV
219 if (scm_is_true (scm_char_set_contains_p (scm_char_set_lower_case, chr)))
220 return SCM_BOOL_T;
221 return scm_char_set_contains_p (scm_char_set_upper_case, chr);
0f2d19dd 222}
1bbd0b84 223#undef FUNC_NAME
0f2d19dd
JB
224
225
226
227
a1ec6916 228SCM_DEFINE (scm_char_to_integer, "char->integer", 1, 0, 0,
1bbd0b84 229 (SCM chr),
cdbc7418
NJ
230 "Return the number corresponding to ordinal position of @var{chr} in the\n"
231 "ASCII sequence.")
1bbd0b84 232#define FUNC_NAME s_scm_char_to_integer
0f2d19dd 233{
34d19ef6 234 SCM_VALIDATE_CHAR (1, chr);
b9bd8526 235 return scm_from_ulong (SCM_CHAR(chr));
0f2d19dd 236}
1bbd0b84 237#undef FUNC_NAME
0f2d19dd
JB
238
239
240
3b3b36dd 241SCM_DEFINE (scm_integer_to_char, "integer->char", 1, 0, 0,
1bbd0b84 242 (SCM n),
cdbc7418 243 "Return the character at position @var{n} in the ASCII sequence.")
1bbd0b84 244#define FUNC_NAME s_scm_integer_to_char
0f2d19dd 245{
a55c2b68 246 return SCM_MAKE_CHAR (scm_to_uchar (n));
0f2d19dd 247}
1bbd0b84 248#undef FUNC_NAME
0f2d19dd
JB
249
250
3b3b36dd 251SCM_DEFINE (scm_char_upcase, "char-upcase", 1, 0, 0,
1bbd0b84 252 (SCM chr),
cdbc7418 253 "Return the uppercase character version of @var{chr}.")
1bbd0b84 254#define FUNC_NAME s_scm_char_upcase
0f2d19dd 255{
34d19ef6 256 SCM_VALIDATE_CHAR (1, chr);
465380de 257 return SCM_MAKE_CHAR (toupper (SCM_CHAR (chr)));
0f2d19dd 258}
1bbd0b84 259#undef FUNC_NAME
0f2d19dd
JB
260
261
3b3b36dd 262SCM_DEFINE (scm_char_downcase, "char-downcase", 1, 0, 0,
1bbd0b84 263 (SCM chr),
cdbc7418 264 "Return the lowercase character version of @var{chr}.")
1bbd0b84 265#define FUNC_NAME s_scm_char_downcase
0f2d19dd 266{
34d19ef6 267 SCM_VALIDATE_CHAR (1, chr);
465380de 268 return SCM_MAKE_CHAR (tolower (SCM_CHAR(chr)));
0f2d19dd 269}
1bbd0b84 270#undef FUNC_NAME
0f2d19dd
JB
271
272\f
273
274
275
84fad130
HWN
276/*
277TODO: change name to scm_i_.. ? --hwn
278*/
279
1cc91f1b 280
0f2d19dd 281int
84fad130 282scm_c_upcase (unsigned int c)
0f2d19dd 283{
465380de
KR
284 if (c <= UCHAR_MAX)
285 return toupper (c);
0f2d19dd
JB
286 else
287 return c;
288}
289
1cc91f1b 290
0f2d19dd 291int
84fad130 292scm_c_downcase (unsigned int c)
0f2d19dd 293{
465380de
KR
294 if (c <= UCHAR_MAX)
295 return tolower (c);
0f2d19dd
JB
296 else
297 return c;
298}
299
300
301#ifdef _DCC
302# define ASCII
303#else
304# if (('\n'=='\025') && (' '=='\100') && ('a'=='\201') && ('A'=='\301'))
305# define EBCDIC
306# endif /* (('\n'=='\025') && (' '=='\100') && ('a'=='\201') && ('A'=='\301')) */
307# if (('\n'=='\012') && (' '=='\040') && ('a'=='\141') && ('A'=='\101'))
308# define ASCII
309# endif /* (('\n'=='\012') && (' '=='\040') && ('a'=='\141') && ('A'=='\101')) */
310#endif /* def _DCC */
311
312
313#ifdef EBCDIC
57e3a543 314char *const scm_charnames[] =
0f2d19dd 315{
34d19ef6
HWN
316 "nul", "soh", "stx", "etx", "pf", "ht", "lc", "del",
317 0 , 0 , "smm", "vt", "ff", "cr", "so", "si",
318 "dle", "dc1", "dc2", "dc3", "res", "nl", "bs", "il",
319 "can", "em", "cc", 0 , "ifs", "igs", "irs", "ius",
320 "ds", "sos", "fs", 0 , "byp", "lf", "eob", "pre",
321 0 , 0 , "sm", 0 , 0 , "enq", "ack", "bel",
322 0 , 0 , "syn", 0 , "pn", "rs", "uc", "eot",
323 0 , 0 , 0 , 0 , "dc4", "nak", 0 , "sub",
0f2d19dd
JB
324 "space", scm_s_newline, "tab", "backspace", "return", "page", "null"};
325
57e3a543 326const char scm_charnums[] =
0f2d19dd
JB
327"\000\001\002\003\004\005\006\007\
328\010\011\012\013\014\015\016\017\
329\020\021\022\023\024\025\026\027\
330\030\031\032\033\034\035\036\037\
331\040\041\042\043\044\045\046\047\
332\050\051\052\053\054\055\056\057\
333\060\061\062\063\064\065\066\067\
334\070\071\072\073\074\075\076\077\
335 \n\t\b\r\f\0";
336#endif /* def EBCDIC */
337#ifdef ASCII
57e3a543 338char *const scm_charnames[] =
0f2d19dd
JB
339{
340 "nul","soh","stx","etx","eot","enq","ack","bel",
35fd4394 341 "bs", "ht", "newline", "vt", "np", "cr", "so", "si",
0f2d19dd
JB
342 "dle","dc1","dc2","dc3","dc4","nak","syn","etb",
343 "can", "em","sub","esc", "fs", "gs", "rs", "us",
66842ba3 344 "space", "sp", "nl", "tab", "backspace", "return", "page", "null", "del"};
57e3a543 345const char scm_charnums[] =
0f2d19dd
JB
346"\000\001\002\003\004\005\006\007\
347\010\011\012\013\014\015\016\017\
348\020\021\022\023\024\025\026\027\
349\030\031\032\033\034\035\036\037\
66842ba3 350 \n\t\b\r\f\0\177";
0f2d19dd
JB
351#endif /* def ASCII */
352
353int scm_n_charnames = sizeof (scm_charnames) / sizeof (char *);
354
355
356\f
357
1cc91f1b 358
0f2d19dd
JB
359void
360scm_init_chars ()
0f2d19dd 361{
a0599745 362#include "libguile/chars.x"
0f2d19dd
JB
363}
364
89e00824
ML
365
366/*
367 Local Variables:
368 c-file-style: "gnu"
369 End:
370*/