Use BSET for write access to Lisp_Object members of struct buffer.
[bpt/emacs.git] / src / editfns.c
index 8b6c29b..60f61d0 100644 (file)
@@ -59,10 +59,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "window.h"
 #include "blockinput.h"
 
-#ifndef USER_FULL_NAME
-#define USER_FULL_NAME pw->pw_gecos
-#endif
-
 #ifndef USE_CRT_DLL
 extern char **environ;
 #endif
@@ -314,7 +310,7 @@ overlays_around (EMACS_INT pos, Lisp_Object *vec, ptrdiff_t len)
   ptrdiff_t startpos, endpos;
   ptrdiff_t idx = 0;
 
-  for (tail = current_buffer->overlays_before; tail; tail = tail->next)
+  for (tail = buffer_get_overlays (NULL, OV_BEFORE); tail; tail = tail->next)
     {
       XSETMISC (overlay, tail);
 
@@ -333,7 +329,7 @@ overlays_around (EMACS_INT pos, Lisp_Object *vec, ptrdiff_t len)
        }
     }
 
-  for (tail = current_buffer->overlays_after; tail; tail = tail->next)
+  for (tail = buffer_get_overlays (NULL, OV_AFTER); tail; tail = tail->next)
     {
       XSETMISC (overlay, tail);
 
@@ -821,104 +817,104 @@ This function does not move point.  */)
                              Qnil, Qt, Qnil);
 }
 
-/* Record buffer state before entering Fsave_excursion. */
-
+\f
 Lisp_Object
 save_excursion_save (void)
 {
-  Lisp_Object excursion;
-  struct buffer *b = current_buffer;
-  struct window *w = XWINDOW (selected_window);
-  struct Lisp_Excursion *ex = xmalloc (sizeof *ex);
-  struct Lisp_Marker *m = XMARKER (BVAR (b, mark));
-
-  ex->size = 0;
-  ex->buffer = b;
-  ex->window = w;
-  ex->visible = (XBUFFER (w->buffer) == b);
-  ex->active = !NILP (BVAR (b, mark_active));
-
-  /* We do not initialize type and gcmarkbit since this marker
-     is never referenced via Lisp_Object and invisible for GC.  */
-  init_marker (&ex->point, b, PT, PT_BYTE, 0);
-
-  /* Likewise.  Note that charpos and bytepos may be zero.  */
-  init_marker (&ex->mark, m->buffer, m->charpos, 
-              m->bytepos, m->insertion_type);
-
-  /* Make it a pseudovector and return excursion object.  */
-  XSETTYPED_PVECTYPE (ex, size, PVEC_EXCURSION);
-  XSETEXCURSION (excursion, ex);
-  return excursion;
+  int visible = (XBUFFER (XWINDOW (selected_window)->buffer)
+                == current_buffer);
+
+  return Fcons (Fpoint_marker (),
+               Fcons (Fcopy_marker (BVAR (current_buffer, mark), Qnil),
+                      Fcons (visible ? Qt : Qnil,
+                             Fcons (BVAR (current_buffer, mark_active),
+                                    selected_window))));
 }
 
-/* Restore buffer state before leaving Fsave_excursion.  */
-
 Lisp_Object
