use dynwind_begin and dynwind_end
[bpt/emacs.git] / src / coding.c
index 03ce482..fc21795 100644 (file)
@@ -1,5 +1,5 @@
 /* Coding system handler (conversion, detection, etc).
-   Copyright (C) 2001-2013 Free Software Foundation, Inc.
+   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)
@@ -1202,7 +1202,7 @@ detect_coding_utf_8 (struct coding_system *coding,
   bool multibytep = coding->src_multibyte;
   ptrdiff_t consumed_chars = 0;
   bool bom_found = 0;
-  int nchars = coding->head_ascii;
+  ptrdiff_t nchars = coding->head_ascii;
   int eol_seen = coding->eol_seen;
 
   detect_info->checked |= CATEGORY_MASK_UTF_8;
@@ -1300,6 +1300,7 @@ detect_coding_utf_8 (struct coding_system *coding,
           means that we found a valid non-ASCII characters.  */
        detect_info->found |= CATEGORY_MASK_UTF_8_AUTO | CATEGORY_MASK_UTF_8_NOSIG;
     }
+  coding->detected_utf8_bytes = src_base - coding->source;
   coding->detected_utf8_chars = nchars;
   return 1;
 }
@@ -1484,7 +1485,7 @@ decode_coding_utf_8 (struct coding_system *coding)
       src = src_base;
       consumed_chars = consumed_chars_base;
       ONE_MORE_BYTE (c);
-      *charbuf++ = ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c);
+      *charbuf++ = ASCII_CHAR_P (c) ? c : BYTE8_TO_CHAR (c);
       coding->errors++;
     }
 
@@ -1548,8 +1549,8 @@ encode_coding_utf_8 (struct coding_system *coding)
            *dst++ = CHAR_TO_BYTE8 (c);
          else
            CHAR_STRING_ADVANCE_NO_UNIFY (c, dst);
-         produced_chars++;
        }
+      produced_chars = dst - (coding->destination + coding->produced);
     }
   record_conversion_result (coding, CODING_RESULT_SUCCESS);
   coding->produced_char += produced_chars;
@@ -1724,7 +1725,7 @@ decode_coding_utf_16 (struct coding_system *coding)
        ONE_MORE_BYTE (c2);
       if (c2 < 0)
        {
-         *charbuf++ = ASCII_BYTE_P (c1) ? c1 : BYTE8_TO_CHAR (c1);
+         *charbuf++ = ASCII_CHAR_P (c1) ? c1 : BYTE8_TO_CHAR (c1);
          *charbuf++ = -c2;
          continue;
        }
@@ -2013,7 +2014,7 @@ emacs_mule_char (struct coding_system *coding, const unsigned char *src,
   int charset_ID;
   unsigned code;
   int c;
-  int consumed_chars = 0;
+  ptrdiff_t consumed_chars = 0;
   bool mseq_found = 0;
 
   ONE_MORE_BYTE (c);
@@ -2107,7 +2108,7 @@ emacs_mule_char (struct coding_system *coding, const unsigned char *src,
 
        case 1:
          code = c;
-         charset_ID = ASCII_BYTE_P (code) ? charset_ascii : charset_eight_bit;
+         charset_ID = ASCII_CHAR_P (code) ? charset_ascii : charset_eight_bit;
          break;
 
        default:
@@ -2595,7 +2596,7 @@ decode_coding_emacs_mule (struct coding_system *coding)
       src = src_base;
       consumed_chars = consumed_chars_base;
       ONE_MORE_BYTE (c);
-      *charbuf++ = ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c);
+      *charbuf++ = ASCII_CHAR_P (c) ? c : BYTE8_TO_CHAR (c);
       char_offset++;
       coding->errors++;
     }
