(M40310): Separate U+925B, C1-6745 and J90-3174.
[chise/xemacs-chise.git] / src / file-coding.c
index 14b0ade..248313a 100644 (file)
@@ -36,7 +36,7 @@ Boston, MA 02111-1307, USA.  */
 #endif
 #include "file-coding.h"
 
-Lisp_Object Qbuffer_file_coding_system, Qcoding_system_error;
+Lisp_Object Qcoding_system_error;
 
 Lisp_Object Vkeyboard_coding_system;
 Lisp_Object Vterminal_coding_system;
@@ -47,14 +47,37 @@ Lisp_Object Vfile_name_coding_system;
 /* Table of symbols identifying each coding category. */
 Lisp_Object coding_category_symbol[CODING_CATEGORY_LAST + 1];
 
-/* Coding system currently associated with each coding category. */
-Lisp_Object coding_category_system[CODING_CATEGORY_LAST + 1];
 
-/* Table of all coding categories in decreasing order of priority.
-   This describes a permutation of the possible coding categories. */
-int coding_category_by_priority[CODING_CATEGORY_LAST + 1];
 
-Lisp_Object Qcoding_system_p;
+struct file_coding_dump {
+  /* Coding system currently associated with each coding category. */
+  Lisp_Object coding_category_system[CODING_CATEGORY_LAST + 1];
+
+  /* Table of all coding categories in decreasing order of priority.
+     This describes a permutation of the possible coding categories. */
+  int coding_category_by_priority[CODING_CATEGORY_LAST + 1];
+
+#ifndef UTF2000
+  Lisp_Object ucs_to_mule_table[65536];
+#endif
+} *fcd;
+
+static const struct lrecord_description fcd_description_1[] = {
+  { XD_LISP_OBJECT, offsetof(struct file_coding_dump, coding_category_system), CODING_CATEGORY_LAST + 1 },
+#ifndef UTF2000
+  { XD_LISP_OBJECT, offsetof(struct file_coding_dump, ucs_to_mule_table),      65536 },
+#endif
+  { XD_END }
+};
+
+static const struct struct_description fcd_description = {
+  sizeof(struct file_coding_dump),
+  fcd_description_1
+};
+
+Lisp_Object mule_to_ucs_table;
+
+Lisp_Object Qcoding_systemp;
 
 Lisp_Object Qraw_text, Qno_conversion, Qccl, Qiso2022;
 /* Qinternal in general.c */
@@ -227,6 +250,26 @@ typedef struct
   Dynarr_declare (codesys_prop);
 } codesys_prop_dynarr;
 
+static const struct lrecord_description codesys_prop_description_1[] = {
+  { XD_LISP_OBJECT, offsetof(codesys_prop, sym), 1 },
+  { XD_END }
+};
+
+static const struct struct_description codesys_prop_description = {
+  sizeof(codesys_prop),
+  codesys_prop_description_1
+};
+
+static const struct lrecord_description codesys_prop_dynarr_description_1[] = {
+  XD_DYNARR_DESC(codesys_prop_dynarr, &codesys_prop_description),
+  { XD_END }
+};
+
+static const struct struct_description codesys_prop_dynarr_description = {
+  sizeof(codesys_prop_dynarr),
+  codesys_prop_dynarr_description_1
+};
+
 codesys_prop_dynarr *the_codesys_prop_dynarr;
 
 enum codesys_prop_enum
@@ -241,7 +284,7 @@ enum codesys_prop_enum
 /*                       Coding system functions                        */
 /************************************************************************/
 
-static Lisp_Object mark_coding_system (Lisp_Object, void (*) (Lisp_Object));
+static Lisp_Object mark_coding_system (Lisp_Object);
 static void print_coding_system (Lisp_Object, Lisp_Object, int);
 static void finalize_coding_system (void *header, int for_disksave);
 
@@ -255,7 +298,7 @@ static const struct struct_description ccs_description = {
   sizeof(charset_conversion_spec),
   ccs_description_1
 };