-save_excursion_restore (Lisp_Object obj)
+save_excursion_restore (Lisp_Object info)
 {
-  struct Lisp_Excursion *ex = XEXCURSION (obj);
-  struct buffer *b = ex->buffer;
-
-  eassert (b != NULL);
-  eassert (ex->window != NULL);
-
-  /* Restore buffer state only if the buffer is live.
-     Otherwise, just cancel an excursion state.  */
+  Lisp_Object tem, tem1, omark, nmark;
+  struct gcpro gcpro1, gcpro2, gcpro3;
+  int visible_p;
+
+  tem = Fmarker_buffer (XCAR (info));
+  /* If buffer being returned to is now deleted, avoid error */
+  /* Otherwise could get error here while unwinding to top level
+     and crash */
+  /* In that case, Fmarker_buffer returns nil now.  */
+  if (NILP (tem))
+    return Qnil;
 
-  if (!NILP (BVAR (b, name)))
+  omark = nmark = Qnil;
+  GCPRO3 (info, omark, nmark);
+
+  Fset_buffer (tem);
+
+  /* Point marker.  */
+  tem = XCAR (info);
+  Fgoto_char (tem);
+  unchain_marker (XMARKER (tem));
+
+  /* Mark marker.  */
+  info = XCDR (info);
+  tem = XCAR (info);
+  omark = Fmarker_position (BVAR (current_buffer, mark));
+  Fset_marker (BVAR (current_buffer, mark), tem, Fcurrent_buffer ());
+  nmark = Fmarker_position (tem);
+  unchain_marker (XMARKER (tem));
+
+  /* visible */
+  info = XCDR (info);
+  visible_p = !NILP (XCAR (info));
+
+#if 0 /* We used to make the current buffer visible in the selected window
+        if that was true previously.  That avoids some anomalies.
+        But it creates others, and it wasn't documented, and it is simpler
+        and cleaner never to alter the window/buffer connections.  */
+  tem1 = Fcar (tem);
+  if (!NILP (tem1)
+      && current_buffer != XBUFFER (XWINDOW (selected_window)->buffer))
+    Fswitch_to_buffer (Fcurrent_buffer (), Qnil);
+#endif /* 0 */
+
+  /* Mark active */
+  info = XCDR (info);
+  tem = XCAR (info);
+  tem1 = BVAR (current_buffer, mark_active);
+  BSET (current_buffer, mark_active, tem);
+
+  /* If mark is active now, and either was not active
+     or was at a different place, run the activate hook.  */
+  if (! NILP (tem))
     {
-      int active;
-      struct Lisp_Marker *m;
-      ptrdiff_t oldpos, newpos;
-
-      /* Restore current buffer.  */
-      set_buffer_internal (b);
-
-      /* Restore buffer position.  */
-      SET_PT_BOTH (clip_to_bounds (BEGV, ex->point.charpos, ZV),
-                  clip_to_bounds (BEGV_BYTE, ex->point.bytepos, ZV_BYTE));
-      unchain_marker (&ex->point);
-
-      /* Restore mark if it was non-zero.  */
-      m = XMARKER (BVAR (b, mark));
-      oldpos = m->charpos;
-      if (BEGV <= ex->mark.charpos)
-       attach_marker (m, b, ex->mark.charpos, ex->mark.bytepos);
-      newpos = ex->mark.charpos;
-      unchain_marker (&ex->mark);
-
-      /* If mark and region was active, restore them.  */
-      active = !NILP (BVAR (b, mark_active));
-      BVAR (b, mark_active) = ex->active ? Qt : Qnil;
-
-      /* If mark is active now, and either was not active
-        or was at a different place, run the activate hook.  */
-      if (ex->active && oldpos != newpos)
-       {
-         obj = intern ("activate-mark-hook");
-         Frun_hooks (1, &obj);
-       }
-      /* If mark has ceased to be active, run deactivate hook.  */
-      else if (active)
-       {
-         obj = intern ("deactivate-mark-hook");
-         Frun_hooks (1, &obj);
-       }
-
-      /* If buffer was visible in a window, and a different window
-        was selected, and the old selected window is still showing
-        this buffer, restore point in that window.  */
-      if (ex->visible)
-       {
-         struct window *w = ex->window;
-
-         if (w != XWINDOW (selected_window) && XBUFFER (w->buffer) == b)
-           attach_marker (XMARKER (w->pointm), b, PT, PT_BYTE);
-       }
+      if (! EQ (omark, nmark))
+        {
+          tem = intern ("activate-mark-hook");
+          Frun_hooks (1, &tem);
+        }
+    }
+  /* If mark has ceased to be active, run deactivate hook.  */
+  else if (! NILP (tem1))
+    {
+      tem = intern ("deactivate-mark-hook");
+      Frun_hooks (1, &tem);
     }
 
-  xfree (ex);
+  /* If buffer was visible in a window, and a different window was
+     selected, and the old selected window is still showing this
+     buffer, restore point in that window.  */
+  tem = XCDR (info);
+  if (visible_p
+      && !EQ (tem, selected_window)
+      && (tem1 = XWINDOW (tem)->buffer,
+         (/* Window is live...  */
+          BUFFERP (tem1)
+          /* ...and it shows the current buffer.  */
+          && XBUFFER (tem1) == current_buffer)))
+    Fset_window_point (tem, make_number (PT));
+
+  UNGCPRO;
   return Qnil;
 }
 
