#include <setjmp.h>
#include <unistd.h>
+#include <verify.h>
+
#include "lisp.h"
#include "intervals.h"
#include "window.h"
#define PER_BUFFER_SYMBOL(OFFSET) \
(*(Lisp_Object *)((OFFSET) + (char *) &buffer_local_symbols))
+/* Maximum length of an overlay vector. */
+#define OVERLAY_COUNT_MAX \
+ ((ptrdiff_t) min (MOST_POSITIVE_FIXNUM, \
+ min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Lisp_Object)))
+
/* Flags indicating which built-in buffer-local variables
are permanent locals. */
static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS];
static Lisp_Object QSFundamental; /* A string "Fundamental" */
static Lisp_Object Qkill_buffer_hook;
+static Lisp_Object Qbuffer_list_update_hook;
static Lisp_Object Qget_file_buffer;
static Lisp_Object Qoverlayp;
Lisp_Object Qpriority, Qbefore_string, Qafter_string;
+
static Lisp_Object Qevaporate;
Lisp_Object Qmodification_hooks;
Lisp_Object Qinsert_in_front_hooks;
Lisp_Object Qinsert_behind_hooks;
-static void alloc_buffer_text (struct buffer *, size_t);
+static void alloc_buffer_text (struct buffer *, ptrdiff_t);
static void free_buffer_text (struct buffer *b);
static struct Lisp_Overlay * copy_overlays (struct buffer *, struct Lisp_Overlay *);
-static void modify_overlay (struct buffer *, EMACS_INT, EMACS_INT);
+static void modify_overlay (struct buffer *, ptrdiff_t, ptrdiff_t);
static Lisp_Object buffer_lisp_local_variables (struct buffer *);
/* For debugging; temporary. See set_buffer_internal. */
DEFUN ("buffer-list", Fbuffer_list, Sbuffer_list, 0, 1, 0,
doc: /* Return a list of all existing live buffers.
-If the optional arg FRAME is a frame, we return the buffer list
-in the proper order for that frame: the buffers in FRAME's `buffer-list'
-frame parameter come first, followed by the rest of the buffers. */)
+If the optional arg FRAME is a frame, we return the buffer list in the
+proper order for that frame: the buffers show in FRAME come first,
+followed by the rest of the buffers. */)
(Lisp_Object frame)
{
Lisp_Object general;
Lisp_Object args[3];
CHECK_FRAME (frame);
-
framelist = Fcopy_sequence (XFRAME (frame)->buffer_list);
- prevlist = Fnreverse (Fcopy_sequence (XFRAME (frame)->buried_buffer_list));
+ prevlist = Fnreverse (Fcopy_sequence
+ (XFRAME (frame)->buried_buffer_list));
/* Remove from GENERAL any buffer that duplicates one in
FRAMELIST or PREVLIST. */
args[2] = prevlist;
return Fnconc (3, args);
}
-
- return general;
+ else
+ return general;
}
/* Like Fassoc, but use Fstring_equal to compare
BUF_END_UNCHANGED (b) = 0;
BUF_BEG_UNCHANGED (b) = 0;
*(BUF_GPT_ADDR (b)) = *(BUF_Z_ADDR (b)) = 0; /* Put an anchor '\0'. */
+ b->text->inhibit_shrinking = 0;
b->newline_cache = 0;
b->width_run_cache = 0;
/* Put this in the alist of all live buffers. */
XSETBUFFER (buffer, b);
Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buffer), Qnil));
+ /* And run buffer-list-update-hook. */
+ if (!NILP (Vrun_hooks))
+ call1 (Vrun_hooks, Qbuffer_list_update_hook);
/* An error in calling the function here (should someone redefine it)
can lead to infinite regress until you run out of stack. rms
for (; list; list = list->next)
{
Lisp_Object overlay, start, end, old_overlay;
- EMACS_INT charpos;
+ ptrdiff_t charpos;
XSETMISC (old_overlay, list);
charpos = marker_position (OVERLAY_START (old_overlay));
/* buffer-local Lisp variables start at `undo_list',
tho only the ones from `name' on are GC'd normally. */
- for (offset = PER_BUFFER_VAR_OFFSET (undo_list);
- offset < sizeof *to;
+ for (offset = PER_BUFFER_VAR_OFFSET (FIRST_FIELD_PER_BUFFER);
+ offset <= PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER);
offset += sizeof (Lisp_Object))
{
Lisp_Object obj;
set_buffer_internal_1 (old_b);
}
+ /* Run buffer-list-update-hook. */
+ if (!NILP (Vrun_hooks))
+ call1 (Vrun_hooks, Qbuffer_list_update_hook);
+
return buf;
}
b->prevent_redisplay_optimizations_p = 1;
BVAR (b, backed_up) = Qnil;
BUF_AUTOSAVE_MODIFF (b) = 0;
- b->auto_save_failure_time = -1;
+ b->auto_save_failure_time = 0;
BVAR (b, auto_save_file_name) = Qnil;
BVAR (b, read_only) = Qnil;
b->overlays_before = NULL;
/* buffer-local Lisp variables start at `undo_list',
tho only the ones from `name' on are GC'd normally. */
- for (offset = PER_BUFFER_VAR_OFFSET (undo_list);
- offset < sizeof *b;
+ for (offset = PER_BUFFER_VAR_OFFSET (FIRST_FIELD_PER_BUFFER);
+ offset <= PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER);
offset += sizeof (Lisp_Object))
{
int idx = PER_BUFFER_IDX (offset);
(register Lisp_Object name, Lisp_Object ignore)
{
register Lisp_Object gentemp, tem;
- EMACS_INT count;
- char number[INT_BUFSIZE_BOUND (EMACS_INT) + sizeof "<>"];
+ ptrdiff_t count;
+ char number[INT_BUFSIZE_BOUND (ptrdiff_t) + sizeof "<>"];
CHECK_STRING (name);
count = 1;
while (1)
{
- sprintf (number, "<%"pI"d>", ++count);
+ sprintf (number, "<%"pD"d>", ++count);
gentemp = concat2 (name, build_string (number));
tem = Fstring_equal (gentemp, ignore);
if (!NILP (tem))
/* buffer-local Lisp variables start at `undo_list',
tho only the ones from `name' on are GC'd normally. */
- for (offset = PER_BUFFER_VAR_OFFSET (undo_list);
- offset < sizeof (struct buffer);
+ for (offset = PER_BUFFER_VAR_OFFSET (FIRST_FIELD_PER_BUFFER);
+ offset <= PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER);
/* sizeof EMACS_INT == sizeof Lisp_Object */
offset += (sizeof (EMACS_INT)))
{
if (NILP (BVAR (current_buffer, filename))
&& !NILP (BVAR (current_buffer, auto_save_file_name)))
call0 (intern ("rename-auto-save-file"));
+
+ /* Run buffer-list-update-hook. */
+ if (!NILP (Vrun_hooks))
+ call1 (Vrun_hooks, Qbuffer_list_update_hook);
+
/* Refetch since that last call may have done GC. */
return BVAR (current_buffer, name);
}
DEFUN ("other-buffer", Fother_buffer, Sother_buffer, 0, 3, 0,
doc: /* Return most recently selected buffer other than BUFFER.
-Buffers not visible in windows are preferred to visible buffers,
-unless optional second argument VISIBLE-OK is non-nil.
-If the optional third argument FRAME is non-nil, use that frame's
-buffer list instead of the selected frame's buffer list.
-If no other buffer exists, the buffer `*scratch*' is returned.
-If BUFFER is omitted or nil, some interesting buffer is returned. */)
+Buffers not visible in windows are preferred to visible buffers, unless
+optional second argument VISIBLE-OK is non-nil. Ignore the argument
+BUFFER unless it denotes a live buffer. If the optional third argument
+FRAME is non-nil, use that frame's buffer list instead of the selected
+frame's buffer list.
+
+The buffer is found by scanning the selected or specified frame's buffer
+list first, followed by the list of all buffers. If no other buffer
+exists, return the buffer `*scratch*' (creating it if necessary). */)
(register Lisp_Object buffer, Lisp_Object visible_ok, Lisp_Object frame)
{
- register Lisp_Object tail, buf, notsogood, tem, pred, add_ons;
- notsogood = Qnil;
+ Lisp_Object Fset_buffer_major_mode (Lisp_Object buffer);
+ Lisp_Object tail, buf, pred;
+ Lisp_Object notsogood = Qnil;
if (NILP (frame))
frame = selected_frame;
CHECK_FRAME (frame);
- tail = Vbuffer_alist;
pred = frame_buffer_predicate (frame);
-
- /* Consider buffers that have been seen in the selected frame
- before other buffers. */
-
- tem = frame_buffer_list (frame);
- add_ons = Qnil;
- while (CONSP (tem))
+ /* Consider buffers that have been seen in the frame first. */
+ tail = XFRAME (frame)->buffer_list;
+ for (; CONSP (tail); tail = XCDR (tail))
{
- if (BUFFERP (XCAR (tem)))
- add_ons = Fcons (Fcons (Qnil, XCAR (tem)), add_ons);
- tem = XCDR (tem);
+ buf = XCAR (tail);
+ if (BUFFERP (buf) && !EQ (buf, buffer)
+ && !NILP (BVAR (XBUFFER (buf), name))
+ && (SREF (BVAR (XBUFFER (buf), name), 0) != ' ')
+ /* If the frame has a buffer_predicate, disregard buffers that
+ don't fit the predicate. */
+ && (NILP (pred) || !NILP (call1 (pred, buf))))
+ {
+ if (!NILP (visible_ok)
+ || NILP (Fget_buffer_window (buf, Qvisible)))
+ return buf;
+ else if (NILP (notsogood))
+ notsogood = buf;
+ }
}
- tail = nconc2 (Fnreverse (add_ons), tail);
+ /* Consider alist of all buffers next. */
+ tail = Vbuffer_alist;
for (; CONSP (tail); tail = XCDR (tail))
{
buf = Fcdr (XCAR (tail));
- if (EQ (buf, buffer))
- continue;
+ if (BUFFERP (buf) && !EQ (buf, buffer)
+ && !NILP (BVAR (XBUFFER (buf), name))
+ && (SREF (BVAR (XBUFFER (buf), name), 0) != ' ')
+ /* If the frame has a buffer_predicate, disregard buffers that
+ don't fit the predicate. */
+ && (NILP (pred) || !NILP (call1 (pred, buf))))
+ {
+ if (!NILP (visible_ok)
+ || NILP (Fget_buffer_window (buf, Qvisible)))
+ return buf;
+ else if (NILP (notsogood))
+ notsogood = buf;
+ }
+ }
+
+ if (!NILP (notsogood))
+ return notsogood;
+ else
+ {
+ buf = Fget_buffer (build_string ("*scratch*"));
if (NILP (buf))
- continue;
- if (NILP (BVAR (XBUFFER (buf), name)))
- continue;
- if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ')
- continue;
- /* If the selected frame has a buffer_predicate,
- disregard buffers that don't fit the predicate. */
- if (!NILP (pred))
{
- tem = call1 (pred, buf);
- if (NILP (tem))
- continue;
+ buf = Fget_buffer_create (build_string ("*scratch*"));
+ Fset_buffer_major_mode (buf);
}
+ return buf;
+ }
+}
- if (NILP (visible_ok))
- tem = Fget_buffer_window (buf, Qvisible);
- else
- tem = Qnil;
- if (NILP (tem))
+/* The following function is a safe variant of Fother_buffer: It doesn't
+ pay attention to any frame-local buffer lists, doesn't care about
+ visibility of buffers, and doesn't evaluate any frame predicates. */
+
+Lisp_Object
+other_buffer_safely (Lisp_Object buffer)
+{
+ Lisp_Object Fset_buffer_major_mode (Lisp_Object buffer);
+ Lisp_Object tail, buf;
+
+ tail = Vbuffer_alist;
+ for (; CONSP (tail); tail = XCDR (tail))
+ {
+ buf = Fcdr (XCAR (tail));
+ if (BUFFERP (buf) && !EQ (buf, buffer)
+ && !NILP (BVAR (XBUFFER (buf), name))
+ && (SREF (BVAR (XBUFFER (buf), name), 0) != ' '))
return buf;
- if (NILP (notsogood))
- notsogood = buf;
}
- if (!NILP (notsogood))
- return notsogood;
+
buf = Fget_buffer (build_string ("*scratch*"));
if (NILP (buf))
{
buf = Fget_buffer_create (build_string ("*scratch*"));
Fset_buffer_major_mode (buf);
}
+
return buf;
}
\f
/* Run hooks with the buffer to be killed the current buffer. */
{
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
Lisp_Object arglist[1];
record_unwind_protect (save_excursion_restore, save_excursion_save ());
if (NILP (BVAR (b, name)))
return Qnil;
+ /* These may run Lisp code and into infinite loops (if someone
+ insisted on circular lists) so allow quitting here. */
+ replace_buffer_in_windows (buffer);
+ frames_discard_buffer (buffer);
+
clear_charpos_cache (b);
tem = Vinhibit_quit;
Vinhibit_quit = Qt;
- replace_buffer_in_all_windows (buffer);
+ /* Remove the buffer from the list of all buffers. */
Vbuffer_alist = Fdelq (Frassq (buffer, Vbuffer_alist), Vbuffer_alist);
- frames_discard_buffer (buffer);
+ /* If replace_buffer_in_windows didn't do its job correctly fix that
+ now. */
+ replace_buffer_in_windows_safely (buffer);
Vinhibit_quit = tem;
/* Delete any auto-save file, if we saved it in this session.
UNBLOCK_INPUT;
BVAR (b, undo_list) = Qnil;
+ /* Run buffer-list-update-hook. */
+ if (!NILP (Vrun_hooks))
+ call1 (Vrun_hooks, Qbuffer_list_update_hook);
+
return Qt;
}
\f
-/* Move the assoc for buffer BUF to the front of buffer-alist. Since
- we do this each time BUF is selected visibly, the more recently
- selected buffers are always closer to the front of the list. This
- means that other_buffer is more likely to choose a relevant buffer. */
+/* Move association for BUFFER to the front of buffer (a)lists. Since
+ we do this each time BUFFER is selected visibly, the more recently
+ selected buffers are always closer to the front of those lists. This
+ means that other_buffer is more likely to choose a relevant buffer.
+
+ Note that this moves BUFFER to the front of the buffer lists of the
+ selected frame even if BUFFER is not shown there. If BUFFER is not
+ shown in the selected frame, consider the present behavior a feature.
+ `select-window' gets this right since it shows BUFFER in the selected
+ window when calling us. */
void
-record_buffer (Lisp_Object buf)
+record_buffer (Lisp_Object buffer)
{
- register Lisp_Object list, prev;
- Lisp_Object frame;
- frame = selected_frame;
+ Lisp_Object aelt, aelt_cons, tem;
+ register struct frame *f = XFRAME (selected_frame);
- prev = Qnil;
- for (list = Vbuffer_alist; CONSP (list); list = XCDR (list))
- {
- if (EQ (XCDR (XCAR (list)), buf))
- break;
- prev = list;
- }
+ CHECK_BUFFER (buffer);
- /* Effectively do Vbuffer_alist = Fdelq (list, Vbuffer_alist);
- we cannot use Fdelq itself here because it allows quitting. */
+ /* Update Vbuffer_alist (we know that it has an entry for BUFFER).
+ Don't allow quitting since this might leave the buffer list in an
+ inconsistent state. */
+ tem = Vinhibit_quit;
+ Vinhibit_quit = Qt;
+ aelt = Frassq (buffer, Vbuffer_alist);
+ aelt_cons = Fmemq (aelt, Vbuffer_alist);
+ Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
+ XSETCDR (aelt_cons, Vbuffer_alist);
+ Vbuffer_alist = aelt_cons;
+ Vinhibit_quit = tem;
- if (NILP (prev))
- Vbuffer_alist = XCDR (Vbuffer_alist);
- else
- XSETCDR (prev, XCDR (XCDR (prev)));
+ /* Update buffer list of selected frame. */
+ f->buffer_list = Fcons (buffer, Fdelq (buffer, f->buffer_list));
+ f->buried_buffer_list = Fdelq (buffer, f->buried_buffer_list);
- XSETCDR (list, Vbuffer_alist);
- Vbuffer_alist = list;
+ /* Run buffer-list-update-hook. */
+ if (!NILP (Vrun_hooks))
+ call1 (Vrun_hooks, Qbuffer_list_update_hook);
+}
- /* Effectively do a delq on buried_buffer_list. */
- prev = Qnil;
- for (list = XFRAME (frame)->buried_buffer_list; CONSP (list);
- list = XCDR (list))
- {
- if (EQ (XCAR (list), buf))
- {
- if (NILP (prev))
- XFRAME (frame)->buried_buffer_list = XCDR (list);
- else
- XSETCDR (prev, XCDR (XCDR (prev)));
- break;
- }
- prev = list;
- }
+/* Move BUFFER to the end of the buffer (a)lists. Do nothing if the
+ buffer is killed. For the selected frame's buffer list this moves
+ BUFFER to its end even if it was never shown in that frame. If
+ this happens we have a feature, hence `unrecord-buffer' should be
+ called only when BUFFER was shown in the selected frame. */
- /* Now move this buffer to the front of frame_buffer_list also. */
+DEFUN ("bury-buffer-internal", Fbury_buffer_internal, Sbury_buffer_internal,
+ 1, 1, 0,
+ doc: /* Move BUFFER to the end of the buffer list. */)
+ (Lisp_Object buffer)
+{
+ Lisp_Object aelt, aelt_cons, tem;
+ register struct frame *f = XFRAME (selected_frame);
- prev = Qnil;
- for (list = frame_buffer_list (frame); CONSP (list);
- list = XCDR (list))
- {
- if (EQ (XCAR (list), buf))
- break;
- prev = list;
- }
+ CHECK_BUFFER (buffer);
- /* Effectively do delq. */
+ /* Update Vbuffer_alist (we know that it has an entry for BUFFER).
+ Don't allow quitting since this might leave the buffer list in an
+ inconsistent state. */
+ tem = Vinhibit_quit;
+ Vinhibit_quit = Qt;
+ aelt = Frassq (buffer, Vbuffer_alist);
+ aelt_cons = Fmemq (aelt, Vbuffer_alist);
+ Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
+ XSETCDR (aelt_cons, Qnil);
+ Vbuffer_alist = nconc2 (Vbuffer_alist, aelt_cons);
+ Vinhibit_quit = tem;
- if (CONSP (list))
- {
- if (NILP (prev))
- set_frame_buffer_list (frame,
- XCDR (frame_buffer_list (frame)));
- else
- XSETCDR (prev, XCDR (XCDR (prev)));
+ /* Update buffer lists of selected frame. */
+ f->buffer_list = Fdelq (buffer, f->buffer_list);
+ f->buried_buffer_list = Fcons (buffer, Fdelq (buffer, f->buried_buffer_list));
- XSETCDR (list, frame_buffer_list (frame));
- set_frame_buffer_list (frame, list);
- }
- else
- set_frame_buffer_list (frame, Fcons (buf, frame_buffer_list (frame)));
+ /* Run buffer-list-update-hook. */
+ if (!NILP (Vrun_hooks))
+ call1 (Vrun_hooks, Qbuffer_list_update_hook);
+
+ return Qnil;
}
DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, Sset_buffer_major_mode, 1, 1, 0,
the current buffer's major mode. */)
(Lisp_Object buffer)
{
- int count;
+ ptrdiff_t count;
Lisp_Object function;
CHECK_BUFFER (buffer);
return unbind_to (count, Qnil);
}
-/* Switch to buffer BUFFER in the selected window.
- If NORECORD is non-nil, don't call record_buffer. */
-
-static Lisp_Object
-switch_to_buffer_1 (Lisp_Object buffer_or_name, Lisp_Object norecord)
-{
- register Lisp_Object buffer;
-
- if (NILP (buffer_or_name))
- buffer = Fother_buffer (Fcurrent_buffer (), Qnil, Qnil);
- else
- {
- buffer = Fget_buffer (buffer_or_name);
- if (NILP (buffer))
- {
- buffer = Fget_buffer_create (buffer_or_name);
- Fset_buffer_major_mode (buffer);
- }
- }
- Fset_buffer (buffer);
- if (NILP (norecord))
- record_buffer (buffer);
-
- Fset_window_buffer (EQ (selected_window, minibuf_window)
- ? Fnext_window (minibuf_window, Qnil, Qnil)
- : selected_window,
- buffer, Qnil);
-
- return buffer;
-}
-
-DEFUN ("switch-to-buffer", Fswitch_to_buffer, Sswitch_to_buffer, 1, 2,
- "(list (read-buffer-to-switch \"Switch to buffer: \"))",
- doc: /* Make BUFFER-OR-NAME current and display it in selected window.
-BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
-nil. Return the buffer switched to.
-
-If BUFFER-OR-NAME is a string and does not identify an existing
-buffer, create a new buffer with that name. Interactively, if
-`confirm-nonexistent-file-or-buffer' is non-nil, request
-confirmation before creating a new buffer. If BUFFER-OR-NAME is
-nil, switch to buffer returned by `other-buffer'.
-
-Optional second arg NORECORD non-nil means do not put this buffer
-at the front of the list of recently selected ones. This
-function returns the buffer it switched to as a Lisp object.
-
-If the selected window is the minibuffer window or dedicated to
-its buffer, use `pop-to-buffer' for displaying the buffer.
-
-WARNING: This is NOT the way to work on another buffer temporarily
-within a Lisp program! Use `set-buffer' instead. That avoids
-messing with the window-buffer correspondences. */)
- (Lisp_Object buffer_or_name, Lisp_Object norecord)
-{
- if (EQ (buffer_or_name, Fwindow_buffer (selected_window)))
- {
- /* Basically a NOP. Avoid signalling an error in the case where
- the selected window is dedicated, or a minibuffer. */
-
- /* But do put this buffer at the front of the buffer list, unless
- that has been inhibited. Note that even if BUFFER-OR-NAME is
- at the front of the main buffer-list already, we still want to
- move it to the front of the frame's buffer list. */
- if (NILP (norecord))
- record_buffer (buffer_or_name);
- return Fset_buffer (buffer_or_name);
- }
- else if (EQ (minibuf_window, selected_window)
- /* If `dedicated' is neither nil nor t, it means it's
- dedicatedness can be overridden by an explicit request
- such as a call to switch-to-buffer. */
- || EQ (Fwindow_dedicated_p (selected_window), Qt))
- /* We can't use the selected window so let `pop-to-buffer' try some
- other window. */
- return call3 (intern ("pop-to-buffer"), buffer_or_name, Qnil, norecord);
- else
- return switch_to_buffer_1 (buffer_or_name, norecord);
-}
-
DEFUN ("current-buffer", Fcurrent_buffer, Scurrent_buffer, 0, 0, 0,
doc: /* Return the current buffer as a Lisp object. */)
(void)
xsignal1 (Qbuffer_read_only, Fcurrent_buffer ());
return Qnil;
}
-
-DEFUN ("bury-buffer", Fbury_buffer, Sbury_buffer, 0, 1, "",
- doc: /* Put BUFFER-OR-NAME at the end of the list of all buffers.
-There it is the least likely candidate for `other-buffer' to return;
-thus, the least likely buffer for \\[switch-to-buffer] to select by
-default.
-
-The argument may be a buffer name or an actual buffer object. If
-BUFFER-OR-NAME is nil or omitted, bury the current buffer and remove it
-from the selected window if it is displayed there. If the selected
-window is dedicated to its buffer, delete that window if there are other
-windows on the same frame. If the selected window is the only window on
-its frame, iconify that frame. */)
- (register Lisp_Object buffer_or_name)
-{
- Lisp_Object buffer;
-
- /* Figure out what buffer we're going to bury. */
- if (NILP (buffer_or_name))
- {
- Lisp_Object tem;
- XSETBUFFER (buffer, current_buffer);
-
- tem = Fwindow_buffer (selected_window);
- /* If we're burying the current buffer, unshow it. */
- if (EQ (buffer, tem))
- {
- if (NILP (Fwindow_dedicated_p (selected_window)))
- Fswitch_to_buffer (Fother_buffer (buffer, Qnil, Qnil), Qnil);
- else if (NILP (XWINDOW (selected_window)->parent))
- Ficonify_frame (Fwindow_frame (selected_window));
- else
- Fdelete_window (selected_window);
- }
- }
- else
- {
- buffer = Fget_buffer (buffer_or_name);
- if (NILP (buffer))
- nsberror (buffer_or_name);
- }
-
- /* Move buffer to the end of the buffer list. Do nothing if the
- buffer is killed. */
- if (!NILP (BVAR (XBUFFER (buffer), name)))
- {
- Lisp_Object aelt, list;
-
- aelt = Frassq (buffer, Vbuffer_alist);
- list = Fmemq (aelt, Vbuffer_alist);
- Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
- XSETCDR (list, Qnil);
- Vbuffer_alist = nconc2 (Vbuffer_alist, list);
-
- XFRAME (selected_frame)->buffer_list
- = Fdelq (buffer, XFRAME (selected_frame)->buffer_list);
- XFRAME (selected_frame)->buried_buffer_list
- = Fcons (buffer, Fdelq (buffer, XFRAME (selected_frame)->buried_buffer_list));
- }
-
- return Qnil;
-}
\f
DEFUN ("erase-buffer", Ferase_buffer, Serase_buffer, 0, 0, "*",
doc: /* Delete the entire contents of the current buffer.
tem = *b; *b = *e; *e = tem;
}
- if (!(BEGV <= XINT (*b) && XINT (*b) <= XINT (*e)
- && XINT (*e) <= ZV))
+ if (! (BEGV <= XINT (*b) && XINT (*e) <= ZV))
args_out_of_range (*b, *e);
}
\f
/* Advance BYTE_POS up to a character boundary
and return the adjusted position. */
-static EMACS_INT
-advance_to_char_boundary (EMACS_INT byte_pos)
+static ptrdiff_t
+advance_to_char_boundary (ptrdiff_t byte_pos)
{
int c;
{
/* We should advance BYTE_POS only when C is a constituent of a
multibyte sequence. */
- EMACS_INT orig_byte_pos = byte_pos;
+ ptrdiff_t orig_byte_pos = byte_pos;
do
{
(POINTER_TYPE **) ¤t_buffer->own_text.beg);
#endif /* REL_ALLOC */
- swapfield (pt, EMACS_INT);
- swapfield (pt_byte, EMACS_INT);
- swapfield (begv, EMACS_INT);
- swapfield (begv_byte, EMACS_INT);
- swapfield (zv, EMACS_INT);
- swapfield (zv_byte, EMACS_INT);
+ swapfield (pt, ptrdiff_t);
+ swapfield (pt_byte, ptrdiff_t);
+ swapfield (begv, ptrdiff_t);
+ swapfield (begv_byte, ptrdiff_t);
+ swapfield (zv, ptrdiff_t);
+ swapfield (zv_byte, ptrdiff_t);
eassert (!current_buffer->base_buffer);
eassert (!other_buffer->base_buffer);
current_buffer->clip_changed = 1; other_buffer->clip_changed = 1;
other_buffer->prevent_redisplay_optimizations_p = 1;
swapfield (overlays_before, struct Lisp_Overlay *);
swapfield (overlays_after, struct Lisp_Overlay *);
- swapfield (overlay_center, EMACS_INT);
+ swapfield (overlay_center, ptrdiff_t);
swapfield_ (undo_list, Lisp_Object);
swapfield_ (mark, Lisp_Object);
swapfield_ (enable_multibyte_characters, Lisp_Object);
{
struct Lisp_Marker *tail, *markers;
struct buffer *other;
- EMACS_INT begv, zv;
+ ptrdiff_t begv, zv;
int narrowed = (BEG != BEGV || Z != ZV);
int modified_p = !NILP (Fbuffer_modified_p (Qnil));
Lisp_Object old_undo = BVAR (current_buffer, undo_list);
if (NILP (flag))
{
- EMACS_INT pos, stop;
+ ptrdiff_t pos, stop;
unsigned char *p;
/* Do this first, so it can use CHAR_TO_BYTE
}
else
{
- EMACS_INT pt = PT;
- EMACS_INT pos, stop;
+ ptrdiff_t pt = PT;
+ ptrdiff_t pos, stop;
unsigned char *p, *pend;
/* Be sure not to have a multibyte sequence striding over the GAP.
while (! CHAR_HEAD_P (*q) && q > BEG_ADDR) q--;
if (LEADING_CODE_P (*q))
{
- EMACS_INT new_gpt = GPT_BYTE - (GPT_ADDR - q);
+ ptrdiff_t new_gpt = GPT_BYTE - (GPT_ADDR - q);
move_gap_both (new_gpt, new_gpt);
}
ZV = chars_in_text (BEG_ADDR, ZV_BYTE - BEG_BYTE) + BEG;
{
- EMACS_INT byte = advance_to_char_boundary (PT_BYTE);
- EMACS_INT position;
+ ptrdiff_t byte = advance_to_char_boundary (PT_BYTE);
+ ptrdiff_t position;
if (byte > GPT_BYTE)
position = chars_in_text (GAP_END_ADDR, byte - GPT_BYTE) + GPT;
*NEXT_PTR is guaranteed to be not equal to POS, unless it is the
default (BEGV or ZV). */
-int
-overlays_at (EMACS_INT pos, int extend, Lisp_Object **vec_ptr, int *len_ptr,
- EMACS_INT *next_ptr, EMACS_INT *prev_ptr, int change_req)
+ptrdiff_t
+overlays_at (EMACS_INT pos, int extend, Lisp_Object **vec_ptr,
+ ptrdiff_t *len_ptr,
+ ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr, int change_req)
{
Lisp_Object overlay, start, end;
struct Lisp_Overlay *tail;
- int idx = 0;
- int len = *len_ptr;
+ ptrdiff_t idx = 0;
+ ptrdiff_t len = *len_ptr;
Lisp_Object *vec = *vec_ptr;
- EMACS_INT next = ZV;
- EMACS_INT prev = BEGV;
+ ptrdiff_t next = ZV;
+ ptrdiff_t prev = BEGV;
int inhibit_storing = 0;
for (tail = current_buffer->overlays_before; tail; tail = tail->next)
{
- EMACS_INT startpos, endpos;
+ ptrdiff_t startpos, endpos;
XSETMISC (overlay, tail);
Either make it bigger, or don't store any more in it. */
if (extend)
{
- /* Make it work with an initial len == 0. */
- len *= 2;
- if (len == 0)
- len = 4;
- *len_ptr = len;
- vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
+ vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
+ sizeof *vec);
*vec_ptr = vec;
+ len = *len_ptr;
}
else
inhibit_storing = 1;
for (tail = current_buffer->overlays_after; tail; tail = tail->next)
{
- EMACS_INT startpos, endpos;
+ ptrdiff_t startpos, endpos;
XSETMISC (overlay, tail);
{
if (extend)
{
- /* Make it work with an initial len == 0. */
- len *= 2;
- if (len == 0)
- len = 4;
- *len_ptr = len;
- vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
+ vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
+ sizeof *vec);
*vec_ptr = vec;
+ len = *len_ptr;
}
else
inhibit_storing = 1;
and we store only as many overlays as will fit.
But we still return the total number of overlays. */
-static int
+static ptrdiff_t
overlays_in (EMACS_INT beg, EMACS_INT end, int extend,
- Lisp_Object **vec_ptr, int *len_ptr,
- EMACS_INT *next_ptr, EMACS_INT *prev_ptr)
+ 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;
- int idx = 0;
- int len = *len_ptr;
+ ptrdiff_t idx = 0;
+ ptrdiff_t len = *len_ptr;
Lisp_Object *vec = *vec_ptr;
- EMACS_INT next = ZV;
- EMACS_INT prev = BEGV;
+ ptrdiff_t next = ZV;
+ ptrdiff_t prev = BEGV;
int inhibit_storing = 0;
int end_is_Z = end == Z;
for (tail = current_buffer->overlays_before; tail; tail = tail->next)
{
- EMACS_INT startpos, endpos;
+ ptrdiff_t startpos, endpos;
XSETMISC (overlay, tail);
Either make it bigger, or don't store any more in it. */
if (extend)
{
- /* Make it work with an initial len == 0. */
- len *= 2;
- if (len == 0)
- len = 4;
- *len_ptr = len;
- vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
+ vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
+ sizeof *vec);
*vec_ptr = vec;
+ len = *len_ptr;
}
else
inhibit_storing = 1;
for (tail = current_buffer->overlays_after; tail; tail = tail->next)
{
- EMACS_INT startpos, endpos;
+ ptrdiff_t startpos, endpos;
XSETMISC (overlay, tail);
{
if (extend)
{
- /* Make it work with an initial len == 0. */
- len *= 2;
- if (len == 0)
- len = 4;
- *len_ptr = len;
- vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
+ vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
+ sizeof *vec);
*vec_ptr = vec;
+ len = *len_ptr;
}
else
inhibit_storing = 1;
int
mouse_face_overlay_overlaps (Lisp_Object overlay)
{
- EMACS_INT start = OVERLAY_POSITION (OVERLAY_START (overlay));
- EMACS_INT end = OVERLAY_POSITION (OVERLAY_END (overlay));
- int n, i, size;
+ ptrdiff_t start = OVERLAY_POSITION (OVERLAY_START (overlay));
+ ptrdiff_t end = OVERLAY_POSITION (OVERLAY_END (overlay));
+ ptrdiff_t n, i, size;
Lisp_Object *v, tem;
size = 10;
\f
/* Fast function to just test if we're at an overlay boundary. */
int
-overlay_touches_p (EMACS_INT pos)
+overlay_touches_p (ptrdiff_t pos)
{
Lisp_Object overlay;
struct Lisp_Overlay *tail;
for (tail = current_buffer->overlays_before; tail; tail = tail->next)
{
- EMACS_INT endpos;
+ ptrdiff_t endpos;
XSETMISC (overlay ,tail);
if (!OVERLAYP (overlay))
for (tail = current_buffer->overlays_after; tail; tail = tail->next)
{
- EMACS_INT startpos;
+ ptrdiff_t startpos;
XSETMISC (overlay, tail);
if (!OVERLAYP (overlay))
struct sortvec
{
Lisp_Object overlay;
- EMACS_INT beg, end;
- int priority;
+ ptrdiff_t beg, end;
+ EMACS_INT priority;
};
static int
const struct sortvec *s1 = (const struct sortvec *) v1;
const struct sortvec *s2 = (const struct sortvec *) v2;
if (s1->priority != s2->priority)
- return s1->priority - s2->priority;
+ return s1->priority < s2->priority ? -1 : 1;
if (s1->beg != s2->beg)
- return s1->beg - s2->beg;
+ return s1->beg < s2->beg ? -1 : 1;
if (s1->end != s2->end)
- return s2->end - s1->end;
+ return s2->end < s1->end ? -1 : 1;
return 0;
}
/* Sort an array of overlays by priority. The array is modified in place.
The return value is the new size; this may be smaller than the original
size if some of the overlays were invalid or were window-specific. */
-int
-sort_overlays (Lisp_Object *overlay_vec, int noverlays, struct window *w)
+ptrdiff_t
+sort_overlays (Lisp_Object *overlay_vec, ptrdiff_t noverlays, struct window *w)
{
- int i, j;
+ ptrdiff_t i, j;
struct sortvec *sortvec;
sortvec = (struct sortvec *) alloca (noverlays * sizeof (struct sortvec));
struct sortstr
{
Lisp_Object string, string2;
- int size;
- int priority;
+ ptrdiff_t size;
+ EMACS_INT priority;
};
struct sortstrlist
{
struct sortstr *buf; /* An array that expands as needed; never freed. */
- int size; /* Allocated length of that array. */
- int used; /* How much of the array is currently in use. */
- EMACS_INT bytes; /* Total length of the strings in buf. */
+ ptrdiff_t size; /* Allocated length of that array. */
+ ptrdiff_t used; /* How much of the array is currently in use. */
+ ptrdiff_t bytes; /* Total length of the strings in buf. */
};
/* Buffers for storing information about the overlays touching a given
static unsigned char *overlay_str_buf;
/* Allocated length of overlay_str_buf. */
-static EMACS_INT overlay_str_len;
+static ptrdiff_t overlay_str_len;
/* A comparison function suitable for passing to qsort. */
static int
struct sortstr *s1 = (struct sortstr *)as1;
struct sortstr *s2 = (struct sortstr *)as2;
if (s1->size != s2->size)
- return s2->size - s1->size;
+ return s2->size < s1->size ? -1 : 1;
if (s1->priority != s2->priority)
- return s1->priority - s2->priority;
+ return s1->priority < s2->priority ? -1 : 1;
return 0;
}
static void
-record_overlay_string (struct sortstrlist *ssl, Lisp_Object str, Lisp_Object str2, Lisp_Object pri, int size)
+record_overlay_string (struct sortstrlist *ssl, Lisp_Object str,
+ Lisp_Object str2, Lisp_Object pri, ptrdiff_t size)
{
- EMACS_INT nbytes;
+ ptrdiff_t nbytes;
if (ssl->used == ssl->size)
- {
- if (ssl->buf)
- ssl->size *= 2;
- else
- ssl->size = 5;
- ssl->buf = ((struct sortstr *)
- xrealloc (ssl->buf, ssl->size * sizeof (struct sortstr)));
- }
+ ssl->buf = xpalloc (ssl->buf, &ssl->size, 5, -1, sizeof *ssl->buf);
ssl->buf[ssl->used].string = str;
ssl->buf[ssl->used].string2 = str2;
ssl->buf[ssl->used].size = size;
else
nbytes = SBYTES (str);
+ if (INT_ADD_OVERFLOW (ssl->bytes, nbytes))
+ memory_full (SIZE_MAX);
ssl->bytes += nbytes;
if (STRINGP (str2))
else
nbytes = SBYTES (str2);
+ if (INT_ADD_OVERFLOW (ssl->bytes, nbytes))
+ memory_full (SIZE_MAX);
ssl->bytes += nbytes;
}
}
PSTR, if that variable is non-null. The string may be overwritten by
subsequent calls. */
-EMACS_INT
-overlay_strings (EMACS_INT pos, struct window *w, unsigned char **pstr)
+ptrdiff_t
+overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
{
Lisp_Object overlay, window, str;
struct Lisp_Overlay *ov;
- EMACS_INT startpos, endpos;
+ ptrdiff_t startpos, endpos;
int multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
overlay_heads.used = overlay_heads.bytes = 0;
if (overlay_heads.bytes || overlay_tails.bytes)
{
Lisp_Object tem;
- EMACS_INT i;
+ ptrdiff_t i;
unsigned char *p;
- EMACS_INT total = overlay_heads.bytes + overlay_tails.bytes;
+ ptrdiff_t total;
+ if (INT_ADD_OVERFLOW (overlay_heads.bytes, overlay_tails.bytes))
+ memory_full (SIZE_MAX);
+ total = overlay_heads.bytes + overlay_tails.bytes;
if (total > overlay_str_len)
- {
- overlay_str_len = total;
- overlay_str_buf = (unsigned char *)xrealloc (overlay_str_buf,
- total);
- }
+ overlay_str_buf = xpalloc (overlay_str_buf, &overlay_str_len,
+ total - overlay_str_len, -1, 1);
+
p = overlay_str_buf;
for (i = overlay_tails.used; --i >= 0;)
{
- EMACS_INT nbytes;
+ ptrdiff_t nbytes;
tem = overlay_tails.buf[i].string;
nbytes = copy_text (SDATA (tem), p,
SBYTES (tem),
}
for (i = 0; i < overlay_heads.used; ++i)
{
- EMACS_INT nbytes;
+ ptrdiff_t nbytes;
tem = overlay_heads.buf[i].string;
nbytes = copy_text (SDATA (tem), p,
SBYTES (tem),
/* Shift overlays in BUF's overlay lists, to center the lists at POS. */
void
-recenter_overlay_lists (struct buffer *buf, EMACS_INT pos)
+recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos)
{
Lisp_Object overlay, beg, end;
struct Lisp_Overlay *prev, *tail, *next;
if (OVERLAY_POSITION (end) > pos)
{
/* OVERLAY needs to be moved. */
- EMACS_INT where = OVERLAY_POSITION (beg);
+ ptrdiff_t where = OVERLAY_POSITION (beg);
struct Lisp_Overlay *other, *other_prev;
/* Splice the cons cell TAIL out of overlays_before. */
if (OVERLAY_POSITION (end) <= pos)
{
/* OVERLAY needs to be moved. */
- EMACS_INT where = OVERLAY_POSITION (end);
+ ptrdiff_t where = OVERLAY_POSITION (end);
struct Lisp_Overlay *other, *other_prev;
/* Splice the cons cell TAIL out of overlays_after. */
}
void
-adjust_overlays_for_insert (EMACS_INT pos, EMACS_INT length)
+adjust_overlays_for_insert (ptrdiff_t pos, ptrdiff_t length)
{
/* After an insertion, the lists are still sorted properly,
but we may need to update the value of the overlay center. */
}
void
-adjust_overlays_for_delete (EMACS_INT pos, EMACS_INT length)
+adjust_overlays_for_delete (ptrdiff_t pos, ptrdiff_t length)
{
if (current_buffer->overlay_center < pos)
/* The deletion was to our right. No change needed; the before- and
after-lists are still consistent. */
;
- else if (current_buffer->overlay_center > pos + length)
+ else if (current_buffer->overlay_center - pos > length)
/* The deletion was to our left. We need to adjust the center value
to account for the change in position, but the lists are consistent
given the new value. */
Such an overlay might even have negative size at this point.
If so, we'll make the overlay empty. */
void
-fix_start_end_in_overlays (register EMACS_INT start, register EMACS_INT end)
+fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end)
{
Lisp_Object overlay;
struct Lisp_Overlay *before_list IF_LINT (= NULL);
current_buffer->overlays_before or overlays_after, depending
which loop we're in. */
struct Lisp_Overlay *tail, *parent;
- EMACS_INT startpos, endpos;
+ ptrdiff_t startpos, endpos;
/* This algorithm shifts links around instead of consing and GCing.
The loop invariant is that before_list (resp. after_list) is a
was at PREV, and now is at POS. */
void
-fix_overlays_before (struct buffer *bp, EMACS_INT prev, EMACS_INT pos)
+fix_overlays_before (struct buffer *bp, ptrdiff_t prev, ptrdiff_t pos)
{
/* If parent is nil, replace overlays_before; otherwise, parent->next. */
struct Lisp_Overlay *tail = bp->overlays_before, *parent = NULL, *right_pair;
Lisp_Object tem;
- EMACS_INT end IF_LINT (= 0);
+ ptrdiff_t end IF_LINT (= 0);
/* After the insertion, the several overlays may be in incorrect
order. The possibility is that, in the list `overlays_before',
/* Mark a section of BUF as needing redisplay because of overlays changes. */
static void
-modify_overlay (struct buffer *buf, EMACS_INT start, EMACS_INT end)
+modify_overlay (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
{
if (start > end)
{
- EMACS_INT temp = start;
+ ptrdiff_t temp = start;
start = end;
end = temp;
}
{
struct buffer *b, *ob;
Lisp_Object obuffer;
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
CHECK_OVERLAY (overlay);
if (NILP (buffer))
CHECK_NUMBER_COERCE_MARKER (beg);
CHECK_NUMBER_COERCE_MARKER (end);
- if (XINT (beg) == XINT (end) && ! NILP (Foverlay_get (overlay, Qevaporate)))
- return Fdelete_overlay (overlay);
-
if (XINT (beg) > XINT (end))
{
Lisp_Object temp;
temp = beg; beg = end; end = temp;
}
+ b = XBUFFER (buffer);
+ if (! (BUF_BEGV (b) <= XINT (beg) && XINT (end) <= BUF_ZV (b)))
+ args_out_of_range (beg, end);
+
+ if (XINT (beg) == XINT (end) && ! NILP (Foverlay_get (overlay, Qevaporate)))
+ return Fdelete_overlay (overlay);
+
specbind (Qinhibit_quit, Qt);
obuffer = Fmarker_buffer (OVERLAY_START (overlay));
- b = XBUFFER (buffer);
ob = BUFFERP (obuffer) ? XBUFFER (obuffer) : (struct buffer *) 0;
/* If the overlay has changed buffers, do a thorough redisplay. */
/* Redisplay where the overlay was. */
if (!NILP (obuffer))
{
- EMACS_INT o_beg;
- EMACS_INT o_end;
+ ptrdiff_t o_beg;
+ ptrdiff_t o_end;
o_beg = OVERLAY_POSITION (OVERLAY_START (overlay));
o_end = OVERLAY_POSITION (OVERLAY_END (overlay));
else
/* Redisplay the area the overlay has just left, or just enclosed. */
{
- EMACS_INT o_beg, o_end;
+ ptrdiff_t o_beg, o_end;
o_beg = OVERLAY_POSITION (OVERLAY_START (overlay));
o_end = OVERLAY_POSITION (OVERLAY_END (overlay));
{
Lisp_Object buffer;
struct buffer *b;
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
CHECK_OVERLAY (overlay);
doc: /* Return a list of the overlays that contain the character at POS. */)
(Lisp_Object pos)
{
- int noverlays;
+ ptrdiff_t len, noverlays;
Lisp_Object *overlay_vec;
- int len;
Lisp_Object result;
CHECK_NUMBER_COERCE_MARKER (pos);
/* 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,
- (EMACS_INT *) 0, (EMACS_INT *) 0, 0);
+ 0, 0, 0);
/* Make a list of them all. */
result = Flist (noverlays, overlay_vec);
end of the buffer. */)
(Lisp_Object beg, Lisp_Object end)
{
- int noverlays;
+ ptrdiff_t len, noverlays;
Lisp_Object *overlay_vec;
- int len;
Lisp_Object result;
CHECK_NUMBER_COERCE_MARKER (beg);
the value is (point-max). */)
(Lisp_Object pos)
{
- int noverlays;
- EMACS_INT endpos;
+ ptrdiff_t i, len, noverlays;
+ ptrdiff_t endpos;
Lisp_Object *overlay_vec;
- int len;
- int i;
CHECK_NUMBER_COERCE_MARKER (pos);
Store the length in len.
endpos gets the position where the next overlay starts. */
noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
- &endpos, (EMACS_INT *) 0, 1);
+ &endpos, 0, 1);
/* If any of these overlays ends before endpos,
use its ending point instead. */
for (i = 0; i < noverlays; i++)
{
Lisp_Object oend;
- EMACS_INT oendpos;
+ ptrdiff_t oendpos;
oend = OVERLAY_END (overlay_vec[i]);
oendpos = OVERLAY_POSITION (oend);
the value is (point-min). */)
(Lisp_Object pos)
{
- EMACS_INT prevpos;
+ ptrdiff_t prevpos;
Lisp_Object *overlay_vec;
- int len;
+ ptrdiff_t len;
CHECK_NUMBER_COERCE_MARKER (pos);
Store the length in len.
prevpos gets the position of the previous change. */
overlays_at (XINT (pos), 1, &overlay_vec, &len,
- (EMACS_INT *) 0, &prevpos, 1);
+ 0, &prevpos, 1);
xfree (overlay_vec);
return make_number (prevpos);
for positions far away from POS). */)
(Lisp_Object pos)
{
+ ptrdiff_t p;
CHECK_NUMBER_COERCE_MARKER (pos);
- recenter_overlay_lists (current_buffer, XINT (pos));
+ p = clip_to_bounds (PTRDIFF_MIN, XINT (pos), PTRDIFF_MAX);
+ recenter_overlay_lists (current_buffer, p);
return Qnil;
}
\f
}
DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 0,
- doc: /* Set one property of overlay OVERLAY: give property PROP value VALUE. */)
+ doc: /* Set one property of overlay OVERLAY: give property PROP value VALUE.
+VALUE will be returned.*/)
(Lisp_Object overlay, Lisp_Object prop, Lisp_Object value)
{
Lisp_Object tail, buffer;
static Lisp_Object last_overlay_modification_hooks;
/* Number of elements actually used in last_overlay_modification_hooks. */
-static int last_overlay_modification_hooks_used;
+static ptrdiff_t last_overlay_modification_hooks_used;
/* Add one functionlist/overlay pair
to the end of last_overlay_modification_hooks. */
static void
add_overlay_mod_hooklist (Lisp_Object functionlist, Lisp_Object overlay)
{
- int oldsize = ASIZE (last_overlay_modification_hooks);
+ ptrdiff_t oldsize = ASIZE (last_overlay_modification_hooks);
- if (last_overlay_modification_hooks_used == oldsize)
- last_overlay_modification_hooks = larger_vector
- (last_overlay_modification_hooks, oldsize * 2, Qnil);
+ if (oldsize - 1 <= last_overlay_modification_hooks_used)
+ last_overlay_modification_hooks =
+ larger_vector (last_overlay_modification_hooks, 2, -1);
ASET (last_overlay_modification_hooks, last_overlay_modification_hooks_used,
functionlist); last_overlay_modification_hooks_used++;
ASET (last_overlay_modification_hooks, last_overlay_modification_hooks_used,
last_overlay_modification_hooks_used = 0;
for (tail = current_buffer->overlays_before; tail; tail = tail->next)
{
- EMACS_INT startpos, endpos;
+ ptrdiff_t startpos, endpos;
Lisp_Object ostart, oend;
XSETMISC (overlay, tail);
for (tail = current_buffer->overlays_after; tail; tail = tail->next)
{
- EMACS_INT startpos, endpos;
+ ptrdiff_t startpos, endpos;
Lisp_Object ostart, oend;
XSETMISC (overlay, tail);
/* Call the functions recorded in last_overlay_modification_hooks.
First copy the vector contents, in case some of these hooks
do subsequent modification of the buffer. */
- int size = last_overlay_modification_hooks_used;
+ ptrdiff_t size = last_overlay_modification_hooks_used;
Lisp_Object *copy = (Lisp_Object *) alloca (size * sizeof (Lisp_Object));
- int i;
+ ptrdiff_t i;
memcpy (copy, XVECTOR (last_overlay_modification_hooks)->contents,
size * sizeof (Lisp_Object));
/* Delete any zero-sized overlays at position POS, if the `evaporate'
property is set. */
void
-evaporate_overlays (EMACS_INT pos)
+evaporate_overlays (ptrdiff_t pos)
{
Lisp_Object overlay, hit_list;
struct Lisp_Overlay *tail;
if (pos <= current_buffer->overlay_center)
for (tail = current_buffer->overlays_before; tail; tail = tail->next)
{
- EMACS_INT endpos;
+ ptrdiff_t endpos;
XSETMISC (overlay, tail);
endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
if (endpos < pos)
else
for (tail = current_buffer->overlays_after; tail; tail = tail->next)
{
- EMACS_INT startpos;
+ ptrdiff_t startpos;
XSETMISC (overlay, tail);
startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
if (startpos > pos)
#define MMAP_ALLOCATED_P(start, end) 1
#endif
-/* Function prototypes. */
+/* Perform necessary intializations for the use of mmap. */
-static int mmap_free_1 (struct mmap_region *);
-static int mmap_enlarge (struct mmap_region *, int);
-static struct mmap_region *mmap_find (POINTER_TYPE *, POINTER_TYPE *);
-static POINTER_TYPE *mmap_alloc (POINTER_TYPE **, size_t);
-static POINTER_TYPE *mmap_realloc (POINTER_TYPE **, size_t);
-static void mmap_free (POINTER_TYPE **ptr);
-static void mmap_init (void);
+static void
+mmap_init (void)
+{
+#if MAP_ANON == 0
+ /* The value of mmap_fd is initially 0 in temacs, and -1
+ in a dumped Emacs. */
+ if (mmap_fd <= 0)
+ {
+ /* No anonymous mmap -- we need the file descriptor. */
+ mmap_fd = open ("/dev/zero", O_RDONLY);
+ if (mmap_fd == -1)
+ fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno));
+ }
+#endif /* MAP_ANON == 0 */
+
+ if (mmap_initialized_p)
+ return;
+ mmap_initialized_p = 1;
+
+#if MAP_ANON != 0
+ mmap_fd = -1;
+#endif
+ mmap_page_size = getpagesize ();
+}
/* Return a region overlapping address range START...END, or null if
none. END is not including, i.e. the last byte in the range
is at END - 1. */
static struct mmap_region *
-mmap_find (start, end)
- POINTER_TYPE *start, *end;
+mmap_find (POINTER_TYPE *start, POINTER_TYPE *end)
{
struct mmap_region *r;
char *s = (char *) start, *e = (char *) end;
the region. Value is non-zero if successful. */
static int
-mmap_free_1 (r)
- struct mmap_region *r;
+mmap_free_1 (struct mmap_region *r)
{
if (r->next)
r->next->prev = r->prev;
Value is non-zero if successful. */
static int
-mmap_enlarge (r, npages)
- struct mmap_region *r;
- int npages;
+mmap_enlarge (struct mmap_region *r, int npages)
{
char *region_end = (char *) r + r->nbytes_mapped;
size_t nbytes;
when Emacs starts. */
void
-mmap_set_vars (restore_p)
- int restore_p;
+mmap_set_vars (int restore_p)
{
struct mmap_region *r;
return null. */
static POINTER_TYPE *
-mmap_alloc (var, nbytes)
- POINTER_TYPE **var;
- size_t nbytes;
+mmap_alloc (POINTER_TYPE **var, size_t nbytes)
{
void *p;
size_t map;
}
+/* Free a block of relocatable storage whose data is pointed to by
+ PTR. Store 0 in *PTR to show there's no block allocated. */
+
+static void
+mmap_free (POINTER_TYPE **var)
+{
+ mmap_init ();
+
+ if (*var)
+ {
+ mmap_free_1 (MMAP_REGION (*var));
+ *var = NULL;
+ }
+}
+
+
/* Given a pointer at address VAR to data allocated with mmap_alloc,
resize it to size NBYTES. Change *VAR to reflect the new block,
and return this value. If more memory cannot be allocated, then
leave *VAR unchanged, and return null. */
static POINTER_TYPE *
-mmap_realloc (var, nbytes)
- POINTER_TYPE **var;
- size_t nbytes;
+mmap_realloc (POINTER_TYPE **var, size_t nbytes)
{
POINTER_TYPE *result;
}
-/* Free a block of relocatable storage whose data is pointed to by
- PTR. Store 0 in *PTR to show there's no block allocated. */
-
-static void
-mmap_free (var)
- POINTER_TYPE **var;
-{
- mmap_init ();
-
- if (*var)
- {
- mmap_free_1 (MMAP_REGION (*var));
- *var = NULL;
- }
-}
-
-
-/* Perform necessary intializations for the use of mmap. */
-
-static void
-mmap_init ()
-{
-#if MAP_ANON == 0
- /* The value of mmap_fd is initially 0 in temacs, and -1
- in a dumped Emacs. */
- if (mmap_fd <= 0)
- {
- /* No anonymous mmap -- we need the file descriptor. */
- mmap_fd = open ("/dev/zero", O_RDONLY);
- if (mmap_fd == -1)
- fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno));
- }
-#endif /* MAP_ANON == 0 */
-
- if (mmap_initialized_p)
- return;
- mmap_initialized_p = 1;
-
-#if MAP_ANON != 0
- mmap_fd = -1;
-#endif
-
- mmap_page_size = getpagesize ();
-}
-
#endif /* USE_MMAP_FOR_BUFFERS */
/* Allocate NBYTES bytes for buffer B's text buffer. */
static void
-alloc_buffer_text (struct buffer *b, size_t nbytes)
+alloc_buffer_text (struct buffer *b, ptrdiff_t nbytes)
{
POINTER_TYPE *p;
shrink it. */
void
-enlarge_buffer_text (struct buffer *b, EMACS_INT delta)
+enlarge_buffer_text (struct buffer *b, ptrdiff_t delta)
{
POINTER_TYPE *p;
- size_t nbytes = (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1
- + delta);
+ ptrdiff_t nbytes = (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1
+ + delta);
BLOCK_INPUT;
#if defined USE_MMAP_FOR_BUFFERS
p = mmap_realloc ((POINTER_TYPE **) &b->text->beg, nbytes);
BVAR (&buffer_defaults, truncate_lines) = Qnil;
BVAR (&buffer_defaults, word_wrap) = Qnil;
BVAR (&buffer_defaults, ctl_arrow) = Qt;
- BVAR (&buffer_defaults, bidi_display_reordering) = Qnil;
+ BVAR (&buffer_defaults, bidi_display_reordering) = Qt;
BVAR (&buffer_defaults, bidi_paragraph_direction) = Qnil;
BVAR (&buffer_defaults, cursor_type) = Qt;
BVAR (&buffer_defaults, extra_line_spacing) = Qnil;
The local flag bits are in the local_var_flags slot of the buffer. */
/* Nothing can work if this isn't true */
- if (sizeof (EMACS_INT) != sizeof (Lisp_Object)) abort ();
+ { verify (sizeof (EMACS_INT) == sizeof (Lisp_Object)); }
/* 0 means not a lisp var, -1 means always local, else mask */
memset (&buffer_local_flags, 0, sizeof buffer_local_flags);
{
char *pwd;
Lisp_Object temp;
- int len;
+ ptrdiff_t len;
#ifdef USE_MMAP_FOR_BUFFERS
{
staticpro (&Vbuffer_alist);
staticpro (&Qprotected_field);
staticpro (&Qpermanent_local);
- Qpermanent_local_hook = intern_c_string ("permanent-local-hook");
- staticpro (&Qpermanent_local_hook);
staticpro (&Qkill_buffer_hook);
- Qoverlayp = intern_c_string ("overlayp");
- staticpro (&Qoverlayp);
- Qevaporate = intern_c_string ("evaporate");
- staticpro (&Qevaporate);
- Qmodification_hooks = intern_c_string ("modification-hooks");
- staticpro (&Qmodification_hooks);
- Qinsert_in_front_hooks = intern_c_string ("insert-in-front-hooks");
- staticpro (&Qinsert_in_front_hooks);
- Qinsert_behind_hooks = intern_c_string ("insert-behind-hooks");
- staticpro (&Qinsert_behind_hooks);
- Qget_file_buffer = intern_c_string ("get-file-buffer");
- staticpro (&Qget_file_buffer);
- Qpriority = intern_c_string ("priority");
- staticpro (&Qpriority);
- Qbefore_string = intern_c_string ("before-string");
- staticpro (&Qbefore_string);
- Qafter_string = intern_c_string ("after-string");
- staticpro (&Qafter_string);
- Qfirst_change_hook = intern_c_string ("first-change-hook");
- staticpro (&Qfirst_change_hook);
- Qbefore_change_functions = intern_c_string ("before-change-functions");
- staticpro (&Qbefore_change_functions);
- Qafter_change_functions = intern_c_string ("after-change-functions");
- staticpro (&Qafter_change_functions);
+
+ DEFSYM (Qpermanent_local_hook, "permanent-local-hook");
+ DEFSYM (Qoverlayp, "overlayp");
+ DEFSYM (Qevaporate, "evaporate");
+ DEFSYM (Qmodification_hooks, "modification-hooks");
+ DEFSYM (Qinsert_in_front_hooks, "insert-in-front-hooks");
+ DEFSYM (Qinsert_behind_hooks, "insert-behind-hooks");
+ DEFSYM (Qget_file_buffer, "get-file-buffer");
+ DEFSYM (Qpriority, "priority");
+ DEFSYM (Qbefore_string, "before-string");
+ DEFSYM (Qafter_string, "after-string");
+ DEFSYM (Qfirst_change_hook, "first-change-hook");
+ DEFSYM (Qbefore_change_functions, "before-change-functions");
+ DEFSYM (Qafter_change_functions, "after-change-functions");
+ DEFSYM (Qkill_buffer_query_functions, "kill-buffer-query-functions");
+
/* The next one is initialized in init_buffer_once. */
staticpro (&Qucs_set_table_for_input);
- Qkill_buffer_query_functions = intern_c_string ("kill-buffer-query-functions");
- staticpro (&Qkill_buffer_query_functions);
-
Fput (Qprotected_field, Qerror_conditions,
pure_cons (Qprotected_field, pure_cons (Qerror, Qnil)));
Fput (Qprotected_field, Qerror_message,
doc: /* Normal hook run before changing the major mode of a buffer.
The function `kill-all-local-variables' runs this before doing anything else. */);
Vchange_major_mode_hook = Qnil;
- Qchange_major_mode_hook = intern_c_string ("change-major-mode-hook");
- staticpro (&Qchange_major_mode_hook);
+ DEFSYM (Qchange_major_mode_hook, "change-major-mode-hook");
+
+ 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',
+`record-buffer' and `unrecord-buffer'. */);
+ Vbuffer_list_update_hook = Qnil;
+ DEFSYM (Qbuffer_list_update_hook, "buffer-list-update-hook");
defsubr (&Sbuffer_live_p);
defsubr (&Sbuffer_list);
defsubr (&Sother_buffer);
defsubr (&Sbuffer_enable_undo);
defsubr (&Skill_buffer);
+ defsubr (&Sbury_buffer_internal);
defsubr (&Sset_buffer_major_mode);
- defsubr (&Sswitch_to_buffer);
defsubr (&Scurrent_buffer);
defsubr (&Sset_buffer);
defsubr (&Sbarf_if_buffer_read_only);
- defsubr (&Sbury_buffer);
defsubr (&Serase_buffer);
defsubr (&Sbuffer_swap_text);
defsubr (&Sset_buffer_multibyte);