/* Basic character set support.
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2008, 2009 Free Software Foundation, Inc.
+ 2008, 2009, 2010 Free Software Foundation, Inc.
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007, 2008, 2009
+ 2005, 2006, 2007, 2008, 2009, 2010
National Institute of Advanced Industrial Science and Technology (AIST)
Registration Number H14PRO021
#include <unistd.h>
#include <ctype.h>
#include <sys/types.h>
+#include <setjmp.h>
#include "lisp.h"
#include "character.h"
#include "charset.h"
int charset_jisx0201_roman;
int charset_jisx0208_1978;
int charset_jisx0208;
+int charset_ksc5601;
/* Value of charset attribute `charset-iso-plane'. */
Lisp_Object Qgl, Qgr;
{
memset (temp_charset_work->table.decoder, -1,
sizeof (int) * 0x10000);
- temp_charset_work->for_encoder = 0;
}
else
{
return n;
}
+extern Lisp_Object Qfile_name_handler_alist;
/* Return a mapping vector for CHARSET loaded from MAPFILE.
Each line of MAPFILE has this form
The returned vector has this form:
[ CODE1 CHAR1 CODE2 CHAR2 .... ]
where CODE1 is a code-point or a cons of code-points specifying a
- range. */
+ range.
+
+ Note that this function uses `openp' to open MAPFILE but ignores
+ `file-name-handler-alist' to avoid running any Lisp code. */
extern void add_to_log P_ ((char *, Lisp_Object, Lisp_Object));
int eof;
Lisp_Object suffixes;
struct charset_map_entries *head, *entries;
- int n_entries;
+ int n_entries, count;
+ USE_SAFE_ALLOCA;
suffixes = Fcons (build_string (".map"),
Fcons (build_string (".TXT"), Qnil));
+ count = SPECPDL_INDEX ();
+ specbind (Qfile_name_handler_alist, Qnil);
fd = openp (Vcharset_map_path, mapfile, suffixes, NULL, Qnil);
+ unbind_to (count, Qnil);
if (fd < 0
|| ! (fp = fdopen (fd, "r")))
- {
- add_to_log ("Failure in loading charset map: %S", mapfile, Qnil);
- return;
- }
+ error ("Failure in loading charset map: %S", SDATA (mapfile));
+
+ /* 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));
+ entries = head;
+ bzero (entries, sizeof (struct charset_map_entries));
- head = entries = ((struct charset_map_entries *)
- alloca (sizeof (struct charset_map_entries)));
n_entries = 0;
eof = 0;
while (1)
if (n_entries > 0 && (n_entries % 0x10000) == 0)
{
- entries->next = ((struct charset_map_entries *)
- alloca (sizeof (struct charset_map_entries)));
+ SAFE_ALLOCA (entries->next, struct charset_map_entries *,
+ sizeof (struct charset_map_entries));
entries = entries->next;
+ bzero (entries, sizeof (struct charset_map_entries));
}
idx = n_entries % 0x10000;
entries->entry[idx].from = from;
close (fd);
load_charset_map (charset, head, n_entries, control_flag);
+ SAFE_FREE ();
}
static void
int n_entries;
int len = ASIZE (vec);
int i;
+ USE_SAFE_ALLOCA;
if (len % 2 == 1)
{
return;
}
- head = entries = ((struct charset_map_entries *)
- alloca (sizeof (struct charset_map_entries)));
+ /* 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));
+ entries = head;
+ bzero (entries, sizeof (struct charset_map_entries));
+
n_entries = 0;
for (i = 0; i < len; i += 2)
{
if (n_entries > 0 && (n_entries % 0x10000) == 0)
{
- entries->next = ((struct charset_map_entries *)
- alloca (sizeof (struct charset_map_entries)));
+ SAFE_ALLOCA (entries->next, struct charset_map_entries *,
+ sizeof (struct charset_map_entries));
entries = entries->next;
+ bzero (entries, sizeof (struct charset_map_entries));
}
idx = n_entries % 0x10000;
entries->entry[idx].from = from;
}
load_charset_map (charset, head, n_entries, control_flag);
+ SAFE_FREE ();
}
if (inhibit_load_charset_map
&& temp_charset_work
&& charset == temp_charset_work->current
- && (control_flag == 2 == temp_charset_work->for_encoder))
+ && ((control_flag == 2) == temp_charset_work->for_encoder))
return;
if (CHARSET_METHOD (charset) == CHARSET_METHOD_MAP)
}
c++;
}
+ UNGCPRO;
}
void
charset = CHARSET_FROM_ID (XFASTINT (XCAR (XCAR (parents))));
offset = XINT (XCDR (XCAR (parents)));
- this_from = from - offset;
- this_to = to - offset;
+ this_from = from > offset ? from - offset : 0;
+ this_to = to > offset ? to - offset : 0;
if (this_from < CHARSET_MIN_CODE (charset))
this_from = CHARSET_MIN_CODE (charset);
if (this_to > CHARSET_MAX_CODE (charset))
characters contained in CHARSET.
The optional 4th and 5th arguments FROM-CODE and TO-CODE specify the
-range of code points of target characters. */)
+range of code points (in CHARSET) of target characters. */)
(function, charset, arg, from_code, to_code)
Lisp_Object function, charset, arg, from_code, to_code;
{
i = (i >> 12) << 12;
for (; i <= charset.max_char; i += 0x1000)
CHARSET_FAST_MAP_SET (i, charset.fast_map);
+ if (charset.code_offset == 0 && charset.max_char >= 0x80)
+ charset.ascii_compatible_p = 1;
}
else if (! NILP (args[charset_arg_map]))
{
charset_jisx0208_1978 = id;
else if (ISO_CHARSET_TABLE (2, 0, 'B') == id)
charset_jisx0208 = id;
+ else if (ISO_CHARSET_TABLE (2, 0, 'C') == id)
+ charset_ksc5601 = id;
}
if (charset.emacs_mule_id >= 0)
args[charset_arg_superset] = Qnil;
args[charset_arg_unify_map] = Qnil;
- plist[0] = intern (":name");
+ plist[0] = intern_c_string (":name");
plist[1] = args[charset_arg_name];
- plist[2] = intern (":dimension");
+ plist[2] = intern_c_string (":dimension");
plist[3] = args[charset_arg_dimension];
- plist[4] = intern (":code-space");
+ plist[4] = intern_c_string (":code-space");
plist[5] = args[charset_arg_code_space];
- plist[6] = intern (":iso-final-char");
+ plist[6] = intern_c_string (":iso-final-char");
plist[7] = args[charset_arg_iso_final];
- plist[8] = intern (":emacs-mule-id");
+ plist[8] = intern_c_string (":emacs-mule-id");
plist[9] = args[charset_arg_emacs_mule_id];
- plist[10] = intern (":ascii-compatible-p");
+ plist[10] = intern_c_string (":ascii-compatible-p");
plist[11] = args[charset_arg_ascii_compatible_p];
- plist[12] = intern (":code-offset");
+ plist[12] = intern_c_string (":code-offset");
plist[13] = args[charset_arg_code_offset];
args[charset_arg_plist] = Flist (14, plist);
if (CHARSET_UNIFIED_P (charset))
{
- Lisp_Object deunifier, deunified;
+ Lisp_Object deunifier;
int code_index = -1;
deunifier = CHARSET_DEUNIFIER (charset);
}
-DEFUN ("char-charset", Fchar_charset, Schar_charset, 1, 1, 0,
- doc: /* Return the charset of highest priority that contains CH. */)
- (ch)
- Lisp_Object ch;
+DEFUN ("char-charset", Fchar_charset, Schar_charset, 1, 2, 0,
+ doc: /* Return the charset of highest priority that contains CH.
+If optional 2nd arg RESTRICTION is non-nil, it is a list of charsets
+from which to find the charset. It may also be a coding system. In
+that case, find the charset from what supported by that coding system. */)
+ (ch, restriction)
+ Lisp_Object ch, restriction;
{
struct charset *charset;
CHECK_CHARACTER (ch);
- charset = CHAR_CHARSET (XINT (ch));
+ if (NILP (restriction))
+ charset = CHAR_CHARSET (XINT (ch));
+ else
+ {
+ Lisp_Object charset_list;
+
+ if (CONSP (restriction))
+ {
+ for (charset_list = Qnil; CONSP (restriction);
+ restriction = XCDR (restriction))
+ {
+ int id;
+
+ CHECK_CHARSET_GET_ID (XCAR (restriction), id);
+ charset_list = Fcons (make_number (id), charset_list);
+ }
+ charset_list = Fnreverse (charset_list);
+ }
+ else
+ charset_list = coding_system_charset_list (restriction);
+ charset = char_charset (XINT (ch), charset_list, NULL);
+ if (! charset)
+ return Qnil;
+ }
return (CHARSET_NAME (charset));
}
It should be called only from temacs invoked for dumping. */)
()
{
- int i;
- struct charset *charset;
- Lisp_Object attrs;
-
if (temp_charset_work)
{
free (temp_charset_work);
Vcharset_ordered_list = Fnconc (2, arglist);
charset_ordered_list_tick++;
+ charset_unibyte = -1;
for (old_list = Vcharset_ordered_list, list_2022 = list_emacs_mule = Qnil;
CONSP (old_list); old_list = XCDR (old_list))
{
list_2022 = Fcons (XCAR (old_list), list_2022);
if (! NILP (Fmemq (XCAR (old_list), Vemacs_mule_charset_list)))
list_emacs_mule = Fcons (XCAR (old_list), list_emacs_mule);
+ if (charset_unibyte < 0)
+ {
+ struct charset *charset = CHARSET_FROM_ID (XINT (XCAR (old_list)));
+
+ if (CHARSET_DIMENSION (charset) == 1
+ && CHARSET_ASCII_COMPATIBLE_P (charset)
+ && CHARSET_MAX_CHAR (charset) >= 0x80)
+ charset_unibyte = CHARSET_ID (charset);
+ }
}
Viso_2022_charset_list = Fnreverse (list_2022);
Vemacs_mule_charset_list = Fnreverse (list_emacs_mule);
+ if (charset_unibyte < 0)
+ charset_unibyte = charset_iso_8859_1;
return Qnil;
}
{
Lisp_Object tempdir;
tempdir = Fexpand_file_name (build_string ("charsets"), Vdata_directory);
- if (access (SDATA (tempdir), 0) < 0)
+ if (access ((char *) SDATA (tempdir), 0) < 0)
{
dir_warning ("Error: charsets directory (%s) does not exist.\n\
Emacs will not function correctly without the character map files.\n\
charset_jisx0201_roman = -1;
charset_jisx0208_1978 = -1;
charset_jisx0208 = -1;
-
- for (i = 0; i < 128; i++)
- unibyte_to_multibyte_table[i] = i;
- for (; i < 256; i++)
- unibyte_to_multibyte_table[i] = BYTE8_TO_CHAR (i);
+ charset_ksc5601 = -1;
}
#ifdef emacs
= define_charset_internal (Qeight_bit, 1, "\x80\xFF\x00\x00\x00\x00",
128, 255, -1, 0, -1, 0, 1,
MAX_5_BYTE_CHAR + 1);
+ charset_unibyte = charset_iso_8859_1;
}
#endif /* emacs */