@@ -1797,7 +1793,7 @@ format_time_string (char const *format, ptrdiff_t formatlen,
       if (STRING_BYTES_BOUND <= len)
        string_overflow ();
       size = len + 1;
-      SAFE_ALLOCA (buf, char *, size);
+      buf = SAFE_ALLOCA (size);
     }
 
   UNBLOCK_INPUT;
@@ -2076,7 +2072,7 @@ the data it can't find.  */)
          int m = offset / 60;
          int am = offset < 0 ? - m : m;
          char buf[sizeof "+00" + INT_STRLEN_BOUND (int)];
-         zone_name = make_formatted_string (buf, "%c%02d%02d", 
+         zone_name = make_formatted_string (buf, "%c%02d%02d",
                                             (offset < 0 ? '-' : '+'),
                                             am / 60, am % 60);
        }
@@ -2820,13 +2816,13 @@ determines whether case is significant or ignored.  */)
 static Lisp_Object
 subst_char_in_region_unwind (Lisp_Object arg)
 {
-  return BVAR (current_buffer, undo_list) = arg;
+  return BSET (current_buffer, undo_list, arg);
 }
 
 static Lisp_Object
 subst_char_in_region_unwind_1 (Lisp_Object arg)
 {
-  return BVAR (current_buffer, filename) = arg;
+  return BSET (current_buffer, filename, arg);
 }
 
 DEFUN ("subst-char-in-region", Fsubst_char_in_region,
@@ -2900,11 +2896,11 @@ Both characters must have the same length of multi-byte form.  */)
     {
       record_unwind_protect (subst_char_in_region_unwind,
                             BVAR (current_buffer, undo_list));
-      BVAR (current_buffer, undo_list) = Qt;
+      BSET (current_buffer, undo_list, Qt);
       /* Don't do file-locking.  */
       record_unwind_protect (subst_char_in_region_unwind_1,
                             BVAR (current_buffer, filename));
-      BVAR (current_buffer, filename) = Qnil;
+      BSET (current_buffer, filename, Qnil);
     }
 
   if (pos_byte < GPT_BYTE)
@@ -2986,7 +2982,7 @@ Both characters must have the same length of multi-byte form.  */)
                INC_POS (pos_byte_next);
 
              if (! NILP (noundo))
-               BVAR (current_buffer, undo_list) = tem;
+               BSET (current_buffer, undo_list, tem);
 
              UNGCPRO;
            }
@@ -3690,7 +3686,7 @@ usage: (format STRING &rest OBJECTS)  */)
     ptrdiff_t i;
     if ((SIZE_MAX - formatlen) / sizeof (struct info) <= nargs)
       memory_full (SIZE_MAX);
-    SAFE_ALLOCA (info, struct info *, (nargs + 1) * sizeof *info + formatlen);
+    info = SAFE_ALLOCA ((nargs + 1) * sizeof *info + formatlen);
     discarded = (char *) &info[nargs + 1];
     for (i = 0; i < nargs + 1; i++)
       {
@@ -3937,7 +3933,7 @@ usage: (format STRING &rest OBJECTS)  */)
 
                  /* If this argument has text properties, record where
                     in the result string it appears.  */
-                 if (STRING_INTERVALS (args[n]))
+                 if (string_get_intervals (args[n]))
                    info[n].intervals = arg_intervals = 1;
 
                  continue;
@@ -4281,7 +4277,7 @@ usage: (format STRING &rest OBJECTS)  */)
      arguments has text properties, set up text properties of the
      result string.  */
 
-  if (STRING_INTERVALS (args[0]) || arg_intervals)
+  if (string_get_intervals (args[0]) || arg_intervals)
     {
       Lisp_Object len, new_len, props;
       struct gcpro gcpro1;
@@ -4531,7 +4527,7 @@ Transposing beyond buffer boundaries is an error.  */)
   Lisp_Object buf;
 
   XSETBUFFER (buf, current_buffer);
-  cur_intv = BUF_INTERVALS (current_buffer);
+  cur_intv = buffer_get_intervals (current_buffer);
 
   validate_region (&startr1, &endr1);
   validate_region (&startr2, &endr2);
