X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/c62c46f33c517369cd3a6a590d6b0053962a5521..cf162aee2b9c574cb0f4095720a19f4efceee22b:/src/charset.c
diff --git a/src/charset.c b/src/charset.c
index 6ecc8d2c4d..43be0e9c78 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -26,12 +26,13 @@ along with GNU Emacs. If not, see . */
#include
+#define CHARSET_INLINE EXTERN_INLINE
+
#include
#include
-#include
#include
#include
-#include
+#include
#include "lisp.h"
#include "character.h"
#include "charset.h"
@@ -213,7 +214,7 @@ static struct
/* Set to 1 to warn that a charset map is loaded and thus a buffer
text and a string data may be relocated. */
-int charset_map_loaded;
+bool charset_map_loaded;
struct charset_map_entries
{
@@ -254,7 +255,7 @@ load_charset_map (struct charset *charset, struct charset_map_entries *entries,
{
Lisp_Object vec IF_LINT (= Qnil), table IF_LINT (= Qnil);
unsigned max_code = CHARSET_MAX_CODE (charset);
- int ascii_compatible_p = charset->ascii_compatible_p;
+ bool ascii_compatible_p = charset->ascii_compatible_p;
int min_char, max_char, nonascii_min_char;
int i;
unsigned char *fast_map = charset->fast_map;
@@ -272,8 +273,8 @@ load_charset_map (struct charset *charset, struct charset_map_entries *entries,
{
int n = CODE_POINT_TO_INDEX (charset, max_code) + 1;
- vec = CHARSET_DECODER (charset)
- = Fmake_vector (make_number (n), make_number (-1));
+ vec = Fmake_vector (make_number (n), make_number (-1));
+ set_charset_attr (charset, charset_decoder, vec);
}
else
{
@@ -285,16 +286,16 @@ load_charset_map (struct charset *charset, struct charset_map_entries *entries,
else
{
table = Fmake_char_table (Qnil, Qnil);
- if (charset->method == CHARSET_METHOD_MAP)
- CHARSET_ENCODER (charset) = table;
- else
- CHARSET_DEUNIFIER (charset) = table;
+ set_charset_attr (charset,
+ (charset->method == CHARSET_METHOD_MAP
+ ? charset_encoder : charset_deunifier),
+ table);
}
}
else
{
if (! temp_charset_work)
- temp_charset_work = xmalloc (sizeof (*temp_charset_work));
+ temp_charset_work = xmalloc (sizeof *temp_charset_work);
if (control_flag == 1)
{
memset (temp_charset_work->table.decoder, -1,
@@ -420,8 +421,8 @@ load_charset_map (struct charset *charset, struct charset_map_entries *entries,
/* Read a hexadecimal number (preceded by "0x") from the file FP while
paying attention to comment character '#'. */
-static inline unsigned
-read_hex (FILE *fp, int *eof, int *overflow)
+static unsigned
+read_hex (FILE *fp, bool *eof, bool *overflow)
{
int c;
unsigned n;
@@ -444,7 +445,7 @@ read_hex (FILE *fp, int *eof, int *overflow)
return 0;
}
n = 0;
- while (isxdigit (c = getc (fp)))
+ while (c_isxdigit (c = getc (fp)))
{
if (UINT_MAX >> 4 < n)
*overflow = 1;
@@ -501,8 +502,7 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, int co
/* Use SAFE_ALLOCA instead of alloca, as `charset_map_entries' is
large (larger than MAX_ALLOCA). */
- SAFE_ALLOCA (head, struct charset_map_entries *,
- sizeof (struct charset_map_entries));
+ head = SAFE_ALLOCA (sizeof *head);
entries = head;
memset (entries, 0, sizeof (struct charset_map_entries));
@@ -511,7 +511,7 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, int co
{
unsigned from, to, c;
int idx;
- int eof = 0, overflow = 0;
+ bool eof = 0, overflow = 0;
from = read_hex (fp, &eof, &overflow);
if (eof)
@@ -533,8 +533,7 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, int co
if (n_entries > 0 && (n_entries % 0x10000) == 0)
{
- SAFE_ALLOCA (entries->next, struct charset_map_entries *,
- sizeof (struct charset_map_entries));
+ entries->next = SAFE_ALLOCA (sizeof *entries->next);
entries = entries->next;
memset (entries, 0, sizeof (struct charset_map_entries));
n_entries = 0;
@@ -570,8 +569,7 @@ load_charset_map_from_vector (struct charset *charset, Lisp_Object vec, int cont
/* Use SAFE_ALLOCA instead of alloca, as `charset_map_entries' is
large (larger than MAX_ALLOCA). */
- SAFE_ALLOCA (head, struct charset_map_entries *,
- sizeof (struct charset_map_entries));
+ head = SAFE_ALLOCA (sizeof *head);
entries = head;
memset (entries, 0, sizeof (struct charset_map_entries));
@@ -602,8 +600,7 @@ load_charset_map_from_vector (struct charset *charset, Lisp_Object vec, int cont
if (n_entries > 0 && (n_entries % 0x10000) == 0)
{
- SAFE_ALLOCA (entries->next, struct charset_map_entries *,
- sizeof (struct charset_map_entries));
+ entries->next = SAFE_ALLOCA (sizeof *entries->next);
entries = entries->next;
memset (entries, 0, sizeof (struct charset_map_entries));
}
@@ -638,7 +635,7 @@ load_charset (struct charset *charset, int control_flag)
else
{
if (! CHARSET_UNIFIED_P (charset))
- abort ();
+ emacs_abort ();
map = CHARSET_UNIFY_MAP (charset);
}
if (STRINGP (map))
@@ -719,10 +716,8 @@ map_charset_chars (void (*c_function)(Lisp_Object, Lisp_Object), Lisp_Object fun
Lisp_Object arg, struct charset *charset, unsigned from, unsigned to)
{
Lisp_Object range;
- int partial;
-
- partial = (from > CHARSET_MIN_CODE (charset)
- || to < CHARSET_MAX_CODE (charset));
+ bool partial = (from > CHARSET_MIN_CODE (charset)
+ || to < CHARSET_MAX_CODE (charset));
if (CHARSET_METHOD (charset) == CHARSET_METHOD_OFFSET)
{
@@ -857,7 +852,7 @@ usage: (define-charset-internal ...) */)
struct charset charset;
int id;
int dimension;
- int new_definition_p;
+ bool new_definition_p;
int nchars;
if (nargs != charset_arg_max)
@@ -878,9 +873,9 @@ usage: (define-charset-internal ...) */)
min_byte_obj = Faref (val, make_number (i * 2));
max_byte_obj = Faref (val, make_number (i * 2 + 1));
- CHECK_RANGED_INTEGER (0, min_byte_obj, 255);
+ CHECK_RANGED_INTEGER (min_byte_obj, 0, 255);
min_byte = XINT (min_byte_obj);
- CHECK_RANGED_INTEGER (min_byte, max_byte_obj, 255);
+ CHECK_RANGED_INTEGER (max_byte_obj, min_byte, 255);
max_byte = XINT (max_byte_obj);
charset.code_space[i * 4] = min_byte;
charset.code_space[i * 4 + 1] = max_byte;
@@ -898,7 +893,7 @@ usage: (define-charset-internal ...) */)
charset.dimension = dimension;
else
{
- CHECK_RANGED_INTEGER (1, val, 4);
+ CHECK_RANGED_INTEGER (val, 1, 4);
charset.dimension = XINT (val);
}
@@ -912,8 +907,7 @@ usage: (define-charset-internal ...) */)
if (! charset.code_linear_p)
{
- charset.code_space_mask = (unsigned char *) xmalloc (256);
- memset (charset.code_space_mask, 0, 256);
+ charset.code_space_mask = xzalloc (256);
for (i = 0; i < 4; i++)
for (j = charset.code_space[i * 4]; j <= charset.code_space[i * 4 + 1];
j++)
@@ -991,7 +985,7 @@ usage: (define-charset-internal ...) */)
charset.iso_revision = -1;
else
{
- CHECK_RANGED_INTEGER (-1, val, 63);
+ CHECK_RANGED_INTEGER (val, -1, 63);
charset.iso_revision = XINT (val);
}
@@ -1134,7 +1128,7 @@ usage: (define-charset-internal ...) */)
{
new_definition_p = 0;
id = XFASTINT (CHARSET_SYMBOL_ID (args[charset_arg_name]));
- HASH_VALUE (hash_table, charset.hash_index) = attrs;
+ set_hash_value_slot (hash_table, charset.hash_index, attrs);
}
else
{
@@ -1148,12 +1142,14 @@ usage: (define-charset-internal ...) */)
example, the IDs are stuffed into struct
coding_system.charbuf[i] entries, which are 'int'. */
int old_size = charset_table_size;
+ ptrdiff_t new_size = old_size;
struct charset *new_table =
- xpalloc (0, &charset_table_size, 1,
+ xpalloc (0, &new_size, 1,
min (INT_MAX, MOST_POSITIVE_FIXNUM),
sizeof *charset_table);
memcpy (new_table, charset_table, old_size * sizeof *new_table);
charset_table = new_table;
+ charset_table_size = new_size;
/* FIXME: This leaks memory, as the old charset_table becomes
unreachable. If the old charset table is charset_table_init
then this leak is intentional; otherwise, it's unclear.
@@ -1253,12 +1249,11 @@ define_charset_internal (Lisp_Object name,
const char *code_space_chars,
unsigned min_code, unsigned max_code,
int iso_final, int iso_revision, int emacs_mule_id,
- int ascii_compatible, int supplementary,
+ bool ascii_compatible, bool supplementary,
int code_offset)
{
const unsigned char *code_space = (const unsigned char *) code_space_chars;
Lisp_Object args[charset_arg_max];
- Lisp_Object plist[14];
Lisp_Object val;
int i;
@@ -1284,22 +1279,22 @@ define_charset_internal (Lisp_Object name,
args[charset_arg_superset] = Qnil;
args[charset_arg_unify_map] = Qnil;
- plist[0] = intern_c_string (":name");
- plist[1] = args[charset_arg_name];
- plist[2] = intern_c_string (":dimension");
- plist[3] = args[charset_arg_dimension];
- plist[4] = intern_c_string (":code-space");
- plist[5] = args[charset_arg_code_space];
- plist[6] = intern_c_string (":iso-final-char");
- plist[7] = args[charset_arg_iso_final];
- plist[8] = intern_c_string (":emacs-mule-id");
- plist[9] = args[charset_arg_emacs_mule_id];
- plist[10] = intern_c_string (":ascii-compatible-p");
- plist[11] = args[charset_arg_ascii_compatible_p];
- plist[12] = intern_c_string (":code-offset");
- plist[13] = args[charset_arg_code_offset];
-
- args[charset_arg_plist] = Flist (14, plist);
+ args[charset_arg_plist] =
+ listn (CONSTYPE_HEAP, 14,
+ intern_c_string (":name"),
+ args[charset_arg_name],
+ intern_c_string (":dimension"),
+ args[charset_arg_dimension],
+ intern_c_string (":code-space"),
+ args[charset_arg_code_space],
+ intern_c_string (":iso-final-char"),
+ args[charset_arg_iso_final],
+ intern_c_string (":emacs-mule-id"),
+ args[charset_arg_emacs_mule_id],
+ intern_c_string (":ascii-compatible-p"),
+ args[charset_arg_ascii_compatible_p],
+ intern_c_string (":code-offset"),
+ args[charset_arg_code_offset]);
Fdefine_charset_internal (charset_arg_max, args);
return XINT (CHARSET_SYMBOL_ID (name));
@@ -1338,7 +1333,7 @@ DEFUN ("set-charset-plist", Fset_charset_plist, Sset_charset_plist, 2, 2, 0,
Lisp_Object attrs;
CHECK_CHARSET_GET_ATTR (charset, attrs);
- CHARSET_ATTR_PLIST (attrs) = plist;
+ ASET (attrs, charset_plist, plist);
return plist;
}
@@ -1377,7 +1372,7 @@ Optional third argument DEUNIFY, if non-nil, means to de-unify CHARSET. */)
{
if (! STRINGP (unify_map) && ! VECTORP (unify_map))
signal_error ("Bad unify-map", unify_map);
- CHARSET_UNIFY_MAP (cs) = unify_map;
+ set_charset_attr (cs, charset_unify_map, unify_map);
}
if (NILP (Vchar_unify_table))
Vchar_unify_table = Fmake_char_table (Qnil, Qnil);
@@ -1452,7 +1447,7 @@ if CHARSET is designated instead. */)
(Lisp_Object dimension, Lisp_Object chars, Lisp_Object final_char, Lisp_Object charset)
{
int id;
- int chars_flag;
+ bool chars_flag;
CHECK_CHARSET_GET_ID (charset, id);
check_iso_charset_parameter (dimension, chars, final_char);
@@ -1503,7 +1498,9 @@ string_xstring_p (Lisp_Object string)
It may lookup a translation table TABLE if supplied. */
static void
-find_charsets_in_text (const unsigned char *ptr, ptrdiff_t nchars, ptrdiff_t nbytes, Lisp_Object charsets, Lisp_Object table, int multibyte)
+find_charsets_in_text (const unsigned char *ptr, ptrdiff_t nchars,
+ ptrdiff_t nbytes, Lisp_Object charsets,
+ Lisp_Object table, bool multibyte)
{
const unsigned char *pend = ptr + nbytes;
@@ -1553,7 +1550,7 @@ only `ascii', `eight-bit-control', and `eight-bit-graphic'. */)
ptrdiff_t from, from_byte, to, stop, stop_byte;
int i;
Lisp_Object val;
- int multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
+ bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
validate_region (&beg, &end);
from = XFASTINT (beg);
@@ -1622,7 +1619,7 @@ only `ascii', `eight-bit-control', and `eight-bit-graphic'. */)
/* Return a unified character code for C (>= 0x110000). VAL is a
value of Vchar_unify_table for C; i.e. it is nil, an integer, or a
charset symbol. */
-int
+static int
maybe_unify_char (int c, Lisp_Object val)
{
struct charset *charset;
@@ -1633,6 +1630,12 @@ maybe_unify_char (int c, Lisp_Object val)
return c;
CHECK_CHARSET_GET_CHARSET (val, charset);
+#ifdef REL_ALLOC
+ /* The call to load_charset below can allocate memory, which screws
+ callers of this function through STRING_CHAR_* macros that hold C
+ pointers to buffer text, if REL_ALLOC is used. */
+ r_alloc_inhibit_buffer_relocation (1);
+#endif
load_charset (charset, 1);
if (! inhibit_load_charset_map)
{
@@ -1648,6 +1651,9 @@ maybe_unify_char (int c, Lisp_Object val)
if (unified > 0)
c = unified;
}
+#ifdef REL_ALLOC
+ r_alloc_inhibit_buffer_relocation (0);
+#endif
return c;
}
@@ -1719,8 +1725,12 @@ decode_char (struct charset *charset, unsigned int code)
{
c = char_index + CHARSET_CODE_OFFSET (charset);
if (CHARSET_UNIFIED_P (charset)
- && c > MAX_UNICODE_CHAR)
- MAYBE_UNIFY_CHAR (c);
+ && MAX_UNICODE_CHAR < c && c <= MAX_5_BYTE_CHAR)
+ {
+ /* Unify C with a Unicode character if possible. */
+ Lisp_Object val = CHAR_TABLE_REF (Vchar_unify_table, c);
+ c = maybe_unify_char (c, val);
+ }
}
}
@@ -1730,7 +1740,7 @@ decode_char (struct charset *charset, unsigned int code)
/* Variable used temporarily by the macro ENCODE_CHAR. */
Lisp_Object charset_work;
-/* Return a code-point of CHAR in CHARSET. If CHAR doesn't belong to
+/* Return a code-point of C in CHARSET. If C doesn't belong to
CHARSET, return CHARSET_INVALID_CODE (CHARSET). If STRICT is true,
use CHARSET's strict_max_char instead of max_char. */
@@ -1973,7 +1983,7 @@ is specified. */)
struct charset *
char_charset (int c, Lisp_Object charset_list, unsigned int *code_return)
{
- int maybe_null = 0;
+ bool maybe_null = 0;
if (NILP (charset_list))
charset_list = Vcharset_ordered_list;
@@ -2020,10 +2030,10 @@ CH in the charset. */)
c = XFASTINT (ch);
charset = CHAR_CHARSET (c);
if (! charset)
- abort ();
+ emacs_abort ();
code = ENCODE_CHAR (charset, c);
if (code == CHARSET_INVALID_CODE (charset))
- abort ();
+ emacs_abort ();
dimension = CHARSET_DIMENSION (charset);
for (val = Qnil; dimension > 0; dimension--)
{
@@ -2101,7 +2111,7 @@ DIMENSION, CHARS, and FINAL-CHAR. */)
(Lisp_Object dimension, Lisp_Object chars, Lisp_Object final_char)
{
int id;
- int chars_flag;
+ bool chars_flag;
check_iso_charset_parameter (dimension, chars, final_char);
chars_flag = XFASTINT (chars) == 96;
@@ -2285,13 +2295,17 @@ init_charset (void)
{
Lisp_Object tempdir;
tempdir = Fexpand_file_name (build_string ("charsets"), Vdata_directory);
- if (access (SSDATA (tempdir), 0) < 0)
+ if (! file_accessible_directory_p (SSDATA (tempdir)))
{
- dir_warning ("Error: charsets directory (%s) does not exist.\n\
+ /* This used to be non-fatal (dir_warning), but it should not
+ happen, and if it does sooner or later it will cause some
+ obscure problem (eg bug#6401), so better abort. */
+ fprintf (stderr, "Error: charsets directory not found:\n\
+%s\n\
Emacs will not function correctly without the character map files.\n\
Please check your installation!\n",
- tempdir);
- /* TODO should this be a fatal error? (Bug#909) */
+ SDATA (tempdir));
+ exit (1);
}
Vcharset_map_path = Fcons (tempdir, Qnil);