Merge chages made in Gnus trunk.
[bpt/emacs.git] / src / charset.c
index 31112c8..c37c33c 100644 (file)
@@ -1,8 +1,8 @@
 /* Basic character set support.
    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-     2008, 2009, 2010  Free Software Foundation, Inc.
+     2008, 2009, 2010, 2011  Free Software Foundation, Inc.
    Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-     2005, 2006, 2007, 2008, 2009, 2010
+     2005, 2006, 2007, 2008, 2009, 2010, 2011
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H14PRO021
 
@@ -54,10 +54,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 */
 
-/* List of all charsets.  This variable is used only from Emacs
-   Lisp.  */
-Lisp_Object Vcharset_list;
-
 /* Hash table that contains attributes of each charset.  Keys are
    charset symbols, and values are vectors of charset attributes.  */
 Lisp_Object Vcharset_hash_table;
@@ -114,26 +110,12 @@ Lisp_Object Viso_2022_charset_list;
 /* List of emacs-mule charsets.  */
 Lisp_Object Vemacs_mule_charset_list;
 
-struct charset *emacs_mule_charset[256];
+int emacs_mule_charset[256];
 
 /* Mapping table from ISO2022's charset (specified by DIMENSION,
    CHARS, and FINAL-CHAR) to Emacs' charset.  */
 int iso_charset_table[ISO_MAX_DIMENSION][ISO_MAX_CHARS][ISO_MAX_FINAL];
 
-Lisp_Object Vcharset_map_path;
-
-/* If nonzero, don't load charset maps.  */
-int inhibit_load_charset_map;
-
-Lisp_Object Vcurrent_iso639_language;
-
-/* Defined in chartab.c */
-extern void
-map_char_table_for_charset (void (*c_function) (Lisp_Object, Lisp_Object),
-                            Lisp_Object function, Lisp_Object table,
-                            Lisp_Object arg, struct charset *charset,
-                            unsigned from, unsigned to);
-
 #define CODE_POINT_TO_INDEX(charset, code)                             \
   ((charset)->code_linear_p                                            \
    ? (code) - (charset)->min_code                                      \
@@ -433,7 +415,7 @@ 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 charcter '#'.  */
+   paying attention to comment character '#'.  */
 
 static INLINE unsigned
 read_hex (FILE *fp, int *eof)
@@ -472,8 +454,6 @@ read_hex (FILE *fp, int *eof)
   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
        0xAAAA 0xCCCC
@@ -491,8 +471,6 @@ extern Lisp_Object Qfile_name_handler_alist;
    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 (char *, Lisp_Object, Lisp_Object);
-
 static void
 load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, int control_flag)
 {
@@ -730,12 +708,8 @@ map_charset_for_dump (void (*c_function) (Lisp_Object, Lisp_Object), Lisp_Object
 }
 
 void
-map_charset_chars (c_function, function, arg,
-                  charset, from, to)
-     void (*c_function) (Lisp_Object, Lisp_Object);
-     Lisp_Object function, arg;
-     struct charset *charset;
-     unsigned from, to;
+map_charset_chars (void (*c_function)(Lisp_Object, Lisp_Object), Lisp_Object function,
+                  Lisp_Object arg, struct charset *charset, unsigned from, unsigned to)
 {
   Lisp_Object range;
   int partial;
@@ -1225,7 +1199,7 @@ usage: (define-charset-internal ...)  */)
 
   if (charset.emacs_mule_id >= 0)
     {
-      emacs_mule_charset[charset.emacs_mule_id] = CHARSET_FROM_ID (id);
+      emacs_mule_charset[charset.emacs_mule_id] = id;
       if (charset.emacs_mule_id < 0xA0)
        emacs_mule_bytes[charset.emacs_mule_id] = charset.dimension + 1;
       else
@@ -1280,7 +1254,7 @@ usage: (define-charset-internal ...)  */)
 static int
 define_charset_internal (Lisp_Object name,
                         int dimension,
-                        unsigned char *code_space,
+                        const unsigned char *code_space,
                         unsigned min_code, unsigned max_code,
                         int iso_final, int iso_revision, int emacs_mule_id,
                         int ascii_compatible, int supplementary,
@@ -2086,23 +2060,22 @@ that case, find the charset from what supported by that coding system.  */)
     charset = CHAR_CHARSET (XINT (ch));
   else
     {
-      Lisp_Object charset_list;
-
       if (CONSP (restriction))
        {
-         for (charset_list = Qnil; CONSP (restriction);
-              restriction = XCDR (restriction))
+         int c = XFASTINT (ch);
+
+         for (; CONSP (restriction); restriction = XCDR (restriction))
            {
-             int id;
+             struct charset *charset;
 
-             CHECK_CHARSET_GET_ID (XCAR (restriction), id);
-             charset_list = Fcons (make_number (id), charset_list);
+             CHECK_CHARSET_GET_CHARSET (XCAR (restriction), charset);
+             if (ENCODE_CHAR (charset, c) != CHARSET_INVALID_CODE (charset))
+               return XCAR (restriction);
            }
-         charset_list = Fnreverse (charset_list);
+         return Qnil;
        }
-      else
-       charset_list = coding_system_charset_list (restriction);
-      charset = char_charset (XINT (ch), charset_list, NULL);
+      restriction = coding_system_charset_list (restriction);
+      charset = char_charset (XINT (ch), restriction, NULL);
       if (! charset)
        return Qnil;
     }
@@ -2253,6 +2226,69 @@ Return charset identification number of CHARSET.  */)
   return make_number (id);
 }
 