-  
+
 static const struct lrecord_description ccsd_description_1[] = {
   XD_DYNARR_DESC(charset_conversion_spec_dynarr, &ccs_description),
   { XD_END }
@@ -287,16 +330,16 @@ DEFINE_LRECORD_IMPLEMENTATION ("coding-system", coding_system,
                               struct Lisp_Coding_System);
 
 static Lisp_Object
-mark_coding_system (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_coding_system (Lisp_Object obj)
 {
   Lisp_Coding_System *codesys = XCODING_SYSTEM (obj);
 
-  markobj (CODING_SYSTEM_NAME (codesys));
-  markobj (CODING_SYSTEM_DOC_STRING (codesys));
-  markobj (CODING_SYSTEM_MNEMONIC (codesys));
-  markobj (CODING_SYSTEM_EOL_LF (codesys));
-  markobj (CODING_SYSTEM_EOL_CRLF (codesys));
-  markobj (CODING_SYSTEM_EOL_CR (codesys));
+  mark_object (CODING_SYSTEM_NAME (codesys));
+  mark_object (CODING_SYSTEM_DOC_STRING (codesys));
+  mark_object (CODING_SYSTEM_MNEMONIC (codesys));
+  mark_object (CODING_SYSTEM_EOL_LF (codesys));
+  mark_object (CODING_SYSTEM_EOL_CRLF (codesys));
+  mark_object (CODING_SYSTEM_EOL_CR (codesys));
 
   switch (CODING_SYSTEM_TYPE (codesys))
     {
@@ -304,15 +347,15 @@ mark_coding_system (Lisp_Object obj, void (*markobj) (Lisp_Object))
       int i;
     case CODESYS_ISO2022:
       for (i = 0; i < 4; i++)
-       markobj (CODING_SYSTEM_ISO2022_INITIAL_CHARSET (codesys, i));
+       mark_object (CODING_SYSTEM_ISO2022_INITIAL_CHARSET (codesys, i));
       if (codesys->iso2022.input_conv)
        {
          for (i = 0; i < Dynarr_length (codesys->iso2022.input_conv); i++)
            {
              struct charset_conversion_spec *ccs =
                Dynarr_atp (codesys->iso2022.input_conv, i);
-             markobj (ccs->from_charset);
-             markobj (ccs->to_charset);
+             mark_object (ccs->from_charset);
+             mark_object (ccs->to_charset);
            }
        }
       if (codesys->iso2022.output_conv)
@@ -321,22 +364,22 @@ mark_coding_system (Lisp_Object obj, void (*markobj) (Lisp_Object))
            {
              struct charset_conversion_spec *ccs =
                Dynarr_atp (codesys->iso2022.output_conv, i);
-             markobj (ccs->from_charset);
-             markobj (ccs->to_charset);
+             mark_object (ccs->from_charset);
+             mark_object (ccs->to_charset);
            }
        }
       break;
 
     case CODESYS_CCL:
-      markobj (CODING_SYSTEM_CCL_DECODE (codesys));
-      markobj (CODING_SYSTEM_CCL_ENCODE (codesys));
+      mark_object (CODING_SYSTEM_CCL_DECODE (codesys));
+      mark_object (CODING_SYSTEM_CCL_ENCODE (codesys));
       break;
 #endif /* MULE */
     default:
       break;
     }
 
-  markobj (CODING_SYSTEM_PRE_WRITE_CONVERSION (codesys));
+  mark_object (CODING_SYSTEM_PRE_WRITE_CONVERSION (codesys));
   return CODING_SYSTEM_POST_READ_CONVERSION (codesys);
 }
 
@@ -385,7 +428,7 @@ finalize_coding_system (void *header, int for_disksave)
     }
 }
 
-static enum eol_type
+static eol_type_t
 symbol_to_eol_type (Lisp_Object symbol)
 {
   CHECK_SYMBOL (symbol);
@@ -399,7 +442,7 @@ symbol_to_eol_type (Lisp_Object symbol)
 }
 
 static Lisp_Object
