X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/b87c4ff2817e71ca71b028792200b1e069a95e04..32ade3f01a0185f2a836c313d9d50564abe4e254:/src/charset.c diff --git a/src/charset.c b/src/charset.c index ef040a9460..171a00f23d 100644 --- a/src/charset.c +++ b/src/charset.c @@ -1,13 +1,15 @@ /* Basic character set support. - Copyright (C) 2001-2013 Free Software Foundation, Inc. - Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008, 2009, 2010, 2011 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H14PRO021 - Copyright (C) 2003, 2004 - National Institute of Advanced Industrial Science and Technology (AIST) - Registration Number H13PRO009 +Copyright (C) 2001-2014 Free Software Foundation, Inc. + +Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, + 2005, 2006, 2007, 2008, 2009, 2010, 2011 + National Institute of Advanced Industrial Science and Technology (AIST) + Registration Number H14PRO021 + +Copyright (C) 2003, 2004 + National Institute of Advanced Industrial Science and Technology (AIST) + Registration Number H13PRO009 This file is part of GNU Emacs. @@ -387,12 +389,12 @@ load_charset_map (struct charset *charset, struct charset_map_entries *entries, { if (ascii_compatible_p) { - if (! ASCII_BYTE_P (from_c)) + if (! ASCII_CHAR_P (from_c)) { if (from_c < nonascii_min_char) nonascii_min_char = from_c; } - else if (! ASCII_BYTE_P (to_c)) + else if (! ASCII_CHAR_P (to_c)) { nonascii_min_char = 0x80; } @@ -483,17 +485,15 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, unsigned max_code = CHARSET_MAX_CODE (charset); int fd; FILE *fp; - Lisp_Object suffixes; struct charset_map_entries *head, *entries; int n_entries; - ptrdiff_t count; - - suffixes = list2 (build_string (".map"), build_string (".TXT")); - - count = SPECPDL_INDEX (); + AUTO_STRING (map, ".map"); + AUTO_STRING (txt, ".txt"); + AUTO_LIST2 (suffixes, map, txt); + ptrdiff_t count = SPECPDL_INDEX (); record_unwind_protect_nothing (); specbind (Qfile_name_handler_alist, Qnil); - fd = openp (Vcharset_map_path, mapfile, suffixes, NULL, Qnil); + fd = openp (Vcharset_map_path, mapfile, suffixes, NULL, Qnil, false); fp = fd < 0 ? 0 : fdopen (fd, "r"); if (!fp) { @@ -665,12 +665,8 @@ map_charset_for_dump (void (*c_function) (Lisp_Object, Lisp_Object), { int from_idx = CODE_POINT_TO_INDEX (temp_charset_work->current, from); int to_idx = CODE_POINT_TO_INDEX (temp_charset_work->current, to); - Lisp_Object range; + Lisp_Object range = Fcons (Qnil, Qnil); int c, stop; - struct gcpro gcpro1; - - range = Fcons (Qnil, Qnil); - GCPRO1 (range); c = temp_charset_work->min_char; stop = (temp_charset_work->max_char < 0x20000 @@ -713,7 +709,6 @@ map_charset_for_dump (void (*c_function) (Lisp_Object, Lisp_Object), } c++; } - UNGCPRO; } void @@ -1398,6 +1393,32 @@ Optional third argument DEUNIFY, if non-nil, means to de-unify CHARSET. */) return Qnil; } +/* Check that DIMENSION, CHARS, and FINAL_CHAR specify a valid ISO charset. + Return true if it's a 96-character set, false if 94. */ + +static bool +check_iso_charset_parameter (Lisp_Object dimension, Lisp_Object chars, + Lisp_Object final_char) +{ + CHECK_NUMBER (dimension); + CHECK_NUMBER (chars); + CHECK_CHARACTER (final_char); + + if (! (1 <= XINT (dimension) && XINT (dimension) <= 3)) + error ("Invalid DIMENSION %"pI"d, it should be 1, 2, or 3", + XINT (dimension)); + + bool chars_flag = XINT (chars) == 96; + if (! (chars_flag || XINT (chars) == 94)) + error ("Invalid CHARS %"pI"d, it should be 94 or 96", XINT (chars)); + + int final_ch = XFASTINT (final_char); + if (! ('0' <= final_ch && final_ch <= '~')) + error ("Invalid FINAL-CHAR '%c', it should be '0'..'~'", final_ch); + + return chars_flag; +} + DEFUN ("get-unused-iso-final-char", Fget_unused_iso_final_char, Sget_unused_iso_final_char, 2, 2, 0, doc: /* @@ -1410,35 +1431,12 @@ If there's no unused final char for the specified kind of charset, return nil. */) (Lisp_Object dimension, Lisp_Object chars) { - int final_char; - - CHECK_NUMBER (dimension); - CHECK_NUMBER (chars); - if (XINT (dimension) != 1 && XINT (dimension) != 2 && XINT (dimension) != 3) - args_out_of_range_3 (dimension, make_number (1), make_number (3)); - if (XINT (chars) != 94 && XINT (chars) != 96) - args_out_of_range_3 (chars, make_number (94), make_number (96)); - for (final_char = '0'; final_char <= '?'; final_char++) - if (ISO_CHARSET_TABLE (XINT (dimension), XINT (chars), final_char) < 0) - break; - return (final_char <= '?' ? make_number (final_char) : Qnil); -} - -static void -check_iso_charset_parameter (Lisp_Object dimension, Lisp_Object chars, Lisp_Object final_char) -{ - CHECK_NATNUM (dimension); - CHECK_NATNUM (chars); - CHECK_CHARACTER (final_char); - - if (XINT (dimension) > 3) - error ("Invalid DIMENSION %"pI"d, it should be 1, 2, or 3", - XINT (dimension)); - if (XINT (chars) != 94 && XINT (chars) != 96) - error ("Invalid CHARS %"pI"d, it should be 94 or 96", XINT (chars)); - if (XINT (final_char) < '0' || XINT (final_char) > '~') - error ("Invalid FINAL-CHAR %c, it should be `0'..`~'", - (int)XINT (final_char)); + bool chars_flag = check_iso_charset_parameter (dimension, chars, + make_number ('0')); + for (int final_char = '0'; final_char <= '?'; final_char++) + if (ISO_CHARSET_TABLE (XINT (dimension), chars_flag, final_char) < 0) + return make_number (final_char); + return Qnil; } @@ -1452,12 +1450,10 @@ if CHARSET is designated instead. */) (Lisp_Object dimension, Lisp_Object chars, Lisp_Object final_char, Lisp_Object charset) { int id; - bool chars_flag; CHECK_CHARSET_GET_ID (charset, id); - check_iso_charset_parameter (dimension, chars, final_char); - chars_flag = XINT (chars) == 96; - ISO_CHARSET_TABLE (XINT (dimension), chars_flag, XINT (final_char)) = id; + bool chars_flag = check_iso_charset_parameter (dimension, chars, final_char); + ISO_CHARSET_TABLE (XINT (dimension), chars_flag, XFASTINT (final_char)) = id; return Qnil; } @@ -1520,7 +1516,7 @@ find_charsets_in_text (const unsigned char *ptr, ptrdiff_t nchars, if (!NILP (table)) c = translate_char (table, c); - if (ASCII_BYTE_P (c)) + if (ASCII_CHAR_P (c)) ASET (charsets, charset_ascii, Qt); else ASET (charsets, charset_eight_bit, Qt); @@ -1860,10 +1856,7 @@ DEFUN ("decode-char", Fdecode_char, Sdecode_char, 2, 3, 0, doc: /* Decode the pair of CHARSET and CODE-POINT into a character. Return nil if CODE-POINT is not valid in CHARSET. -CODE-POINT may be a cons (HIGHER-16-BIT-VALUE . LOWER-16-BIT-VALUE). - -Optional argument RESTRICTION specifies a way to map the pair of CCS -and CODE-POINT to a character. Currently not supported and just ignored. */) +CODE-POINT may be a cons (HIGHER-16-BIT-VALUE . LOWER-16-BIT-VALUE). */) (Lisp_Object charset, Lisp_Object code_point, Lisp_Object restriction) { int c, id; @@ -1880,10 +1873,7 @@ and CODE-POINT to a character. Currently not supported and just ignored. */) DEFUN ("encode-char", Fencode_char, Sencode_char, 2, 3, 0, doc: /* Encode the character CH into a code-point of CHARSET. -Return nil if CHARSET doesn't include CH. - -Optional argument RESTRICTION specifies a way to map CH to a -code-point in CCS. Currently not supported and just ignored. */) +Return nil if CHARSET doesn't include CH. */) (Lisp_Object ch, Lisp_Object charset, Lisp_Object restriction) { int c, id; @@ -2117,13 +2107,9 @@ See the documentation of the function `charset-info' for the meanings of DIMENSION, CHARS, and FINAL-CHAR. */) (Lisp_Object dimension, Lisp_Object chars, Lisp_Object final_char) { - int id; - bool chars_flag; - - check_iso_charset_parameter (dimension, chars, final_char); - chars_flag = XFASTINT (chars) == 96; - id = ISO_CHARSET_TABLE (XFASTINT (dimension), chars_flag, - XFASTINT (final_char)); + bool chars_flag = check_iso_charset_parameter (dimension, chars, final_char); + int id = ISO_CHARSET_TABLE (XINT (dimension), chars_flag, + XFASTINT (final_char)); return (id >= 0 ? CHARSET_NAME (CHARSET_FROM_ID (id)) : Qnil); } @@ -2302,16 +2288,18 @@ init_charset (void) { Lisp_Object tempdir; tempdir = Fexpand_file_name (build_string ("charsets"), Vdata_directory); - if (! file_accessible_directory_p (SSDATA (tempdir))) + if (! file_accessible_directory_p (tempdir)) { /* 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\ +Emacs will not function correctly without the character map files.\n%s\ Please check your installation!\n", - SDATA (tempdir)); + SDATA (tempdir), + egetenv("EMACSDATA") ? "The EMACSDATA environment \ +variable is set, maybe it has the wrong value?\n" : ""); exit (1); } @@ -2388,7 +2376,7 @@ syms_of_charset (void) } charset_table = charset_table_init; - charset_table_size = sizeof charset_table_init / sizeof *charset_table_init; + charset_table_size = ARRAYELTS (charset_table_init); charset_table_used = 0; defsubr (&Scharsetp); @@ -2434,19 +2422,19 @@ the value may be a list of mnemonics. */); Vcurrent_iso639_language = Qnil; charset_ascii - = define_charset_internal (Qascii, 1, "\x00\x7F\x00\x00\x00\x00", + = define_charset_internal (Qascii, 1, "\x00\x7F\0\0\0\0\0", 0, 127, 'B', -1, 0, 1, 0, 0); charset_iso_8859_1 - = define_charset_internal (Qiso_8859_1, 1, "\x00\xFF\x00\x00\x00\x00", + = define_charset_internal (Qiso_8859_1, 1, "\x00\xFF\0\0\0\0\0", 0, 255, -1, -1, -1, 1, 0, 0); charset_unicode - = define_charset_internal (Qunicode, 3, "\x00\xFF\x00\xFF\x00\x10", + = define_charset_internal (Qunicode, 3, "\x00\xFF\x00\xFF\x00\x10\0", 0, MAX_UNICODE_CHAR, -1, 0, -1, 1, 0, 0); charset_emacs - = define_charset_internal (Qemacs, 3, "\x00\xFF\x00\xFF\x00\x3F", + = define_charset_internal (Qemacs, 3, "\x00\xFF\x00\xFF\x00\x3F\0", 0, MAX_5_BYTE_CHAR, -1, 0, -1, 1, 1, 0); charset_eight_bit - = define_charset_internal (Qeight_bit, 1, "\x80\xFF\x00\x00\x00\x00", + = define_charset_internal (Qeight_bit, 1, "\x80\xFF\0\0\0\0\0", 128, 255, -1, 0, -1, 0, 1, MAX_5_BYTE_CHAR + 1); charset_unibyte = charset_iso_8859_1;