+struct charset_sort_data
+{
+  Lisp_Object charset;
+  int id;
+  int priority;
+};
+
+static int
+charset_compare (const void *d1, const void *d2)
+{
+  const struct charset_sort_data *data1 = d1, *data2 = d2;
+  return (data1->priority - data2->priority);
+}
+
+DEFUN ("sort-charsets", Fsort_charsets, Ssort_charsets, 1, 1, 0,
+       doc: /* Sort charset list CHARSETS by a priority of each charset.
+Return the sorted list.  CHARSETS is modified by side effects.
+See also `charset-priority-list' and `set-charset-priority'.  */)
+     (Lisp_Object charsets)
+{
+  Lisp_Object len = Flength (charsets);
+  int n = XFASTINT (len), i, j, done;
+  Lisp_Object tail, elt, attrs;
+  struct charset_sort_data *sort_data;
+  int id, min_id, max_id;
+  USE_SAFE_ALLOCA;
+
+  if (n == 0)
+    return Qnil;
+  SAFE_ALLOCA (sort_data, struct charset_sort_data *, sizeof (*sort_data) * n);
+  for (tail = charsets, i = 0; CONSP (tail); tail = XCDR (tail), i++)
+    {
+      elt = XCAR (tail);
+      CHECK_CHARSET_GET_ATTR (elt, attrs);
+      sort_data[i].charset = elt;
+      sort_data[i].id = id = XINT (CHARSET_ATTR_ID (attrs));
+      if (i == 0)
+       min_id = max_id = id;
+      else if (id < min_id)
+       min_id = id;
+      else if (id > max_id)
+       max_id = id;
+    }
+  for (done = 0, tail = Vcharset_ordered_list, i = 0;
+       done < n && CONSP (tail); tail = XCDR (tail), i++)
+    {
+      elt = XCAR (tail);
+      id = XFASTINT (elt);
+      if (id >= min_id && id <= max_id)
+       for (j = 0; j < n; j++)
+         if (sort_data[j].id == id)
+           {
+             sort_data[j].priority = i;
+             done++;
+           }
+    }
+  qsort (sort_data, n, sizeof *sort_data, charset_compare);
+  for (i = 0, tail = charsets; CONSP (tail); tail = XCDR (tail), i++)
+    XSETCAR (tail, sort_data[i].charset);
+  SAFE_FREE ();
+  return charsets;
+}
+
 \f
 void
 init_charset (void)
@@ -2283,7 +2319,7 @@ init_charset_once (void)
        iso_charset_table[i][j][k] = -1;
 
   for (i = 0; i < 256; i++)
-    emacs_mule_charset[i] = NULL;
+    emacs_mule_charset[i] = -1;
 
   charset_jisx0201_roman = -1;
   charset_jisx0208_1978 = -1;
@@ -2317,8 +2353,8 @@ syms_of_charset (void)
   Vemacs_mule_charset_list = Qnil;
 
   /* Don't staticpro them here.  It's done in syms_of_fns.  */
-  QCtest = intern (":test");
-  Qeq = intern ("eq");
+  QCtest = intern_c_string (":test");
+  Qeq = intern_c_string ("eq");
 
   staticpro (&Vcharset_hash_table);
   {
@@ -2355,20 +2391,21 @@ syms_of_charset (void)
   defsubr (&Scharset_priority_list);
   defsubr (&Sset_charset_priority);
   defsubr (&Scharset_id_internal);
+  defsubr (&Ssort_charsets);
 
-  DEFVAR_LISP ("charset-map-path", &Vcharset_map_path,
+  DEFVAR_LISP ("charset-map-path", Vcharset_map_path,
               doc: /* *List of directories to search for charset map files.  */);
   Vcharset_map_path = Qnil;
 
-  DEFVAR_BOOL ("inhibit-load-charset-map", &inhibit_load_charset_map,
+  DEFVAR_BOOL ("inhibit-load-charset-map", inhibit_load_charset_map,
               doc: /* Inhibit loading of charset maps.  Used when dumping Emacs.  */);
   inhibit_load_charset_map = 0;
 
-  DEFVAR_LISP ("charset-list", &Vcharset_list,
+  DEFVAR_LISP ("charset-list", Vcharset_list,
               doc: /* List of all charsets ever defined.  */);
   Vcharset_list = Qnil;
 
-  DEFVAR_LISP ("current-iso639-language", &Vcurrent_iso639_language,
+  DEFVAR_LISP ("current-iso639-language", Vcurrent_iso639_language,
               doc: /* ISO639 language mnemonic symbol for the current language environment.
 If the current language environment is for multiple languages (e.g. "Latin-1"),
 the value may be a list of mnemonics.  */);
@@ -2395,5 +2432,3 @@ the value may be a list of mnemonics.  */);
 
 #endif /* emacs */
 
-/* arch-tag: 66a89b8d-4c28-47d3-9ca1-56f78440d69f
-   (do not change this comment) */