Add 'scm_c_make_char' and use it where appropriate.
This reverts the change to SCM_MAKE_CHAR made in the previous commit
63818453ad226cd3c2d1fd8ade12e3d7c1d43c05, which used an arithmetic trick
to avoid evaluating its argument more than once.
Here, we restore the previous implementation of SCM_MAKE_CHAR, which
evaluates its argument twice. Instead, we introduce a new inlinable
function 'scm_c_make_char' and replace uses of SCM_MAKE_CHAR with calls
to 'scm_c_make_char' where appropriate.
* libguile/chars.h (scm_c_make_char): New inline function.
* libguile/inline.c: Include chars.h.
* libguile/srfi-13.c (REF_IN_CHARSET, scm_string_any, scm_string_every)
(scm_string_trim, scm_string_trim_right, scm_string_trim_both)
(scm_string_index, scm_string_index_right, scm_string_skip)
(scm_string_skip_right, scm_string_count, string_titlecase_x)
(string_reverse_x, scm_string_fold, scm_string_fold_right)
(scm_string_for_each, scm_string_filter, scm_string_delete):
Use 'scm_c_make_char' instead of 'SCM_MAKE_CHAR' in cases where the
argument calls a function.
* libguile/chars.c (scm_char_upcase, scm_char_downcase, scm_char_titlecase),
libguile/ports.c (scm_port_decode_char),
libguile/print.c (scm_simple_format),
libguile/read.c (scm_read_character),
libguile/strings.c (scm_string_ref, scm_c_string_ref),
2019-05-07 02:28:26 -04:00
|
|
|
|
/* Copyright 1995-1996,1998,2000-2001,2004,2006,2008-2011,2014,2018-2019
|
2018-06-20 20:01:49 +02:00
|
|
|
|
Free Software Foundation, Inc.
|
|
|
|
|
|
|
|
|
|
|
|
This file is part of Guile.
|
|
|
|
|
|
|
|
|
|
|
|
Guile is free software: you can redistribute it and/or modify it
|
|
|
|
|
|
under the terms of the GNU Lesser General Public License as published
|
|
|
|
|
|
by the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
|
|
|
|
Guile is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
|
|
|
|
License for more details.
|
|
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
|
License along with Guile. If not, see
|
|
|
|
|
|
<https://www.gnu.org/licenses/>. */
|
1999-12-12 02:36:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2018-06-20 18:31:24 +02:00
|
|
|
|
|
2008-09-13 15:35:27 +02:00
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
|
|
# include <config.h>
|
|
|
|
|
|
#endif
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
|
|
|
|
|
#include <ctype.h>
|
2004-04-24 22:03:28 +00:00
|
|
|
|
#include <limits.h>
|
2018-06-19 11:48:09 +02:00
|
|
|
|
#include <string.h>
|
2009-07-29 06:38:32 -07:00
|
|
|
|
#include <unicase.h>
|
2009-12-24 00:25:19 -05:00
|
|
|
|
#include <unictype.h>
|
2009-07-29 06:38:32 -07:00
|
|
|
|
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "boolean.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "gsubr.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "numbers.h"
|
|
|
|
|
|
#include "pairs.h"
|
|
|
|
|
|
#include "srfi-14.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "symbols.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "chars.h"
|
|
|
|
|
|
|
2004-08-24 22:12:59 +00:00
|
|
|
|
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
|
SCM_DEFINE (scm_char_p, "char?", 1, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
|
(SCM x),
|
2000-08-18 09:30:54 +00:00
|
|
|
|
"Return @code{#t} iff @var{x} is a character, else @code{#f}.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_char_p
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2004-07-06 10:59:25 +00:00
|
|
|
|
return scm_from_bool (SCM_CHARP(x));
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2010-01-06 11:06:37 +01:00
|
|
|
|
static SCM scm_i_char_eq_p (SCM x, SCM y, SCM rest);
|
2009-12-04 13:05:00 +01:00
|
|
|
|
SCM_DEFINE (scm_i_char_eq_p, "char=?", 0, 2, 1,
|
|
|
|
|
|
(SCM x, SCM y, SCM rest),
|
|
|
|
|
|
"Return @code{#t} if the Unicode code point of @var{x} is equal to the\n"
|
|
|
|
|
|
"code point of @var{y}, else @code{#f}.\n")
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_char_eq_p
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SCM_UNBNDP (x) || SCM_UNBNDP (y))
|
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
while (!scm_is_null (rest))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (scm_is_false (scm_char_eq_p (x, y)))
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
x = y;
|
|
|
|
|
|
y = scm_car (rest);
|
|
|
|
|
|
rest = scm_cdr (rest);
|
|
|
|
|
|
}
|
|
|
|
|
|
return scm_char_eq_p (x, y);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM scm_char_eq_p (SCM x, SCM y)
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_char_eq_p
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2000-12-04 17:19:35 +00:00
|
|
|
|
SCM_VALIDATE_CHAR (1, x);
|
|
|
|
|
|
SCM_VALIDATE_CHAR (2, y);
|
2004-07-27 15:41:49 +00:00
|
|
|
|
return scm_from_bool (scm_is_eq (x, y));
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
2010-01-06 11:06:37 +01:00
|
|
|
|
static SCM scm_i_char_less_p (SCM x, SCM y, SCM rest);
|
2009-12-04 13:05:00 +01:00
|
|
|
|
SCM_DEFINE (scm_i_char_less_p, "char<?", 0, 2, 1,
|
|
|
|
|
|
(SCM x, SCM y, SCM rest),
|
|
|
|
|
|
"Return @code{#t} iff the code point of @var{x} is less than the code\n"
|
|
|
|
|
|
"point of @var{y}, else @code{#f}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_char_less_p
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SCM_UNBNDP (x) || SCM_UNBNDP (y))
|
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
while (!scm_is_null (rest))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (scm_is_false (scm_char_less_p (x, y)))
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
x = y;
|
|
|
|
|
|
y = scm_car (rest);
|
|
|
|
|
|
rest = scm_cdr (rest);
|
|
|
|
|
|
}
|
|
|
|
|
|
return scm_char_less_p (x, y);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM scm_char_less_p (SCM x, SCM y)
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_char_less_p
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
|
SCM_VALIDATE_CHAR (1, x);
|
|
|
|
|
|
SCM_VALIDATE_CHAR (2, y);
|
2004-07-06 10:59:25 +00:00
|
|
|
|
return scm_from_bool (SCM_CHAR(x) < SCM_CHAR(y));
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2010-01-06 11:06:37 +01:00
|
|
|
|
static SCM scm_i_char_leq_p (SCM x, SCM y, SCM rest);
|
2009-12-04 13:05:00 +01:00
|
|
|
|
SCM_DEFINE (scm_i_char_leq_p, "char<=?", 0, 2, 1,
|
|
|
|
|
|
(SCM x, SCM y, SCM rest),
|
|
|
|
|
|
"Return @code{#t} if the Unicode code point of @var{x} is less than or\n"
|
|
|
|
|
|
"equal to the code point of @var{y}, else @code{#f}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_char_leq_p
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SCM_UNBNDP (x) || SCM_UNBNDP (y))
|
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
while (!scm_is_null (rest))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (scm_is_false (scm_char_leq_p (x, y)))
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
x = y;
|
|
|
|
|
|
y = scm_car (rest);
|
|
|
|
|
|
rest = scm_cdr (rest);
|
|
|
|
|
|
}
|
|
|
|
|
|
return scm_char_leq_p (x, y);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM scm_char_leq_p (SCM x, SCM y)
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_char_leq_p
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
|
SCM_VALIDATE_CHAR (1, x);
|
|
|
|
|
|
SCM_VALIDATE_CHAR (2, y);
|
2004-07-06 10:59:25 +00:00
|
|
|
|
return scm_from_bool (SCM_CHAR(x) <= SCM_CHAR(y));
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2010-01-06 11:06:37 +01:00
|
|
|
|
static SCM scm_i_char_gr_p (SCM x, SCM y, SCM rest);
|
2009-12-04 13:05:00 +01:00
|
|
|
|
SCM_DEFINE (scm_i_char_gr_p, "char>?", 0, 2, 1,
|
|
|
|
|
|
(SCM x, SCM y, SCM rest),
|
|
|
|
|
|
"Return @code{#t} if the Unicode code point of @var{x} is greater than\n"
|
|
|
|
|
|
"the code point of @var{y}, else @code{#f}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_char_gr_p
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SCM_UNBNDP (x) || SCM_UNBNDP (y))
|
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
while (!scm_is_null (rest))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (scm_is_false (scm_char_gr_p (x, y)))
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
x = y;
|
|
|
|
|
|
y = scm_car (rest);
|
|
|
|
|
|
rest = scm_cdr (rest);
|
|
|
|
|
|
}
|
|
|
|
|
|
return scm_char_gr_p (x, y);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM scm_char_gr_p (SCM x, SCM y)
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_char_gr_p
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
|
SCM_VALIDATE_CHAR (1, x);
|
|
|
|
|
|
SCM_VALIDATE_CHAR (2, y);
|
2004-07-06 10:59:25 +00:00
|
|
|
|
return scm_from_bool (SCM_CHAR(x) > SCM_CHAR(y));
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2010-01-06 11:06:37 +01:00
|
|
|
|
static SCM scm_i_char_geq_p (SCM x, SCM y, SCM rest);
|
2009-12-04 13:05:00 +01:00
|
|
|
|
SCM_DEFINE (scm_i_char_geq_p, "char>=?", 0, 2, 1,
|
|
|
|
|
|
(SCM x, SCM y, SCM rest),
|
|
|
|
|
|
"Return @code{#t} if the Unicode code point of @var{x} is greater than\n"
|
|
|
|
|
|
"or equal to the code point of @var{y}, else @code{#f}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_char_geq_p
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SCM_UNBNDP (x) || SCM_UNBNDP (y))
|
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
while (!scm_is_null (rest))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (scm_is_false (scm_char_geq_p (x, y)))
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
x = y;
|
|
|
|
|
|
y = scm_car (rest);
|
|
|
|
|
|
rest = scm_cdr (rest);
|
|
|
|
|
|
}
|
|
|
|
|
|
return scm_char_geq_p (x, y);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM scm_char_geq_p (SCM x, SCM y)
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_char_geq_p
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
|
SCM_VALIDATE_CHAR (1, x);
|
|
|
|
|
|
SCM_VALIDATE_CHAR (2, y);
|
2004-07-06 10:59:25 +00:00
|
|
|
|
return scm_from_bool (SCM_CHAR(x) >= SCM_CHAR(y));
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2009-08-30 15:58:32 -07:00
|
|
|
|
/* FIXME?: R6RS specifies that these comparisons are case-folded.
|
|
|
|
|
|
This is the same thing as comparing the uppercase characters in
|
|
|
|
|
|
practice, but, not in theory. Unicode has table containing their
|
|
|
|
|
|
definition of case-folded character mappings. A more correct
|
|
|
|
|
|
implementation would be to use that table and make a char-foldcase
|
|
|
|
|
|
function. */
|
|
|
|
|
|
|
2010-01-06 11:06:37 +01:00
|
|
|
|
static SCM scm_i_char_ci_eq_p (SCM x, SCM y, SCM rest);
|
2009-12-04 13:05:00 +01:00
|
|
|
|
SCM_DEFINE (scm_i_char_ci_eq_p, "char-ci=?", 0, 2, 1,
|
|
|
|
|
|
(SCM x, SCM y, SCM rest),
|
|
|
|
|
|
"Return @code{#t} if the case-folded Unicode code point of @var{x} is\n"
|
|
|
|
|
|
"the same as the case-folded code point of @var{y}, else @code{#f}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_char_ci_eq_p
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SCM_UNBNDP (x) || SCM_UNBNDP (y))
|
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
while (!scm_is_null (rest))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (scm_is_false (scm_char_ci_eq_p (x, y)))
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
x = y;
|
|
|
|
|
|
y = scm_car (rest);
|
|
|
|
|
|
rest = scm_cdr (rest);
|
|
|
|
|
|
}
|
|
|
|
|
|
return scm_char_ci_eq_p (x, y);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM scm_char_ci_eq_p (SCM x, SCM y)
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_char_ci_eq_p
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
|
SCM_VALIDATE_CHAR (1, x);
|
|
|
|
|
|
SCM_VALIDATE_CHAR (2, y);
|
2004-07-06 10:59:25 +00:00
|
|
|
|
return scm_from_bool (scm_c_upcase(SCM_CHAR(x))==scm_c_upcase(SCM_CHAR(y)));
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2010-01-06 11:06:37 +01:00
|
|
|
|
static SCM scm_i_char_ci_less_p (SCM x, SCM y, SCM rest);
|
2009-12-04 13:05:00 +01:00
|
|
|
|
SCM_DEFINE (scm_i_char_ci_less_p, "char-ci<?", 0, 2, 1,
|
|
|
|
|
|
(SCM x, SCM y, SCM rest),
|
|
|
|
|
|
"Return @code{#t} if the case-folded Unicode code point of @var{x} is\n"
|
|
|
|
|
|
"less than the case-folded code point of @var{y}, else @code{#f}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_char_ci_less_p
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SCM_UNBNDP (x) || SCM_UNBNDP (y))
|
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
while (!scm_is_null (rest))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (scm_is_false (scm_char_ci_less_p (x, y)))
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
x = y;
|
|
|
|
|
|
y = scm_car (rest);
|
|
|
|
|
|
rest = scm_cdr (rest);
|
|
|
|
|
|
}
|
|
|
|
|
|
return scm_char_ci_less_p (x, y);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM scm_char_ci_less_p (SCM x, SCM y)
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_char_ci_less_p
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
|
SCM_VALIDATE_CHAR (1, x);
|
|
|
|
|
|
SCM_VALIDATE_CHAR (2, y);
|
2004-07-06 10:59:25 +00:00
|
|
|
|
return scm_from_bool ((scm_c_upcase(SCM_CHAR(x))) < scm_c_upcase(SCM_CHAR(y)));
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2010-01-06 11:06:37 +01:00
|
|
|
|
static SCM scm_i_char_ci_leq_p (SCM x, SCM y, SCM rest);
|
2009-12-04 13:05:00 +01:00
|
|
|
|
SCM_DEFINE (scm_i_char_ci_leq_p, "char-ci<=?", 0, 2, 1,
|
|
|
|
|
|
(SCM x, SCM y, SCM rest),
|
fix typos in the manual bits generated from source comments.
* libguile/bitvectors.c, libguile/chars.c,
libguile/deprecated.c, libguile/numbers.c, libguile/random.c,
libguile/read.c, libguile/root.c, libguile/srfi-1.c,
libguile/srfi-13.c, libguile/srfi-14.c, libguile/uniform.c:
Fix typos, add missing newlines.
2011-02-07 00:29:51 +01:00
|
|
|
|
"Return @code{#t} iff the case-folded Unicode code point of @var{x} is\n"
|
2009-12-04 13:05:00 +01:00
|
|
|
|
"less than or equal to the case-folded code point of @var{y}, else\n"
|
|
|
|
|
|
"@code{#f}")
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_char_ci_leq_p
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SCM_UNBNDP (x) || SCM_UNBNDP (y))
|
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
while (!scm_is_null (rest))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (scm_is_false (scm_char_ci_leq_p (x, y)))
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
x = y;
|
|
|
|
|
|
y = scm_car (rest);
|
|
|
|
|
|
rest = scm_cdr (rest);
|
|
|
|
|
|
}
|
|
|
|
|
|
return scm_char_ci_leq_p (x, y);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM scm_char_ci_leq_p (SCM x, SCM y)
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_char_ci_leq_p
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
|
SCM_VALIDATE_CHAR (1, x);
|
|
|
|
|
|
SCM_VALIDATE_CHAR (2, y);
|
2004-07-06 10:59:25 +00:00
|
|
|
|
return scm_from_bool (scm_c_upcase(SCM_CHAR(x)) <= scm_c_upcase(SCM_CHAR(y)));
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2010-01-06 11:06:37 +01:00
|
|
|
|
static SCM scm_i_char_ci_gr_p (SCM x, SCM y, SCM rest);
|
2009-12-04 13:05:00 +01:00
|
|
|
|
SCM_DEFINE (scm_i_char_ci_gr_p, "char-ci>?", 0, 2, 1,
|
|
|
|
|
|
(SCM x, SCM y, SCM rest),
|
|
|
|
|
|
"Return @code{#t} iff the case-folded code point of @var{x} is greater\n"
|
|
|
|
|
|
"than the case-folded code point of @var{y}, else @code{#f}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_char_ci_gr_p
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SCM_UNBNDP (x) || SCM_UNBNDP (y))
|
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
while (!scm_is_null (rest))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (scm_is_false (scm_char_ci_gr_p (x, y)))
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
x = y;
|
|
|
|
|
|
y = scm_car (rest);
|
|
|
|
|
|
rest = scm_cdr (rest);
|
|
|
|
|
|
}
|
|
|
|
|
|
return scm_char_ci_gr_p (x, y);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM scm_char_ci_gr_p (SCM x, SCM y)
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_char_ci_gr_p
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
|
SCM_VALIDATE_CHAR (1, x);
|
|
|
|
|
|
SCM_VALIDATE_CHAR (2, y);
|
2004-07-06 10:59:25 +00:00
|
|
|
|
return scm_from_bool (scm_c_upcase(SCM_CHAR(x)) > scm_c_upcase(SCM_CHAR(y)));
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2010-01-06 11:06:37 +01:00
|
|
|
|
static SCM scm_i_char_ci_geq_p (SCM x, SCM y, SCM rest);
|
2009-12-04 13:05:00 +01:00
|
|
|
|
SCM_DEFINE (scm_i_char_ci_geq_p, "char-ci>=?", 0, 2, 1,
|
|
|
|
|
|
(SCM x, SCM y, SCM rest),
|
|
|
|
|
|
"Return @code{#t} iff the case-folded Unicode code point of @var{x} is\n"
|
|
|
|
|
|
"greater than or equal to the case-folded code point of @var{y}, else\n"
|
|
|
|
|
|
"@code{#f}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_char_ci_geq_p
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SCM_UNBNDP (x) || SCM_UNBNDP (y))
|
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
while (!scm_is_null (rest))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (scm_is_false (scm_char_ci_geq_p (x, y)))
|
|
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
x = y;
|
|
|
|
|
|
y = scm_car (rest);
|
|
|
|
|
|
rest = scm_cdr (rest);
|
|
|
|
|
|
}
|
|
|
|
|
|
return scm_char_ci_geq_p (x, y);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM scm_char_ci_geq_p (SCM x, SCM y)
|
|
|
|
|
|
#define FUNC_NAME s_scm_i_char_ci_geq_p
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
|
SCM_VALIDATE_CHAR (1, x);
|
|
|
|
|
|
SCM_VALIDATE_CHAR (2, y);
|
2004-07-06 10:59:25 +00:00
|
|
|
|
return scm_from_bool (scm_c_upcase(SCM_CHAR(x)) >= scm_c_upcase(SCM_CHAR(y)));
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
2000-01-05 19:25:37 +00:00
|
|
|
|
SCM_DEFINE (scm_char_alphabetic_p, "char-alphabetic?", 1, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
|
(SCM chr),
|
2004-08-24 22:12:59 +00:00
|
|
|
|
"Return @code{#t} iff @var{chr} is alphabetic, else @code{#f}.\n")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_char_alphabetic_p
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2004-08-24 22:12:59 +00:00
|
|
|
|
return scm_char_set_contains_p (scm_char_set_letter, chr);
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2000-01-05 19:25:37 +00:00
|
|
|
|
SCM_DEFINE (scm_char_numeric_p, "char-numeric?", 1, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
|
(SCM chr),
|
2004-08-24 22:12:59 +00:00
|
|
|
|
"Return @code{#t} iff @var{chr} is numeric, else @code{#f}.\n")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_char_numeric_p
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2004-08-24 22:12:59 +00:00
|
|
|
|
return scm_char_set_contains_p (scm_char_set_digit, chr);
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2000-01-05 19:25:37 +00:00
|
|
|
|
SCM_DEFINE (scm_char_whitespace_p, "char-whitespace?", 1, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
|
(SCM chr),
|
2004-08-24 22:12:59 +00:00
|
|
|
|
"Return @code{#t} iff @var{chr} is whitespace, else @code{#f}.\n")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_char_whitespace_p
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2004-08-24 22:12:59 +00:00
|
|
|
|
return scm_char_set_contains_p (scm_char_set_whitespace, chr);
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
2000-01-05 19:25:37 +00:00
|
|
|
|
SCM_DEFINE (scm_char_upper_case_p, "char-upper-case?", 1, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
|
(SCM chr),
|
2004-08-24 22:12:59 +00:00
|
|
|
|
"Return @code{#t} iff @var{chr} is uppercase, else @code{#f}.\n")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_char_upper_case_p
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2004-08-24 22:12:59 +00:00
|
|
|
|
return scm_char_set_contains_p (scm_char_set_upper_case, chr);
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
2000-01-05 19:25:37 +00:00
|
|
|
|
SCM_DEFINE (scm_char_lower_case_p, "char-lower-case?", 1, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
|
(SCM chr),
|
2004-08-24 22:12:59 +00:00
|
|
|
|
"Return @code{#t} iff @var{chr} is lowercase, else @code{#f}.\n")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_char_lower_case_p
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2004-08-24 22:12:59 +00:00
|
|
|
|
return scm_char_set_contains_p (scm_char_set_lower_case, chr);
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
|
SCM_DEFINE (scm_char_is_both_p, "char-is-both?", 1, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
|
(SCM chr),
|
2009-09-03 08:48:23 -07:00
|
|
|
|
"Return @code{#t} iff @var{chr} is either uppercase or lowercase, else\n"
|
|
|
|
|
|
"@code{#f}.\n")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_char_is_both_p
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2004-08-24 22:12:59 +00:00
|
|
|
|
if (scm_is_true (scm_char_set_contains_p (scm_char_set_lower_case, chr)))
|
|
|
|
|
|
return SCM_BOOL_T;
|
|
|
|
|
|
return scm_char_set_contains_p (scm_char_set_upper_case, chr);
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
2000-01-05 19:05:23 +00:00
|
|
|
|
SCM_DEFINE (scm_char_to_integer, "char->integer", 1, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
|
(SCM chr),
|
2009-09-03 08:48:23 -07:00
|
|
|
|
"Return the Unicode code point of @var{chr}.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_char_to_integer
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
|
SCM_VALIDATE_CHAR (1, chr);
|
2009-07-29 06:38:32 -07:00
|
|
|
|
return scm_from_uint32 (SCM_CHAR(chr));
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
2000-01-05 19:25:37 +00:00
|
|
|
|
SCM_DEFINE (scm_integer_to_char, "integer->char", 1, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
|
(SCM n),
|
2009-09-03 08:48:23 -07:00
|
|
|
|
"Return the character that has Unicode code point @var{n}. The integer\n"
|
|
|
|
|
|
"@var{n} must be a valid code point. Valid code points are in the\n"
|
|
|
|
|
|
"ranges 0 to @code{#xD7FF} inclusive or @code{#xE000} to\n"
|
|
|
|
|
|
"@code{#x10FFFF} inclusive.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_integer_to_char
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2009-07-29 06:38:32 -07:00
|
|
|
|
scm_t_wchar cn;
|
|
|
|
|
|
|
|
|
|
|
|
cn = scm_to_wchar (n);
|
|
|
|
|
|
|
|
|
|
|
|
/* Avoid the surrogates. */
|
|
|
|
|
|
if (!SCM_IS_UNICODE_CHAR (cn))
|
|
|
|
|
|
scm_out_of_range (FUNC_NAME, n);
|
|
|
|
|
|
|
|
|
|
|
|
return SCM_MAKE_CHAR (cn);
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
2000-01-05 19:25:37 +00:00
|
|
|
|
SCM_DEFINE (scm_char_upcase, "char-upcase", 1, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
|
(SCM chr),
|
2000-08-18 09:30:54 +00:00
|
|
|
|
"Return the uppercase character version of @var{chr}.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_char_upcase
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
|
SCM_VALIDATE_CHAR (1, chr);
|
2019-08-24 11:57:39 +02:00
|
|
|
|
return scm_c_make_char (scm_c_upcase (SCM_CHAR (chr)));
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
2000-01-05 19:25:37 +00:00
|
|
|
|
SCM_DEFINE (scm_char_downcase, "char-downcase", 1, 0, 0,
|
1999-12-12 02:36:16 +00:00
|
|
|
|
(SCM chr),
|
2000-08-18 09:30:54 +00:00
|
|
|
|
"Return the lowercase character version of @var{chr}.")
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#define FUNC_NAME s_scm_char_downcase
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
2002-07-20 14:08:34 +00:00
|
|
|
|
SCM_VALIDATE_CHAR (1, chr);
|
2019-08-24 11:57:39 +02:00
|
|
|
|
return scm_c_make_char (scm_c_downcase (SCM_CHAR(chr)));
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
1999-12-12 02:36:16 +00:00
|
|
|
|
#undef FUNC_NAME
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
Improved support for Unicode title case in Guile's string and character APIs.
* doc/ref/api-data.texi (Characters): Documentation for `char-titlecase'.
* doc/ref/api-i18n.texi (Character Case Mapping): Documentation for
`char-locale-titlecase' and `string-locale-titlecase'.
* libguile/chars.c, libguile/chars.h (scm_char_titlecase, scm_c_titlecase): New
functions.
* libguile/i18n.c, libguile/i18n.h (chr_to_case, scm_char_locale_titlecase,
str_to_case, scm_string_locale_titlecase): New functions.
* libguile/i18n.c (scm_char_locale_downcase, scm_char_locale_upcase,
scm_string_locale_downcase, scm_string_locale_upcase): Refactor to share code
via chr_to_case and str_to_case, as appropriate.
* module/ice-9/i18n.scm (char-locale-title-case, string-locale-titlecase): New
functions.
* libguile/srfi-13.c (string_titlecase_x): Use uc_totitle instead of uc_toupper.
* test-suite/tests/chars.test: Tests for `char-titlecase'.
* test-suite/tests/i18n.test: Tests for `char-locale-titlecase' and
`string-locale-titlecase'.
* test-suite/tests/srfi-13.test: Tests for `string-titlecase'.
2009-12-22 00:19:56 -05:00
|
|
|
|
SCM_DEFINE (scm_char_titlecase, "char-titlecase", 1, 0, 0,
|
|
|
|
|
|
(SCM chr),
|
|
|
|
|
|
"Return the titlecase character version of @var{chr}.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_char_titlecase
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_VALIDATE_CHAR (1, chr);
|
2019-08-24 11:57:39 +02:00
|
|
|
|
return scm_c_make_char (scm_c_titlecase (SCM_CHAR(chr)));
|
Improved support for Unicode title case in Guile's string and character APIs.
* doc/ref/api-data.texi (Characters): Documentation for `char-titlecase'.
* doc/ref/api-i18n.texi (Character Case Mapping): Documentation for
`char-locale-titlecase' and `string-locale-titlecase'.
* libguile/chars.c, libguile/chars.h (scm_char_titlecase, scm_c_titlecase): New
functions.
* libguile/i18n.c, libguile/i18n.h (chr_to_case, scm_char_locale_titlecase,
str_to_case, scm_string_locale_titlecase): New functions.
* libguile/i18n.c (scm_char_locale_downcase, scm_char_locale_upcase,
scm_string_locale_downcase, scm_string_locale_upcase): Refactor to share code
via chr_to_case and str_to_case, as appropriate.
* module/ice-9/i18n.scm (char-locale-title-case, string-locale-titlecase): New
functions.
* libguile/srfi-13.c (string_titlecase_x): Use uc_totitle instead of uc_toupper.
* test-suite/tests/chars.test: Tests for `char-titlecase'.
* test-suite/tests/i18n.test: Tests for `char-locale-titlecase' and
`string-locale-titlecase'.
* test-suite/tests/srfi-13.test: Tests for `string-titlecase'.
2009-12-22 00:19:56 -05:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
2009-12-24 00:25:19 -05:00
|
|
|
|
SCM_DEFINE (scm_char_general_category, "char-general-category", 1, 0, 0,
|
|
|
|
|
|
(SCM chr),
|
|
|
|
|
|
"Return a symbol representing the Unicode general category of "
|
|
|
|
|
|
"@var{chr} or @code{#f} if a named category cannot be found.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_char_general_category
|
|
|
|
|
|
{
|
|
|
|
|
|
const char *sym;
|
|
|
|
|
|
uc_general_category_t cat;
|
|
|
|
|
|
|
|
|
|
|
|
SCM_VALIDATE_CHAR (1, chr);
|
|
|
|
|
|
cat = uc_general_category (SCM_CHAR (chr));
|
|
|
|
|
|
sym = uc_general_category_name (cat);
|
|
|
|
|
|
|
|
|
|
|
|
if (sym != NULL)
|
2011-10-25 17:45:29 +02:00
|
|
|
|
return scm_from_utf8_symbol (sym);
|
2009-12-24 00:25:19 -05:00
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2004-04-06 21:48:02 +00:00
|
|
|
|
/*
|
|
|
|
|
|
TODO: change name to scm_i_.. ? --hwn
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
* __scm.h, alist.c, alist.h, append.c, append.h, appinit.c,
arbiters.c, arbiters.h, async.c, async.h, boolean.c, boolean.h,
chars.c, chars.h, continuations.c, continuations.h, debug.c,
debug.h, dynwind.c, dynwind.h, eq.c, eq.h, error.c, eval.c,
eval.h, extchrs.c, extchrs.h, fdsocket.c, fdsocket.h, filesys.c,
filesys.h, fports.c, fports.h, gc.c, gdb_interface.h, gdbint.c,
gdbint.h, genio.c, genio.h, gscm.c, gscm.h, gsubr.c, gsubr.h,
hash.c, hash.h, hashtab.c, hashtab.h, init.c, ioext.c, ioext.h,
kw.c, kw.h, libguile.h, mallocs.c, mallocs.h, markers.c,
markers.h, mbstrings.c, mbstrings.h, numbers.c, numbers.h,
objprop.c, objprop.h, options.c, options.h, pairs.c, pairs.h,
ports.c, ports.h, posix.c, posix.h, print.c, print.h, procprop.c,
procprop.h, procs.c, procs.h, ramap.c, ramap.h, read.c, read.h,
root.c, scmsigs.c, scmsigs.h, sequences.c, sequences.h, simpos.c,
simpos.h, smob.c, socket.c, socket.h, srcprop.c, srcprop.h,
stackchk.c, stackchk.h, stime.c, stime.h, strings.c, strings.h,
strop.c, strop.h, strorder.c, strorder.h, strports.c, strports.h,
struct.c, struct.h, symbols.c, symbols.h, tag.c, tag.h, unif.c,
unif.h, variable.c, variable.h, vectors.c, vectors.h, version.c,
version.h, vports.c, vports.h, weaks.c, weaks.h: Use SCM_P to
declare functions with prototypes. (Patch thanks to Marius
Vollmer.)
1996-10-14 01:33:50 +00:00
|
|
|
|
|
2009-07-29 06:38:32 -07:00
|
|
|
|
scm_t_wchar
|
|
|
|
|
|
scm_c_upcase (scm_t_wchar c)
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
Unicode-capable srfi-14 charsets
* libguile/Makefile.am: distribute new files srfi-14.i.c and
unidata_to_charset.pl
* chars.c (scm_c_upcase, scm_c_downcase): use unicode-enable toupper
and tolower
* libguile/srfi-14.h (scm_t_char_range, scm_t_char_set): new structures
to describe char-sets
(scm_t_char_set_cursor): new structure to describe char-set-cursors
(SCM_BITS_PER_LONG): removed
(SCM_CHARSET_GET): calls function
New declarations for scm_i_charset_get, scm_i_charset_set,
scm_i_charset_unset, and scm_debug_char_set.
* test-suite/tests/srfi-14.test: new tests
* libguile/srfi-14.c (SCM_CHARSET_DATA): new macro
(SCM_CHARSET_SET, SCM_CHARSET_UNSET): call function
(BYTES_PER_CHARSET, LONGS_PER_CHARSET): removed
(scm_i_charset_get, scm_i_charset_set, scm_i_charset_unset)
(charsets_equal, charsets_leq, charsets_union)
(charsets_intersection, charsets_complement, charsets_xor): new
functions that are low-level charset operators
(charset_print, charset_free): modified for new charset struct
(charset_cursor_print, charset_cursor_free): new function
(make_char_set, scm_char_set_p, scm_char_set_eq, scm_car_set_leq)
(scm_char_set_hash, scm_char_set_cursor, scm_char_set_ref)
(scm_char_set_cursor_next, scm_end_of_char_set_p, scm_char_set_fold)
(scm_char_set_unfold, scm_char_set_unfold_x, scm_char_set_for_each)
(scm_char_set_map, scm_char_set_copy, scm_char_set, scm_list_to_char_set)
(scm_list_to_char_set_x, scm_string_to_char_set, scm_string_to_char_set_x)
(scm_char_set_filter, scm_char_set_filter_x, scm_ucs_range_to_char_set)
(scm_ucs_range_to_char_set_x, scm_to_char_set, scm_char_set_size)
(scm_char_set_count, scm_char_set_to_list, scm_char_set_to_string)
(scm_char_set_contains_p, scm_char_set_every, scm_char_set_any)
(scm_char_set_adjoin, scm_char_set_delete, scm_char_set_adjoin_x)
(scm_char_set_delete_x, scm_char_set_complement, scm_char_set_union)
(scm_char_set_intersection, scm_char_set_difference, scm_char_set_xor)
(scm_char_set_diff_plus_intersection, scm_char_set_complement_x)
(scm_char_set_union_x, scm_char_set_intersection_x, scm_char_set_difference_x)
(scm_char_set_xor_x, scm_char_set_diff_plus_intersection_x): modified
to use new charset and charset-cursor data structures
(CSET_BLANK_PRED, CSET_SYMBOL_PRED, CSET_PUNCT_PRED, CSET_LOWER_PRED)
(CSET_UPPER_PRED, CSET_LETTER_PRED, CSET_DIGIT_PRED, CSET_WHITESPACE_PRED)
(CSET_CONTROL_PRED, CSET_HEX_DIGIT_PRED, CSET_ASCII_PRED, CSET_LETTER_PRED)
(CSET_LETTER_AND_DIGIT_PRED, CSET_PRINTING_PRED, CSET_TRUE_PRED)
(CSET_FALSE_PRED): removed
(scm_srfi_14_compute_char_sets): removed - too slow to iterate
over all of unicode at startup
(scm_debug_char_set) [SCM_CHARSET_DEBUG]: new function
2009-08-27 07:32:50 -07:00
|
|
|
|
return uc_toupper ((int) c);
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
* __scm.h, alist.c, alist.h, append.c, append.h, appinit.c,
arbiters.c, arbiters.h, async.c, async.h, boolean.c, boolean.h,
chars.c, chars.h, continuations.c, continuations.h, debug.c,
debug.h, dynwind.c, dynwind.h, eq.c, eq.h, error.c, eval.c,
eval.h, extchrs.c, extchrs.h, fdsocket.c, fdsocket.h, filesys.c,
filesys.h, fports.c, fports.h, gc.c, gdb_interface.h, gdbint.c,
gdbint.h, genio.c, genio.h, gscm.c, gscm.h, gsubr.c, gsubr.h,
hash.c, hash.h, hashtab.c, hashtab.h, init.c, ioext.c, ioext.h,
kw.c, kw.h, libguile.h, mallocs.c, mallocs.h, markers.c,
markers.h, mbstrings.c, mbstrings.h, numbers.c, numbers.h,
objprop.c, objprop.h, options.c, options.h, pairs.c, pairs.h,
ports.c, ports.h, posix.c, posix.h, print.c, print.h, procprop.c,
procprop.h, procs.c, procs.h, ramap.c, ramap.h, read.c, read.h,
root.c, scmsigs.c, scmsigs.h, sequences.c, sequences.h, simpos.c,
simpos.h, smob.c, socket.c, socket.h, srcprop.c, srcprop.h,
stackchk.c, stackchk.h, stime.c, stime.h, strings.c, strings.h,
strop.c, strop.h, strorder.c, strorder.h, strports.c, strports.h,
struct.c, struct.h, symbols.c, symbols.h, tag.c, tag.h, unif.c,
unif.h, variable.c, variable.h, vectors.c, vectors.h, version.c,
version.h, vports.c, vports.h, weaks.c, weaks.h: Use SCM_P to
declare functions with prototypes. (Patch thanks to Marius
Vollmer.)
1996-10-14 01:33:50 +00:00
|
|
|
|
|
2009-07-29 06:38:32 -07:00
|
|
|
|
scm_t_wchar
|
|
|
|
|
|
scm_c_downcase (scm_t_wchar c)
|
1996-07-25 22:56:11 +00:00
|
|
|
|
{
|
Unicode-capable srfi-14 charsets
* libguile/Makefile.am: distribute new files srfi-14.i.c and
unidata_to_charset.pl
* chars.c (scm_c_upcase, scm_c_downcase): use unicode-enable toupper
and tolower
* libguile/srfi-14.h (scm_t_char_range, scm_t_char_set): new structures
to describe char-sets
(scm_t_char_set_cursor): new structure to describe char-set-cursors
(SCM_BITS_PER_LONG): removed
(SCM_CHARSET_GET): calls function
New declarations for scm_i_charset_get, scm_i_charset_set,
scm_i_charset_unset, and scm_debug_char_set.
* test-suite/tests/srfi-14.test: new tests
* libguile/srfi-14.c (SCM_CHARSET_DATA): new macro
(SCM_CHARSET_SET, SCM_CHARSET_UNSET): call function
(BYTES_PER_CHARSET, LONGS_PER_CHARSET): removed
(scm_i_charset_get, scm_i_charset_set, scm_i_charset_unset)
(charsets_equal, charsets_leq, charsets_union)
(charsets_intersection, charsets_complement, charsets_xor): new
functions that are low-level charset operators
(charset_print, charset_free): modified for new charset struct
(charset_cursor_print, charset_cursor_free): new function
(make_char_set, scm_char_set_p, scm_char_set_eq, scm_car_set_leq)
(scm_char_set_hash, scm_char_set_cursor, scm_char_set_ref)
(scm_char_set_cursor_next, scm_end_of_char_set_p, scm_char_set_fold)
(scm_char_set_unfold, scm_char_set_unfold_x, scm_char_set_for_each)
(scm_char_set_map, scm_char_set_copy, scm_char_set, scm_list_to_char_set)
(scm_list_to_char_set_x, scm_string_to_char_set, scm_string_to_char_set_x)
(scm_char_set_filter, scm_char_set_filter_x, scm_ucs_range_to_char_set)
(scm_ucs_range_to_char_set_x, scm_to_char_set, scm_char_set_size)
(scm_char_set_count, scm_char_set_to_list, scm_char_set_to_string)
(scm_char_set_contains_p, scm_char_set_every, scm_char_set_any)
(scm_char_set_adjoin, scm_char_set_delete, scm_char_set_adjoin_x)
(scm_char_set_delete_x, scm_char_set_complement, scm_char_set_union)
(scm_char_set_intersection, scm_char_set_difference, scm_char_set_xor)
(scm_char_set_diff_plus_intersection, scm_char_set_complement_x)
(scm_char_set_union_x, scm_char_set_intersection_x, scm_char_set_difference_x)
(scm_char_set_xor_x, scm_char_set_diff_plus_intersection_x): modified
to use new charset and charset-cursor data structures
(CSET_BLANK_PRED, CSET_SYMBOL_PRED, CSET_PUNCT_PRED, CSET_LOWER_PRED)
(CSET_UPPER_PRED, CSET_LETTER_PRED, CSET_DIGIT_PRED, CSET_WHITESPACE_PRED)
(CSET_CONTROL_PRED, CSET_HEX_DIGIT_PRED, CSET_ASCII_PRED, CSET_LETTER_PRED)
(CSET_LETTER_AND_DIGIT_PRED, CSET_PRINTING_PRED, CSET_TRUE_PRED)
(CSET_FALSE_PRED): removed
(scm_srfi_14_compute_char_sets): removed - too slow to iterate
over all of unicode at startup
(scm_debug_char_set) [SCM_CHARSET_DEBUG]: new function
2009-08-27 07:32:50 -07:00
|
|
|
|
return uc_tolower ((int) c);
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
Improved support for Unicode title case in Guile's string and character APIs.
* doc/ref/api-data.texi (Characters): Documentation for `char-titlecase'.
* doc/ref/api-i18n.texi (Character Case Mapping): Documentation for
`char-locale-titlecase' and `string-locale-titlecase'.
* libguile/chars.c, libguile/chars.h (scm_char_titlecase, scm_c_titlecase): New
functions.
* libguile/i18n.c, libguile/i18n.h (chr_to_case, scm_char_locale_titlecase,
str_to_case, scm_string_locale_titlecase): New functions.
* libguile/i18n.c (scm_char_locale_downcase, scm_char_locale_upcase,
scm_string_locale_downcase, scm_string_locale_upcase): Refactor to share code
via chr_to_case and str_to_case, as appropriate.
* module/ice-9/i18n.scm (char-locale-title-case, string-locale-titlecase): New
functions.
* libguile/srfi-13.c (string_titlecase_x): Use uc_totitle instead of uc_toupper.
* test-suite/tests/chars.test: Tests for `char-titlecase'.
* test-suite/tests/i18n.test: Tests for `char-locale-titlecase' and
`string-locale-titlecase'.
* test-suite/tests/srfi-13.test: Tests for `string-titlecase'.
2009-12-22 00:19:56 -05:00
|
|
|
|
scm_t_wchar
|
|
|
|
|
|
scm_c_titlecase (scm_t_wchar c)
|
|
|
|
|
|
{
|
|
|
|
|
|
return uc_totitle ((int) c);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2009-07-27 21:02:23 -07:00
|
|
|
|
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2009-07-27 21:02:23 -07:00
|
|
|
|
/* There are a few sets of character names: R5RS, Guile
|
|
|
|
|
|
extensions for control characters, and leftover Guile extensions.
|
|
|
|
|
|
They are listed in order of precedence. */
|
|
|
|
|
|
|
2009-08-01 08:12:15 -07:00
|
|
|
|
static const char *const scm_r5rs_charnames[] = {
|
|
|
|
|
|
"space", "newline"
|
|
|
|
|
|
};
|
2009-07-27 21:02:23 -07:00
|
|
|
|
|
2018-06-21 08:39:03 +02:00
|
|
|
|
static const uint32_t scm_r5rs_charnums[] = {
|
2010-01-10 15:08:19 -08:00
|
|
|
|
0x20, 0x0a
|
2009-08-01 08:12:15 -07:00
|
|
|
|
};
|
2009-07-27 21:02:23 -07:00
|
|
|
|
|
2009-08-01 08:12:15 -07:00
|
|
|
|
#define SCM_N_R5RS_CHARNAMES (sizeof (scm_r5rs_charnames) / sizeof (char *))
|
2009-07-27 21:02:23 -07:00
|
|
|
|
|
2010-01-10 15:08:19 -08:00
|
|
|
|
static const char *const scm_r6rs_charnames[] = {
|
|
|
|
|
|
"nul", "alarm", "backspace", "tab", "linefeed", "vtab", "page",
|
|
|
|
|
|
"return", "esc", "delete"
|
|
|
|
|
|
/* 'space' and 'newline' are already included from the R5RS list. */
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2018-06-21 08:39:03 +02:00
|
|
|
|
static const uint32_t scm_r6rs_charnums[] = {
|
2010-01-10 15:08:19 -08:00
|
|
|
|
0x00, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
|
|
|
|
|
|
0x0d, 0x1b, 0x7f
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#define SCM_N_R6RS_CHARNAMES (sizeof (scm_r6rs_charnames) / sizeof (char *))
|
|
|
|
|
|
|
2014-01-12 04:36:57 -05:00
|
|
|
|
static const char *const scm_r7rs_charnames[] = {
|
|
|
|
|
|
"escape"
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2018-06-21 08:39:03 +02:00
|
|
|
|
static const uint32_t scm_r7rs_charnums[] = {
|
2014-01-12 04:36:57 -05:00
|
|
|
|
0x1b
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#define SCM_N_R7RS_CHARNAMES (sizeof (scm_r7rs_charnames) / sizeof (char *))
|
|
|
|
|
|
|
2009-07-27 21:02:23 -07:00
|
|
|
|
/* The abbreviated names for control characters. */
|
2009-08-01 08:12:15 -07:00
|
|
|
|
static const char *const scm_C0_control_charnames[] = {
|
|
|
|
|
|
/* C0 controls */
|
|
|
|
|
|
"nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
|
|
|
|
|
|
"bs", "ht", "lf", "vt", "ff", "cr", "so", "si",
|
|
|
|
|
|
"dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb",
|
|
|
|
|
|
"can", "em", "sub", "esc", "fs", "gs", "rs", "us",
|
|
|
|
|
|
"sp", "del"
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2018-06-21 08:39:03 +02:00
|
|
|
|
static const uint32_t scm_C0_control_charnums[] = {
|
2009-08-01 08:12:15 -07:00
|
|
|
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
|
|
|
|
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
|
|
|
|
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
|
|
|
|
|
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
|
|
|
|
|
0x20, 0x7f
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#define SCM_N_C0_CONTROL_CHARNAMES (sizeof (scm_C0_control_charnames) / sizeof (char *))
|
|
|
|
|
|
|
|
|
|
|
|
static const char *const scm_alt_charnames[] = {
|
2010-01-10 15:08:19 -08:00
|
|
|
|
"null", "nl", "np"
|
2009-08-01 08:12:15 -07:00
|
|
|
|
};
|
|
|
|
|
|
|
2018-06-21 08:39:03 +02:00
|
|
|
|
static const uint32_t scm_alt_charnums[] = {
|
2010-01-10 15:08:19 -08:00
|
|
|
|
0x00, 0x0a, 0x0c
|
2009-08-01 08:12:15 -07:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#define SCM_N_ALT_CHARNAMES (sizeof (scm_alt_charnames) / sizeof (char *))
|
2009-07-27 21:02:23 -07:00
|
|
|
|
|
|
|
|
|
|
/* Returns the string charname for a character if it exists, or NULL
|
|
|
|
|
|
otherwise. */
|
|
|
|
|
|
const char *
|
|
|
|
|
|
scm_i_charname (SCM chr)
|
|
|
|
|
|
{
|
2009-08-11 22:52:49 -07:00
|
|
|
|
size_t c;
|
2018-06-21 08:39:03 +02:00
|
|
|
|
uint32_t i = SCM_CHAR (chr);
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2009-08-01 08:12:15 -07:00
|
|
|
|
for (c = 0; c < SCM_N_R5RS_CHARNAMES; c++)
|
2009-07-27 21:02:23 -07:00
|
|
|
|
if (scm_r5rs_charnums[c] == i)
|
|
|
|
|
|
return scm_r5rs_charnames[c];
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2010-01-10 15:08:19 -08:00
|
|
|
|
for (c = 0; c < SCM_N_R6RS_CHARNAMES; c++)
|
|
|
|
|
|
if (scm_r6rs_charnums[c] == i)
|
|
|
|
|
|
return scm_r6rs_charnames[c];
|
|
|
|
|
|
|
2014-01-12 04:36:57 -05:00
|
|
|
|
for (c = 0; c < SCM_N_R7RS_CHARNAMES; c++)
|
|
|
|
|
|
if (scm_r7rs_charnums[c] == i)
|
|
|
|
|
|
return scm_r7rs_charnames[c];
|
|
|
|
|
|
|
2009-08-01 08:12:15 -07:00
|
|
|
|
for (c = 0; c < SCM_N_C0_CONTROL_CHARNAMES; c++)
|
2009-07-27 21:02:23 -07:00
|
|
|
|
if (scm_C0_control_charnums[c] == i)
|
|
|
|
|
|
return scm_C0_control_charnames[c];
|
|
|
|
|
|
|
2009-12-27 18:44:29 -08:00
|
|
|
|
/* Since the characters in scm_alt_charnums is a subset of
|
|
|
|
|
|
scm_C0_control_charnums, this code is never reached. */
|
2009-08-01 08:12:15 -07:00
|
|
|
|
for (c = 0; c < SCM_N_ALT_CHARNAMES; c++)
|
2009-07-27 21:02:23 -07:00
|
|
|
|
if (scm_alt_charnums[c] == i)
|
2009-12-27 18:44:29 -08:00
|
|
|
|
return scm_alt_charnames[c];
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
2009-07-27 21:02:23 -07:00
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Return a character from a string charname. */
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_i_charname_to_char (const char *charname, size_t charname_len)
|
|
|
|
|
|
{
|
2009-08-11 22:52:49 -07:00
|
|
|
|
size_t c;
|
2009-07-27 21:02:23 -07:00
|
|
|
|
|
2010-01-10 15:08:19 -08:00
|
|
|
|
/* The R5RS charnames. These are supposed to be case insensitive. */
|
2009-08-01 08:12:15 -07:00
|
|
|
|
for (c = 0; c < SCM_N_R5RS_CHARNAMES; c++)
|
2009-07-27 21:02:23 -07:00
|
|
|
|
if ((strlen (scm_r5rs_charnames[c]) == charname_len)
|
|
|
|
|
|
&& (!strncasecmp (scm_r5rs_charnames[c], charname, charname_len)))
|
|
|
|
|
|
return SCM_MAKE_CHAR (scm_r5rs_charnums[c]);
|
|
|
|
|
|
|
2014-01-12 04:36:57 -05:00
|
|
|
|
/* The R6RS charnames. R6RS says that these should be case-sensitive.
|
|
|
|
|
|
They are left as case-insensitive to avoid confusion. */
|
2010-01-10 15:08:19 -08:00
|
|
|
|
for (c = 0; c < SCM_N_R6RS_CHARNAMES; c++)
|
|
|
|
|
|
if ((strlen (scm_r6rs_charnames[c]) == charname_len)
|
|
|
|
|
|
&& (!strncasecmp (scm_r6rs_charnames[c], charname, charname_len)))
|
|
|
|
|
|
return SCM_MAKE_CHAR (scm_r6rs_charnums[c]);
|
|
|
|
|
|
|
2014-01-12 04:36:57 -05:00
|
|
|
|
/* The R7RS charnames. R7RS says that these should be case-sensitive.
|
|
|
|
|
|
They are left as case-insensitive to avoid confusion. */
|
|
|
|
|
|
for (c = 0; c < SCM_N_R7RS_CHARNAMES; c++)
|
|
|
|
|
|
if ((strlen (scm_r7rs_charnames[c]) == charname_len)
|
|
|
|
|
|
&& (!strncasecmp (scm_r7rs_charnames[c], charname, charname_len)))
|
|
|
|
|
|
return SCM_MAKE_CHAR (scm_r7rs_charnums[c]);
|
|
|
|
|
|
|
2010-01-10 15:08:19 -08:00
|
|
|
|
/* Then come the controls. By Guile convention, these are not case
|
|
|
|
|
|
sensitive. */
|
2009-08-01 08:12:15 -07:00
|
|
|
|
for (c = 0; c < SCM_N_C0_CONTROL_CHARNAMES; c++)
|
2009-07-27 21:02:23 -07:00
|
|
|
|
if ((strlen (scm_C0_control_charnames[c]) == charname_len)
|
|
|
|
|
|
&& (!strncasecmp (scm_C0_control_charnames[c], charname, charname_len)))
|
|
|
|
|
|
return SCM_MAKE_CHAR (scm_C0_control_charnums[c]);
|
|
|
|
|
|
|
|
|
|
|
|
/* Lastly are some old names carried over for compatibility. */
|
2009-08-01 08:12:15 -07:00
|
|
|
|
for (c = 0; c < SCM_N_ALT_CHARNAMES; c++)
|
2009-07-27 21:02:23 -07:00
|
|
|
|
if ((strlen (scm_alt_charnames[c]) == charname_len)
|
|
|
|
|
|
&& (!strncasecmp (scm_alt_charnames[c], charname, charname_len)))
|
|
|
|
|
|
return SCM_MAKE_CHAR (scm_alt_charnums[c]);
|
2009-08-01 08:12:15 -07:00
|
|
|
|
|
2009-07-27 21:02:23 -07:00
|
|
|
|
return SCM_BOOL_F;
|
|
|
|
|
|
}
|
1996-07-25 22:56:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
* __scm.h, alist.c, alist.h, append.c, append.h, appinit.c,
arbiters.c, arbiters.h, async.c, async.h, boolean.c, boolean.h,
chars.c, chars.h, continuations.c, continuations.h, debug.c,
debug.h, dynwind.c, dynwind.h, eq.c, eq.h, error.c, eval.c,
eval.h, extchrs.c, extchrs.h, fdsocket.c, fdsocket.h, filesys.c,
filesys.h, fports.c, fports.h, gc.c, gdb_interface.h, gdbint.c,
gdbint.h, genio.c, genio.h, gscm.c, gscm.h, gsubr.c, gsubr.h,
hash.c, hash.h, hashtab.c, hashtab.h, init.c, ioext.c, ioext.h,
kw.c, kw.h, libguile.h, mallocs.c, mallocs.h, markers.c,
markers.h, mbstrings.c, mbstrings.h, numbers.c, numbers.h,
objprop.c, objprop.h, options.c, options.h, pairs.c, pairs.h,
ports.c, ports.h, posix.c, posix.h, print.c, print.h, procprop.c,
procprop.h, procs.c, procs.h, ramap.c, ramap.h, read.c, read.h,
root.c, scmsigs.c, scmsigs.h, sequences.c, sequences.h, simpos.c,
simpos.h, smob.c, socket.c, socket.h, srcprop.c, srcprop.h,
stackchk.c, stackchk.h, stime.c, stime.h, strings.c, strings.h,
strop.c, strop.h, strorder.c, strorder.h, strports.c, strports.h,
struct.c, struct.h, symbols.c, symbols.h, tag.c, tag.h, unif.c,
unif.h, variable.c, variable.h, vectors.c, vectors.h, version.c,
version.h, vports.c, vports.h, weaks.c, weaks.h: Use SCM_P to
declare functions with prototypes. (Patch thanks to Marius
Vollmer.)
1996-10-14 01:33:50 +00:00
|
|
|
|
|
1996-07-25 22:56:11 +00:00
|
|
|
|
void
|
|
|
|
|
|
scm_init_chars ()
|
|
|
|
|
|
{
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "chars.x"
|
1996-07-25 22:56:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|