@@ -4641,7 +4637,7 @@ Transposing beyond buffer boundaries is an error.  */)
       /* Don't use Fset_text_properties: that can cause GC, which can
         clobber objects stored in the tmp_intervals.  */
       tmp_interval3 = validate_interval_range (buf, &startr1, &endr2, 0);
-      if (!NULL_INTERVAL_P (tmp_interval3))
+      if (tmp_interval3)
        set_text_properties_1 (startr1, endr2, Qnil, buf, tmp_interval3);
 
       /* First region smaller than second.  */
@@ -4649,7 +4645,7 @@ Transposing beyond buffer boundaries is an error.  */)
         {
          USE_SAFE_ALLOCA;
 
-         SAFE_ALLOCA (temp, unsigned char *, len2_byte);
+         temp = SAFE_ALLOCA (len2_byte);
 
          /* Don't precompute these addresses.  We have to compute them
             at the last minute, because the relocating allocator might
@@ -4667,7 +4663,7 @@ Transposing beyond buffer boundaries is an error.  */)
         {
          USE_SAFE_ALLOCA;
 
-         SAFE_ALLOCA (temp, unsigned char *, len1_byte);
+         temp = SAFE_ALLOCA (len1_byte);
          start1_addr = BYTE_POS_ADDR (start1_byte);
          start2_addr = BYTE_POS_ADDR (start2_byte);
           memcpy (temp, start1_addr, len1_byte);
@@ -4700,14 +4696,14 @@ Transposing beyond buffer boundaries is an error.  */)
           tmp_interval2 = copy_intervals (cur_intv, start2, len2);
 
          tmp_interval3 = validate_interval_range (buf, &startr1, &endr1, 0);
-         if (!NULL_INTERVAL_P (tmp_interval3))
+         if (tmp_interval3)
            set_text_properties_1 (startr1, endr1, Qnil, buf, tmp_interval3);
 
          tmp_interval3 = validate_interval_range (buf, &startr2, &endr2, 0);
-         if (!NULL_INTERVAL_P (tmp_interval3))
+         if (tmp_interval3)
            set_text_properties_1 (startr2, endr2, Qnil, buf, tmp_interval3);
 
-         SAFE_ALLOCA (temp, unsigned char *, len1_byte);
+         temp = SAFE_ALLOCA (len1_byte);
          start1_addr = BYTE_POS_ADDR (start1_byte);
          start2_addr = BYTE_POS_ADDR (start2_byte);
           memcpy (temp, start1_addr, len1_byte);
@@ -4733,11 +4729,11 @@ Transposing beyond buffer boundaries is an error.  */)
           tmp_interval2 = copy_intervals (cur_intv, start2, len2);
 
          tmp_interval3 = validate_interval_range (buf, &startr1, &endr2, 0);
-         if (!NULL_INTERVAL_P (tmp_interval3))
+         if (tmp_interval3)
            set_text_properties_1 (startr1, endr2, Qnil, buf, tmp_interval3);
 
          /* holds region 2 */
-         SAFE_ALLOCA (temp, unsigned char *, len2_byte);
+         temp = SAFE_ALLOCA (len2_byte);
          start1_addr = BYTE_POS_ADDR (start1_byte);
          start2_addr = BYTE_POS_ADDR (start2_byte);
           memcpy (temp, start2_addr, len2_byte);
@@ -4766,11 +4762,11 @@ Transposing beyond buffer boundaries is an error.  */)
           tmp_interval2 = copy_intervals (cur_intv, start2, len2);
 
          tmp_interval3 = validate_interval_range (buf, &startr1, &endr2, 0);
-         if (!NULL_INTERVAL_P (tmp_interval3))
+         if (tmp_interval3)
            set_text_properties_1 (startr1, endr2, Qnil, buf, tmp_interval3);
 
          /* holds region 1 */
-         SAFE_ALLOCA (temp, unsigned char *, len1_byte);
+         temp = SAFE_ALLOCA (len1_byte);
          start1_addr = BYTE_POS_ADDR (start1_byte);
          start2_addr = BYTE_POS_ADDR (start2_byte);
           memcpy (temp, start1_addr, len1_byte);