@@ -3190,7 +3191,7 @@ detect_coding_iso_2022 (struct coding_system *coding,
              if (! single_shifting
                  && ! (rejected & CATEGORY_MASK_ISO_8_2))
                {
-                 int len = 1;
+                 ptrdiff_t len = 1;
                  while (src < src_end)
                    {
                      src_base = src;
@@ -3572,7 +3573,7 @@ decode_coding_iso_2022 (struct coding_system *coding)
 
       if (CODING_ISO_EXTSEGMENT_LEN (coding) > 0)
        {
-         *charbuf++ = ASCII_BYTE_P (c1) ? c1 : BYTE8_TO_CHAR (c1);
+         *charbuf++ = ASCII_CHAR_P (c1) ? c1 : BYTE8_TO_CHAR (c1);
          char_offset++;
          CODING_ISO_EXTSEGMENT_LEN (coding)--;
          continue;
@@ -3599,7 +3600,7 @@ decode_coding_iso_2022 (struct coding_system *coding)
            }
          else
            {
-             *charbuf++ = ASCII_BYTE_P (c1) ? c1 : BYTE8_TO_CHAR (c1);
+             *charbuf++ = ASCII_CHAR_P (c1) ? c1 : BYTE8_TO_CHAR (c1);
              char_offset++;
            }
          continue;
@@ -3973,7 +3974,7 @@ decode_coding_iso_2022 (struct coding_system *coding)
          MAYBE_FINISH_COMPOSITION ();
          for (; src_base < src; src_base++, char_offset++)
            {
-             if (ASCII_BYTE_P (*src_base))
+             if (ASCII_CHAR_P (*src_base))
                *charbuf++ = *src_base;
              else
                *charbuf++ = BYTE8_TO_CHAR (*src_base);
@@ -4003,7 +4004,7 @@ decode_coding_iso_2022 (struct coding_system *coding)
       src = src_base;
       consumed_chars = consumed_chars_base;
       ONE_MORE_BYTE (c);
-      *charbuf++ = c < 0 ? -c : ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c);
+      *charbuf++ = c < 0 ? -c : ASCII_CHAR_P (c) ? c : BYTE8_TO_CHAR (c);
       char_offset++;
       coding->errors++;
       /* Reset the invocation and designation status to the safest
@@ -4456,7 +4457,7 @@ encode_coding_iso_2022 (struct coding_system *coding)
        {
          /* We have to produce designation sequences if any now.  */
          unsigned char desig_buf[16];
-         int nbytes;
+         ptrdiff_t nbytes;
          ptrdiff_t offset;
 
          charset_map_loaded = 0;
@@ -5639,7 +5640,7 @@ decode_coding_charset (struct coding_system *coding)
       src = src_base;
       consumed_chars = consumed_chars_base;
       ONE_MORE_BYTE (c);
-      *charbuf++ = c < 0 ? -c : ASCII_BYTE_P (c) ? c : BYTE8_TO_CHAR (c);
+      *charbuf++ = c < 0 ? -c : ASCII_CHAR_P (c) ? c : BYTE8_TO_CHAR (c);
       char_offset++;
       coding->errors++;
     }
@@ -6211,7 +6212,7 @@ static Lisp_Object adjust_coding_eol_type (struct coding_system *coding,
    EOL_SEEN_LF, EOL_SEEN_CR, and EOL_SEEN_CRLF, but the value is
    reliable only when all the source bytes are ASCII.  */
 
-static int
+static ptrdiff_t
 check_ascii (struct coding_system *coding)
 {
   const unsigned char *src, *end;
@@ -6283,12 +6284,12 @@ check_ascii (struct coding_system *coding)
    the value is reliable only when all the source bytes are valid
    UTF-8.  */
 
-static int
+static ptrdiff_t
 check_utf_8 (struct coding_system *coding)
 {
   const unsigned char *src, *end;
   int eol_seen;
-  int nchars = coding->head_ascii;
+  ptrdiff_t nchars = coding->head_ascii;
 
   if (coding->head_ascii < 0)
     check_ascii (coding);
@@ -7264,13 +7265,16 @@ produce_charset (struct coding_system *coding, int *charbuf, ptrdiff_t pos)
                      coding->dst_object);
 }
 
+#define MAX_CHARBUF_SIZE 0x4000
+#define MIN_CHARBUF_SIZE 0x10
 
-#define CHARBUF_SIZE 0x4000
-
-#define ALLOC_CONVERSION_WORK_AREA(coding)                             \
-  do {                                                                 \
-    coding->charbuf = SAFE_ALLOCA (CHARBUF_SIZE * sizeof (int));       \
-    coding->charbuf_size = CHARBUF_SIZE;                               \
+#define ALLOC_CONVERSION_WORK_AREA(coding, size)               \
+  do {                                                         \
+    int units = ((size) > MAX_CHARBUF_SIZE ? MAX_CHARBUF_SIZE  \
+                : (size) < MIN_CHARBUF_SIZE ? MIN_CHARBUF_SIZE \
+                : size);                                       \
+    coding->charbuf = SAFE_ALLOCA ((units) * sizeof (int));    \
+    coding->charbuf_size = (units);                            \
   } while (0)
 
 
@@ -7372,7 +7376,7 @@ decode_coding (struct coding_system *coding)
   record_conversion_result (coding, CODING_RESULT_SUCCESS);
   coding->errors = 0;
 
-  ALLOC_CONVERSION_WORK_AREA (coding);
+  ALLOC_CONVERSION_WORK_AREA (coding, coding->src_bytes);
 
   attrs = CODING_ID_ATTRS (coding->id);
   translation_table = get_translation_table (attrs, 0, NULL);
@@ -7414,7 +7418,7 @@ decode_coding (struct coding_system *coding)
   coding->carryover_bytes = 0;
   if (coding->consumed < coding->src_bytes)
     {
-      int nbytes = coding->src_bytes - coding->consumed;
+      ptrdiff_t nbytes = coding->src_bytes - coding->consumed;
       const unsigned char *src;
 
       coding_set_source (coding);
@@ -7768,7 +7772,7 @@ encode_coding (struct coding_system *coding)
   record_conversion_result (coding, CODING_RESULT_SUCCESS);
   coding->errors = 0;
 
-  ALLOC_CONVERSION_WORK_AREA (coding);
+  ALLOC_CONVERSION_WORK_AREA (coding, coding->src_chars);
 
   if (coding->encoder == encode_coding_ccl)
     {
@@ -7875,7 +7879,7 @@ void
 decode_coding_gap (struct coding_system *coding,
                   ptrdiff_t chars, ptrdiff_t bytes)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
   Lisp_Object attrs;
 
   coding->src_object = Fcurrent_buffer ();
@@ -7890,7 +7894,7 @@ decode_coding_gap (struct coding_system *coding,
   coding->dst_multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
 
   coding->head_ascii = -1;
-  coding->detected_utf8_chars = -1;
+  coding->detected_utf8_bytes = coding->detected_utf8_chars = -1;
   coding->eol_seen = EOL_SEEN_NONE;
   if (CODING_REQUIRE_DETECTION (coding))
     detect_coding (coding);
@@ -7907,7 +7911,8 @@ decode_coding_gap (struct coding_system *coding,
       if (chars != bytes)
        {
          /* There exists a non-ASCII byte.  */
-         if (EQ (CODING_ATTR_TYPE (attrs), Qutf_8))
+         if (EQ (CODING_ATTR_TYPE (attrs), Qutf_8)
+             && coding->detected_utf8_bytes == coding->src_bytes)
            {
              if (coding->detected_utf8_chars >= 0)
                chars = coding->detected_utf8_chars;
@@ -7968,6 +7973,7 @@ decode_coding_gap (struct coding_system *coding,
          coding->produced = bytes;
          coding->produced_char = chars;
          insert_from_gap (chars, bytes, 1);
+         dynwind_end ();
          return;
        }
     }
@@ -7991,7 +7997,7 @@ decode_coding_gap (struct coding_system *coding,
       coding->produced += Z_BYTE - prev_Z_BYTE;
     }
 
-  unbind_to (count, Qnil);
+  dynwind_end ();
 }
 
 
@@ -8031,7 +8037,7 @@ decode_coding_object (struct coding_system *coding,
                      ptrdiff_t to, ptrdiff_t to_byte,
                      Lisp_Object dst_object)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
   unsigned char *destination IF_LINT (= NULL);
   ptrdiff_t dst_bytes IF_LINT (= 0);
   ptrdiff_t chars = to - from;
@@ -8204,7 +8210,7 @@ decode_coding_object (struct coding_system *coding,
     }
 
   Vdeactivate_mark = old_deactivate_mark;
-  unbind_to (count, coding->dst_object);
+  dynwind_end ();
 }
 
 
@@ -8215,7 +8221,7 @@ encode_coding_object (struct coding_system *coding,
                      ptrdiff_t to, ptrdiff_t to_byte,
                      Lisp_Object dst_object)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
   ptrdiff_t chars = to - from;
   ptrdiff_t bytes = to_byte - from_byte;
   Lisp_Object attrs;
@@ -8337,7 +8343,7 @@ encode_coding_object (struct coding_system *coding,
     {
       ptrdiff_t dst_bytes = max (1, coding->src_chars);
       coding->dst_object = Qnil;
-      coding->destination = xmalloc (dst_bytes);
+      coding->destination = xmalloc_atomic (dst_bytes);
       coding->dst_bytes = dst_bytes;
       coding->dst_multibyte = 0;
     }
@@ -8413,7 +8419,7 @@ encode_coding_object (struct coding_system *coding,
     Fkill_buffer (coding->src_object);
 
   Vdeactivate_mark = old_deactivate_mark;
-  unbind_to (count, Qnil);
+  dynwind_end ();
 }
 
 
@@ -8441,11 +8447,11 @@ from_unicode (Lisp_Object str)
 }
 
 Lisp_Object
-from_unicode_buffer (const wchar_twstr)
+from_unicode_buffer (const wchar_t *wstr)
 {
     return from_unicode (
         make_unibyte_string (
-            (char*) wstr,
+            (char *) wstr,
             /* we get one of the two final 0 bytes for free. */
             1 + sizeof (wchar_t) * wcslen (wstr)));
 }
@@ -8511,7 +8517,7 @@ are lower-case).  */)
   (Lisp_Object prompt, Lisp_Object default_coding_system)
 {
   Lisp_Object val;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
 
   if (SYMBOLP (default_coding_system))
     default_coding_system = SYMBOL_NAME (default_coding_system);
@@ -8519,7 +8525,7 @@ are lower-case).  */)
   val = Fcompleting_read (prompt, Vcoding_system_alist, Qnil,
                          Qt, Qnil, Qcoding_system_history,
                          default_coding_system, Qnil);
-  unbind_to (count, Qnil);
+  dynwind_end ();
   return (SCHARS (val) == 0 ? Qnil : Fintern (val, Qnil));
 }
 
@@ -9029,13 +9035,13 @@ DEFUN ("find-coding-systems-region-internal",
     p = pbeg = BYTE_POS_ADDR (start_byte);
   pend = p + (end_byte - start_byte);
 
-  while (p < pend && ASCII_BYTE_P (*p)) p++;
-  while (p < pend && ASCII_BYTE_P (*(pend - 1))) pend--;
+  while (p < pend && ASCII_CHAR_P (*p)) p++;
+  while (p < pend && ASCII_CHAR_P (*(pend - 1))) pend--;
 
   work_table = Fmake_char_table (Qnil, Qnil);
   while (p < pend)
     {
-      if (ASCII_BYTE_P (*p))
+      if (ASCII_CHAR_P (*p))
        p++;
       else
        {
@@ -9089,8 +9095,7 @@ DEFUN ("find-coding-systems-region-internal",
 
 DEFUN ("unencodable-char-position", Funencodable_char_position,
        Sunencodable_char_position, 3, 5, 0,
-       doc: /*
-Return position of first un-encodable character in a region.
+       doc: /* Return position of first un-encodable character in a region.
 START and END specify the region and CODING-SYSTEM specifies the
 encoding to check.  Return nil if CODING-SYSTEM does encode the region.
 
@@ -9100,8 +9105,9 @@ list of positions.
 
 If optional 5th argument STRING is non-nil, it is a string to search
 for un-encodable characters.  In that case, START and END are indexes
-to the string.  */)
-  (Lisp_Object start, Lisp_Object end, Lisp_Object coding_system, Lisp_Object count, Lisp_Object string)
+to the string and treated as in `substring'.  */)
+  (Lisp_Object start, Lisp_Object end, Lisp_Object coding_system,
+   Lisp_Object count, Lisp_Object string)
 {
   EMACS_INT n;
   struct coding_system coding;
@@ -9138,12 +9144,7 @@ to the string.  */)
   else
     {
       CHECK_STRING (string);
-      CHECK_NATNUM (start);
-      CHECK_NATNUM (end);
-      if (! (XINT (start) <= XINT (end) && XINT (end) <= SCHARS (string)))
-       args_out_of_range_3 (string, start, end);
-      from = XINT (start);
-      to = XINT (end);
+      validate_subarray (string, start, end, SCHARS (string), &from, &to);
       if (! STRING_MULTIBYTE (string))
        return Qnil;
       p = SDATA (string) + string_char_to_byte (string, from);
@@ -9167,7 +9168,7 @@ to the string.  */)
       int c;
 
       if (ascii_compatible)
-       while (p < stop && ASCII_BYTE_P (*p))
+       while (p < stop && ASCII_CHAR_P (*p))
          p++, from++;
       if (p >= stop)
        {
@@ -9283,12 +9284,12 @@ is nil.  */)
     p = pbeg = BYTE_POS_ADDR (start_byte);
   pend = p + (end_byte - start_byte);
 
-  while (p < pend && ASCII_BYTE_P (*p)) p++, pos++;
-  while (p < pend && ASCII_BYTE_P (*(pend - 1))) pend--;
+  while (p < pend && ASCII_CHAR_P (*p)) p++, pos++;
+  while (p < pend && ASCII_CHAR_P (*(pend - 1))) pend--;
 
   while (p < pend)
     {
-      if (ASCII_BYTE_P (*p))
+      if (ASCII_CHAR_P (*p))
        p++;
       else
        {
@@ -9596,7 +9597,7 @@ Return the corresponding character.  */)
   CHECK_CODING_SYSTEM_GET_SPEC (Vsjis_coding_system, spec);
   attrs = AREF (spec, 0);
 
-  if (ASCII_BYTE_P (ch)
+  if (ASCII_CHAR_P (ch)
       && ! NILP (CODING_ATTR_ASCII_COMPAT (attrs)))
     return code;
 
@@ -9677,7 +9678,7 @@ Return the corresponding character.  */)
   CHECK_CODING_SYSTEM_GET_SPEC (Vbig5_coding_system, spec);
   attrs = AREF (spec, 0);
 
-  if (ASCII_BYTE_P (ch)
+  if (ASCII_CHAR_P (ch)
       && ! NILP (CODING_ATTR_ASCII_COMPAT (attrs)))
     return code;
 
@@ -10797,6 +10798,8 @@ init_coding_once (void)
 void
 syms_of_coding (void)
 {
+#include "coding.x"
+
   staticpro (&Vcoding_system_hash_table);
   {
     Lisp_Object args[2];
@@ -10958,39 +10961,6 @@ syms_of_coding (void)
   DEFSYM (Qinterrupted, "interrupted");
   DEFSYM (Qcoding_system_define_form, "coding-system-define-form");
 
-  defsubr (&Scoding_system_p);
-  defsubr (&Sread_coding_system);
-  defsubr (&Sread_non_nil_coding_system);
-  defsubr (&Scheck_coding_system);
-  defsubr (&Sdetect_coding_region);
-  defsubr (&Sdetect_coding_string);
-  defsubr (&Sfind_coding_systems_region_internal);
-  defsubr (&Sunencodable_char_position);
-  defsubr (&Scheck_coding_systems_region);
-  defsubr (&Sdecode_coding_region);
-  defsubr (&Sencode_coding_region);
-  defsubr (&Sdecode_coding_string);
-  defsubr (&Sencode_coding_string);
-  defsubr (&Sdecode_sjis_char);
-  defsubr (&Sencode_sjis_char);
-  defsubr (&Sdecode_big5_char);
-  defsubr (&Sencode_big5_char);
-  defsubr (&Sset_terminal_coding_system_internal);
-  defsubr (&Sset_safe_terminal_coding_system_internal);
-  defsubr (&Sterminal_coding_system);
-  defsubr (&Sset_keyboard_coding_system_internal);
-  defsubr (&Skeyboard_coding_system);
-  defsubr (&Sfind_operation_coding_system);
-  defsubr (&Sset_coding_system_priority);
-  defsubr (&Sdefine_coding_system_internal);
-  defsubr (&Sdefine_coding_system_alias);
-  defsubr (&Scoding_system_put);
-  defsubr (&Scoding_system_base);
-  defsubr (&Scoding_system_plist);
-  defsubr (&Scoding_system_aliases);
-  defsubr (&Scoding_system_eol_type);
-  defsubr (&Scoding_system_priority_list);
-
   DEFVAR_LISP ("coding-system-list", Vcoding_system_list,
               doc: /* List of coding systems.