From: Dmitry Antipov Date: Tue, 15 Jan 2013 08:38:07 +0000 (+0400) Subject: Some convenient bits to deal with Lisp_Save_Values. X-Git-Tag: emacs-24.3.90~173^2~7^2~292 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=1b971ac155006504b6b1c2688199747f976723af;p=emacs.git 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. --- diff --git a/src/ChangeLog b/src/ChangeLog index 80f5875ef16..34c137a35c6 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,16 @@ +2013-01-15 Dmitry Antipov + + 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 Avoid needless casts with XSAVE_POINTER. diff --git a/src/alloc.c b/src/alloc.c index 3f1ccc82a58..e1cb97163ce 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -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 diff --git a/src/editfns.c b/src/editfns.c index feac17f64b8..3fe085caac8 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -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, diff --git a/src/lisp.h b/src/lisp.h index 7decd54c9d1..ac7346c5386 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -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);