Commit d17337e5 authored by Dmitry Antipov's avatar Dmitry Antipov

New macro to iterate over all buffers, miscellaneous cleanups.

* lisp.h (all_buffers): Remove declaration.
* buffer.h (all_buffers): Add declaration, with comment.
(for_each_buffer): New macro.
* alloc.c (Fgarbage_collect, mark_object): Use it.
* buffer.c (Fkill_buffer, Fbuffer_swap_text, Fset_buffer_multibyte)
(init_buffer): Likewise.
* data.c (Fset_default): Likewise.
* coding.c (code_conversion_restore): Remove redundant check
for dead buffer.
* buffer.c (Fkill_buffer): Likewise.  Remove obsolete comment.
parent 1d29cc7d
2012-07-19 Dmitry Antipov <dmantipov@yandex.ru>
New macro to iterate over all buffers, miscellaneous cleanups.
* lisp.h (all_buffers): Remove declaration.
* buffer.h (all_buffers): Add declaration, with comment.
(for_each_buffer): New macro.
* alloc.c (Fgarbage_collect, mark_object): Use it.
* buffer.c (Fkill_buffer, Fbuffer_swap_text, Fset_buffer_multibyte)
(init_buffer): Likewise.
* data.c (Fset_default): Likewise.
* coding.c (code_conversion_restore): Remove redundant check
for dead buffer.
* buffer.c (Fkill_buffer): Likewise. Remove obsolete comment.
2012-07-18 Andreas Schwab <schwab@linux-m68k.org>
Fix bug that created negative-length intervals.
......@@ -110,7 +124,6 @@
* gnutls.c (emacs_gnutls_handshake): Only retry if
GNUTLS_E_INTERRUPTED.
2012-07-17 Eli Zaretskii <eliz@gnu.org>
2012-07-17 Dmitry Antipov <dmantipov@yandex.ru>
Cleanup and convert miscellaneous checks to eassert.
......
......@@ -5392,6 +5392,7 @@ See Info node `(elisp)Garbage Collection'. */)
(void)
{
register struct specbinding *bind;
register struct buffer *nextb;
char stack_top_variable;
ptrdiff_t i;
int message_p;
......@@ -5411,40 +5412,34 @@ See Info node `(elisp)Garbage Collection'. */)
/* Don't keep undo information around forever.
Do this early on, so it is no problem if the user quits. */
{
register struct buffer *nextb = all_buffers;
while (nextb)
{
/* If a buffer's undo list is Qt, that means that undo is
turned off in that buffer. Calling truncate_undo_list on
Qt tends to return NULL, which effectively turns undo back on.
So don't call truncate_undo_list if undo_list is Qt. */
if (! NILP (nextb->BUFFER_INTERNAL_FIELD (name))
&& ! EQ (nextb->BUFFER_INTERNAL_FIELD (undo_list), Qt))
truncate_undo_list (nextb);
/* Shrink buffer gaps, but skip indirect and dead buffers. */
if (nextb->base_buffer == 0 && !NILP (nextb->BUFFER_INTERNAL_FIELD (name))
&& ! nextb->text->inhibit_shrinking)
{
/* If a buffer's gap size is more than 10% of the buffer
size, or larger than 2000 bytes, then shrink it
accordingly. Keep a minimum size of 20 bytes. */
int size = min (2000, max (20, (nextb->text->z_byte / 10)));
if (nextb->text->gap_size > size)
{
struct buffer *save_current = current_buffer;
current_buffer = nextb;
make_gap (-(nextb->text->gap_size - size));
current_buffer = save_current;
}
}
for_each_buffer (nextb)
{
/* If a buffer's undo list is Qt, that means that undo is
turned off in that buffer. Calling truncate_undo_list on
Qt tends to return NULL, which effectively turns undo back on.
So don't call truncate_undo_list if undo_list is Qt. */
if (! NILP (nextb->BUFFER_INTERNAL_FIELD (name))
&& ! EQ (nextb->BUFFER_INTERNAL_FIELD (undo_list), Qt))
truncate_undo_list (nextb);
/* Shrink buffer gaps, but skip indirect and dead buffers. */
if (nextb->base_buffer == 0 && !NILP (nextb->BUFFER_INTERNAL_FIELD (name))
&& ! nextb->text->inhibit_shrinking)
{
/* If a buffer's gap size is more than 10% of the buffer
size, or larger than 2000 bytes, then shrink it
accordingly. Keep a minimum size of 20 bytes. */
int size = min (2000, max (20, (nextb->text->z_byte / 10)));
nextb = nextb->header.next.buffer;
}
}
if (nextb->text->gap_size > size)
{
struct buffer *save_current = current_buffer;
current_buffer = nextb;
make_gap (-(nextb->text->gap_size - size));
current_buffer = save_current;
}
}
}
t1 = current_emacs_time ();
......@@ -5558,48 +5553,42 @@ See Info node `(elisp)Garbage Collection'. */)
Look thru every buffer's undo list
for elements that update markers that were not marked,
and delete them. */
{
register struct buffer *nextb = all_buffers;
while (nextb)
{
/* If a buffer's undo list is Qt, that means that undo is
turned off in that buffer. Calling truncate_undo_list on
Qt tends to return NULL, which effectively turns undo back on.
So don't call truncate_undo_list if undo_list is Qt. */
if (! EQ (nextb->BUFFER_INTERNAL_FIELD (undo_list), Qt))
{
Lisp_Object tail, prev;
tail = nextb->BUFFER_INTERNAL_FIELD (undo_list);
prev = Qnil;
while (CONSP (tail))
{
if (CONSP (XCAR (tail))
&& MARKERP (XCAR (XCAR (tail)))
&& !XMARKER (XCAR (XCAR (tail)))->gcmarkbit)
{
if (NILP (prev))
nextb->BUFFER_INTERNAL_FIELD (undo_list) = tail = XCDR (tail);
else
{
tail = XCDR (tail);
XSETCDR (prev, tail);
}
}
else
{
prev = tail;
tail = XCDR (tail);
}
}
}
/* Now that we have stripped the elements that need not be in the
undo_list any more, we can finally mark the list. */
mark_object (nextb->BUFFER_INTERNAL_FIELD (undo_list));
nextb = nextb->header.next.buffer;
}
}
for_each_buffer (nextb)
{
/* If a buffer's undo list is Qt, that means that undo is
turned off in that buffer. Calling truncate_undo_list on
Qt tends to return NULL, which effectively turns undo back on.
So don't call truncate_undo_list if undo_list is Qt. */
if (! EQ (nextb->BUFFER_INTERNAL_FIELD (undo_list), Qt))
{
Lisp_Object tail, prev;
tail = nextb->BUFFER_INTERNAL_FIELD (undo_list);
prev = Qnil;
while (CONSP (tail))
{
if (CONSP (XCAR (tail))
&& MARKERP (XCAR (XCAR (tail)))
&& !XMARKER (XCAR (XCAR (tail)))->gcmarkbit)
{
if (NILP (prev))
nextb->BUFFER_INTERNAL_FIELD (undo_list) = tail = XCDR (tail);
else
{
tail = XCDR (tail);
XSETCDR (prev, tail);
}
}
else
{
prev = tail;
tail = XCDR (tail);
}
}
}
/* Now that we have stripped the elements that need not be in the
undo_list any more, we can finally mark the list. */
mark_object (nextb->BUFFER_INTERNAL_FIELD (undo_list));
}
gc_sweep ();
......@@ -5987,9 +5976,10 @@ mark_object (Lisp_Object arg)
#ifdef GC_CHECK_MARKED_OBJECTS
if (po != &buffer_defaults && po != &buffer_local_symbols)
{
struct buffer *b = all_buffers;
for (; b && b != po; b = b->header.next.buffer)
;
struct buffer *b;
for_each_buffer (b)
if (b == po)
break;
if (b == NULL)
abort ();
}
......
......@@ -1532,10 +1532,8 @@ cleaning up all windows currently displaying the buffer to be killed. */)
GCPRO1 (buffer);
for (other = all_buffers; other; other = other->header.next.buffer)
/* all_buffers contains dead buffers too;
don't re-kill them. */
if (other->base_buffer == b && !NILP (BVAR (other, name)))
for_each_buffer (other)
if (other->base_buffer == b)
{
Lisp_Object buf;
XSETBUFFER (buf, other);
......@@ -2052,7 +2050,7 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
{ /* This is probably harder to make work. */
struct buffer *other;
for (other = all_buffers; other; other = other->header.next.buffer)
for_each_buffer (other)
if (other->base_buffer == other_buffer
|| other->base_buffer == current_buffer)
error ("One of the buffers to swap has indirect buffers");
......@@ -2429,7 +2427,7 @@ current buffer is cleared. */)
/* Copy this buffer's new multibyte status
into all of its indirect buffers. */
for (other = all_buffers; other; other = other->header.next.buffer)
for_each_buffer (other)
if (other->base_buffer == current_buffer && !NILP (BVAR (other, name)))
{
BVAR (other, enable_multibyte_characters)
......@@ -5035,7 +5033,7 @@ init_buffer (void)
Map new memory. */
struct buffer *b;
for (b = all_buffers; b; b = b->header.next.buffer)
for_each_buffer (b)
if (b->text->beg == NULL)
enlarge_buffer_text (b, 0);
}
......
......@@ -857,6 +857,15 @@ struct buffer
};
/* Chain of all buffers, including killed ones. */
extern struct buffer *all_buffers;
/* Used to iterate over the chain above. */
#define for_each_buffer(b) \
for ((b) = all_buffers; (b); (b) = (b)->header.next.buffer)
/* This points to the current buffer. */
extern struct buffer *current_buffer;
......
......@@ -7588,7 +7588,7 @@ code_conversion_restore (Lisp_Object arg)
{
if (EQ (workbuf, Vcode_conversion_reused_workbuf))
reused_workbuf_in_use = 0;
else if (! NILP (Fbuffer_live_p (workbuf)))
else
Fkill_buffer (workbuf);
}
set_buffer_internal (XBUFFER (current));
......
......@@ -1401,7 +1401,7 @@ for this variable. */)
{
struct buffer *b;
for (b = all_buffers; b; b = b->header.next.buffer)
for_each_buffer (b)
if (!PER_BUFFER_VALUE_P (b, idx))
PER_BUFFER_VALUE (b, offset) = value;
}
......
......@@ -2858,7 +2858,6 @@ extern Lisp_Object set_buffer_if_live (Lisp_Object);
extern Lisp_Object other_buffer_safely (Lisp_Object);
extern Lisp_Object Qpriority, Qwindow, Qbefore_string, Qafter_string;
extern Lisp_Object get_truename_buffer (Lisp_Object);
extern struct buffer *all_buffers;
extern void init_buffer_once (void);
extern void init_buffer (void);
extern void syms_of_buffer (void);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment