update.
[chise/xemacs-chise.git-] / src / insdel.c
index 7a7c3f9..90efb77 100644 (file)
@@ -1633,7 +1633,7 @@ static void
 adjust_markers (struct buffer *buf, Memind from, Memind to,
                Bytecount amount)
 {
-  struct Lisp_Marker *m;
+  Lisp_Marker *m;
 
   for (m = BUF_MARKERS (buf); m; m = marker_next (m))
     m->memind = do_marker_adjustment (m->memind, from, to, amount);
@@ -1645,7 +1645,7 @@ adjust_markers (struct buffer *buf, Memind from, Memind to,
 static void
 adjust_markers_for_insert (struct buffer *buf, Memind ind, Bytecount amount)
 {
-  struct Lisp_Marker *m;
+  Lisp_Marker *m;
 
   for (m = BUF_MARKERS (buf); m; m = marker_next (m))
     {
@@ -1659,18 +1659,6 @@ adjust_markers_for_insert (struct buffer *buf, Memind ind, Bytecount amount)
 /*                  Routines for dealing with the gap                   */
 /************************************************************************/
 
-/* XEmacs requires an ANSI C compiler, and it damn well better have a
-   working memmove() */
-#define GAP_USE_BCOPY
-#ifdef BCOPY_UPWARD_SAFE
-# undef BCOPY_UPWARD_SAFE
-#endif
-#ifdef BCOPY_DOWNWARD_SAFE
-# undef BCOPY_DOWNWARD_SAFE
-#endif
-#define BCOPY_UPWARD_SAFE 1
-#define BCOPY_DOWNWARD_SAFE 1
-
 /* maximum amount of memory moved in a single chunk.  Increasing this
    value improves gap-motion efficiency but decreases QUIT responsiveness
    time.  Was 32000 but today's processors are faster and files are
@@ -1711,23 +1699,15 @@ gap_left (struct buffer *buf, Bytind pos)
       /* Move at most GAP_MOVE_CHUNK chars before checking again for a quit. */
       if (i > GAP_MOVE_CHUNK)
        i = GAP_MOVE_CHUNK;
-#ifdef GAP_USE_BCOPY
-      if (i >= 128
-         /* bcopy is safe if the two areas of memory do not overlap
-            or on systems where bcopy is always safe for moving upward.  */
-         && (BCOPY_UPWARD_SAFE
-             || to - from >= 128))
+
+      if (i >= 128)
        {
-         /* If overlap is not safe, avoid it by not moving too many
-            characters at once.  */
-         if (!BCOPY_UPWARD_SAFE && i > to - from)
-           i = to - from;
          new_s1 -= i;
-         from -= i, to -= i;
+         from   -= i;
+         to     -= i;
          memmove (to, from, i);
        }
       else
-#endif
        {
          new_s1 -= i;
          while (--i >= 0)
@@ -1790,23 +1770,15 @@ gap_right (struct buffer *buf, Bytind pos)
       /* Move at most GAP_MOVE_CHUNK chars before checking again for a quit. */
       if (i > GAP_MOVE_CHUNK)
        i = GAP_MOVE_CHUNK;
-#ifdef GAP_USE_BCOPY
-      if (i >= 128
-         /* bcopy is safe if the two areas of memory do not overlap
-            or on systems where bcopy is always safe for moving downward. */
-         && (BCOPY_DOWNWARD_SAFE
-             || from - to >= 128))
+
+      if (i >= 128)
        {
-         /* If overlap is not safe, avoid it by not moving too many
-            characters at once.  */
-         if (!BCOPY_DOWNWARD_SAFE && i > from - to)
-           i = from - to;
          new_s1 += i;
          memmove (to, from, i);
-         from += i, to += i;
+         from += i;
+         to   += i;
        }
       else
-#endif
        {
          new_s1 += i;
          while (--i >= 0)
@@ -2085,7 +2057,12 @@ multiple_change_finish_up (Lisp_Object buffer)
    of the specified region, that will also be handled correctly.
 
    begin_multiple_change() returns a number (actually a specpdl depth)
-   that you must pass to end_multiple_change() when you are done. */
+   that you must pass to end_multiple_change() when you are done.
+
+   FSF Emacs 20 implements a similar feature, accessible from Lisp
+   through a `combine-after-change-calls' special form, which is
+   essentially equivalent to this function.  We should consider
+   whether we want to introduce a similar Lisp form.  */
 
 int
 begin_multiple_change (struct buffer *buf, Bufpos start, Bufpos end)
@@ -2133,7 +2110,8 @@ change_function_restore (Lisp_Object buffer)
   /* We should first reset the variable and then change the buffer,
      because Fset_buffer() can throw.  */
   inside_change_hook = 0;
-  Fset_buffer (buffer);
+  if (XBUFFER (buffer) != current_buffer)
+    Fset_buffer (buffer);
   return Qnil;
 }
 
@@ -2183,6 +2161,7 @@ signal_before_change (struct buffer *buf, Bufpos start, Bufpos end)
   if (!inside_change_hook)
     {
       Lisp_Object buffer;
+      int speccount;
 
       /* Are we in a multiple-change session? */
       if (buf->text->changes->in_multiple_change &&
@@ -2220,6 +2199,9 @@ signal_before_change (struct buffer *buf, Bufpos start, Bufpos end)
        }
 
       /* Now in any case run the before-change-functions if any.  */
+      speccount = specpdl_depth ();
+      record_unwind_protect (change_function_restore, Fcurrent_buffer ());
+      inside_change_hook = 1;
 
       MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
        {
@@ -2228,25 +2210,28 @@ signal_before_change (struct buffer *buf, Bufpos start, Bufpos end)
              /* Obsolete, for compatibility */
              || !NILP (symbol_value_in_buffer (Qbefore_change_function, buffer)))
            {
-             int speccount = specpdl_depth ();
-             record_unwind_protect (change_function_restore, Fcurrent_buffer ());
              set_buffer_internal (buf);
-             inside_change_hook = 1;
              va_run_hook_with_args (Qbefore_change_functions, 2,
                                     make_int (start), make_int (end));
              /* Obsolete, for compatibility */
              va_run_hook_with_args (Qbefore_change_function, 2,
                                     make_int (start), make_int (end));
-             unbind_to (speccount, Qnil);
            }
        }
 
+      /* Make sure endpoints remain valid.  before-change-functions
+        might have modified the buffer. */
+      if (start < BUF_BEGV (buf)) start = BUF_BEGV (buf);
+      if (start > BUF_ZV (buf))   start = BUF_ZV (buf);
+      if (end < BUF_BEGV (buf)) end = BUF_BEGV (buf);
+      if (end > BUF_ZV (buf))   end = BUF_ZV (buf);
+
       MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
        {
          XSETBUFFER (buffer, mbuf);
-         report_extent_modification (buffer, start, end,
-                                     &inside_change_hook, 0);
+         report_extent_modification (buffer, start, end, 0);
        }
+      unbind_to (speccount, Qnil);
 
       /* Only now do we indicate that the before-change-functions have
         been called, in case some function throws out. */
@@ -2283,6 +2268,7 @@ signal_after_change (struct buffer *buf, Bufpos start, Bufpos orig_end,
   if (!inside_change_hook)
     {
       Lisp_Object buffer;
+      int speccount;
 
       if (buf->text->changes->in_multiple_change &&
          buf->text->changes->mc_begin != 0)
@@ -2295,6 +2281,9 @@ signal_after_change (struct buffer *buf, Bufpos start, Bufpos orig_end,
          return; /* after-change-functions signalled when all changes done */
        }
 
+      speccount = specpdl_depth ();
+      record_unwind_protect (change_function_restore, Fcurrent_buffer ());
+      inside_change_hook = 1;
       MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
        {
          XSETBUFFER (buffer, mbuf);
@@ -2303,10 +2292,7 @@ signal_after_change (struct buffer *buf, Bufpos start, Bufpos orig_end,
              /* Obsolete, for compatibility */
              || !NILP (symbol_value_in_buffer (Qafter_change_function, buffer)))
            {
-             int speccount = specpdl_depth ();
-             record_unwind_protect (change_function_restore, Fcurrent_buffer ());
              set_buffer_internal (buf);
-             inside_change_hook = 1;
              /* The actual after-change functions take slightly
                 different arguments than what we were passed. */
              va_run_hook_with_args (Qafter_change_functions, 3,
@@ -2316,16 +2302,24 @@ signal_after_change (struct buffer *buf, Bufpos start, Bufpos orig_end,
              va_run_hook_with_args (Qafter_change_function, 3,
                                     make_int (start), make_int (new_end),
                                     make_int (orig_end - start));
-             unbind_to (speccount, Qnil);
            }
        }
 
+      /* Make sure endpoints remain valid.  after-change-functions
+        might have modified the buffer. */
+      if (start < BUF_BEGV (buf)) start = BUF_BEGV (buf);
+      if (start > BUF_ZV (buf))   start = BUF_ZV (buf);
+      if (new_end < BUF_BEGV (buf)) new_end = BUF_BEGV (buf);
+      if (new_end > BUF_ZV (buf))   new_end = BUF_ZV (buf);
+      if (orig_end < BUF_BEGV (buf)) orig_end = BUF_BEGV (buf);
+      if (orig_end > BUF_ZV (buf))   orig_end = BUF_ZV (buf);
+
       MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
        {
          XSETBUFFER (buffer, mbuf);
-         report_extent_modification (buffer, start, new_end,
-                                     &inside_change_hook, 1);
+         report_extent_modification (buffer, start, new_end, 1);
        }
+      unbind_to (speccount, Qnil); /* sets inside_change_hook back to 0 */
     }
 }
 
@@ -3107,7 +3101,7 @@ barf_if_buffer_read_only (struct buffer *buf, Bufpos from, Bufpos to)
 }
 
 void
-find_charsets_in_bufbyte_string (unsigned char *charsets, CONST Bufbyte *str,
+find_charsets_in_bufbyte_string (Charset_ID *charsets, CONST Bufbyte *str,
                                 Bytecount len)
 {
 #ifndef MULE
@@ -3115,18 +3109,25 @@ find_charsets_in_bufbyte_string (unsigned char *charsets, CONST Bufbyte *str,
   charsets[0] = 1;
 #else
   CONST Bufbyte *strend = str + len;
-  memset (charsets, 0, NUM_LEADING_BYTES);
+  memset (charsets, 0, NUM_LEADING_BYTES * sizeof(Charset_ID));
 
   while (str < strend)
     {
-      charsets[CHAR_LEADING_BYTE (charptr_emchar (str)) - 128] = 1;
+#ifdef UTF2000
+      charsets[CHAR_CHARSET_ID (charptr_emchar (str))
+             - MIN_LEADING_BYTE] = 1;
+#else /* I'm not sure the definition for UTF2000 works with leading-byte
+        representation. */
+      charsets[CHAR_LEADING_BYTE (charptr_emchar (str))
+             - MIN_LEADING_BYTE] = 1;
+#endif
       INC_CHARPTR (str);
     }
 #endif
 }
 
 void
-find_charsets_in_emchar_string (unsigned char *charsets, CONST Emchar *str,
+find_charsets_in_emchar_string (Charset_ID *charsets, CONST Emchar *str,
                                Charcount len)
 {
 #ifndef MULE
@@ -3135,10 +3136,15 @@ find_charsets_in_emchar_string (unsigned char *charsets, CONST Emchar *str,
 #else
   int i;
 
-  memset (charsets, 0, NUM_LEADING_BYTES);
+  memset (charsets, 0, NUM_LEADING_BYTES * sizeof(Charset_ID));
   for (i = 0; i < len; i++)
     {
-      charsets[CHAR_LEADING_BYTE (str[i]) - 128] = 1;
+#ifdef UTF2000
+      charsets[CHAR_CHARSET_ID (str[i]) - MIN_LEADING_BYTE] = 1;
+#else /* I'm not sure the definition for UTF2000 works with leading-byte
+        representation. */
+      charsets[CHAR_LEADING_BYTE (str[i]) - MIN_LEADING_BYTE] = 1;
+#endif
     }
 #endif
 }
@@ -3153,7 +3159,7 @@ bufbyte_string_displayed_columns (CONST Bufbyte *str, Bytecount len)
     {
 #ifdef MULE
       Emchar ch = charptr_emchar (str);
-      cols += XCHARSET_COLUMNS (CHAR_CHARSET (ch));
+      cols += CHAR_COLUMNS (ch);
 #else
       cols++;
 #endif
@@ -3171,7 +3177,7 @@ emchar_string_displayed_columns (CONST Emchar *str, Charcount len)
   int i;
 
   for (i = 0; i < len; i++)
-    cols += XCHARSET_COLUMNS (CHAR_CHARSET (str[i]));
+    cols += CHAR_COLUMNS (str[i]);
 
   return cols;
 #else  /* not MULE */
@@ -3262,9 +3268,11 @@ convert_emchar_string_into_malloced_string (Emchar *arr, int nels,
 /************************************************************************/
 
 void
-vars_of_insdel (void)
+reinit_vars_of_insdel (void)
 {
+#ifndef UTF2000
   int i;
+#endif
 
   inside_change_hook = 0;
   in_first_change = 0;
@@ -3276,6 +3284,12 @@ vars_of_insdel (void)
 }
 
 void
+vars_of_insdel (void)
+{
+  reinit_vars_of_insdel ();
+}
+
+void
 init_buffer_text (struct buffer *b)
 {
   if (!b->base_buffer)