2
character.d -- Character routines.
5
Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya.
6
Copyright (c) 1990, Giuseppe Attardi.
8
ECL is free software; you can redistribute it and/or
9
modify it under the terms of the GNU Library General Public
10
License as published by the Free Software Foundation; either
11
version 2 of the License, or (at your option) any later version.
13
See file '../Copyright' for full details.
21
char_code(cl_object c)
25
FEtype_error_character(c);
29
cl_standard_char_p(cl_object c)
31
/* INV: char_code() checks the type */
32
cl_fixnum i = char_code(c);
33
@(return (((' ' <= i && i < '\177') || i == '\n')? Ct : Cnil))
37
cl_graphic_char_p(cl_object c)
39
/* INV: char_code() checks the type */
40
cl_fixnum i = char_code(c); /* ' ' < '\177' ??? Beppe*/
41
@(return ((' ' <= i && i < '\177')? Ct : Cnil))
45
cl_alpha_char_p(cl_object c)
47
/* INV: char_code() checks the type */
48
cl_fixnum i = char_code(c);
49
@(return (isalpha(i)? Ct : Cnil))
53
cl_upper_case_p(cl_object c)
55
/* INV: char_code() checks the type */
56
@(return (isupper(char_code(c))? Ct : Cnil))
60
cl_lower_case_p(cl_object c)
62
/* INV: char_code() checks the type */
63
@(return (islower(char_code(c))? Ct : Cnil))
67
cl_both_case_p(cl_object c)
69
/* INV: char_code() checks the type */
70
cl_fixnum code = char_code(c);
71
@(return ((isupper(code) || islower(code)) ? Ct : Cnil))
75
ecl_string_case(cl_object s)
80
for (i = 0, upcase = 0, text = s->string.self; i <= s->string.dim; i++) {
81
if (isupper(text[i])) {
85
} else if (islower(text[i])) {
94
#define basep(d) (d <= 36)
96
@(defun digit_char_p (c &optional (r MAKE_FIXNUM(10)))
99
/* INV: char_code() checks `c' and fixnnint() checks `r' */
100
if (type_of(r) == t_bignum) {
103
cl_fixnum d = fixnnint(r);
104
if (!basep(d) || (d = digitp(char_code(c), d)) < 0)
107
output = MAKE_FIXNUM(d);
113
Digitp(i, r) returns the weight of code i
114
as a digit of radix r, which must be 1 < r <= 36.
115
If i is not a digit, -1 is returned.
120
if (('0' <= i) && (i <= '9') && (i < '0' + r))
122
if (('A' <= i) && (10 < r) && (i < 'A' + (r - 10)))
123
return(i - 'A' + 10);
124
if (('a' <= i) && (10 < r) && (i < 'a' + (r - 10)))
125
return(i - 'a' + 10);
130
cl_alphanumericp(cl_object c)
132
/* INV: char_code() checks type of `c' */
133
cl_fixnum i = char_code(c);
134
@(return (isalnum(i)? Ct : Cnil))
137
@(defun char= (c &rest cs)
139
/* INV: char_eq() checks types of `c' and `cs' */
141
if (!char_eq(c, cl_va_arg(cs)))
147
char_eq(cl_object x, cl_object y)
149
return char_code(x) == char_code(y);
152
@(defun char/= (&rest cs)
156
/* INV: char_eq() checks types of its arguments */
158
FEwrong_num_arguments(@'char/=');
160
for (i = 2; i<=narg; i++) {
162
cl_va_start(ds, narg, narg, 0);
164
for (j = 1; j<i; j++)
165
if (char_eq(cl_va_arg(ds), c))
172
Lchar_cmp(cl_narg narg, int s, int t, cl_va_list args)
177
FEwrong_num_arguments_anonym();
179
for (; --narg; c = d) {
181
if (s*char_cmp(d, c) < t)
188
char_cmp(cl_object x, cl_object y)
190
/* char_code(x) returns an integer which is well in the range
191
* of positive fixnums. Therefore, this subtraction never
193
return char_code(x) - char_code(y);
196
@(defun char< (&rest args)
198
return Lchar_cmp(narg, 1, 1, args);
201
@(defun char> (&rest args)
203
return Lchar_cmp(narg,-1, 1, args);
206
@(defun char<= (&rest args)
208
return Lchar_cmp(narg, 1, 0, args);
211
@(defun char>= (&rest args)
213
return Lchar_cmp(narg,-1, 0, args);
216
@(defun char_equal (c &rest cs)
219
/* INV: char_equal() checks the type of its arguments */
220
for (narg--, i = 0; i < narg; i++) {
221
if (!char_equal(c, cl_va_arg(cs)))
228
char_equal(cl_object x, cl_object y)
230
cl_fixnum i = char_code(x);
231
cl_fixnum j = char_code(y);
240
@(defun char-not-equal (&rest cs)
244
/* INV: char_equal() checks the type of its arguments */
246
FEwrong_num_arguments(@'char-not-equal');
248
for (i = 2; i<=narg; i++) {
250
cl_va_start(ds, narg, narg, 0);
253
if (char_equal(c, cl_va_arg(ds)))
260
Lchar_compare(cl_narg narg, int s, int t, cl_va_list args)
264
/* INV: char_compare() checks the types of its arguments */
266
FEwrong_num_arguments_anonym();
268
for (; --narg; c = d) {
270
if (s*char_compare(d, c) < t)
277
char_compare(cl_object x, cl_object y)
279
cl_fixnum i = char_code(x);
280
cl_fixnum j = char_code(y);
294
@(defun char-lessp (&rest args)
296
return Lchar_compare(narg, 1, 1, args);
299
@(defun char-greaterp (&rest args)
301
return Lchar_compare(narg,-1, 1, args);
304
@(defun char-not-greaterp (&rest args)
306
return Lchar_compare(narg, 1, 0, args);
309
@(defun char-not-lessp (&rest args)
311
return Lchar_compare(narg,-1, 0, args);
316
cl_character(cl_object x)
318
switch (type_of(x)) {
324
if (x->string.fillp == 1)
325
x = CODE_CHAR(x->string.self[0]);
328
FEtype_error_character(x);
334
cl_char_code(cl_object c)
336
/* INV: char_code() checks the type of `c' */
337
@(return MAKE_FIXNUM(char_code(c)))
341
cl_code_char(cl_object c)
345
switch (type_of(c)) {
348
if (fc < CHAR_CODE_LIMIT && fc >= 0) {
356
FEtype_error_integer(c);
362
cl_char_upcase(cl_object c)
364
/* INV: char_code() checks the type of `c' */
365
cl_fixnum code = char_code(c);
366
@(return (islower(code) ? CODE_CHAR(toupper(code)) : c))
370
cl_char_downcase(cl_object c)
372
/* INV: char_code() checks the type of `c' */
373
cl_fixnum code = char_code(c);
374
@(return (isupper(code) ? CODE_CHAR(tolower(code)) : c))
377
@(defun digit_char (w &optional (r MAKE_FIXNUM(10)))
380
/* INV: fixnnint() checks the types of `w' and `r' */
381
if (type_of(w) == t_bignum) {
384
int dw = ecl_digit_char(fixnnint(w), fixnnint(r));
385
output = (dw < 0)? Cnil : CODE_CHAR(dw);
391
ecl_digit_char(cl_fixnum w, cl_fixnum r)
393
if (r < 2 || r > 36 || w < 0 || w >= r)
398
return(w - 10 + 'A');
402
cl_char_int(cl_object c)
404
/* INV: char_code() checks the type of `c' */
405
return1(MAKE_FIXNUM(char_code(c)));
409
cl_char_name(cl_object c)
411
cl_index code = char_code(c);
415
name[2] = ecl_digit_char(code & 0xF, 16);
416
name[1] = ecl_digit_char(code / 16, 16);
417
output = make_string_copy(name);
419
output = gethash_safe(c, cl_core.char_names, Cnil);
425
cl_name_char(cl_object name)
427
cl_object c = gethash_safe((name = cl_string(name)), cl_core.char_names, Cnil);
428
if (c == Cnil && length(name) == 3) {
429
char *s = name->string.self;
430
if (s[0] == 'A' || s[0] == 'a') {
431
int d2 = digitp(s[2], 16);
432
int d1 = digitp(s[1], 16);
433
if (d1 >= 0 && d2 >= 0) {
434
c = CODE_CHAR(d1 * 16 + d2);