]> code.delx.au - gnu-emacs/blobdiff - src/coding.c
(get_next_display_element): Display codes 8a0 and 8ad
[gnu-emacs] / src / coding.c
index d6d8bb342d63dd73a515d330b2c2550d8cc2e5df..93a18d1cd9c666e9a74e3b9a30eb1bba21f5f3e2 100644 (file)
@@ -1024,9 +1024,26 @@ decode_coding_emacs_mule (coding, source, destination, src_bytes, dst_bytes)
        }
       else
        {
-         bytes = CHAR_STRING (*src, tmp);
-         p = tmp;
+         int i, c;
+
+         bytes = BYTES_BY_CHAR_HEAD (*src);
          src++;
+         for (i = 1; i < bytes; i++)
+           {
+             ONE_MORE_BYTE (c);
+             if (CHAR_HEAD_P (c))
+               break;
+           }
+         if (i < bytes)
+           {
+             bytes = CHAR_STRING (*src_base, tmp);
+             p = tmp;
+             src = src_base + 1;
+           }
+         else
+           {
+             p = src_base;
+           }
        }
       if (dst + bytes >= (dst_bytes ? dst_end : src))
        {
@@ -2081,7 +2098,7 @@ decode_coding_iso2022 (coding, source, destination, src_bytes, dst_bytes)
                  int dim, M, L;
                  int size, required;
                  int produced_chars;
-                 
+
                  ONE_MORE_BYTE (dim);
                  ONE_MORE_BYTE (M);
                  ONE_MORE_BYTE (L);
@@ -4029,7 +4046,7 @@ setup_raw_text_coding_system (coding)
    o coding-category-utf-8
 
        The category for a coding system which has the same code range
-       as UTF-8 (cf. RFC2279).  Assigned the coding-system (Lisp
+       as UTF-8 (cf. RFC3629).  Assigned the coding-system (Lisp
        symbol) `utf-8' by default.
 
    o coding-category-utf-16-be
@@ -4535,10 +4552,6 @@ struct conversion_buffer
   unsigned char *data;
 };
 
-/* Don't use alloca for allocating memory space larger than this, lest
-   we overflow their stack.  */
-#define MAX_ALLOCA 16*1024
-
 /* Allocate LEN bytes of memory for BUF (struct conversion_buffer).  */
 #define allocate_conversion_buffer(buf, len)           \
   do {                                                 \
@@ -5458,6 +5471,9 @@ coding_restore_composition (coding, obj)
              if (method == COMPOSITION_WITH_RULE_ALTCHARS
                  && len % 2 == 0)
                len --;
+             if (len < 1)
+               /* Invalid composition data.  */
+               break;
              for (j = 0; j < len; j++)
                args[j] = make_number (data[4 + j]);
              components = (method == COMPOSITION_WITH_ALTCHARS
@@ -5634,8 +5650,11 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)
        coding_allocate_composition_data (coding, from);
     }
 
-  /* Try to skip the heading and tailing ASCIIs.  */
-  if (coding->type != coding_type_ccl)
+  /* Try to skip the heading and tailing ASCIIs.  We can't skip them
+     if we must run CCL program or there are compositions to
+     encode.  */
+  if (coding->type != coding_type_ccl
+      && (! coding->cmp_data || coding->cmp_data->used == 0))
     {
       int from_byte_orig = from_byte, to_byte_orig = to_byte;
 
@@ -5651,6 +5670,7 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)
          if (!replace)
            /* We must record and adjust for this new text now.  */
            adjust_after_insert (from, from_byte_orig, to, to_byte_orig, len);
+         coding_free_composition_data (coding);
          return 0;
        }
 
@@ -5988,6 +6008,37 @@ code_convert_region (from, from_byte, to, to_byte, coding, encodep, replace)
   return 0;
 }
 
+/* Name (or base name) of work buffer for code conversion.  */
+static Lisp_Object Vcode_conversion_workbuf_name;
+
+/* Set the current buffer to the working buffer prepared for
+   code-conversion.  MULTIBYTE specifies the multibyteness of the
+   buffer.  */
+
+static struct buffer *
+set_conversion_work_buffer (multibyte)
+     int multibyte;
+{
+  Lisp_Object buffer;
+  struct buffer *buf;
+
+  buffer = Fget_buffer_create (Vcode_conversion_workbuf_name);
+  buf = XBUFFER (buffer);
+  delete_all_overlays (buf);
+  buf->directory = current_buffer->directory;
+  buf->read_only = Qnil;
+  buf->filename = Qnil;
+  buf->undo_list = Qt;
+  eassert (buf->overlays_before == NULL);
+  eassert (buf->overlays_after == NULL);
+  set_buffer_internal (buf);
+  if (BEG != BEGV || Z != ZV)
+    Fwiden ();
+  del_range_2 (BEG, BEG_BYTE, Z, Z_BYTE, 0);
+  buf->enable_multibyte_characters = multibyte ? Qt : Qnil;
+  return buf;
+}
+
 Lisp_Object
 run_pre_post_conversion_on_str (str, coding, encodep)
      Lisp_Object str;
@@ -5997,7 +6048,6 @@ run_pre_post_conversion_on_str (str, coding, encodep)
   int count = SPECPDL_INDEX ();
   struct gcpro gcpro1, gcpro2;
   int multibyte = STRING_MULTIBYTE (str);
-  Lisp_Object buffer;
   struct buffer *buf;
   Lisp_Object old_deactivate_mark;
 
@@ -6008,23 +6058,10 @@ run_pre_post_conversion_on_str (str, coding, encodep)
   old_deactivate_mark = Vdeactivate_mark;
   GCPRO2 (str, old_deactivate_mark);
 
-  buffer = Fget_buffer_create (build_string (" *code-converting-work*"));
-  buf = XBUFFER (buffer);
-
-  delete_all_overlays (buf);
-  buf->directory = current_buffer->directory;
-  buf->read_only = Qnil;
-  buf->filename = Qnil;
-  buf->undo_list = Qt;
-  eassert (buf->overlays_before == NULL);
-  eassert (buf->overlays_after == NULL);
-
-  set_buffer_internal (buf);
   /* We must insert the contents of STR as is without
      unibyte<->multibyte conversion.  For that, we adjust the
      multibyteness of the working buffer to that of STR.  */
-  Ferase_buffer ();
-  buf->enable_multibyte_characters = multibyte ? Qt : Qnil;
+  set_conversion_work_buffer (multibyte);
 
   insert_from_string (str, 0, 0,
                      SCHARS (str), SBYTES (str), 0);
@@ -6045,6 +6082,64 @@ run_pre_post_conversion_on_str (str, coding, encodep)
   return unbind_to (count, str);
 }
 
+
+/* Run pre-write-conversion function of CODING on NCHARS/NBYTES
+   text in *STR.  *SIZE is the allocated bytes for STR.  As it
+   is intended that this function is called from encode_terminal_code,
+   the pre-write-conversion function is run by safe_call and thus
+   "Error during redisplay: ..." is logged when an error occurs.
+
+   Store the resulting text in *STR and set CODING->produced_char and
+   CODING->produced to the number of characters and bytes
+   respectively.  If the size of *STR is too small, enlarge it by
+   xrealloc and update *STR and *SIZE.  */
+
+void
+run_pre_write_conversin_on_c_str (str, size, nchars, nbytes, coding)
+     unsigned char **str;
+     int *size, nchars, nbytes;
+     struct coding_system *coding;
+{
+  struct gcpro gcpro1, gcpro2;
+  struct buffer *cur = current_buffer;
+  Lisp_Object old_deactivate_mark, old_last_coding_system_used;
+  Lisp_Object args[3];
+
+  /* It is not crucial to specbind this.  */
+  old_deactivate_mark = Vdeactivate_mark;
+  old_last_coding_system_used = Vlast_coding_system_used;
+  GCPRO2 (old_deactivate_mark, old_last_coding_system_used);
+
+  /* We must insert the contents of STR as is without
+     unibyte<->multibyte conversion.  For that, we adjust the
+     multibyteness of the working buffer to that of STR.  */
+  set_conversion_work_buffer (coding->src_multibyte);
+  insert_1_both (*str, nchars, nbytes, 0, 0, 0);
+  UNGCPRO;
+  inhibit_pre_post_conversion = 1;
+  args[0] = coding->pre_write_conversion;
+  args[1] = make_number (BEG);
+  args[2] = make_number (Z);
+  safe_call (3, args);
+  inhibit_pre_post_conversion = 0;
+  Vdeactivate_mark = old_deactivate_mark;
+  Vlast_coding_system_used = old_last_coding_system_used;
+  coding->produced_char = Z - BEG;
+  coding->produced = Z_BYTE - BEG_BYTE;
+  if (coding->produced > *size)
+    {
+      *size = coding->produced;
+      *str = xrealloc (*str, *size);
+    }
+  if (BEG < GPT && GPT < Z)
+    move_gap (BEG);
+  bcopy (BEG_ADDR, *str, coding->produced);
+  coding->src_multibyte
+    = ! NILP (current_buffer->enable_multibyte_characters);
+  set_buffer_internal (cur);
+}
+
+
 Lisp_Object
 decode_coding_string (str, coding, nocopy)
      Lisp_Object str;
@@ -6222,6 +6317,11 @@ decode_coding_string (str, coding, nocopy)
                   shrinked_bytes - from);
   free_conversion_buffer (&buf);
 
+  coding->consumed += shrinked_bytes;
+  coding->consumed_char += shrinked_bytes;
+  coding->produced += shrinked_bytes;
+  coding->produced_char += shrinked_bytes;
+
   if (coding->cmp_data && coding->cmp_data->used)
     coding_restore_composition (coding, newstr);
   coding_free_composition_data (coding);
@@ -6276,13 +6376,19 @@ encode_coding_string (str, coding, nocopy)
   if (coding->composing != COMPOSITION_DISABLED)
     coding_save_composition (coding, from, to, str);
 
-  /* Try to skip the heading and tailing ASCIIs.  */
-  if (coding->type != coding_type_ccl)
+  /* Try to skip the heading and tailing ASCIIs.  We can't skip them
+     if we must run CCL program or there are compositions to
+     encode.  */
+  if (coding->type != coding_type_ccl
+      && (! coding->cmp_data || coding->cmp_data->used == 0))
     {
       SHRINK_CONVERSION_REGION (&from, &to_byte, coding, SDATA (str),
                                1);
       if (from == to_byte)
-       return (nocopy ? str : Fcopy_sequence (str));
+       {
+         coding_free_composition_data (coding);
+         return (nocopy ? str : Fcopy_sequence (str));
+       }
       shrinked_bytes = from + (SBYTES (str) - to_byte);
     }
 
@@ -6300,6 +6406,7 @@ encode_coding_string (str, coding, nocopy)
       produced += coding->produced;
       produced_char += coding->produced_char;
       if (result == CODING_FINISH_NORMAL
+         || result == CODING_FINISH_INTERRUPT
          || (result == CODING_FINISH_INSUFFICIENT_SRC
              && coding->consumed == 0))
        break;
@@ -6386,7 +6493,7 @@ DEFUN ("check-coding-system", Fcheck_coding_system, Scheck_coding_system,
        doc: /* Check validity of CODING-SYSTEM.
 If valid, return CODING-SYSTEM, else signal a `coding-system-error' error.
 It is valid if it is nil or a symbol with a non-nil `coding-system' property.
-The value of property should be a vector of length 5.  */)
+The value of this property should be a vector of length 5.  */)
      (coding_system)
      Lisp_Object coding_system;
 {
@@ -6550,8 +6657,8 @@ highest priority.  */)
     possible coding systems.  If it is nil, it means that we have not
     yet found any coding systems.
 
-    WORK_TABLE is a copy of the char-table Vchar_coding_system_table.  An
-    element of WORK_TABLE is set to t once the element is looked up.
+    WORK_TABLE a char-table of which element is set to t once the
+    element is looked up.
 
     If a non-ASCII single byte char is found, set
     *single_byte_char_found to 1.  */
@@ -6566,6 +6673,8 @@ find_safe_codings (p, pend, safe_codings, work_table, single_byte_char_found)
   Lisp_Object val, ch;
   Lisp_Object prev, tail;
 
+  if (NILP (safe_codings))
+    goto done_safe_codings;
   while (p < pend)
     {
       c = STRING_CHAR_AND_LENGTH (p, pend - p, len);
@@ -6575,11 +6684,6 @@ find_safe_codings (p, pend, safe_codings, work_table, single_byte_char_found)
        continue;
       if (SINGLE_BYTE_CHAR_P (c))
        *single_byte_char_found = 1;
-      if (NILP (safe_codings))
-       /* Already all coding systems are excluded.  But, we can't
-          terminate the loop here because non-ASCII single-byte char
-          must be found.  */
-       continue;
       /* Check the safe coding systems for C.  */
       ch = make_number (c);
       val = Faref (work_table, ch);
@@ -6640,7 +6744,7 @@ find_safe_codings (p, pend, safe_codings, work_table, single_byte_char_found)
                                        accept_latin_extra));
                }
            }
-             
+
          if (! encodable
              && ((CHAR_TABLE_P (translation_table)
                   && ! NILP (Faref (translation_table, ch)))
@@ -6657,12 +6761,33 @@ find_safe_codings (p, pend, safe_codings, work_table, single_byte_char_found)
            {
              /* Exclude this coding system from SAFE_CODINGS.  */
              if (EQ (tail, safe_codings))
-               safe_codings = XCDR (safe_codings);
+               {
+                 safe_codings = XCDR (safe_codings);
+                 if (NILP (safe_codings))
+                   goto done_safe_codings;
+               }
              else
                XSETCDR (prev, XCDR (tail));
            }
        }
     }
+
+ done_safe_codings:
+  /* If the above loop was terminated before P reaches PEND, it means
+     SAFE_CODINGS was set to nil.  If we have not yet found an
+     non-ASCII single-byte char, check it now.  */
+  if (! *single_byte_char_found)
+    while (p < pend)
+      {
+       c = STRING_CHAR_AND_LENGTH (p, pend - p, len);
+       p += len;
+       if (! ASCII_BYTE_P (c)
+           && SINGLE_BYTE_CHAR_P (c))
+         {
+           *single_byte_char_found = 1;
+           break;
+         }
+      }
   return safe_codings;
 }
 
@@ -7189,7 +7314,7 @@ DEFUN ("set-safe-terminal-coding-system-internal", Fset_safe_terminal_coding_sys
   /* Character composition should be disabled.  */
   safe_terminal_coding.composing = COMPOSITION_DISABLED;
   /* Error notification should be suppressed.  */
-  terminal_coding.suppress_error = 1;
+  safe_terminal_coding.suppress_error = 1;
   safe_terminal_coding.src_multibyte = 1;
   safe_terminal_coding.dst_multibyte = 0;
   return Qnil;
@@ -7493,6 +7618,9 @@ init_coding_once ()
 void
 syms_of_coding ()
 {
+  staticpro (&Vcode_conversion_workbuf_name);
+  Vcode_conversion_workbuf_name = build_string (" *code-conversion-work*");
+
   Qtarget_idx = intern ("target-idx");
   staticpro (&Qtarget_idx);