summaryrefslogtreecommitdiff
path: root/src/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c669
1 files changed, 347 insertions, 322 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 244c1851fab..62a3d66c8b7 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1,6 +1,6 @@
/* Buffer manipulation primitives for GNU Emacs.
-Copyright (C) 1985-1989, 1993-1995, 1997-2018 Free Software Foundation,
+Copyright (C) 1985-1989, 1993-1995, 1997-2019 Free Software Foundation,
Inc.
This file is part of GNU Emacs.
@@ -37,6 +37,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "window.h"
#include "commands.h"
#include "character.h"
+#include "coding.h"
#include "buffer.h"
#include "region-cache.h"
#include "indent.h"
@@ -44,6 +45,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "keymap.h"
#include "frame.h"
#include "xwidget.h"
+#include "pdumper.h"
#ifdef WINDOWSNT
#include "w32heap.h" /* for mmap_* */
@@ -466,7 +468,7 @@ See also `find-buffer-visiting'. */)
filename = Fexpand_file_name (filename, Qnil);
/* If the file name has special constructs in it,
- call the corresponding file handler. */
+ call the corresponding file name handler. */
handler = Ffind_file_name_handler (filename, Qget_file_buffer);
if (!NILP (handler))
{
@@ -529,6 +531,8 @@ even if it is dead. The return value is never nil. */)
/* No one shows us now. */
b->window_count = 0;
+ memset (&b->local_flags, 0, sizeof (b->local_flags));
+
BUF_GAP_SIZE (b) = 20;
block_input ();
/* We allocate extra 1-byte at the tail and keep it always '\0' for
@@ -580,6 +584,11 @@ even if it is dead. The return value is never nil. */)
set_string_intervals (name, NULL);
bset_name (b, name);
+ b->inhibit_buffer_hooks
+ = (STRINGP (Vcode_conversion_workbuf_name)
+ && strncmp (SSDATA (name), SSDATA (Vcode_conversion_workbuf_name),
+ SBYTES (Vcode_conversion_workbuf_name)) == 0);
+
bset_undo_list (b, SREF (name, 0) != ' ' ? Qnil : Qt);
reset_buffer (b);
@@ -592,7 +601,7 @@ even if it is dead. The return value is never nil. */)
XSETBUFFER (buffer, b);
Vbuffer_alist = nconc2 (Vbuffer_alist, list1 (Fcons (name, buffer)));
/* And run buffer-list-update-hook. */
- if (!NILP (Vrun_hooks))
+ if (!NILP (Vrun_hooks) && !b->inhibit_buffer_hooks)
call1 (Vrun_hooks, Qbuffer_list_update_hook);
return buffer;
@@ -781,6 +790,8 @@ CLONE nil means the indirect buffer's state is reset to default values. */)
/* Always -1 for an indirect buffer. */
b->window_count = -1;
+ memset (&b->local_flags, 0, sizeof (b->local_flags));
+
b->pt = b->base_buffer->pt;
b->begv = b->base_buffer->begv;
b->zv = b->base_buffer->zv;
@@ -849,7 +860,7 @@ CLONE nil means the indirect buffer's state is reset to default values. */)
clone_per_buffer_values (b->base_buffer, b);
bset_filename (b, Qnil);
bset_file_truename (b, Qnil);
- bset_display_count (b, make_number (0));
+ bset_display_count (b, make_fixnum (0));
bset_backed_up (b, Qnil);
bset_auto_save_file_name (b, Qnil);
set_buffer_internal_1 (b);
@@ -939,7 +950,7 @@ reset_buffer (register struct buffer *b)
bset_file_format (b, Qnil);
bset_auto_save_file_format (b, Qt);
bset_last_selected_window (b, Qnil);
- bset_display_count (b, make_number (0));
+ bset_display_count (b, make_fixnum (0));
bset_display_time (b, Qnil);
bset_enable_multibyte_characters
(b, BVAR (&buffer_defaults, enable_multibyte_characters));
@@ -1102,8 +1113,8 @@ is first appended to NAME, to speed up finding a non-existent buffer. */)
{
char number[sizeof "-999999"];
- /* Use XINT instead of XFASTINT to work around GCC bug 80776. */
- int i = XINT (Frandom (make_number (1000000)));
+ /* Use XFIXNUM instead of XFIXNAT to work around GCC bug 80776. */
+ int i = XFIXNUM (Frandom (make_fixnum (1000000)));
eassume (0 <= i && i < 1000000);
AUTO_STRING_WITH_LEN (lnumber, number, sprintf (number, "-%d", i));
@@ -1196,7 +1207,7 @@ buffer_local_value (Lisp_Object variable, Lisp_Object buffer)
result = Fassoc (variable, BVAR (buf, local_var_alist), Qnil);
if (!NILP (result))
{
- if (blv->fwd)
+ if (blv->fwd.fwdptr)
{ /* What binding is loaded right now? */
Lisp_Object current_alist_element = blv->valcell;
@@ -1217,7 +1228,7 @@ buffer_local_value (Lisp_Object variable, Lisp_Object buffer)
}
case SYMBOL_FORWARDED:
{
- union Lisp_Fwd *fwd = SYMBOL_FWD (sym);
+ lispfwd fwd = SYMBOL_FWD (sym);
if (BUFFER_OBJFWDP (fwd))
result = per_buffer_value (buf, XBUFFER_OBJFWD (fwd)->offset);
else
@@ -1408,7 +1419,7 @@ state of the current buffer. Use with care. */)
/* If SAVE_MODIFF == auto_save_modified == MODIFF,
we can either decrease SAVE_MODIFF and auto_save_modified
or increase MODIFF. */
- : MODIFF++);
+ : modiff_incr (&MODIFF));
return flag;
}
@@ -1417,11 +1428,11 @@ DEFUN ("buffer-modified-tick", Fbuffer_modified_tick, Sbuffer_modified_tick,
0, 1, 0,
doc: /* Return BUFFER's tick counter, incremented for each change in text.
Each buffer has a tick counter which is incremented each time the
-text in that buffer is changed. It wraps around occasionally.
-No argument or nil as argument means use current buffer as BUFFER. */)
- (register Lisp_Object buffer)
+text in that buffer is changed. No argument or nil as argument means
+use current buffer as BUFFER. */)
+ (Lisp_Object buffer)
{
- return make_number (BUF_MODIFF (decode_buffer (buffer)));
+ return modiff_to_integer (BUF_MODIFF (decode_buffer (buffer)));
}
DEFUN ("buffer-chars-modified-tick", Fbuffer_chars_modified_tick,
@@ -1434,9 +1445,9 @@ values returned by two individual calls of `buffer-chars-modified-tick',
you can tell whether a character change occurred in that buffer in
between these calls. No argument or nil as argument means use current
buffer as BUFFER. */)
- (register Lisp_Object buffer)
+ (Lisp_Object buffer)
{
- return make_number (BUF_CHARS_MODIFF (decode_buffer (buffer)));
+ return modiff_to_integer (BUF_CHARS_MODIFF (decode_buffer (buffer)));
}
DEFUN ("rename-buffer", Frename_buffer, Srename_buffer, 1, 2,
@@ -1488,7 +1499,7 @@ This does not change the name of the visited file (if any). */)
call0 (intern ("rename-auto-save-file"));
/* Run buffer-list-update-hook. */
- if (!NILP (Vrun_hooks))
+ if (!NILP (Vrun_hooks) && !current_buffer->inhibit_buffer_hooks)
call1 (Vrun_hooks, Qbuffer_list_update_hook);
/* Refetch since that last call may have done GC. */
@@ -1701,10 +1712,13 @@ cleaning up all windows currently displaying the buffer to be killed. */)
/* First run the query functions; if any query is answered no,
don't kill the buffer. */
- tem = CALLN (Frun_hook_with_args_until_failure,
- Qkill_buffer_query_functions);
- if (NILP (tem))
- return unbind_to (count, Qnil);
+ if (!b->inhibit_buffer_hooks)
+ {
+ tem = CALLN (Frun_hook_with_args_until_failure,
+ Qkill_buffer_query_functions);
+ if (NILP (tem))
+ return unbind_to (count, Qnil);
+ }
/* Query if the buffer is still modified. */
if (INTERACTIVE && !NILP (BVAR (b, filename))
@@ -1721,7 +1735,8 @@ cleaning up all windows currently displaying the buffer to be killed. */)
return unbind_to (count, Qt);
/* Then run the hooks. */
- run_hook (Qkill_buffer_hook);
+ if (!b->inhibit_buffer_hooks)
+ run_hook (Qkill_buffer_hook);
unbind_to (count, Qnil);
}
@@ -1923,7 +1938,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
bset_undo_list (b, Qnil);
/* Run buffer-list-update-hook. */
- if (!NILP (Vrun_hooks))
+ if (!NILP (Vrun_hooks) && !b->inhibit_buffer_hooks)
call1 (Vrun_hooks, Qbuffer_list_update_hook);
return Qt;
@@ -1965,7 +1980,7 @@ record_buffer (Lisp_Object buffer)
fset_buried_buffer_list (f, Fdelq (buffer, f->buried_buffer_list));
/* Run buffer-list-update-hook. */
- if (!NILP (Vrun_hooks))
+ if (!NILP (Vrun_hooks) && !XBUFFER (buffer)->inhibit_buffer_hooks)
call1 (Vrun_hooks, Qbuffer_list_update_hook);
}
@@ -2004,7 +2019,7 @@ DEFUN ("bury-buffer-internal", Fbury_buffer_internal, Sbury_buffer_internal,
(f, Fcons (buffer, Fdelq (buffer, f->buried_buffer_list)));
/* Run buffer-list-update-hook. */
- if (!NILP (Vrun_hooks))
+ if (!NILP (Vrun_hooks) && !XBUFFER (buffer)->inhibit_buffer_hooks)
call1 (Vrun_hooks, Qbuffer_list_update_hook);
return Qnil;
@@ -2125,7 +2140,7 @@ void set_buffer_internal_2 (register struct buffer *b)
Lisp_Object var = XCAR (XCAR (tail));
struct Lisp_Symbol *sym = XSYMBOL (var);
if (sym->u.s.redirect == SYMBOL_LOCALIZED /* Just to be sure. */
- && SYMBOL_BLV (sym)->fwd)
+ && SYMBOL_BLV (sym)->fwd.fwdptr)
/* Just reference the variable
to cause it to become set for this buffer. */
Fsymbol_value (var);
@@ -2203,7 +2218,7 @@ If the text under POSITION (which defaults to point) has the
if (NILP (position))
XSETFASTINT (position, PT);
else
- CHECK_NUMBER (position);
+ CHECK_FIXNUM (position);
if (!NILP (BVAR (current_buffer, read_only))
&& NILP (Vinhibit_read_only)
@@ -2233,23 +2248,23 @@ so the buffer is truly empty after this. */)
void
validate_region (register Lisp_Object *b, register Lisp_Object *e)
{
- CHECK_NUMBER_COERCE_MARKER (*b);
- CHECK_NUMBER_COERCE_MARKER (*e);
+ CHECK_FIXNUM_COERCE_MARKER (*b);
+ CHECK_FIXNUM_COERCE_MARKER (*e);
- if (XINT (*b) > XINT (*e))
+ if (XFIXNUM (*b) > XFIXNUM (*e))
{
Lisp_Object tem;
tem = *b; *b = *e; *e = tem;
}
- if (! (BEGV <= XINT (*b) && XINT (*e) <= ZV))
+ if (! (BEGV <= XFIXNUM (*b) && XFIXNUM (*e) <= ZV))
args_out_of_range_3 (Fcurrent_buffer (), *b, *e);
}
/* Advance BYTE_POS up to a character boundary
and return the adjusted position. */
-static ptrdiff_t
+ptrdiff_t
advance_to_char_boundary (ptrdiff_t byte_pos)
{
int c;
@@ -2370,9 +2385,12 @@ results, see Info node `(elisp)Swapping Text'. */)
bset_point_before_scroll (current_buffer, Qnil);
bset_point_before_scroll (other_buffer, Qnil);
- current_buffer->text->modiff++; other_buffer->text->modiff++;
- current_buffer->text->chars_modiff++; other_buffer->text->chars_modiff++;
- current_buffer->text->overlay_modiff++; other_buffer->text->overlay_modiff++;
+ modiff_incr (&current_buffer->text->modiff);
+ modiff_incr (&other_buffer->text->modiff);
+ modiff_incr (&current_buffer->text->chars_modiff);
+ modiff_incr (&other_buffer->text->chars_modiff);
+ modiff_incr (&current_buffer->text->overlay_modiff);
+ modiff_incr (&other_buffer->text->overlay_modiff);
current_buffer->text->beg_unchanged = current_buffer->text->gpt;
current_buffer->text->end_unchanged = current_buffer->text->gpt;
other_buffer->text->beg_unchanged = other_buffer->text->gpt;
@@ -2409,7 +2427,7 @@ results, see Info node `(elisp)Swapping Text'. */)
&& (EQ (XWINDOW (w)->contents, buf1)
|| EQ (XWINDOW (w)->contents, buf2)))
Fset_marker (XWINDOW (w)->pointm,
- make_number
+ make_fixnum
(BUF_BEGV (XBUFFER (XWINDOW (w)->contents))),
XWINDOW (w)->contents);
/* Blindly copied from pointm part. */
@@ -2417,14 +2435,14 @@ results, see Info node `(elisp)Swapping Text'. */)
&& (EQ (XWINDOW (w)->contents, buf1)
|| EQ (XWINDOW (w)->contents, buf2)))
Fset_marker (XWINDOW (w)->old_pointm,
- make_number
+ make_fixnum
(BUF_BEGV (XBUFFER (XWINDOW (w)->contents))),
XWINDOW (w)->contents);
if (MARKERP (XWINDOW (w)->start)
&& (EQ (XWINDOW (w)->contents, buf1)
|| EQ (XWINDOW (w)->contents, buf2)))
Fset_marker (XWINDOW (w)->start,
- make_number
+ make_fixnum
(XBUFFER (XWINDOW (w)->contents)->last_window_start),
XWINDOW (w)->contents);
w = Fnext_window (w, Qt, Qt);
@@ -2547,7 +2565,7 @@ current buffer is cleared. */)
}
}
if (narrowed)
- Fnarrow_to_region (make_number (begv), make_number (zv));
+ Fnarrow_to_region (make_fixnum (begv), make_fixnum (zv));
}
else
{
@@ -2628,7 +2646,7 @@ current buffer is cleared. */)
TEMP_SET_PT (pt);
if (narrowed)
- Fnarrow_to_region (make_number (begv), make_number (zv));
+ Fnarrow_to_region (make_fixnum (begv), make_fixnum (zv));
/* Do this first, so that chars_in_text asks the right question.
set_intervals_multibyte needs it too. */
@@ -2684,6 +2702,9 @@ current buffer is cleared. */)
/* Do this last, so it can calculate the new correspondences
between chars and bytes. */
+ /* FIXME: Is it worth the trouble, really? Couldn't we just throw
+ away all the text-properties instead of trying to guess how
+ to adjust them? AFAICT the result is not reliable anyway. */
set_intervals_multibyte (1);
}
@@ -2789,8 +2810,6 @@ overlays_at (EMACS_INT pos, bool extend, Lisp_Object **vec_ptr,
ptrdiff_t *len_ptr,
ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr, bool change_req)
{
- Lisp_Object overlay, start, end;
- struct Lisp_Overlay *tail;
ptrdiff_t idx = 0;
ptrdiff_t len = *len_ptr;
Lisp_Object *vec = *vec_ptr;
@@ -2798,22 +2817,20 @@ overlays_at (EMACS_INT pos, bool extend, Lisp_Object **vec_ptr,
ptrdiff_t prev = BEGV;
bool inhibit_storing = 0;
- for (tail = current_buffer->overlays_before; tail; tail = tail->next)
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
+ tail; tail = tail->next)
{
- ptrdiff_t startpos, endpos;
-
- XSETMISC (overlay, tail);
-
- start = OVERLAY_START (overlay);
- end = OVERLAY_END (overlay);
- endpos = OVERLAY_POSITION (end);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
+ Lisp_Object start = OVERLAY_START (overlay);
+ Lisp_Object end = OVERLAY_END (overlay);
+ ptrdiff_t endpos = OVERLAY_POSITION (end);
if (endpos < pos)
{
if (prev < endpos)
prev = endpos;
break;
}
- startpos = OVERLAY_POSITION (start);
+ ptrdiff_t startpos = OVERLAY_POSITION (start);
/* This one ends at or after POS
so its start counts for PREV_PTR if it's before POS. */
if (prev < startpos && startpos < pos)
@@ -2846,22 +2863,20 @@ overlays_at (EMACS_INT pos, bool extend, Lisp_Object **vec_ptr,
next = startpos;
}
- for (tail = current_buffer->overlays_after; tail; tail = tail->next)
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
+ tail; tail = tail->next)
{
- ptrdiff_t startpos, endpos;
-
- XSETMISC (overlay, tail);
-
- start = OVERLAY_START (overlay);
- end = OVERLAY_END (overlay);
- startpos = OVERLAY_POSITION (start);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
+ Lisp_Object start = OVERLAY_START (overlay);
+ Lisp_Object end = OVERLAY_END (overlay);
+ ptrdiff_t startpos = OVERLAY_POSITION (start);
if (pos < startpos)
{
if (startpos < next)
next = startpos;
break;
}
- endpos = OVERLAY_POSITION (end);
+ ptrdiff_t endpos = OVERLAY_POSITION (end);
if (pos < endpos)
{
if (idx == len)
@@ -2923,8 +2938,6 @@ overlays_in (EMACS_INT beg, EMACS_INT end, bool extend,
Lisp_Object **vec_ptr, ptrdiff_t *len_ptr,
ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr)
{
- Lisp_Object overlay, ostart, oend;
- struct Lisp_Overlay *tail;
ptrdiff_t idx = 0;
ptrdiff_t len = *len_ptr;
Lisp_Object *vec = *vec_ptr;
@@ -2933,22 +2946,20 @@ overlays_in (EMACS_INT beg, EMACS_INT end, bool extend,
bool inhibit_storing = 0;
bool end_is_Z = end == Z;
- for (tail = current_buffer->overlays_before; tail; tail = tail->next)
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
+ tail; tail = tail->next)
{
- ptrdiff_t startpos, endpos;
-
- XSETMISC (overlay, tail);
-
- ostart = OVERLAY_START (overlay);
- oend = OVERLAY_END (overlay);
- endpos = OVERLAY_POSITION (oend);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
+ Lisp_Object ostart = OVERLAY_START (overlay);
+ Lisp_Object oend = OVERLAY_END (overlay);
+ ptrdiff_t endpos = OVERLAY_POSITION (oend);
if (endpos < beg)
{
if (prev < endpos)
prev = endpos;
break;
}
- startpos = OVERLAY_POSITION (ostart);
+ ptrdiff_t startpos = OVERLAY_POSITION (ostart);
/* Count an interval if it overlaps the range, is empty at the
start of the range, or is empty at END provided END denotes the
end of the buffer. */
@@ -2980,22 +2991,20 @@ overlays_in (EMACS_INT beg, EMACS_INT end, bool extend,
next = startpos;
}
- for (tail = current_buffer->overlays_after; tail; tail = tail->next)
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
+ tail; tail = tail->next)
{
- ptrdiff_t startpos, endpos;
-
- XSETMISC (overlay, tail);
-
- ostart = OVERLAY_START (overlay);
- oend = OVERLAY_END (overlay);
- startpos = OVERLAY_POSITION (ostart);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
+ Lisp_Object ostart = OVERLAY_START (overlay);
+ Lisp_Object oend = OVERLAY_END (overlay);
+ ptrdiff_t startpos = OVERLAY_POSITION (ostart);
if (end < startpos)
{
if (startpos < next)
next = startpos;
break;
}
- endpos = OVERLAY_POSITION (oend);
+ ptrdiff_t endpos = OVERLAY_POSITION (oend);
/* Count an interval if it overlaps the range, is empty at the
start of the range, or is empty at END provided END denotes the
end of the buffer. */
@@ -3097,31 +3106,26 @@ disable_line_numbers_overlay_at_eob (void)
bool
overlay_touches_p (ptrdiff_t pos)
{
- Lisp_Object overlay;
- struct Lisp_Overlay *tail;
-
- for (tail = current_buffer->overlays_before; tail; tail = tail->next)
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
+ tail; tail = tail->next)
{
- ptrdiff_t endpos;
-
- XSETMISC (overlay ,tail);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
eassert (OVERLAYP (overlay));
- endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
+ ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
if (endpos < pos)
break;
if (endpos == pos || OVERLAY_POSITION (OVERLAY_START (overlay)) == pos)
return 1;
}
- for (tail = current_buffer->overlays_after; tail; tail = tail->next)
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
+ tail; tail = tail->next)
{
- ptrdiff_t startpos;
-
- XSETMISC (overlay, tail);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
eassert (OVERLAYP (overlay));
- startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
+ ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
if (pos < startpos)
break;
if (startpos == pos || OVERLAY_POSITION (OVERLAY_END (overlay)) == pos)
@@ -3212,17 +3216,17 @@ sort_overlays (Lisp_Object *overlay_vec, ptrdiff_t noverlays, struct window *w)
sortvec[j].priority = 0;
sortvec[j].spriority = 0;
}
- else if (INTEGERP (tem))
+ else if (FIXNUMP (tem))
{
- sortvec[j].priority = XINT (tem);
+ sortvec[j].priority = XFIXNUM (tem);
sortvec[j].spriority = 0;
}
else if (CONSP (tem))
{
Lisp_Object car = XCAR (tem);
Lisp_Object cdr = XCDR (tem);
- sortvec[j].priority = INTEGERP (car) ? XINT (car) : 0;
- sortvec[j].spriority = INTEGERP (cdr) ? XINT (cdr) : 0;
+ sortvec[j].priority = FIXNUMP (car) ? XFIXNUM (car) : 0;
+ sortvec[j].spriority = FIXNUMP (cdr) ? XFIXNUM (cdr) : 0;
}
j++;
}
@@ -3290,7 +3294,7 @@ record_overlay_string (struct sortstrlist *ssl, Lisp_Object str,
ssl->buf[ssl->used].string = str;
ssl->buf[ssl->used].string2 = str2;
ssl->buf[ssl->used].size = size;
- ssl->buf[ssl->used].priority = (INTEGERP (pri) ? XINT (pri) : 0);
+ ssl->buf[ssl->used].priority = (FIXNUMP (pri) ? XFIXNUM (pri) : 0);
ssl->used++;
if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
@@ -3337,27 +3341,26 @@ record_overlay_string (struct sortstrlist *ssl, Lisp_Object str,
ptrdiff_t
overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
{
- Lisp_Object overlay, window, str;
- struct Lisp_Overlay *ov;
- ptrdiff_t startpos, endpos;
bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
overlay_heads.used = overlay_heads.bytes = 0;
overlay_tails.used = overlay_tails.bytes = 0;
- for (ov = current_buffer->overlays_before; ov; ov = ov->next)
+ for (struct Lisp_Overlay *ov = current_buffer->overlays_before;
+ ov; ov = ov->next)
{
- XSETMISC (overlay, ov);
+ Lisp_Object overlay = make_lisp_ptr (ov, Lisp_Vectorlike);
eassert (OVERLAYP (overlay));
- startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
- endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
+ ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
+ ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
if (endpos < pos)
break;
if (endpos != pos && startpos != pos)
continue;
- window = Foverlay_get (overlay, Qwindow);
+ Lisp_Object window = Foverlay_get (overlay, Qwindow);
if (WINDOWP (window) && XWINDOW (window) != w)
continue;
+ Lisp_Object str;
if (startpos == pos
&& (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
record_overlay_string (&overlay_heads, str,
@@ -3372,20 +3375,22 @@ overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
Foverlay_get (overlay, Qpriority),
endpos - startpos);
}
- for (ov = current_buffer->overlays_after; ov; ov = ov->next)
+ for (struct Lisp_Overlay *ov = current_buffer->overlays_after;
+ ov; ov = ov->next)
{
- XSETMISC (overlay, ov);
+ Lisp_Object overlay = make_lisp_ptr (ov, Lisp_Vectorlike);
eassert (OVERLAYP (overlay));
- startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
- endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
+ ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
+ ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
if (startpos > pos)
break;
if (endpos != pos && startpos != pos)
continue;
- window = Foverlay_get (overlay, Qwindow);
+ Lisp_Object window = Foverlay_get (overlay, Qwindow);
if (WINDOWP (window) && XWINDOW (window) != w)
continue;
+ Lisp_Object str;
if (startpos == pos
&& (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
record_overlay_string (&overlay_heads, str,
@@ -3460,8 +3465,7 @@ overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
void
recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos)
{
- Lisp_Object overlay, beg, end;
- struct Lisp_Overlay *prev, *tail, *next;
+ struct Lisp_Overlay *prev, *next;
/* See if anything in overlays_before should move to overlays_after. */
@@ -3469,14 +3473,15 @@ recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos)
But we use it for symmetry and in case that should cease to be true
with some future change. */
prev = NULL;
- for (tail = buf->overlays_before; tail; prev = tail, tail = next)
+ for (struct Lisp_Overlay *tail = buf->overlays_before;
+ tail; prev = tail, tail = next)
{
next = tail->next;
- XSETMISC (overlay, tail);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
eassert (OVERLAYP (overlay));
- beg = OVERLAY_START (overlay);
- end = OVERLAY_END (overlay);
+ Lisp_Object beg = OVERLAY_START (overlay);
+ Lisp_Object end = OVERLAY_END (overlay);
if (OVERLAY_POSITION (end) > pos)
{
@@ -3495,12 +3500,10 @@ recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos)
for (other = buf->overlays_after; other;
other_prev = other, other = other->next)
{
- Lisp_Object otherbeg, otheroverlay;
-
- XSETMISC (otheroverlay, other);
+ Lisp_Object otheroverlay = make_lisp_ptr (other, Lisp_Vectorlike);
eassert (OVERLAYP (otheroverlay));
- otherbeg = OVERLAY_START (otheroverlay);
+ Lisp_Object otherbeg = OVERLAY_START (otheroverlay);
if (OVERLAY_POSITION (otherbeg) >= where)
break;
}
@@ -3522,14 +3525,15 @@ recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos)
/* See if anything in overlays_after should be in overlays_before. */
prev = NULL;
- for (tail = buf->overlays_after; tail; prev = tail, tail = next)
+ for (struct Lisp_Overlay *tail = buf->overlays_after;
+ tail; prev = tail, tail = next)
{
next = tail->next;
- XSETMISC (overlay, tail);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
eassert (OVERLAYP (overlay));
- beg = OVERLAY_START (overlay);
- end = OVERLAY_END (overlay);
+ Lisp_Object beg = OVERLAY_START (overlay);
+ Lisp_Object end = OVERLAY_END (overlay);
/* Stop looking, when we know that nothing further
can possibly end before POS. */
@@ -3553,12 +3557,10 @@ recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos)
for (other = buf->overlays_before; other;
other_prev = other, other = other->next)
{
- Lisp_Object otherend, otheroverlay;
-
- XSETMISC (otheroverlay, other);
+ Lisp_Object otheroverlay = make_lisp_ptr (other, Lisp_Vectorlike);
eassert (OVERLAYP (otheroverlay));
- otherend = OVERLAY_END (otheroverlay);
+ Lisp_Object otherend = OVERLAY_END (otheroverlay);
if (OVERLAY_POSITION (otherend) <= where)
break;
}
@@ -3613,7 +3615,6 @@ adjust_overlays_for_delete (ptrdiff_t pos, ptrdiff_t length)
void
fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end)
{
- Lisp_Object overlay;
struct Lisp_Overlay *before_list UNINIT;
struct Lisp_Overlay *after_list UNINIT;
/* These are either nil, indicating that before_list or after_list
@@ -3623,8 +3624,7 @@ fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end)
/* 'Parent', likewise, indicates a cons cell or
current_buffer->overlays_before or overlays_after, depending
which loop we're in. */
- struct Lisp_Overlay *tail, *parent;
- ptrdiff_t startpos, endpos;
+ struct Lisp_Overlay *parent;
/* This algorithm shifts links around instead of consing and GCing.
The loop invariant is that before_list (resp. after_list) is a
@@ -3633,18 +3633,20 @@ fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end)
(after_list) if it is, is still uninitialized. So it's not a bug
that before_list isn't initialized, although it may look
strange. */
- for (parent = NULL, tail = current_buffer->overlays_before; tail;)
+ parent = NULL;
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
+ tail; tail = tail->next)
{
- XSETMISC (overlay, tail);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
- endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
- startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
+ ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
+ ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
/* If the overlay is backwards, make it empty. */
if (endpos < startpos)
{
startpos = endpos;
- Fset_marker (OVERLAY_START (overlay), make_number (startpos),
+ Fset_marker (OVERLAY_START (overlay), make_fixnum (startpos),
Qnil);
}
@@ -3676,23 +3678,24 @@ fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end)
set_buffer_overlays_before (current_buffer, tail->next);
else
parent->next = tail->next;
- tail = tail->next;
}
else
- parent = tail, tail = parent->next;
+ parent = tail;
}
- for (parent = NULL, tail = current_buffer->overlays_after; tail;)
+ parent = NULL;
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
+ tail; tail = tail->next)
{
- XSETMISC (overlay, tail);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
- startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
- endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
+ ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
+ ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
/* If the overlay is backwards, make it empty. */
if (endpos < startpos)
{
startpos = endpos;
- Fset_marker (OVERLAY_START (overlay), make_number (startpos),
+ Fset_marker (OVERLAY_START (overlay), make_fixnum (startpos),
Qnil);
}
@@ -3722,10 +3725,9 @@ fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end)
set_buffer_overlays_after (current_buffer, tail->next);
else
parent->next = tail->next;
- tail = tail->next;
}
else
- parent = tail, tail = parent->next;
+ parent = tail;
}
/* Splice the constructed (wrong) lists into the buffer's lists,
@@ -3776,7 +3778,7 @@ fix_overlays_before (struct buffer *bp, ptrdiff_t prev, ptrdiff_t pos)
overlay whose ending marker is after-insertion-marker if disorder
exists). */
while (tail
- && (XSETMISC (tem, tail),
+ && (tem = make_lisp_ptr (tail, Lisp_Vectorlike),
(end = OVERLAY_POSITION (OVERLAY_END (tem))) >= pos))
{
parent = tail;
@@ -3801,7 +3803,7 @@ fix_overlays_before (struct buffer *bp, ptrdiff_t prev, ptrdiff_t pos)
overlays are in correct order. */
while (tail)
{
- XSETMISC (tem, tail);
+ tem = make_lisp_ptr (tail, Lisp_Vectorlike);
end = OVERLAY_POSITION (OVERLAY_END (tem));
if (end == pos)
@@ -3867,10 +3869,10 @@ for the rear of the overlay advance when text is inserted there
if (MARKERP (end) && !EQ (Fmarker_buffer (end), buffer))
signal_error ("Marker points into wrong buffer", end);
- CHECK_NUMBER_COERCE_MARKER (beg);
- CHECK_NUMBER_COERCE_MARKER (end);
+ CHECK_FIXNUM_COERCE_MARKER (beg);
+ CHECK_FIXNUM_COERCE_MARKER (end);
- if (XINT (beg) > XINT (end))
+ if (XFIXNUM (beg) > XFIXNUM (end))
{
Lisp_Object temp;
temp = beg; beg = end; end = temp;
@@ -3927,7 +3929,7 @@ modify_overlay (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
bset_redisplay (buf);
- ++BUF_OVERLAY_MODIFF (buf);
+ modiff_incr (&BUF_OVERLAY_MODIFF (buf));
}
/* Remove OVERLAY from LIST. */
@@ -3987,10 +3989,10 @@ buffer. */)
if (MARKERP (end) && !EQ (Fmarker_buffer (end), buffer))
signal_error ("Marker points into wrong buffer", end);
- CHECK_NUMBER_COERCE_MARKER (beg);
- CHECK_NUMBER_COERCE_MARKER (end);
+ CHECK_FIXNUM_COERCE_MARKER (beg);
+ CHECK_FIXNUM_COERCE_MARKER (end);
- if (XINT (beg) > XINT (end))
+ if (XFIXNUM (beg) > XFIXNUM (end))
{
Lisp_Object temp;
temp = beg; beg = end; end = temp;
@@ -4010,6 +4012,16 @@ buffer. */)
unchain_both (ob, overlay);
}
+ else
+ /* An overlay not associated with any buffer will normally have its
+ `next' field set to NULL, but not always: when killing a buffer,
+ we just set its overlays_after and overlays_before to NULL without
+ manually setting each overlay's `next' field to NULL.
+ Let's correct it here, to simplify subsequent assertions.
+ FIXME: Maybe the better fix is to change `kill-buffer'!? */
+ XOVERLAY (overlay)->next = NULL;
+
+ eassert (XOVERLAY (overlay)->next == NULL);
/* Set the overlay boundaries, which may clip them. */
Fset_marker (OVERLAY_START (overlay), beg, buffer);
@@ -4039,10 +4051,20 @@ buffer. */)
modify_overlay (b, min (o_beg, n_beg), max (o_end, n_end));
}
+ eassert (XOVERLAY (overlay)->next == NULL);
+
/* Delete the overlay if it is empty after clipping and has the
evaporate property. */
if (n_beg == n_end && !NILP (Foverlay_get (overlay, Qevaporate)))
- return unbind_to (count, Fdelete_overlay (overlay));
+ { /* We used to call `Fdelete_overlay' here, but it causes problems:
+ - At this stage, `overlay' is not included in its buffer's lists
+ of overlays (the data-structure is in an inconsistent state),
+ contrary to `Fdelete_overlay's assumptions.
+ - Most of the work done by Fdelete_overlay has already been done
+ here for other reasons. */
+ drop_overlay (XBUFFER (buffer), XOVERLAY (overlay));
+ return unbind_to (count, overlay);
+ }
/* Put the overlay into the new buffer's overlay lists, first on the
wrong list. */
@@ -4156,7 +4178,7 @@ If SORTED is non-nil, then sort them by decreasing priority. */)
Lisp_Object *overlay_vec;
Lisp_Object result;
- CHECK_NUMBER_COERCE_MARKER (pos);
+ CHECK_FIXNUM_COERCE_MARKER (pos);
if (!buffer_has_overlays ())
return Qnil;
@@ -4167,7 +4189,7 @@ If SORTED is non-nil, then sort them by decreasing priority. */)
/* Put all the overlays we want in a vector in overlay_vec.
Store the length in len. */
- noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
+ noverlays = overlays_at (XFIXNUM (pos), 1, &overlay_vec, &len,
NULL, NULL, 0);
if (!NILP (sorted))
@@ -4200,8 +4222,8 @@ end of the buffer. */)
Lisp_Object *overlay_vec;
Lisp_Object result;
- CHECK_NUMBER_COERCE_MARKER (beg);
- CHECK_NUMBER_COERCE_MARKER (end);
+ CHECK_FIXNUM_COERCE_MARKER (beg);
+ CHECK_FIXNUM_COERCE_MARKER (end);
if (!buffer_has_overlays ())
return Qnil;
@@ -4211,7 +4233,7 @@ end of the buffer. */)
/* Put all the overlays we want in a vector in overlay_vec.
Store the length in len. */
- noverlays = overlays_in (XINT (beg), XINT (end), 1, &overlay_vec, &len,
+ noverlays = overlays_in (XFIXNUM (beg), XFIXNUM (end), 1, &overlay_vec, &len,
NULL, NULL);
/* Make a list of them all. */
@@ -4232,10 +4254,10 @@ the value is (point-max). */)
ptrdiff_t endpos;
Lisp_Object *overlay_vec;
- CHECK_NUMBER_COERCE_MARKER (pos);
+ CHECK_FIXNUM_COERCE_MARKER (pos);
if (!buffer_has_overlays ())
- return make_number (ZV);
+ return make_fixnum (ZV);
len = 10;
overlay_vec = xmalloc (len * sizeof *overlay_vec);
@@ -4243,7 +4265,7 @@ the value is (point-max). */)
/* Put all the overlays we want in a vector in overlay_vec.
Store the length in len.
endpos gets the position where the next overlay starts. */
- noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
+ noverlays = overlays_at (XFIXNUM (pos), 1, &overlay_vec, &len,
&endpos, 0, 1);
/* If any of these overlays ends before endpos,
@@ -4260,7 +4282,7 @@ the value is (point-max). */)
}
xfree (overlay_vec);
- return make_number (endpos);
+ return make_fixnum (endpos);
}
DEFUN ("previous-overlay-change", Fprevious_overlay_change,
@@ -4274,14 +4296,14 @@ the value is (point-min). */)
Lisp_Object *overlay_vec;
ptrdiff_t len;
- CHECK_NUMBER_COERCE_MARKER (pos);
+ CHECK_FIXNUM_COERCE_MARKER (pos);
if (!buffer_has_overlays ())
- return make_number (BEGV);
+ return make_fixnum (BEGV);
/* At beginning of buffer, we know the answer;
avoid bug subtracting 1 below. */
- if (XINT (pos) == BEGV)
+ if (XFIXNUM (pos) == BEGV)
return pos;
len = 10;
@@ -4290,11 +4312,11 @@ the value is (point-min). */)
/* Put all the overlays we want in a vector in overlay_vec.
Store the length in len.
prevpos gets the position of the previous change. */
- overlays_at (XINT (pos), 1, &overlay_vec, &len,
+ overlays_at (XFIXNUM (pos), 1, &overlay_vec, &len,
0, &prevpos, 1);
xfree (overlay_vec);
- return make_number (prevpos);
+ return make_fixnum (prevpos);
}
/* These functions are for debugging overlays. */
@@ -4308,19 +4330,14 @@ The lists you get are copies, so that changing them has no effect.
However, the overlays you get are the real objects that the buffer uses. */)
(void)
{
- struct Lisp_Overlay *ol;
- Lisp_Object before = Qnil, after = Qnil, tmp;
+ Lisp_Object before = Qnil, after = Qnil;
- for (ol = current_buffer->overlays_before; ol; ol = ol->next)
- {
- XSETMISC (tmp, ol);
- before = Fcons (tmp, before);
- }
- for (ol = current_buffer->overlays_after; ol; ol = ol->next)
- {
- XSETMISC (tmp, ol);
- after = Fcons (tmp, after);
- }
+ for (struct Lisp_Overlay *ol = current_buffer->overlays_before;
+ ol; ol = ol->next)
+ before = Fcons (make_lisp_ptr (ol, Lisp_Vectorlike), before);
+ for (struct Lisp_Overlay *ol = current_buffer->overlays_after;
+ ol; ol = ol->next)
+ after = Fcons (make_lisp_ptr (ol, Lisp_Vectorlike), after);
return Fcons (Fnreverse (before), Fnreverse (after));
}
@@ -4332,9 +4349,9 @@ for positions far away from POS). */)
(Lisp_Object pos)
{
ptrdiff_t p;
- CHECK_NUMBER_COERCE_MARKER (pos);
+ CHECK_FIXNUM_COERCE_MARKER (pos);
- p = clip_to_bounds (PTRDIFF_MIN, XINT (pos), PTRDIFF_MAX);
+ p = clip_to_bounds (PTRDIFF_MIN, XFIXNUM (pos), PTRDIFF_MAX);
recenter_overlay_lists (current_buffer, p);
return Qnil;
}
@@ -4439,13 +4456,8 @@ void
report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3)
{
- Lisp_Object prop, overlay;
- struct Lisp_Overlay *tail;
/* True if this change is an insertion. */
- bool insertion = (after ? XFASTINT (arg3) == 0 : EQ (start, end));
-
- overlay = Qnil;
- tail = NULL;
+ bool insertion = (after ? XFIXNAT (arg3) == 0 : EQ (start, end));
/* We used to run the functions as soon as we found them and only register
them in last_overlay_modification_hooks for the purpose of the `after'
@@ -4460,75 +4472,77 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
/* We are being called before a change.
Scan the overlays to find the functions to call. */
last_overlay_modification_hooks_used = 0;
- for (tail = current_buffer->overlays_before; tail; tail = tail->next)
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
+ tail; tail = tail->next)
{
ptrdiff_t startpos, endpos;
Lisp_Object ostart, oend;
- XSETMISC (overlay, tail);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
ostart = OVERLAY_START (overlay);
oend = OVERLAY_END (overlay);
endpos = OVERLAY_POSITION (oend);
- if (XFASTINT (start) > endpos)
+ if (XFIXNAT (start) > endpos)
break;
startpos = OVERLAY_POSITION (ostart);
- if (insertion && (XFASTINT (start) == startpos
- || XFASTINT (end) == startpos))
+ if (insertion && (XFIXNAT (start) == startpos
+ || XFIXNAT (end) == startpos))
{
- prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
+ Lisp_Object prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
if (!NILP (prop))
add_overlay_mod_hooklist (prop, overlay);
}
- if (insertion && (XFASTINT (start) == endpos
- || XFASTINT (end) == endpos))
+ if (insertion && (XFIXNAT (start) == endpos
+ || XFIXNAT (end) == endpos))
{
- prop = Foverlay_get (overlay, Qinsert_behind_hooks);
+ Lisp_Object prop = Foverlay_get (overlay, Qinsert_behind_hooks);
if (!NILP (prop))
add_overlay_mod_hooklist (prop, overlay);
}
/* Test for intersecting intervals. This does the right thing
for both insertion and deletion. */
- if (XFASTINT (end) > startpos && XFASTINT (start) < endpos)
+ if (XFIXNAT (end) > startpos && XFIXNAT (start) < endpos)
{
- prop = Foverlay_get (overlay, Qmodification_hooks);
+ Lisp_Object prop = Foverlay_get (overlay, Qmodification_hooks);
if (!NILP (prop))
add_overlay_mod_hooklist (prop, overlay);
}
}
- for (tail = current_buffer->overlays_after; tail; tail = tail->next)
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
+ tail; tail = tail->next)
{
ptrdiff_t startpos, endpos;
Lisp_Object ostart, oend;
- XSETMISC (overlay, tail);
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
ostart = OVERLAY_START (overlay);
oend = OVERLAY_END (overlay);
startpos = OVERLAY_POSITION (ostart);
endpos = OVERLAY_POSITION (oend);
- if (XFASTINT (end) < startpos)
+ if (XFIXNAT (end) < startpos)
break;
- if (insertion && (XFASTINT (start) == startpos
- || XFASTINT (end) == startpos))
+ if (insertion && (XFIXNAT (start) == startpos
+ || XFIXNAT (end) == startpos))
{
- prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
+ Lisp_Object prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
if (!NILP (prop))
add_overlay_mod_hooklist (prop, overlay);
}
- if (insertion && (XFASTINT (start) == endpos
- || XFASTINT (end) == endpos))
+ if (insertion && (XFIXNAT (start) == endpos
+ || XFIXNAT (end) == endpos))
{
- prop = Foverlay_get (overlay, Qinsert_behind_hooks);
+ Lisp_Object prop = Foverlay_get (overlay, Qinsert_behind_hooks);
if (!NILP (prop))
add_overlay_mod_hooklist (prop, overlay);
}
/* Test for intersecting intervals. This does the right thing
for both insertion and deletion. */
- if (XFASTINT (end) > startpos && XFASTINT (start) < endpos)
+ if (XFIXNAT (end) > startpos && XFIXNAT (start) < endpos)
{
- prop = Foverlay_get (overlay, Qmodification_hooks);
+ Lisp_Object prop = Foverlay_get (overlay, Qmodification_hooks);
if (!NILP (prop))
add_overlay_mod_hooklist (prop, overlay);
}
@@ -4543,23 +4557,6 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
Lisp_Object *copy;
ptrdiff_t i;
- if (size)
- {
- Lisp_Object ovl
- = XVECTOR (last_overlay_modification_hooks)->contents[1];
-
- /* If the buffer of the first overlay in the array doesn't
- match the current buffer, then these modification hooks
- should not be run in this buffer. This could happen when
- some code calls some insdel functions, such as del_range_1,
- with the PREPARE argument false -- in that case this
- function is never called to record the overlay modification
- hook functions in the last_overlay_modification_hooks
- array, so anything we find there is not ours. */
- if (XMARKER (OVERLAY_START (ovl))->buffer != current_buffer)
- return;
- }
-
USE_SAFE_ALLOCA;
SAFE_ALLOCA_LISP (copy, size);
memcpy (copy, XVECTOR (last_overlay_modification_hooks)->contents,
@@ -4570,7 +4567,12 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
Lisp_Object prop_i, overlay_i;
prop_i = copy[i++];
overlay_i = copy[i++];
- call_overlay_mod_hooks (prop_i, overlay_i, after, arg1, arg2, arg3);
+ /* It is possible that the recorded overlay has been deleted
+ (which makes its markers' buffers be nil), or that (due to
+ some bug) it belongs to a different buffer. Only run this
+ hook if the overlay belongs to the current buffer. */
+ if (XMARKER (OVERLAY_START (overlay_i))->buffer == current_buffer)
+ call_overlay_mod_hooks (prop_i, overlay_i, after, arg1, arg2, arg3);
}
SAFE_FREE ();
@@ -4596,16 +4598,13 @@ call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay, bool after,
void
evaporate_overlays (ptrdiff_t pos)
{
- Lisp_Object overlay, hit_list;
- struct Lisp_Overlay *tail;
-
- hit_list = Qnil;
+ Lisp_Object hit_list = Qnil;
if (pos <= current_buffer->overlay_center)
- for (tail = current_buffer->overlays_before; tail; tail = tail->next)
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
+ tail; tail = tail->next)
{
- ptrdiff_t endpos;
- XSETMISC (overlay, tail);
- endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
+ ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
if (endpos < pos)
break;
if (endpos == pos && OVERLAY_POSITION (OVERLAY_START (overlay)) == pos
@@ -4613,11 +4612,11 @@ evaporate_overlays (ptrdiff_t pos)
hit_list = Fcons (overlay, hit_list);
}
else
- for (tail = current_buffer->overlays_after; tail; tail = tail->next)
+ for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
+ tail; tail = tail->next)
{
- ptrdiff_t startpos;
- XSETMISC (overlay, tail);
- startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
+ Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
+ ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
if (startpos > pos)
break;
if (startpos == pos && OVERLAY_POSITION (OVERLAY_END (overlay)) == pos
@@ -5023,24 +5022,37 @@ alloc_buffer_text (struct buffer *b, ptrdiff_t nbytes)
void
enlarge_buffer_text (struct buffer *b, ptrdiff_t delta)
{
- void *p;
- ptrdiff_t nbytes = (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1
- + delta);
block_input ();
+ void *p;
+ unsigned char *old_beg = b->text->beg;
+ ptrdiff_t old_nbytes =
+ BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1;
+ ptrdiff_t new_nbytes = old_nbytes + delta;
+
+ if (pdumper_object_p (old_beg))
+ b->text->beg = NULL;
+ else
+ old_beg = NULL;
+
#if defined USE_MMAP_FOR_BUFFERS
- p = mmap_realloc ((void **) &b->text->beg, nbytes);
+ p = mmap_realloc ((void **) &b->text->beg, new_nbytes);
#elif defined REL_ALLOC
- p = r_re_alloc ((void **) &b->text->beg, nbytes);
+ p = r_re_alloc ((void **) &b->text->beg, new_nbytes);
#else
- p = xrealloc (b->text->beg, nbytes);
+ p = xrealloc (b->text->beg, new_nbytes);
#endif
if (p == NULL)
{
+ if (old_beg)
+ b->text->beg = old_beg;
unblock_input ();
- memory_full (nbytes);
+ memory_full (new_nbytes);
}
+ if (old_beg)
+ memcpy (p, old_beg, min (old_nbytes, new_nbytes));
+
BUF_BEG_ADDR (b) = p;
unblock_input ();
}
@@ -5053,13 +5065,16 @@ free_buffer_text (struct buffer *b)
{
block_input ();
+ if (!pdumper_object_p (b->text->beg))
+ {
#if defined USE_MMAP_FOR_BUFFERS
- mmap_free ((void **) &b->text->beg);
+ mmap_free ((void **) &b->text->beg);
#elif defined REL_ALLOC
- r_alloc_free ((void **) &b->text->beg);
+ r_alloc_free ((void **) &b->text->beg);
#else
- xfree (b->text->beg);
+ xfree (b->text->beg);
#endif
+ }
BUF_BEG_ADDR (b) = NULL;
unblock_input ();
@@ -5070,53 +5085,64 @@ free_buffer_text (struct buffer *b)
/***********************************************************************
Initialization
***********************************************************************/
-
void
init_buffer_once (void)
{
+ /* TODO: clean up the buffer-local machinery. Right now,
+ we have:
+
+ buffer_defaults: default values of buffer-locals
+ buffer_local_flags: metadata
+ buffer_permanent_local_flags: metadata
+ buffer_local_symbols: metadata
+
+ There must be a simpler way to store the metadata.
+ */
+
int idx;
/* Items flagged permanent get an explicit permanent-local property
added in bindings.el, for clarity. */
+ PDUMPER_REMEMBER_SCALAR (buffer_permanent_local_flags);
memset (buffer_permanent_local_flags, 0, sizeof buffer_permanent_local_flags);
/* 0 means not a lisp var, -1 means always local, else mask. */
memset (&buffer_local_flags, 0, sizeof buffer_local_flags);
- bset_filename (&buffer_local_flags, make_number (-1));
- bset_directory (&buffer_local_flags, make_number (-1));
- bset_backed_up (&buffer_local_flags, make_number (-1));
- bset_save_length (&buffer_local_flags, make_number (-1));
- bset_auto_save_file_name (&buffer_local_flags, make_number (-1));
- bset_read_only (&buffer_local_flags, make_number (-1));
- bset_major_mode (&buffer_local_flags, make_number (-1));
- bset_mode_name (&buffer_local_flags, make_number (-1));
- bset_undo_list (&buffer_local_flags, make_number (-1));
- bset_mark_active (&buffer_local_flags, make_number (-1));
- bset_point_before_scroll (&buffer_local_flags, make_number (-1));
- bset_file_truename (&buffer_local_flags, make_number (-1));
- bset_invisibility_spec (&buffer_local_flags, make_number (-1));
- bset_file_format (&buffer_local_flags, make_number (-1));
- bset_auto_save_file_format (&buffer_local_flags, make_number (-1));
- bset_display_count (&buffer_local_flags, make_number (-1));
- bset_display_time (&buffer_local_flags, make_number (-1));
- bset_enable_multibyte_characters (&buffer_local_flags, make_number (-1));
+ bset_filename (&buffer_local_flags, make_fixnum (-1));
+ bset_directory (&buffer_local_flags, make_fixnum (-1));
+ bset_backed_up (&buffer_local_flags, make_fixnum (-1));
+ bset_save_length (&buffer_local_flags, make_fixnum (-1));
+ bset_auto_save_file_name (&buffer_local_flags, make_fixnum (-1));
+ bset_read_only (&buffer_local_flags, make_fixnum (-1));
+ bset_major_mode (&buffer_local_flags, make_fixnum (-1));
+ bset_mode_name (&buffer_local_flags, make_fixnum (-1));
+ bset_undo_list (&buffer_local_flags, make_fixnum (-1));
+ bset_mark_active (&buffer_local_flags, make_fixnum (-1));
+ bset_point_before_scroll (&buffer_local_flags, make_fixnum (-1));
+ bset_file_truename (&buffer_local_flags, make_fixnum (-1));
+ bset_invisibility_spec (&buffer_local_flags, make_fixnum (-1));
+ bset_file_format (&buffer_local_flags, make_fixnum (-1));
+ bset_auto_save_file_format (&buffer_local_flags, make_fixnum (-1));
+ bset_display_count (&buffer_local_flags, make_fixnum (-1));
+ bset_display_time (&buffer_local_flags, make_fixnum (-1));
+ bset_enable_multibyte_characters (&buffer_local_flags, make_fixnum (-1));
/* These used to be stuck at 0 by default, but now that the all-zero value
means Qnil, we have to initialize them explicitly. */
- bset_name (&buffer_local_flags, make_number (0));
- bset_mark (&buffer_local_flags, make_number (0));
- bset_local_var_alist (&buffer_local_flags, make_number (0));
- bset_keymap (&buffer_local_flags, make_number (0));
- bset_downcase_table (&buffer_local_flags, make_number (0));
- bset_upcase_table (&buffer_local_flags, make_number (0));
- bset_case_canon_table (&buffer_local_flags, make_number (0));
- bset_case_eqv_table (&buffer_local_flags, make_number (0));
- bset_minor_modes (&buffer_local_flags, make_number (0));
- bset_width_table (&buffer_local_flags, make_number (0));
- bset_pt_marker (&buffer_local_flags, make_number (0));
- bset_begv_marker (&buffer_local_flags, make_number (0));
- bset_zv_marker (&buffer_local_flags, make_number (0));
- bset_last_selected_window (&buffer_local_flags, make_number (0));
+ bset_name (&buffer_local_flags, make_fixnum (0));
+ bset_mark (&buffer_local_flags, make_fixnum (0));
+ bset_local_var_alist (&buffer_local_flags, make_fixnum (0));
+ bset_keymap (&buffer_local_flags, make_fixnum (0));
+ bset_downcase_table (&buffer_local_flags, make_fixnum (0));
+ bset_upcase_table (&buffer_local_flags, make_fixnum (0));
+ bset_case_canon_table (&buffer_local_flags, make_fixnum (0));
+ bset_case_eqv_table (&buffer_local_flags, make_fixnum (0));
+ bset_minor_modes (&buffer_local_flags, make_fixnum (0));
+ bset_width_table (&buffer_local_flags, make_fixnum (0));
+ bset_pt_marker (&buffer_local_flags, make_fixnum (0));
+ bset_begv_marker (&buffer_local_flags, make_fixnum (0));
+ bset_zv_marker (&buffer_local_flags, make_fixnum (0));
+ bset_last_selected_window (&buffer_local_flags, make_fixnum (0));
idx = 1;
XSETFASTINT (BVAR (&buffer_local_flags, mode_line_format), idx); ++idx;
@@ -5166,10 +5192,15 @@ init_buffer_once (void)
XSETFASTINT (BVAR (&buffer_local_flags, extra_line_spacing), idx); ++idx;
XSETFASTINT (BVAR (&buffer_local_flags, cursor_in_non_selected_windows), idx); ++idx;
+ /* buffer_local_flags contains no pointers, so it's safe to treat it
+ as a blob for pdumper. */
+ PDUMPER_REMEMBER_SCALAR (buffer_local_flags);
+
/* Need more room? */
if (idx >= MAX_PER_BUFFER_VARS)
emacs_abort ();
last_per_buffer_idx = idx;
+ PDUMPER_REMEMBER_SCALAR (last_per_buffer_idx);
/* Make sure all markable slots in buffer_defaults
are initialized reasonably, so mark_buffer won't choke. */
@@ -5264,7 +5295,9 @@ init_buffer_once (void)
Vbuffer_alist = Qnil;
current_buffer = 0;
+ pdumper_remember_lv_ptr_raw (&current_buffer, Lisp_Vectorlike);
all_buffers = 0;
+ pdumper_remember_lv_ptr_raw (&all_buffers, Lisp_Vectorlike);
QSFundamental = build_pure_c_string ("Fundamental");
@@ -5288,14 +5321,12 @@ init_buffer_once (void)
}
void
-init_buffer (int initialized)
+init_buffer (void)
{
- char *pwd;
Lisp_Object temp;
- ptrdiff_t len;
#ifdef USE_MMAP_FOR_BUFFERS
- if (initialized)
+ if (dumped_with_unexec_p ())
{
struct buffer *b;
@@ -5336,9 +5367,6 @@ init_buffer (int initialized)
eassert (b->text->beg != NULL);
}
}
-#else /* not USE_MMAP_FOR_BUFFERS */
- /* Avoid compiler warnings. */
- (void) initialized;
#endif /* USE_MMAP_FOR_BUFFERS */
AUTO_STRING (scratch, "*scratch*");
@@ -5346,7 +5374,7 @@ init_buffer (int initialized)
if (NILP (BVAR (&buffer_defaults, enable_multibyte_characters)))
Fset_buffer_multibyte (Qnil);
- pwd = emacs_get_current_dir_name ();
+ char const *pwd = emacs_wd;
if (!pwd)
{
@@ -5358,22 +5386,16 @@ init_buffer (int initialized)
{
/* Maybe this should really use some standard subroutine
whose definition is filename syntax dependent. */
- len = strlen (pwd);
- if (!(IS_DIRECTORY_SEP (pwd[len - 1])))
- {
- /* Grow buffer to add directory separator and '\0'. */
- pwd = realloc (pwd, len + 2);
- if (!pwd)
- fatal ("get_current_dir_name: %s\n", strerror (errno));
- pwd[len] = DIRECTORY_SEP;
- pwd[len + 1] = '\0';
- len++;
- }
+ ptrdiff_t len = strlen (pwd);
+ bool add_slash = ! IS_DIRECTORY_SEP (pwd[len - 1]);
/* At this moment, we still don't know how to decode the directory
name. So, we keep the bytes in unibyte form so that file I/O
routines correctly get the original bytes. */
- bset_directory (current_buffer, make_unibyte_string (pwd, len));
+ Lisp_Object dirname = make_unibyte_string (pwd, len + add_slash);
+ if (add_slash)
+ SSET (dirname, len, DIRECTORY_SEP);
+ bset_directory (current_buffer, dirname);
/* Add /: to the front of the name
if it would otherwise be treated as magic. */
@@ -5394,8 +5416,6 @@ init_buffer (int initialized)
temp = get_minibuffer (0);
bset_directory (XBUFFER (temp), BVAR (current_buffer, directory));
-
- free (pwd);
}
/* Similar to defvar_lisp but define a variable whose value is the
@@ -5427,7 +5447,7 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring,
bo_fwd->predicate = predicate;
sym->u.s.declared_special = true;
sym->u.s.redirect = SYMBOL_FORWARDED;
- SET_SYMBOL_FWD (sym, (union Lisp_Fwd *) bo_fwd);
+ SET_SYMBOL_FWD (sym, bo_fwd);
XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym);
if (PER_BUFFER_IDX (offset) == 0)
@@ -5442,8 +5462,7 @@ void
syms_of_buffer (void)
{
staticpro (&last_overlay_modification_hooks);
- last_overlay_modification_hooks
- = Fmake_vector (make_number (10), Qnil);
+ last_overlay_modification_hooks = make_nil_vector (10);
staticpro (&QSFundamental);
staticpro (&Vbuffer_alist);
@@ -5481,7 +5500,7 @@ syms_of_buffer (void)
Qoverwrite_mode_binary));
Fput (Qprotected_field, Qerror_conditions,
- listn (CONSTYPE_PURE, 2, Qprotected_field, Qerror));
+ pure_list (Qprotected_field, Qerror));
Fput (Qprotected_field, Qerror_message,
build_pure_c_string ("Attempt to modify a protected field"));
@@ -5640,7 +5659,11 @@ This variable is never applied to a way of decoding a file while reading it. */
DEFVAR_PER_BUFFER ("bidi-display-reordering",
&BVAR (current_buffer, bidi_display_reordering), Qnil,
- doc: /* Non-nil means reorder bidirectional text for display in the visual order. */);
+ doc: /* Non-nil means reorder bidirectional text for display in the visual order.
+Setting this to nil is intended for use in debugging the display code.
+Don't set to nil in normal sessions, as that is not supported.
+See also `bidi-paragraph-direction'; setting that non-nil might
+speed up redisplay. */);
DEFVAR_PER_BUFFER ("bidi-paragraph-start-re",
&BVAR (current_buffer, bidi_paragraph_start_re), Qnil,
@@ -5728,8 +5751,8 @@ visual lines rather than logical lines. See the documentation of
DEFVAR_PER_BUFFER ("default-directory", &BVAR (current_buffer, directory),
Qstringp,
doc: /* Name of default directory of current buffer.
-It should be a directory name (as opposed to a directory file-name).
-On GNU and Unix systems, directory names end in a slash `/'.
+It should be an absolute directory name; on GNU and Unix systems,
+these names start with `/' or `~' and end with `/'.
To interactively change the default directory, use command `cd'. */);
DEFVAR_PER_BUFFER ("auto-fill-function", &BVAR (current_buffer, auto_fill_function),
@@ -6052,11 +6075,11 @@ An entry (TEXT . POSITION) represents the deletion of the string TEXT
from (abs POSITION). If POSITION is positive, point was at the front
of the text being deleted; if negative, point was at the end.
-An entry (t HIGH LOW USEC PSEC) indicates that the buffer was previously
-unmodified; (HIGH LOW USEC PSEC) is in the same style as (current-time)
-and is the visited file's modification time, as of that time. If the
-modification time of the most recent save is different, this entry is
-obsolete.
+An entry (t . TIMESTAMP), where TIMESTAMP is in the style of
+`current-time', indicates that the buffer was previously unmodified;
+TIMESTAMP is the visited file's modification time, as of that time.
+If the modification time of the most recent save is different, this
+entry is obsolete.
An entry (t . 0) means the buffer was previously unmodified but
its time stamp was unknown because it was not associated with a file.
@@ -6250,9 +6273,11 @@ The function `kill-all-local-variables' runs this before doing anything else. *
DEFVAR_LISP ("buffer-list-update-hook", Vbuffer_list_update_hook,
doc: /* Hook run when the buffer list changes.
-Functions running this hook are, `get-buffer-create',
-`make-indirect-buffer', `rename-buffer', `kill-buffer',
-`bury-buffer-internal' and `select-window'. */);
+Functions (implicitly) running this hook are `get-buffer-create',
+`make-indirect-buffer', `rename-buffer', `kill-buffer', `bury-buffer'
+and `select-window'. Functions run by this hook should avoid calling
+`select-window' with a nil NORECORD argument or `with-temp-buffer'
+since either may lead to infinite recursion. */);
Vbuffer_list_update_hook = Qnil;
DEFSYM (Qbuffer_list_update_hook, "buffer-list-update-hook");