]> git.eshelyaron.com Git - emacs.git/commitdiff
Some convenient bits to deal with Lisp_Save_Values.
authorDmitry Antipov <dmantipov@yandex.ru>
Tue, 15 Jan 2013 08:38:07 +0000 (12:38 +0400)
committerDmitry Antipov <dmantipov@yandex.ru>
Tue, 15 Jan 2013 08:38:07 +0000 (12:38 +0400)
* lisp.h (XSAVE_OBJECT): New macro to extract saved objects.
(allocate_misc): Remove prototype.
(format_save_value): New prototype.
* alloc.c (allocate_misc): Revert back to static.
(format_save_value): New function to build Lisp_Save_Value
object with the specified internal structure.
(make_save_value): Reimplement using format_save_value.
* editfns.c (save_excursion_save): Use format_save_value.
(save_excursion_restore): Use XSAVE_OBJECT.

src/ChangeLog
src/alloc.c
src/editfns.c
src/lisp.h

index 80f5875ef166dc70c814432b264e160c0c2c56d3..34c137a35c68c05a7df40ddd172f0f55a020fa94 100644 (file)
@@ -1,3 +1,16 @@
+2013-01-15  Dmitry Antipov  <dmantipov@yandex.ru>
+
+       Some convenient bits to deal with Lisp_Save_Values.
+       * lisp.h (XSAVE_OBJECT): New macro to extract saved objects.
+       (allocate_misc): Remove prototype.
+       (format_save_value): New prototype.
+       * alloc.c (allocate_misc): Revert back to static.
+       (format_save_value): New function to build Lisp_Save_Value
+       object with the specified internal structure.
+       (make_save_value): Reimplement using format_save_value.
+       * editfns.c (save_excursion_save): Use format_save_value.
+       (save_excursion_restore): Use XSAVE_OBJECT.
+
 2013-01-14  Paul Eggert  <eggert@cs.ucla.edu>
 
        Avoid needless casts with XSAVE_POINTER.
index 3f1ccc82a58a898b1da97970e3185721d2a21fa7..e1cb97163ce199e3229d34fd7b884797af031869 100644 (file)
@@ -3302,7 +3302,7 @@ static union Lisp_Misc *marker_free_list;
 
 /* Return a newly allocated Lisp_Misc object of specified TYPE.  */
 
-Lisp_Object
+static Lisp_Object
 allocate_misc (enum Lisp_Misc_Type type)
 {
   Lisp_Object val;
@@ -3350,6 +3350,59 @@ free_misc (Lisp_Object misc)
   total_free_markers++;
 }
 
+/* Return a Lisp_Save_Value object with the data saved according to
+   FMT.  Format specifiers are `i' for an integer, `p' for a pointer
+   and `o' for Lisp_Object.  Up to 4 objects can be specified.  */
+
+Lisp_Object
+format_save_value (const char *fmt, ...)
+{
+  va_list ap;
+  int len = strlen (fmt);
+  Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value);
+  struct Lisp_Save_Value *p = XSAVE_VALUE (val);
+
+  eassert (0 < len && len < 5);
+  va_start (ap, fmt);
+
+#define INITX(index)                                           \
+  do {                                                         \
+    if (len <= index)                                          \
+      p->type ## index = SAVE_UNUSED;                          \
+    else                                                       \
+      {                                                               \
+        if (fmt[index] == 'i')                                 \
+         {                                                     \
+           p->type ## index = SAVE_INTEGER;                    \
+           p->data[index].integer = va_arg (ap, ptrdiff_t);    \
+         }                                                     \
+       else if (fmt[index] == 'p')                             \
+         {                                                     \
+           p->type ## index = SAVE_POINTER;                    \
+           p->data[index].pointer = va_arg (ap, void *);       \
+         }                                                     \
+       else if (fmt[index] == 'o')                             \
+         {                                                     \
+           p->type ## index = SAVE_OBJECT;                     \
+           p->data[index].object = va_arg (ap, Lisp_Object);   \
+         }                                                     \
+       else                                                    \
+         emacs_abort ();                                       \
+      }                                                               \
+  } while (0)
+
+  INITX (0);
+  INITX (1);
+  INITX (2);
+  INITX (3);
+
+#undef INITX
+
+  va_end (ap);
+  p->area = 0;
+  return val;
+}
+
 /* Return a Lisp_Save_Value object containing POINTER and INTEGER.
    Most code should use this to package C integers and pointers
    to call record_unwind_protect.  The unwind function can get the
@@ -3358,18 +3411,7 @@ free_misc (Lisp_Object misc)
 Lisp_Object
 make_save_value (void *pointer, ptrdiff_t integer)
 {
-  register Lisp_Object val;
-  register struct Lisp_Save_Value *p;
-
-  val = allocate_misc (Lisp_Misc_Save_Value);
-  p = XSAVE_VALUE (val);
-  p->type0 = SAVE_POINTER;
-  p->data[0].pointer = pointer;
-  p->type1 = SAVE_INTEGER;
-  p->data[1].integer = integer;
-  p->type2 = p->type3 = SAVE_UNUSED;
-  p->area = 0;
-  return val;
+  return format_save_value ("pi", pointer, integer);
 }
 
 /* Free a Lisp_Save_Value object.  Do not use this function
index feac17f64b83cac0c8a26b23f39df551e7a7e00f..3fe085caac8de48c77010eb48623244e2a025c93 100644 (file)
@@ -833,31 +833,17 @@ This function does not move point.  */)
 Lisp_Object
 save_excursion_save (void)
 {
-  Lisp_Object save = allocate_misc (Lisp_Misc_Save_Value);
-  register struct Lisp_Save_Value *v = XSAVE_VALUE (save);
-
-  /* Do not allocate extra space and pack everything in SAVE.  */
-  v->area = 0;
-
-  v->type0 = SAVE_OBJECT;
-  v->data[0].object = Fpoint_marker ();
-
-  /* Do not copy the mark if it points to nowhere.  */
-  v->type1 = SAVE_OBJECT;
-  v->data[1].object = (XMARKER (BVAR (current_buffer, mark))->buffer
-                      ? Fcopy_marker (BVAR (current_buffer, mark), Qnil)
-                      : Qnil);
-
-  /* Selected window if current buffer is shown in it, nil otherwise.  */
-  v->type2 = SAVE_OBJECT;
-  v->data[2].object
-    = ((XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
-       ? selected_window : Qnil);
-
-  v->type3 = SAVE_OBJECT;
-  v->data[3].object = BVAR (current_buffer, mark_active);
-
-  return save;
+  return format_save_value
+    ("oooo",
+     Fpoint_marker (),
+     /* Do not copy the mark if it points to nowhere.  */
+     (XMARKER (BVAR (current_buffer, mark))->buffer
+      ? Fcopy_marker (BVAR (current_buffer, mark), Qnil)
+      : Qnil),
+     /* Selected window if current buffer is shown in it, nil otherwise.  */
+     ((XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
+      ? selected_window : Qnil),
+     BVAR (current_buffer, mark_active));
 }
 
 /* Restore saved buffer before leaving `save-excursion' special form.  */
@@ -867,13 +853,8 @@ save_excursion_restore (Lisp_Object info)
 {
   Lisp_Object tem, tem1, omark, nmark;
   struct gcpro gcpro1, gcpro2, gcpro3;
-  register struct Lisp_Save_Value *v = XSAVE_VALUE (info);
-
-  /* Paranoid.  */
-  eassert (v->type0 == SAVE_OBJECT && v->type1 == SAVE_OBJECT
-          && v->type2 == SAVE_OBJECT && v->type3 == SAVE_OBJECT);
 
-  tem = Fmarker_buffer (v->data[0].object);
+  tem = Fmarker_buffer (XSAVE_OBJECT (info, 0));
   /* If we're unwinding to top level, saved buffer may be deleted.  This
      means that all of its markers are unchained and so tem is nil.  */
   if (NILP (tem))
@@ -885,12 +866,12 @@ save_excursion_restore (Lisp_Object info)
   Fset_buffer (tem);
 
   /* Point marker.  */
-  tem = v->data[0].object;
+  tem = XSAVE_OBJECT (info, 0);
   Fgoto_char (tem);
   unchain_marker (XMARKER (tem));
 
   /* Mark marker.  */
-  tem = v->data[1].object;
+  tem = XSAVE_OBJECT (info, 1);
   omark = Fmarker_position (BVAR (current_buffer, mark));
   if (NILP (tem))
     unchain_marker (XMARKER (BVAR (current_buffer, mark)));
@@ -902,7 +883,7 @@ save_excursion_restore (Lisp_Object info)
     }
 
   /* Mark active.  */
-  tem = v->data[3].object;
+  tem = XSAVE_OBJECT (info, 3);
   tem1 = BVAR (current_buffer, mark_active);
   bset_mark_active (current_buffer, tem);
 
@@ -926,7 +907,7 @@ save_excursion_restore (Lisp_Object info)
   /* 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 = v->data[2].object;
+  tem = XSAVE_OBJECT (info, 2);
   if (WINDOWP (tem)
       && !EQ (tem, selected_window)
       && (tem1 = XWINDOW (tem)->buffer,
index 7decd54c9d1b08fc030351d6d34435bab3216a1a..ac7346c5386af3b73297980098dbe3a35914d200 100644 (file)
@@ -1421,6 +1421,12 @@ struct Lisp_Save_Value
 
 #define XSAVE_INTEGER(obj) XSAVE_VALUE (obj)->data[1].integer
 
+/* Macro to extract Nth saved object.  */
+
+#define XSAVE_OBJECT(obj, n)                                   \
+  (eassert (XSAVE_VALUE (obj)->type ## n == SAVE_OBJECT),      \
+   XSAVE_VALUE (obj)->data[n].object)
+
 /* A miscellaneous object, when it's on the free list.  */
 struct Lisp_Free
   {
@@ -2921,7 +2927,6 @@ extern void memory_warnings (void *, void (*warnfun) (const char *));
 
 /* Defined in alloc.c.  */
 extern void check_pure_size (void);
-extern Lisp_Object allocate_misc (enum Lisp_Misc_Type);
 extern void free_misc (Lisp_Object);
 extern void allocate_string_data (struct Lisp_String *, EMACS_INT, EMACS_INT);
 extern void malloc_warning (const char *);
@@ -3007,6 +3012,7 @@ extern bool abort_on_gc;
 extern Lisp_Object make_float (double);
 extern void display_malloc_warning (void);
 extern ptrdiff_t inhibit_garbage_collection (void);
+extern Lisp_Object format_save_value (const char *, ...);
 extern Lisp_Object make_save_value (void *, ptrdiff_t);
 extern void free_save_value (Lisp_Object);
 extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object);