-eol_type_to_symbol (enum eol_type type)
+eol_type_to_symbol (eol_type_t type)
 {
   switch (type)
     {
@@ -532,8 +575,7 @@ add_coding_system_to_list_mapper (Lisp_Object key, Lisp_Object value,
     (struct coding_system_list_closure *) coding_system_list_closure;
   Lisp_Object *coding_system_list = cscl->coding_system_list;
 
-  *coding_system_list = Fcons (XCODING_SYSTEM (value)->name,
-                              *coding_system_list);
+  *coding_system_list = Fcons (key, *coding_system_list);
   return 0;
 }
 
@@ -858,10 +900,6 @@ if TYPE is 'ccl:
     CHECK_STRING (doc_string);
   CODING_SYSTEM_DOC_STRING (codesys) = doc_string;
 
-#ifdef UTF2000
-  if (ty == CODESYS_NO_CONVERSION)
-    codesys->fixed.size = 1;
-#endif
   EXTERNAL_PROPERTY_LIST_LOOP (rest, key, value, props)
     {
       if (EQ (key, Qmnemonic))
@@ -1018,14 +1056,14 @@ Define symbol ALIAS as an alias for coding system CODING-SYSTEM.
       FROB (CR,   "-mac");
 #undef FROB
     }
-  /* FSF return value is a vector of [ALIAS-unix ALIAS-doc ALIAS-mac],
+  /* FSF return value is a vector of [ALIAS-unix ALIAS-dos ALIAS-mac],
      but it doesn't look intentional, so I'd rather return something
      meaningful or nothing at all. */
   return Qnil;
 }
 
 static Lisp_Object
-subsidiary_coding_system (Lisp_Object coding_system, enum eol_type type)
+subsidiary_coding_system (Lisp_Object coding_system, eol_type_t type)
 {
   Lisp_Coding_System *cs = XCODING_SYSTEM (coding_system);
   Lisp_Object new_coding_system;
@@ -1305,7 +1343,7 @@ previously.
      order. */
   for (j = 0; j <= CODING_CATEGORY_LAST; j++)
     {
-      int cat = coding_category_by_priority[j];
+      int cat = fcd->coding_category_by_priority[j];
       if (category_to_priority[cat] < 0)
        category_to_priority[cat] = i++;
     }
@@ -1314,7 +1352,7 @@ previously.
      constructed. */
 
   for (i = 0; i <= CODING_CATEGORY_LAST; i++)
-    coding_category_by_priority[category_to_priority[i]] = i;
+    fcd->coding_category_by_priority[category_to_priority[i]] = i;
 
   /* Phew!  That was confusing. */
   return Qnil;
@@ -1329,7 +1367,7 @@ Return a list of coding categories in descending order of priority.
   Lisp_Object list = Qnil;
 
   for (i = CODING_CATEGORY_LAST; i >= 0; i--)
-    list = Fcons (coding_category_symbol[coding_category_by_priority[i]],
+    list = Fcons (coding_category_symbol[fcd->coding_category_by_priority[i]],
                  list);
   return list;
 }
@@ -1342,7 +1380,7 @@ Change the coding system associated with a coding category.
   int cat = decode_coding_category (coding_category);
 
   coding_system = Fget_coding_system (coding_system);
-  coding_category_system[cat] = coding_system;
+  fcd->coding_category_system[cat] = coding_system;
   return Qnil;
 }
 
@@ -1352,7 +1390,7 @@ Return the coding system associated with a coding category.
        (coding_category))
 {
   int cat = decode_coding_category (coding_category);
-  Lisp_Object sys = coding_category_system[cat];
+  Lisp_Object sys = fcd->coding_category_system[cat];
 
   if (!NILP (sys))
     return XCODING_SYSTEM_NAME (sys);
@@ -1366,7 +1404,7 @@ Return the coding system associated with a coding category.
 
 struct detection_state
 {
-  enum eol_type eol_type;
+  eol_type_t eol_type;
   int seen_non_ascii;
   int mask;
 #ifdef MULE
@@ -1447,7 +1485,7 @@ mask_has_at_most_one_bit_p (int mask)
   return (mask & (mask - 1)) == 0;
 }
 
-static enum eol_type
+static eol_type_t
 detect_eol_type (struct detection_state *st, CONST unsigned char *src,
                 unsigned int n)
 {
@@ -1456,21 +1494,19 @@ detect_eol_type (struct detection_state *st, CONST unsigned char *src,
   while (n--)
     {
       c = *src++;
-      if (c == '\r')
-       st->eol.just_saw_cr = 1;
-      else
+      if (c == '\n')
        {
-         if (c == '\n')
-           {
-             if (st->eol.just_saw_cr)
-               return EOL_CRLF;
-             else if (st->eol.seen_anything)
-               return EOL_LF;
-           }
-         else if (st->eol.just_saw_cr)
-           return EOL_CR;
-         st->eol.just_saw_cr = 0;
+         if (st->eol.just_saw_cr)
+           return EOL_CRLF;
+         else if (st->eol.seen_anything)
+           return EOL_LF;
        }
+      else if (st->eol.just_saw_cr)
+       return EOL_CR;
+      else if (c == '\r')
+       st->eol.just_saw_cr = 1;
+      else
+       st->eol.just_saw_cr = 0;
       st->eol.seen_anything = 1;
     }
 
@@ -1495,7 +1531,7 @@ detect_eol_type (struct detection_state *st, CONST unsigned char *src,
 */
 
 static int
-detect_coding_type (struct detection_state *st, CONST unsigned char *src,
+detect_coding_type (struct detection_state *st, CONST Extbyte *src,
                    unsigned int n, int just_do_eol)
 {
   int c;
@@ -1586,13 +1622,13 @@ coding_system_from_mask (int mask)
         the first one that is allowed. */
       for (i = 0; i <= CODING_CATEGORY_LAST; i++)
        {
-         cat = coding_category_by_priority[i];
+         cat = fcd->coding_category_by_priority[i];
          if ((mask & (1 << cat)) &&
-             !NILP (coding_category_system[cat]))
+             !NILP (fcd->coding_category_system[cat]))
            break;
        }
       if (cat >= 0)
-       return coding_category_system[cat];
+       return fcd->coding_category_system[cat];
       else
        return Fget_coding_system (Qraw_text);
     }
@@ -1600,16 +1636,18 @@ coding_system_from_mask (int mask)
 
 /* Given a seekable read stream and potential coding system and EOL type
    as specified, do any autodetection that is called for.  If the
-   coding system and/or EOL type are not autodetect, they will be left
+   coding system and/or EOL type are not `autodetect', they will be left
    alone; but this function will never return an autodetect coding system
    or EOL type.
 
    This function does not automatically fetch subsidiary coding systems;
    that should be unnecessary with the explicit eol-type argument. */
 
+#define LENGTH(string_constant) (sizeof (string_constant) - 1)
+
 void
 determine_real_coding_system (Lstream *stream, Lisp_Object *codesys_in_out,
-                             enum eol_type *eol_type_in_out)
+                             eol_type_t *eol_type_in_out)
 {
   struct detection_state decst;
 
@@ -1621,68 +1659,110 @@ determine_real_coding_system (Lstream *stream, Lisp_Object *codesys_in_out,
   decst.mask = ~0;
 
   /* If autodetection is called for, do it now. */
-  if (XCODING_SYSTEM_TYPE (*codesys_in_out) == CODESYS_AUTODETECT ||
-      *eol_type_in_out == EOL_AUTODETECT)
+  if (XCODING_SYSTEM_TYPE (*codesys_in_out) == CODESYS_AUTODETECT
+      || *eol_type_in_out == EOL_AUTODETECT)
     {
-      unsigned char random_buffer[4096];
-      int nread;
+      Extbyte buf[4096];
       Lisp_Object coding_system = Qnil;
-
-      nread = Lstream_read (stream, random_buffer, sizeof (random_buffer));
-      if (nread)
-       {
-         unsigned char *cp = random_buffer;
-
-         while (cp < random_buffer + nread)
-           {
-             if ((*cp++ == 'c') && (cp < random_buffer + nread) &&
-                 (*cp++ == 'o') && (cp < random_buffer + nread) &&
-                 (*cp++ == 'd') && (cp < random_buffer + nread) &&
-                 (*cp++ == 'i') && (cp < random_buffer + nread) &&
-                 (*cp++ == 'n') && (cp < random_buffer + nread) &&
-                 (*cp++ == 'g') && (cp < random_buffer + nread) &&
-                 (*cp++ == ':') && (cp < random_buffer + nread))
+      Extbyte *p;
+      ssize_t nread = Lstream_read (stream, buf, sizeof (buf));
+      Extbyte *scan_end;
+
+      /* Look for initial "-*-"; mode line prefix */
+      for (p = buf,
+            scan_end = buf + nread - LENGTH ("-*-coding:?-*-");
+          p <= scan_end
+            && *p != '\n'
+            && *p != '\r';
+          p++)
+       if (*p == '-' && *(p+1) == '*' && *(p+2) == '-')
+         {
+           Extbyte *local_vars_beg = p + 3;
+           /* Look for final "-*-"; mode line suffix */
+           for (p = local_vars_beg,
+                  scan_end = buf + nread - LENGTH ("-*-");
+                p <= scan_end
+                  && *p != '\n'
+                  && *p != '\r';
+                p++)
+             if (*p == '-' && *(p+1) == '*' && *(p+2) == '-')
                {
-                 unsigned char coding_system_name[4096 - 6];
-                 unsigned char *np = coding_system_name;
-
-                 while ( (cp < random_buffer + nread)
-                         && ((*cp == ' ') || (*cp == '\t')) )
-                   {
-                     cp++;
-                   }
-                 while ( (cp < random_buffer + nread) &&
-                         (*cp != ' ') && (*cp != '\t') && (*cp != ';') )
-                   {
-                     *np++ = *cp++;
-                   }
-                 *np = 0;
-                 coding_system
-                   = Ffind_coding_system (intern (coding_system_name));
+                 Extbyte *suffix = p;
+                 /* Look for "coding:" */
+                 for (p = local_vars_beg,
+                        scan_end = suffix - LENGTH ("coding:?");
+                      p <= scan_end;
+                      p++)
+                   if (memcmp ("coding:", p, LENGTH ("coding:")) == 0
+                       && (p == local_vars_beg
+                           || (*(p-1) == ' '  ||
+                               *(p-1) == '\t' ||
+                               *(p-1) == ';')))
+                     {
+                       Extbyte save;
+                       int n;
+                       p += LENGTH ("coding:");
+                       while (*p == ' ' || *p == '\t') p++;
+
+                       /* Get coding system name */
+                       save = *suffix; *suffix = '\0';
+                       /* Characters valid in a MIME charset name (rfc 1521),
+                          and in a Lisp symbol name. */
+                       n = strspn ( (char *) p,
+                                   "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                                   "abcdefghijklmnopqrstuvwxyz"
+                                   "0123456789"
+                                   "!$%&*+-.^_{|}~");
+                       *suffix = save;
+                       if (n > 0)
+                         {
+                           save = p[n]; p[n] = '\0';
+                           coding_system =
+                             Ffind_coding_system (intern ((char *) p));
+                           p[n] = save;
+                         }
+                       break;
+                     }
                  break;
                }
-           }
-         if (EQ(coding_system, Qnil))
-           do{
-             if (detect_coding_type (&decst, random_buffer, nread,
-                                     XCODING_SYSTEM_TYPE (*codesys_in_out)
-                                     != CODESYS_AUTODETECT))
-               break;
-             nread = Lstream_read (stream,
-                                   random_buffer, sizeof (random_buffer));
-             if (!nread)
-               break;
-           } while(1);
-       }
+           break;
+         }
+
+      if (NILP (coding_system))
+       do
+         {
+           if (detect_coding_type (&decst, buf, nread,
+                                   XCODING_SYSTEM_TYPE (*codesys_in_out)
+                                   != CODESYS_AUTODETECT))
+             break;
+           nread = Lstream_read (stream, buf, sizeof (buf));
+           if (nread == 0)
+             break;
+         }
+       while (1);
+
+      else if (XCODING_SYSTEM_TYPE (*codesys_in_out) == CODESYS_AUTODETECT
+              && XCODING_SYSTEM_EOL_TYPE (coding_system) == EOL_AUTODETECT)
+       do
+         {
+           if (detect_coding_type (&decst, buf, nread, 1))
+             break;
+           nread = Lstream_read (stream, buf, sizeof (buf));
+           if (!nread)
+             break;
+         }
+       while (1);
+
       *eol_type_in_out = decst.eol_type;
       if (XCODING_SYSTEM_TYPE (*codesys_in_out) == CODESYS_AUTODETECT)
        {
-         if (EQ(coding_system, Qnil))
+         if (NILP (coding_system))
            *codesys_in_out = coding_system_from_mask (decst.mask);
          else
            *codesys_in_out = coding_system;
        }
     }
+
   /* If we absolutely can't determine the EOL type, just assume LF. */
   if (*eol_type_in_out == EOL_AUTODETECT)
     *eol_type_in_out = EOL_LF;
@@ -1719,7 +1799,7 @@ type.  Optional arg BUFFER defaults to the current buffer.
   while (1)
     {
       unsigned char random_buffer[4096];
-      int nread = Lstream_read (istr, random_buffer, sizeof (random_buffer));
+      ssize_t nread = Lstream_read (istr, random_buffer, sizeof (random_buffer));
 
       if (!nread)
        break;
@@ -1740,10 +1820,10 @@ type.  Optional arg BUFFER defaults to the current buffer.
 #endif
       for (i = CODING_CATEGORY_LAST; i >= 0; i--)
        {
-         int sys = coding_category_by_priority[i];
+         int sys = fcd->coding_category_by_priority[i];
          if (decst.mask & (1 << sys))
            {
-             Lisp_Object codesys = coding_category_system[sys];
+             Lisp_Object codesys = fcd->coding_category_system[sys];
              if (!NILP (codesys))
                codesys = subsidiary_coding_system (codesys, decst.eol_type);
              val = Fcons (codesys, val);
@@ -1927,7 +2007,7 @@ struct decoding_stream
      EOL type stored in CODESYS because the latter might indicate
      automatic EOL-type detection while the former will always
      indicate a particular EOL type. */
-  enum eol_type eol_type;
+  eol_type_t eol_type;
 #ifdef MULE
   /* Additional ISO2022 information.  We define the structure above
      because it's also needed by the detection routines. */
@@ -1943,21 +2023,22 @@ struct decoding_stream
   struct detection_state decst;
 };
 
-static int decoding_reader     (Lstream *stream,       unsigned char *data, size_t size);
-static int decoding_writer     (Lstream *stream, CONST unsigned char *data, size_t size);
+static ssize_t decoding_reader (Lstream *stream,
+                               unsigned char *data, size_t size);
+static ssize_t decoding_writer (Lstream *stream,
+                               CONST unsigned char *data, size_t size);
 static int decoding_rewinder   (Lstream *stream);
 static int decoding_seekable_p (Lstream *stream);
 static int decoding_flusher    (Lstream *stream);
 static int decoding_closer     (Lstream *stream);
 
-static Lisp_Object decoding_marker (Lisp_Object stream,
-                                   void (*markobj) (Lisp_Object));
+static Lisp_Object decoding_marker (Lisp_Object stream);
 
 DEFINE_LSTREAM_IMPLEMENTATION ("decoding", lstream_decoding,
                               sizeof (struct decoding_stream));
 
 static Lisp_Object
-decoding_marker (Lisp_Object stream, void (*markobj) (Lisp_Object))
+decoding_marker (Lisp_Object stream)
 {
   Lstream *str = DECODING_STREAM_DATA (XLSTREAM (stream))->other_end;
   Lisp_Object str_obj;
@@ -1967,9 +2048,9 @@ decoding_marker (Lisp_Object stream, void (*markobj) (Lisp_Object))
      and automatically marked. */
 
   XSETLSTREAM (str_obj, str);
-  markobj (str_obj);
+  mark_object (str_obj);
   if (str->imp->marker)
-    return (str->imp->marker) (str_obj, markobj);
+    return (str->imp->marker) (str_obj);
   else
     return Qnil;
 }
@@ -1977,12 +2058,12 @@ decoding_marker (Lisp_Object stream, void (*markobj) (Lisp_Object))
 /* Read SIZE bytes of data and store it into DATA.  We are a decoding stream
    so we read data from the other end, decode it, and store it into DATA. */
 
-static int
+static ssize_t
 decoding_reader (Lstream *stream, unsigned char *data, size_t size)
 {
   struct decoding_stream *str = DECODING_STREAM_DATA (stream);
   unsigned char *orig_data = data;
-  int read_size;
+  ssize_t read_size;
   int error_occurred = 0;
 
   /* We need to interface to mule_decode(), which expects to take some
@@ -2039,11 +2120,11 @@ decoding_reader (Lstream *stream, unsigned char *data, size_t size)
     return data - orig_data;
 }
 
-static int
+static ssize_t
 decoding_writer (Lstream *stream, CONST unsigned char *data, size_t size)
 {
   struct decoding_stream *str = DECODING_STREAM_DATA (stream);
-  int retval;
+  ssize_t retval;
 
   /* Decode all our data into the runoff, and then attempt to write
      it all out to the other end.  Remove whatever chunk we succeeded
@@ -2313,7 +2394,7 @@ BUFFER defaults to the current buffer if unspecified.
       char tempbuf[1024]; /* some random amount */
       Bufpos newpos, even_newer_pos;
       Bufpos oldpos = lisp_buffer_stream_startpos (istr);
-      int size_in_bytes = Lstream_read (istr, tempbuf, sizeof (tempbuf));
+      ssize_t size_in_bytes = Lstream_read (istr, tempbuf, sizeof (tempbuf));
 
       if (!size_in_bytes)
        break;
@@ -2398,22 +2479,21 @@ struct encoding_stream
 #endif /* MULE */
 };
 
-static int encoding_reader (Lstream *stream, unsigned char *data, size_t size);
-static int encoding_writer (Lstream *stream, CONST unsigned char *data,
-                           size_t size);
+static ssize_t encoding_reader (Lstream *stream, unsigned char *data, size_t size);
+static ssize_t encoding_writer (Lstream *stream, CONST unsigned char *data,
+                               size_t size);
 static int encoding_rewinder   (Lstream *stream);
 static int encoding_seekable_p (Lstream *stream);
 static int encoding_flusher    (Lstream *stream);
 static int encoding_closer     (Lstream *stream);
 
-static Lisp_Object encoding_marker (Lisp_Object stream,
-                                   void (*markobj) (Lisp_Object));
+static Lisp_Object encoding_marker (Lisp_Object stream);
 
 DEFINE_LSTREAM_IMPLEMENTATION ("encoding", lstream_encoding,
                               sizeof (struct encoding_stream));
 
 static Lisp_Object
-encoding_marker (Lisp_Object stream, void (*markobj) (Lisp_Object))
+encoding_marker (Lisp_Object stream)
 {
   Lstream *str = ENCODING_STREAM_DATA (XLSTREAM (stream))->other_end;
   Lisp_Object str_obj;
@@ -2423,9 +2503,9 @@ encoding_marker (Lisp_Object stream, void (*markobj) (Lisp_Object))
      and automatically marked. */
 
   XSETLSTREAM (str_obj, str);
-  markobj (str_obj);
+  mark_object (str_obj);
   if (str->imp->marker)
-    return (str->imp->marker) (str_obj, markobj);
+    return (str->imp->marker) (str_obj);
   else
     return Qnil;
 }
@@ -2433,12 +2513,12 @@ encoding_marker (Lisp_Object stream, void (*markobj) (Lisp_Object))
 /* Read SIZE bytes of data and store it into DATA.  We are a encoding stream
    so we read data from the other end, encode it, and store it into DATA. */
 
-static int
+static ssize_t
 encoding_reader (Lstream *stream, unsigned char *data, size_t size)
 {
   struct encoding_stream *str = ENCODING_STREAM_DATA (stream);
   unsigned char *orig_data = data;
-  int read_size;
+  ssize_t read_size;
   int error_occurred = 0;
 
   /* We need to interface to mule_encode(), which expects to take some
@@ -2495,11 +2575,11 @@ encoding_reader (Lstream *stream, unsigned char *data, size_t size)
     return data - orig_data;
 }
 
-static int
+static ssize_t
 encoding_writer (Lstream *stream, CONST unsigned char *data, size_t size)
 {
   struct encoding_stream *str = ENCODING_STREAM_DATA (stream);
-  int retval;
+  ssize_t retval;
 
   /* Encode all our data into the runoff, and then attempt to write
      it all out to the other end.  Remove whatever chunk we succeeded
@@ -2726,7 +2806,7 @@ text.  BUFFER defaults to the current buffer if unspecified.
       char tempbuf[1024]; /* some random amount */
       Bufpos newpos, even_newer_pos;
       Bufpos oldpos = lisp_buffer_stream_startpos (istr);
-      int size_in_bytes = Lstream_read (istr, tempbuf, sizeof (tempbuf));
+      ssize_t size_in_bytes = Lstream_read (istr, tempbuf, sizeof (tempbuf));
 
       if (!size_in_bytes)
        break;
@@ -3357,9 +3437,7 @@ Return the corresponding character code in Big5.
 /*                                                                      */
 /************************************************************************/
 
-Lisp_Object ucs_to_mule_table[65536];
-Lisp_Object mule_to_ucs_table;
-
+#ifndef UTF2000
 DEFUN ("set-ucs-char", Fset_ucs_char, 2, 2, 0, /*
 Map UCS-4 code CODE to Mule character CHARACTER.
 
@@ -3373,9 +3451,9 @@ Return T on success, NIL on failure.
   CHECK_INT (code);
   c = XINT (code);
 
-  if (c < sizeof (ucs_to_mule_table))
+  if (c < sizeof (fcd->ucs_to_mule_table))
     {
-      ucs_to_mule_table[c] = character;
+      fcd->ucs_to_mule_table[c] = character;
       return Qt;
     }
   else
@@ -3385,9 +3463,9 @@ Return T on success, NIL on failure.
 static Lisp_Object
 ucs_to_char (unsigned long code)
 {
-  if (code < sizeof (ucs_to_mule_table))
+  if (code < sizeof (fcd->ucs_to_mule_table))
     {
-      return ucs_to_mule_table[code];
+      return fcd->ucs_to_mule_table[code];
     }
   else if ((0xe00000 <= code) && (code <= 0xe00000 + 94 * 94 * 14))
     {
@@ -3434,6 +3512,7 @@ Return the UCS code (a positive integer) corresponding to CHARACTER.
 {
   return Fget_char_table (character, mule_to_ucs_table);
 }
+#endif
 
 #ifdef UTF2000
 #define decode_ucs4 DECODE_ADD_UCS_CHAR
@@ -3468,6 +3547,7 @@ decode_ucs4 (unsigned long ch, unsigned_char_dynarr *dst)
 }
 #endif
 
+#ifndef UTF2000
 static unsigned long
 mule_char_to_ucs4 (Lisp_Object charset,
                   unsigned char h, unsigned char l)
@@ -3511,6 +3591,7 @@ encode_ucs4 (Lisp_Object charset,
   Dynarr_add (dst, (code >>  8) & 255);
   Dynarr_add (dst,  code        & 255);
 }
+#endif
 
 static int
 detect_coding_ucs4 (struct detection_state *st, CONST unsigned char *src,
@@ -3942,7 +4023,7 @@ encode_coding_utf8 (Lstream *encoding, CONST unsigned char *src,
 
  back_to_square_n:
 #endif /* ENABLE_COMPOSITE_CHARS */
-  
+
   while (n--)
     {
       unsigned char c = *src++;
@@ -5794,31 +5875,7 @@ encode_coding_no_conversion (Lstream *encoding, CONST unsigned char *src,
          break;
        case 1:
          ch = ( ch << 6 ) | ( c & 0x3f );
-         switch ( str->codesys->fixed.size )
-           {
-           case 1:
-             Dynarr_add (dst, ch & 0xff);
-             break;
-           case 2:
-             Dynarr_add (dst, (ch >> 8) & 0xff);
-             Dynarr_add (dst,  ch       & 0xff);
-             break;
-           case 3:
-             Dynarr_add (dst, (ch >> 16) & 0xff);
-             Dynarr_add (dst, (ch >>  8) & 0xff);
-             Dynarr_add (dst,  ch        & 0xff);
-             break;
-           case 4:
-             Dynarr_add (dst, (ch >> 24) & 0xff);
-             Dynarr_add (dst, (ch >> 16) & 0xff);
-             Dynarr_add (dst, (ch >>  8) & 0xff);
-             Dynarr_add (dst,  ch        & 0xff);
-             break;
-           default:
-             fprintf(stderr, "It seems %d bytes stream.\n",
-                     str->codesys->fixed.size);
-             abort ();
-           }
+         Dynarr_add (dst, ch & 0xff);
          char_boundary = 0;
          break;
        default:
@@ -5958,7 +6015,7 @@ convert_to_external_format (CONST Bufbyte *ptr,
       GCPRO3 (instream, outstream, da_outstream);
       while (1)
         {
-          int size_in_bytes = Lstream_read (istr, tempbuf, sizeof (tempbuf));
+          ssize_t size_in_bytes = Lstream_read (istr, tempbuf, sizeof (tempbuf));
           if (!size_in_bytes)
             break;
           Lstream_write (ostr, tempbuf, size_in_bytes);
@@ -6015,7 +6072,7 @@ convert_from_external_format (CONST Extbyte *ptr,
       GCPRO3 (instream, outstream, da_outstream);
       while (1)
         {
-          int size_in_bytes = Lstream_read (istr, tempbuf, sizeof (tempbuf));
+          ssize_t size_in_bytes = Lstream_read (istr, tempbuf, sizeof (tempbuf));
           if (!size_in_bytes)
             break;
           Lstream_write (ostr, tempbuf, size_in_bytes);
@@ -6041,7 +6098,6 @@ convert_from_external_format (CONST Extbyte *ptr,
 void
 syms_of_file_coding (void)
 {
-  defsymbol (&Qbuffer_file_coding_system, "buffer-file-coding-system");
   deferror (&Qcoding_system_error, "coding-system-error",
            "Coding-system error", Qio_error);
 
@@ -6076,12 +6132,14 @@ syms_of_file_coding (void)
   DEFSUBR (Fencode_shift_jis_char);
   DEFSUBR (Fdecode_big5_char);
   DEFSUBR (Fencode_big5_char);
+#ifndef UTF2000
   DEFSUBR (Fset_ucs_char);
   DEFSUBR (Fucs_char);
   DEFSUBR (Fset_char_ucs);
   DEFSUBR (Fchar_ucs);
+#endif /* not UTF2000 */
 #endif /* MULE */
-  defsymbol (&Qcoding_system_p, "coding-system-p");
+  defsymbol (&Qcoding_systemp, "coding-system-p");
   defsymbol (&Qno_conversion, "no-conversion");
   defsymbol (&Qraw_text, "raw-text");
 #ifdef MULE
@@ -6176,11 +6234,14 @@ vars_of_file_coding (void)
 {
   int i;
 
+  fcd = xnew (struct file_coding_dump);
+  dumpstruct (&fcd, &fcd_description);
+
   /* Initialize to something reasonable ... */
   for (i = 0; i <= CODING_CATEGORY_LAST; i++)
     {
-      coding_category_system[i] = Qnil;
-      coding_category_by_priority[i] = i;
+      fcd->coding_category_system[i] = Qnil;
+      fcd->coding_category_by_priority[i] = i;
     }
 
   Fprovide (intern ("file-coding"));
@@ -6241,6 +6302,7 @@ complex_vars_of_file_coding (void)
     make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
 
   the_codesys_prop_dynarr = Dynarr_new (codesys_prop);
+  dumpstruct (&the_codesys_prop_dynarr, &codesys_prop_dynarr_description);
 
 #define DEFINE_CODESYS_PROP(Prop_Type, Sym) do \
 {                                              \
@@ -6301,20 +6363,20 @@ complex_vars_of_file_coding (void)
   Fdefine_coding_system_alias (Qno_conversion, Qraw_text);
 
   /* Need this for bootstrapping */
-  coding_category_system[CODING_CATEGORY_NO_CONVERSION] =
+  fcd->coding_category_system[CODING_CATEGORY_NO_CONVERSION] =
     Fget_coding_system (Qraw_text);
 
 #ifdef UTF2000
-  coding_category_system[CODING_CATEGORY_UTF8]
+  fcd->coding_category_system[CODING_CATEGORY_UTF8]
    = Fget_coding_system (Qutf8);
 #endif
 
-#ifdef MULE
+#if defined(MULE) && !defined(UTF2000)
   {
     unsigned int i;
 
     for (i = 0; i < 65536; i++)
-      ucs_to_mule_table[i] = Qnil;
+      fcd->ucs_to_mule_table[i] = Qnil;
   }
   staticpro (&mule_to_ucs_table);
   mule_to_ucs_table = Fmake_char_table(Qgeneric);