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.
This commit is contained in:
parent
cb9c0a53bc
commit
1b971ac155
4 changed files with 91 additions and 49 deletions
|
@ -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.
|
||||
|
|
68
src/alloc.c
68
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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue