#include <config.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <errno.h>
#include <stdio.h>
#ifndef USE_CRT_DLL
extern int errno;
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "lisp.h"
#include "intervals.h"
#include "window.h"
#include "commands.h"
#include "buffer.h"
#include "charset.h"
#include "region-cache.h"
#include "indent.h"
#include "blockinput.h"
#include "keyboard.h"
#include "keymap.h"
#include "frame.h"
struct buffer *current_buffer;
struct buffer *all_buffers;
DECL_ALIGN (struct buffer, buffer_defaults);
static Lisp_Object Vbuffer_defaults;
struct buffer buffer_local_flags;
DECL_ALIGN (struct buffer, buffer_local_symbols);
static Lisp_Object Vbuffer_local_symbols;
struct buffer buffer_local_types;
static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS];
int last_per_buffer_idx;
Lisp_Object Fset_buffer ();
void set_buffer_internal ();
void set_buffer_internal_1 ();
static void call_overlay_mod_hooks ();
static void swap_out_buffer_local_variables ();
static void reset_buffer_local_variables ();
Lisp_Object Vbuffer_alist;
Lisp_Object Vbefore_change_functions;
Lisp_Object Vafter_change_functions;
Lisp_Object Vtransient_mark_mode;
Lisp_Object Vinhibit_read_only;
Lisp_Object Vkill_buffer_query_functions;
Lisp_Object Qkill_buffer_query_functions;
Lisp_Object Vchange_major_mode_hook, Qchange_major_mode_hook;
Lisp_Object Vfirst_change_hook;
Lisp_Object Qfirst_change_hook;
Lisp_Object Qbefore_change_functions;
Lisp_Object Qafter_change_functions;
Lisp_Object Qucs_set_table_for_input;
int inhibit_modification_hooks;
Lisp_Object Qfundamental_mode, Qmode_class, Qpermanent_local;
Lisp_Object Qprotected_field;
Lisp_Object QSFundamental;
Lisp_Object Qkill_buffer_hook;
Lisp_Object Qget_file_buffer;
Lisp_Object Qoverlayp;
Lisp_Object Qpriority, Qwindow, Qevaporate, Qbefore_string, Qafter_string;
Lisp_Object Qmodification_hooks;
Lisp_Object Qinsert_in_front_hooks;
Lisp_Object Qinsert_behind_hooks;
static void alloc_buffer_text P_ ((struct buffer *, size_t));
static void free_buffer_text P_ ((struct buffer *b));
static struct Lisp_Overlay * copy_overlays P_ ((struct buffer *, struct Lisp_Overlay *));
static void modify_overlay P_ ((struct buffer *, EMACS_INT, EMACS_INT));
static Lisp_Object buffer_lisp_local_variables P_ ((struct buffer *));
void
nsberror (spec)
Lisp_Object spec;
{
if (STRINGP (spec))
error ("No buffer named %s", SDATA (spec));
error ("Invalid buffer argument");
}
DEFUN ("buffer-live-p", Fbuffer_live_p, Sbuffer_live_p, 1, 1, 0,
doc: )
(object)
Lisp_Object object;
{
return ((BUFFERP (object) && ! NILP (XBUFFER (object)->name))
? Qt : Qnil);
}
DEFUN ("buffer-list", Fbuffer_list, Sbuffer_list, 0, 1, 0,
doc: )
(frame)
Lisp_Object frame;
{
Lisp_Object framelist, general;
general = Fmapcar (Qcdr, Vbuffer_alist);
if (FRAMEP (frame))
{
Lisp_Object tail;
CHECK_FRAME (frame);
framelist = Fcopy_sequence (XFRAME (frame)->buffer_list);
tail = framelist;
while (! NILP (tail))
{
general = Fdelq (XCAR (tail), general);
tail = XCDR (tail);
}
return nconc2 (framelist, general);
}
return general;
}
static Lisp_Object
assoc_ignore_text_properties (key, list)
register Lisp_Object key;
Lisp_Object list;
{
register Lisp_Object tail;
for (tail = list; CONSP (tail); tail = XCDR (tail))
{
register Lisp_Object elt, tem;
elt = XCAR (tail);
tem = Fstring_equal (Fcar (elt), key);
if (!NILP (tem))
return elt;
}
return Qnil;
}
DEFUN ("get-buffer", Fget_buffer, Sget_buffer, 1, 1, 0,
doc: )
(name)
register Lisp_Object name;
{
if (BUFFERP (name))
return name;
CHECK_STRING (name);
return Fcdr (assoc_ignore_text_properties (name, Vbuffer_alist));
}
DEFUN ("get-file-buffer", Fget_file_buffer, Sget_file_buffer, 1, 1, 0,
doc: )
(filename)
register Lisp_Object filename;
{
register Lisp_Object tail, buf, tem;
Lisp_Object handler;
CHECK_STRING (filename);
filename = Fexpand_file_name (filename, Qnil);
handler = Ffind_file_name_handler (filename, Qget_file_buffer);
if (!NILP (handler))
return call2 (handler, Qget_file_buffer, filename);
for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
{
buf = Fcdr (XCAR (tail));
if (!BUFFERP (buf)) continue;
if (!STRINGP (XBUFFER (buf)->filename)) continue;
tem = Fstring_equal (XBUFFER (buf)->filename, filename);
if (!NILP (tem))
return buf;
}
return Qnil;
}
Lisp_Object
get_truename_buffer (filename)
register Lisp_Object filename;
{
register Lisp_Object tail, buf, tem;
for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
{
buf = Fcdr (XCAR (tail));
if (!BUFFERP (buf)) continue;
if (!STRINGP (XBUFFER (buf)->file_truename)) continue;
tem = Fstring_equal (XBUFFER (buf)->file_truename, filename);
if (!NILP (tem))
return buf;
}
return Qnil;
}
int buffer_count;
DEFUN ("get-buffer-create", Fget_buffer_create, Sget_buffer_create, 1, 1, 0,
doc: )
(name)
register Lisp_Object name;
{
register Lisp_Object buf;
register struct buffer *b;
buf = Fget_buffer (name);
if (!NILP (buf))
return buf;
if (SCHARS (name) == 0)
error ("Empty string for buffer name is not allowed");
b = (struct buffer *) allocate_buffer ();
b->size = sizeof (struct buffer) / sizeof (EMACS_INT);
b->text = &b->own_text;
b->base_buffer = 0;
BUF_GAP_SIZE (b) = 20;
BLOCK_INPUT;
alloc_buffer_text (b, BUF_GAP_SIZE (b) + 1);
UNBLOCK_INPUT;
if (! BUF_BEG_ADDR (b))
buffer_memory_full ();
BUF_PT (b) = BEG;
BUF_GPT (b) = BEG;
BUF_BEGV (b) = BEG;
BUF_ZV (b) = BEG;
BUF_Z (b) = BEG;
BUF_PT_BYTE (b) = BEG_BYTE;
BUF_GPT_BYTE (b) = BEG_BYTE;
BUF_BEGV_BYTE (b) = BEG_BYTE;
BUF_ZV_BYTE (b) = BEG_BYTE;
BUF_Z_BYTE (b) = BEG_BYTE;
BUF_MODIFF (b) = 1;
BUF_CHARS_MODIFF (b) = 1;
BUF_OVERLAY_MODIFF (b) = 1;
BUF_SAVE_MODIFF (b) = 1;
BUF_INTERVALS (b) = 0;
BUF_UNCHANGED_MODIFIED (b) = 1;
BUF_OVERLAY_UNCHANGED_MODIFIED (b) = 1;
BUF_END_UNCHANGED (b) = 0;
BUF_BEG_UNCHANGED (b) = 0;
*(BUF_GPT_ADDR (b)) = *(BUF_Z_ADDR (b)) = 0;
b->newline_cache = 0;
b->width_run_cache = 0;
b->width_table = Qnil;
b->prevent_redisplay_optimizations_p = 1;
b->next = all_buffers;
all_buffers = b;
b->pt_marker = Qnil;
b->begv_marker = Qnil;
b->zv_marker = Qnil;
name = Fcopy_sequence (name);
STRING_SET_INTERVALS (name, NULL_INTERVAL);
b->name = name;
if (SREF (name, 0) != ' ')
b->undo_list = Qnil;
else
b->undo_list = Qt;
reset_buffer (b);
reset_buffer_local_variables (b, 1);
b->mark = Fmake_marker ();
BUF_MARKERS (b) = NULL;
b->name = name;
XSETBUFFER (buf, b);
Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buf), Qnil));
if (!NILP (Ffboundp (Qucs_set_table_for_input)))
call1 (Qucs_set_table_for_input, buf);
return buf;
}
static struct Lisp_Overlay *
copy_overlays (b, list)
struct buffer *b;
struct Lisp_Overlay *list;
{
Lisp_Object buffer;
struct Lisp_Overlay *result = NULL, *tail = NULL;
XSETBUFFER (buffer, b);
for (; list; list = list->next)
{
Lisp_Object overlay, start, end, old_overlay;
EMACS_INT charpos;
XSETMISC (old_overlay, list);
charpos = marker_position (OVERLAY_START (old_overlay));
start = Fmake_marker ();
Fset_marker (start, make_number (charpos), buffer);
XMARKER (start)->insertion_type
= XMARKER (OVERLAY_START (old_overlay))->insertion_type;
charpos = marker_position (OVERLAY_END (old_overlay));
end = Fmake_marker ();
Fset_marker (end, make_number (charpos), buffer);
XMARKER (end)->insertion_type
= XMARKER (OVERLAY_END (old_overlay))->insertion_type;
overlay = allocate_misc ();
XMISCTYPE (overlay) = Lisp_Misc_Overlay;
OVERLAY_START (overlay) = start;
OVERLAY_END (overlay) = end;
OVERLAY_PLIST (overlay) = Fcopy_sequence (OVERLAY_PLIST (old_overlay));
XOVERLAY (overlay)->next = NULL;
if (tail)
tail = tail->next = XOVERLAY (overlay);
else
result = tail = XOVERLAY (overlay);
}
return result;
}
static void
clone_per_buffer_values (from, to)
struct buffer *from, *to;
{
Lisp_Object to_buffer;
int offset;
XSETBUFFER (to_buffer, to);
for (offset = PER_BUFFER_VAR_OFFSET (name) + sizeof (Lisp_Object);
offset < sizeof *to;
offset += sizeof (Lisp_Object))
{
Lisp_Object obj;
obj = PER_BUFFER_VALUE (from, offset);
if (MARKERP (obj))
{
struct Lisp_Marker *m = XMARKER (obj);
obj = Fmake_marker ();
XMARKER (obj)->insertion_type = m->insertion_type;
set_marker_both (obj, to_buffer, m->charpos, m->bytepos);
}
PER_BUFFER_VALUE (to, offset) = obj;
}
bcopy (from->local_flags, to->local_flags, sizeof to->local_flags);
to->overlays_before = copy_overlays (to, from->overlays_before);
to->overlays_after = copy_overlays (to, from->overlays_after);
to->local_var_alist = buffer_lisp_local_variables (from);
}
DEFUN ("make-indirect-buffer", Fmake_indirect_buffer, Smake_indirect_buffer,
2, 3,
"bMake indirect buffer (to buffer): \nBName of indirect buffer: ",
doc: )
(base_buffer, name, clone)
Lisp_Object base_buffer, name, clone;
{
Lisp_Object buf, tem;
struct buffer *b;
CHECK_STRING (name);
buf = Fget_buffer (name);
if (!NILP (buf))
error ("Buffer name `%s' is in use", SDATA (name));
tem = base_buffer;
base_buffer = Fget_buffer (base_buffer);
if (NILP (base_buffer))
error ("No such buffer: `%s'", SDATA (tem));
if (NILP (XBUFFER (base_buffer)->name))
error ("Base buffer has been killed");
if (SCHARS (name) == 0)
error ("Empty string for buffer name is not allowed");
b = (struct buffer *) allocate_buffer ();
b->size = sizeof (struct buffer) / sizeof (EMACS_INT);
if (XBUFFER (base_buffer)->base_buffer)
b->base_buffer = XBUFFER (base_buffer)->base_buffer;
else
b->base_buffer = XBUFFER (base_buffer);
b->text = b->base_buffer->text;
BUF_BEGV (b) = BUF_BEGV (b->base_buffer);
BUF_ZV (b) = BUF_ZV (b->base_buffer);
BUF_PT (b) = BUF_PT (b->base_buffer);
BUF_BEGV_BYTE (b) = BUF_BEGV_BYTE (b->base_buffer);
BUF_ZV_BYTE (b) = BUF_ZV_BYTE (b->base_buffer);
BUF_PT_BYTE (b) = BUF_PT_BYTE (b->base_buffer);
b->newline_cache = 0;
b->width_run_cache = 0;
b->width_table = Qnil;
b->next = all_buffers;
all_buffers = b;
name = Fcopy_sequence (name);
STRING_SET_INTERVALS (name, NULL_INTERVAL);
b->name = name;
reset_buffer (b);
reset_buffer_local_variables (b, 1);
XSETBUFFER (buf, b);
Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buf), Qnil));
b->mark = Fmake_marker ();
b->name = name;
b->enable_multibyte_characters = b->base_buffer->enable_multibyte_characters;
if (NILP (b->base_buffer->pt_marker))
{
b->base_buffer->pt_marker = Fmake_marker ();
set_marker_both (b->base_buffer->pt_marker, base_buffer,
BUF_PT (b->base_buffer),
BUF_PT_BYTE (b->base_buffer));
}
if (NILP (b->base_buffer->begv_marker))
{
b->base_buffer->begv_marker = Fmake_marker ();
set_marker_both (b->base_buffer->begv_marker, base_buffer,
BUF_BEGV (b->base_buffer),
BUF_BEGV_BYTE (b->base_buffer));
}
if (NILP (b->base_buffer->zv_marker))
{
b->base_buffer->zv_marker = Fmake_marker ();
set_marker_both (b->base_buffer->zv_marker, base_buffer,
BUF_ZV (b->base_buffer),
BUF_ZV_BYTE (b->base_buffer));
XMARKER (b->base_buffer->zv_marker)->insertion_type = 1;
}
if (NILP (clone))
{
b->pt_marker = Fmake_marker ();
set_marker_both (b->pt_marker, buf, BUF_PT (b), BUF_PT_BYTE (b));
b->begv_marker = Fmake_marker ();
set_marker_both (b->begv_marker, buf, BUF_BEGV (b), BUF_BEGV_BYTE (b));
b->zv_marker = Fmake_marker ();
set_marker_both (b->zv_marker, buf, BUF_ZV (b), BUF_ZV_BYTE (b));
XMARKER (b->zv_marker)->insertion_type = 1;
}
else
{
struct buffer *old_b = current_buffer;
clone_per_buffer_values (b->base_buffer, b);
b->filename = Qnil;
b->file_truename = Qnil;
b->display_count = make_number (0);
b->backed_up = Qnil;
b->auto_save_file_name = Qnil;
set_buffer_internal_1 (b);
Fset (intern ("buffer-save-without-query"), Qnil);
Fset (intern ("buffer-file-number"), Qnil);
Fset (intern ("buffer-stale-function"), Qnil);
set_buffer_internal_1 (old_b);
}
return buf;
}
void
delete_all_overlays (b)
struct buffer *b;
{
Lisp_Object overlay;
while (b->overlays_before)
{
XSETMISC (overlay, b->overlays_before);
Fdelete_overlay (overlay);
}
while (b->overlays_after)
{
XSETMISC (overlay, b->overlays_after);
Fdelete_overlay (overlay);
}
eassert (b->overlays_before == NULL);
eassert (b->overlays_after == NULL);
}
void
reset_buffer (b)
register struct buffer *b;
{
b->filename = Qnil;
b->file_truename = Qnil;
b->directory = (current_buffer) ? current_buffer->directory : Qnil;
b->modtime = 0;
XSETFASTINT (b->save_length, 0);
b->last_window_start = 1;
b->clip_changed = 0;
b->prevent_redisplay_optimizations_p = 1;
b->backed_up = Qnil;
b->auto_save_modified = 0;
b->auto_save_failure_time = -1;
b->auto_save_file_name = Qnil;
b->read_only = Qnil;
b->overlays_before = NULL;
b->overlays_after = NULL;
b->overlay_center = BEG;
b->mark_active = Qnil;
b->point_before_scroll = Qnil;
b->file_format = Qnil;
b->auto_save_file_format = Qt;
b->last_selected_window = Qnil;
XSETINT (b->display_count, 0);
b->display_time = Qnil;
b->enable_multibyte_characters = buffer_defaults.enable_multibyte_characters;
b->cursor_type = buffer_defaults.cursor_type;
b->extra_line_spacing = buffer_defaults.extra_line_spacing;
b->display_error_modiff = 0;
}
static void
reset_buffer_local_variables (b, permanent_too)
register struct buffer *b;
int permanent_too;
{
register int offset;
int i;
b->major_mode = Qfundamental_mode;
b->keymap = Qnil;
b->mode_name = QSFundamental;
b->minor_modes = Qnil;
if (! (CHAR_TABLE_P (XCHAR_TABLE (Vascii_downcase_table)->extras[0])
&& CHAR_TABLE_P (XCHAR_TABLE (Vascii_downcase_table)->extras[1])
&& CHAR_TABLE_P (XCHAR_TABLE (Vascii_downcase_table)->extras[2])))
Fset_standard_case_table (Vascii_downcase_table);
b->downcase_table = Vascii_downcase_table;
b->upcase_table = XCHAR_TABLE (Vascii_downcase_table)->extras[0];
b->case_canon_table = XCHAR_TABLE (Vascii_downcase_table)->extras[1];
b->case_eqv_table = XCHAR_TABLE (Vascii_downcase_table)->extras[2];
b->invisibility_spec = Qt;
#ifndef DOS_NT
b->buffer_file_type = Qnil;
#endif
b->local_var_alist = Qnil;
for (i = 0; i < last_per_buffer_idx; ++i)
if (permanent_too || buffer_permanent_local_flags[i] == 0)
SET_PER_BUFFER_VALUE_P (b, i, 0);
for (offset = PER_BUFFER_VAR_OFFSET (name);
offset < sizeof *b;
offset += sizeof (Lisp_Object))
{
int idx = PER_BUFFER_IDX (offset);
if ((idx > 0
&& (permanent_too
|| buffer_permanent_local_flags[idx] == 0))
|| idx == -2)
PER_BUFFER_VALUE (b, offset) = PER_BUFFER_DEFAULT (offset);
}
}
DEFUN ("generate-new-buffer-name", Fgenerate_new_buffer_name, Sgenerate_new_buffer_name,
1, 2, 0,
doc: )
(name, ignore)
register Lisp_Object name, ignore;
{
register Lisp_Object gentemp, tem;
int count;
char number[10];
CHECK_STRING (name);
tem = Fstring_equal (name, ignore);
if (!NILP (tem))
return name;
tem = Fget_buffer (name);
if (NILP (tem))
return name;
count = 1;
while (1)
{
sprintf (number, "<%d>", ++count);
gentemp = concat2 (name, build_string (number));
tem = Fstring_equal (gentemp, ignore);
if (!NILP (tem))
return gentemp;
tem = Fget_buffer (gentemp);
if (NILP (tem))
return gentemp;
}
}
DEFUN ("buffer-name", Fbuffer_name, Sbuffer_name, 0, 1, 0,
doc: )
(buffer)
register Lisp_Object buffer;
{
if (NILP (buffer))
return current_buffer->name;
CHECK_BUFFER (buffer);
return XBUFFER (buffer)->name;
}
DEFUN ("buffer-file-name", Fbuffer_file_name, Sbuffer_file_name, 0, 1, 0,
doc: )
(buffer)
register Lisp_Object buffer;
{
if (NILP (buffer))
return current_buffer->filename;
CHECK_BUFFER (buffer);
return XBUFFER (buffer)->filename;
}
DEFUN ("buffer-base-buffer", Fbuffer_base_buffer, Sbuffer_base_buffer,
0, 1, 0,
doc: )
(buffer)
register Lisp_Object buffer;
{
struct buffer *base;
Lisp_Object base_buffer;
if (NILP (buffer))
base = current_buffer->base_buffer;
else
{
CHECK_BUFFER (buffer);
base = XBUFFER (buffer)->base_buffer;
}
if (! base)
return Qnil;
XSETBUFFER (base_buffer, base);
return base_buffer;
}
DEFUN ("buffer-local-value", Fbuffer_local_value,
Sbuffer_local_value, 2, 2, 0,
doc: )
(variable, buffer)
register Lisp_Object variable;
register Lisp_Object buffer;
{
register struct buffer *buf;
register Lisp_Object result;
CHECK_SYMBOL (variable);
CHECK_BUFFER (buffer);
buf = XBUFFER (buffer);
if (SYMBOLP (variable))
variable = indirect_variable (variable);
result = Fassoc (variable, buf->local_var_alist);
if (NILP (result))
{
int offset, idx;
int found = 0;
for (offset = PER_BUFFER_VAR_OFFSET (name);
offset < sizeof (struct buffer);
offset += (sizeof (EMACS_INT)))
{
idx = PER_BUFFER_IDX (offset);
if ((idx == -1 || PER_BUFFER_VALUE_P (buf, idx))
&& SYMBOLP (PER_BUFFER_SYMBOL (offset))
&& EQ (PER_BUFFER_SYMBOL (offset), variable))
{
result = PER_BUFFER_VALUE (buf, offset);
found = 1;
break;
}
}
if (!found)
result = Fdefault_value (variable);
}
else
{
Lisp_Object valcontents;
Lisp_Object current_alist_element;
valcontents = SYMBOL_VALUE (variable);
current_alist_element
= XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr);
Fsetcdr (current_alist_element,
do_symval_forwarding (XBUFFER_LOCAL_VALUE (valcontents)->realvalue));
result = XCDR (result);
}
if (!EQ (result, Qunbound))
return result;
xsignal1 (Qvoid_variable, variable);
}
static Lisp_Object
buffer_lisp_local_variables (buf)
struct buffer *buf;
{
Lisp_Object result = Qnil;
register Lisp_Object tail;
for (tail = buf->local_var_alist; CONSP (tail); tail = XCDR (tail))
{
Lisp_Object val, elt;
elt = XCAR (tail);
val = find_symbol_value (XCAR (elt));
if (buf != current_buffer)
val = XCDR (elt);
if (EQ (val, Qunbound))
result = Fcons (XCAR (elt), result);
else
result = Fcons (Fcons (XCAR (elt), val), result);
}
return result;
}
DEFUN ("buffer-local-variables", Fbuffer_local_variables,
Sbuffer_local_variables, 0, 1, 0,
doc: )
(buffer)
register Lisp_Object buffer;
{
register struct buffer *buf;
register Lisp_Object result;
if (NILP (buffer))
buf = current_buffer;
else
{
CHECK_BUFFER (buffer);
buf = XBUFFER (buffer);
}
result = buffer_lisp_local_variables (buf);
{
int offset, idx;
for (offset = PER_BUFFER_VAR_OFFSET (name);
offset < sizeof (struct buffer);
offset += (sizeof (EMACS_INT)))
{
idx = PER_BUFFER_IDX (offset);
if ((idx == -1 || PER_BUFFER_VALUE_P (buf, idx))
&& SYMBOLP (PER_BUFFER_SYMBOL (offset)))
result = Fcons (Fcons (PER_BUFFER_SYMBOL (offset),
PER_BUFFER_VALUE (buf, offset)),
result);
}
}
return result;
}
DEFUN ("buffer-modified-p", Fbuffer_modified_p, Sbuffer_modified_p,
0, 1, 0,
doc: )
(buffer)
register Lisp_Object buffer;
{
register struct buffer *buf;
if (NILP (buffer))
buf = current_buffer;
else
{
CHECK_BUFFER (buffer);
buf = XBUFFER (buffer);
}
return BUF_SAVE_MODIFF (buf) < BUF_MODIFF (buf) ? Qt : Qnil;
}
DEFUN ("set-buffer-modified-p", Fset_buffer_modified_p, Sset_buffer_modified_p,
1, 1, 0,
doc: )
(flag)
register Lisp_Object flag;
{
register int already;
register Lisp_Object fn;
Lisp_Object buffer, window;
#ifdef CLASH_DETECTION
fn = current_buffer->file_truename;
if (!NILP (fn) && ! NILP (current_buffer->filename))
{
already = SAVE_MODIFF < MODIFF;
if (!already && !NILP (flag))
lock_file (fn);
else if (already && NILP (flag))
unlock_file (fn);
}
#endif
SAVE_MODIFF = NILP (flag) ? MODIFF : 0;
XSETBUFFER (buffer, current_buffer);
window = Fget_buffer_window (buffer, Qt);
if (WINDOWP (window))
{
++update_mode_lines;
current_buffer->prevent_redisplay_optimizations_p = 1;
}
return flag;
}
DEFUN ("restore-buffer-modified-p", Frestore_buffer_modified_p,
Srestore_buffer_modified_p, 1, 1, 0,
doc: )
(flag)
Lisp_Object flag;
{
#ifdef CLASH_DETECTION
Lisp_Object fn;
fn = current_buffer->file_truename;
if (!NILP (fn) && ! NILP (current_buffer->filename))
{
int already = SAVE_MODIFF < MODIFF;
if (!already && !NILP (flag))
lock_file (fn);
else if (already && NILP (flag))
unlock_file (fn);
}
#endif
SAVE_MODIFF = NILP (flag) ? MODIFF : 0;
return flag;
}
DEFUN ("buffer-modified-tick", Fbuffer_modified_tick, Sbuffer_modified_tick,
0, 1, 0,
doc: )
(buffer)
register Lisp_Object buffer;
{
register struct buffer *buf;
if (NILP (buffer))
buf = current_buffer;
else
{
CHECK_BUFFER (buffer);
buf = XBUFFER (buffer);
}
return make_number (BUF_MODIFF (buf));
}
DEFUN ("buffer-chars-modified-tick", Fbuffer_chars_modified_tick,
Sbuffer_chars_modified_tick, 0, 1, 0,
doc: )
(buffer)
register Lisp_Object buffer;
{
register struct buffer *buf;
if (NILP (buffer))
buf = current_buffer;
else
{
CHECK_BUFFER (buffer);
buf = XBUFFER (buffer);
}
return make_number (BUF_CHARS_MODIFF (buf));
}
DEFUN ("rename-buffer", Frename_buffer, Srename_buffer, 1, 2,
"sRename buffer (to new name): \nP",
doc: )
(newname, unique)
register Lisp_Object newname, unique;
{
register Lisp_Object tem, buf;
CHECK_STRING (newname);
if (SCHARS (newname) == 0)
error ("Empty string is invalid as a buffer name");
tem = Fget_buffer (newname);
if (!NILP (tem))
{
if (NILP (unique) && XBUFFER (tem) == current_buffer)
return current_buffer->name;
if (!NILP (unique))
newname = Fgenerate_new_buffer_name (newname, current_buffer->name);
else
error ("Buffer name `%s' is in use", SDATA (newname));
}
current_buffer->name = newname;
update_mode_lines++;
XSETBUFFER (buf, current_buffer);
Fsetcar (Frassq (buf, Vbuffer_alist), newname);
if (NILP (current_buffer->filename)
&& !NILP (current_buffer->auto_save_file_name))
call0 (intern ("rename-auto-save-file"));
return current_buffer->name;
}
DEFUN ("other-buffer", Fother_buffer, Sother_buffer, 0, 3, 0,
doc: )
(buffer, visible_ok, frame)
register Lisp_Object buffer, visible_ok, frame;
{
Lisp_Object Fset_buffer_major_mode ();
register Lisp_Object tail, buf, notsogood, tem, pred, add_ons;
notsogood = Qnil;
if (NILP (frame))
frame = selected_frame;
tail = Vbuffer_alist;
pred = frame_buffer_predicate (frame);
tem = frame_buffer_list (frame);
add_ons = Qnil;
while (CONSP (tem))
{
if (BUFFERP (XCAR (tem)))
add_ons = Fcons (Fcons (Qnil, XCAR (tem)), add_ons);
tem = XCDR (tem);
}
tail = nconc2 (Fnreverse (add_ons), tail);
for (; CONSP (tail); tail = XCDR (tail))
{
buf = Fcdr (XCAR (tail));
if (EQ (buf, buffer))
continue;
if (NILP (buf))
continue;
if (NILP (XBUFFER (buf)->name))
continue;
if (SREF (XBUFFER (buf)->name, 0) == ' ')
continue;
if (!NILP (pred))
{
tem = call1 (pred, buf);
if (NILP (tem))
continue;
}
if (NILP (visible_ok))
tem = Fget_buffer_window (buf, Qvisible);
else
tem = Qnil;
if (NILP (tem))
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;
}
DEFUN ("buffer-enable-undo", Fbuffer_enable_undo, Sbuffer_enable_undo,
0, 1, "",
doc: )
(buffer)
register Lisp_Object buffer;
{
Lisp_Object real_buffer;
if (NILP (buffer))
XSETBUFFER (real_buffer, current_buffer);
else
{
real_buffer = Fget_buffer (buffer);
if (NILP (real_buffer))
nsberror (buffer);
}
if (EQ (XBUFFER (real_buffer)->undo_list, Qt))
XBUFFER (real_buffer)->undo_list = Qnil;
return Qnil;
}
DEFUN ("kill-buffer", Fkill_buffer, Skill_buffer, 1, 1, "bKill buffer: ",
doc: )
(buffer)
Lisp_Object buffer;
{
Lisp_Object buf;
register struct buffer *b;
register Lisp_Object tem;
register struct Lisp_Marker *m;
struct gcpro gcpro1;
if (NILP (buffer))
buf = Fcurrent_buffer ();
else
buf = Fget_buffer (buffer);
if (NILP (buf))
nsberror (buffer);
b = XBUFFER (buf);
if (NILP (b->name))
return Qnil;
if (INTERACTIVE && !NILP (b->filename)
&& BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
{
GCPRO1 (buf);
tem = do_yes_or_no_p (format2 ("Buffer %s modified; kill anyway? ",
b->name, make_number (0)));
UNGCPRO;
if (NILP (tem))
return Qnil;
}
{
int count = SPECPDL_INDEX ();
Lisp_Object arglist[1];
record_unwind_protect (save_excursion_restore, save_excursion_save ());
set_buffer_internal (b);
arglist[0] = Qkill_buffer_query_functions;
tem = Frun_hook_with_args_until_failure (1, arglist);
if (NILP (tem))
return unbind_to (count, Qnil);
Frun_hooks (1, &Qkill_buffer_hook);
unbind_to (count, Qnil);
}
if (EQ (buf, XWINDOW (minibuf_window)->buffer))
return Qnil;
if (NILP (b->name))
return Qnil;
if (! b->base_buffer)
{
struct buffer *other;
GCPRO1 (buf);
for (other = all_buffers; other; other = other->next)
if (other->base_buffer == b && !NILP (other->name))
{
Lisp_Object buf;
XSETBUFFER (buf, other);
Fkill_buffer (buf);
}
UNGCPRO;
}
if (b == current_buffer)
{
tem = Fother_buffer (buf, Qnil, Qnil);
Fset_buffer (tem);
if (b == current_buffer)
return Qnil;
}
XSETBUFFER (tem, current_buffer);
if (EQ (tem, XWINDOW (minibuf_window)->buffer))
{
tem = Fother_buffer (buf, Qnil, Qnil);
if (EQ (buf, tem))
return Qnil;
}
#ifdef CLASH_DETECTION
unlock_buffer (b);
#endif
GCPRO1 (buf);
kill_buffer_processes (buf);
UNGCPRO;
if (NILP (b->name))
return Qnil;
clear_charpos_cache (b);
tem = Vinhibit_quit;
Vinhibit_quit = Qt;
replace_buffer_in_all_windows (buf);
Vbuffer_alist = Fdelq (Frassq (buf, Vbuffer_alist), Vbuffer_alist);
frames_discard_buffer (buf);
Vinhibit_quit = tem;
if (STRINGP (b->auto_save_file_name)
&& b->auto_save_modified != 0
&& BUF_SAVE_MODIFF (b) < b->auto_save_modified
&& BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)
&& NILP (Fsymbol_value (intern ("auto-save-visited-file-name"))))
{
Lisp_Object tem;
tem = Fsymbol_value (intern ("delete-auto-save-files"));
if (! NILP (tem))
internal_delete_file (b->auto_save_file_name);
}
if (b->base_buffer)
{
for (m = BUF_MARKERS (b); m; )
{
struct Lisp_Marker *next = m->next;
if (m->buffer == b)
unchain_marker (m);
m = next;
}
}
else
{
for (m = BUF_MARKERS (b); m; )
{
struct Lisp_Marker *next = m->next;
m->buffer = 0;
m->next = NULL;
m = next;
}
BUF_MARKERS (b) = NULL;
BUF_INTERVALS (b) = NULL_INTERVAL;
}
swap_out_buffer_local_variables (b);
reset_buffer_local_variables (b, 1);
b->name = Qnil;
BLOCK_INPUT;
if (! b->base_buffer)
free_buffer_text (b);
if (b->newline_cache)
{
free_region_cache (b->newline_cache);
b->newline_cache = 0;
}
if (b->width_run_cache)
{
free_region_cache (b->width_run_cache);
b->width_run_cache = 0;
}
b->width_table = Qnil;
UNBLOCK_INPUT;
b->undo_list = Qnil;
return Qt;
}
void
record_buffer (buf)
Lisp_Object buf;
{
register Lisp_Object link, prev;
Lisp_Object frame;
frame = selected_frame;
prev = Qnil;
for (link = Vbuffer_alist; CONSP (link); link = XCDR (link))
{
if (EQ (XCDR (XCAR (link)), buf))
break;
prev = link;
}
if (NILP (prev))
Vbuffer_alist = XCDR (Vbuffer_alist);
else
XSETCDR (prev, XCDR (XCDR (prev)));
XSETCDR (link, Vbuffer_alist);
Vbuffer_alist = link;
prev = Qnil;
for (link = frame_buffer_list (frame); CONSP (link);
link = XCDR (link))
{
if (EQ (XCAR (link), buf))
break;
prev = link;
}
if (CONSP (link))
{
if (NILP (prev))
set_frame_buffer_list (frame,
XCDR (frame_buffer_list (frame)));
else
XSETCDR (prev, XCDR (XCDR (prev)));
XSETCDR (link, frame_buffer_list (frame));
set_frame_buffer_list (frame, link);
}
else
set_frame_buffer_list (frame, Fcons (buf, frame_buffer_list (frame)));
}
DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, Sset_buffer_major_mode, 1, 1, 0,
doc: )
(buffer)
Lisp_Object buffer;
{
int count;
Lisp_Object function;
CHECK_BUFFER (buffer);
if (STRINGP (XBUFFER (buffer)->name)
&& strcmp (SDATA (XBUFFER (buffer)->name), "*scratch*") == 0)
function = find_symbol_value (intern ("initial-major-mode"));
else
{
function = buffer_defaults.major_mode;
if (NILP (function)
&& NILP (Fget (current_buffer->major_mode, Qmode_class)))
function = current_buffer->major_mode;
}
if (NILP (function) || EQ (function, Qfundamental_mode))
return Qnil;
count = SPECPDL_INDEX ();
record_unwind_protect (save_excursion_restore, save_excursion_save ());
Fset_buffer (buffer);
call0 (function);
return unbind_to (count, Qnil);
}
char *
no_switch_window (window)
Lisp_Object window;
{
Lisp_Object tem;
if (EQ (minibuf_window, window))
return "Cannot switch buffers in minibuffer window";
tem = Fwindow_dedicated_p (window);
if (EQ (tem, Qt))
return "Cannot switch buffers in a dedicated window";
return NULL;
}
Lisp_Object
switch_to_buffer_1 (buffer, norecord)
Lisp_Object buffer, norecord;
{
register Lisp_Object buf;
if (NILP (buffer))
buf = Fother_buffer (Fcurrent_buffer (), Qnil, Qnil);
else
{
buf = Fget_buffer (buffer);
if (NILP (buf))
{
buf = Fget_buffer_create (buffer);
Fset_buffer_major_mode (buf);
}
}
Fset_buffer (buf);
if (NILP (norecord))
record_buffer (buf);
Fset_window_buffer (EQ (selected_window, minibuf_window)
? Fnext_window (minibuf_window, Qnil, Qnil)
: selected_window,
buf, Qnil);
return buf;
}
DEFUN ("switch-to-buffer", Fswitch_to_buffer, Sswitch_to_buffer, 1, 2, "BSwitch to buffer: ",
doc: )
(buffer, norecord)
Lisp_Object buffer, norecord;
{
char *err;
if (EQ (buffer, Fwindow_buffer (selected_window)))
{
if (NILP (norecord))
record_buffer (buffer);
return Fset_buffer (buffer);
}
err = no_switch_window (selected_window);
if (err) error (err);
return switch_to_buffer_1 (buffer, norecord);
}
DEFUN ("pop-to-buffer", Fpop_to_buffer, Spop_to_buffer, 1, 3, 0,
doc: )
(buffer, other_window, norecord)
Lisp_Object buffer, other_window, norecord;
{
register Lisp_Object buf;
if (NILP (buffer))
buf = Fother_buffer (Fcurrent_buffer (), Qnil, Qnil);
else
{
buf = Fget_buffer (buffer);
if (NILP (buf))
{
buf = Fget_buffer_create (buffer);
Fset_buffer_major_mode (buf);
}
}
Fset_buffer (buf);
Fselect_window (Fdisplay_buffer (buf, other_window, Qnil), norecord);
return buf;
}
DEFUN ("current-buffer", Fcurrent_buffer, Scurrent_buffer, 0, 0, 0,
doc: )
()
{
register Lisp_Object buf;
XSETBUFFER (buf, current_buffer);
return buf;
}
void
set_buffer_internal (b)
register struct buffer *b;
{
if (current_buffer != b)
set_buffer_internal_1 (b);
}
void
set_buffer_internal_1 (b)
register struct buffer *b;
{
register struct buffer *old_buf;
register Lisp_Object tail, valcontents;
Lisp_Object tem;
#ifdef USE_MMAP_FOR_BUFFERS
if (b->text->beg == NULL)
enlarge_buffer_text (b, 0);
#endif
if (current_buffer == b)
return;
old_buf = current_buffer;
current_buffer = b;
last_known_column_point = -1;
if (old_buf)
{
if (old_buf->base_buffer)
old_buf->base_buffer->undo_list = old_buf->undo_list;
if (! NILP (old_buf->pt_marker))
{
Lisp_Object obuf;
XSETBUFFER (obuf, old_buf);
set_marker_both (old_buf->pt_marker, obuf,
BUF_PT (old_buf), BUF_PT_BYTE (old_buf));
}
if (! NILP (old_buf->begv_marker))
{
Lisp_Object obuf;
XSETBUFFER (obuf, old_buf);
set_marker_both (old_buf->begv_marker, obuf,
BUF_BEGV (old_buf), BUF_BEGV_BYTE (old_buf));
}
if (! NILP (old_buf->zv_marker))
{
Lisp_Object obuf;
XSETBUFFER (obuf, old_buf);
set_marker_both (old_buf->zv_marker, obuf,
BUF_ZV (old_buf), BUF_ZV_BYTE (old_buf));
}
}
if (b->base_buffer)
b->undo_list = b->base_buffer->undo_list;
if (! NILP (b->pt_marker))
{
BUF_PT (b) = marker_position (b->pt_marker);
BUF_PT_BYTE (b) = marker_byte_position (b->pt_marker);
}
if (! NILP (b->begv_marker))
{
BUF_BEGV (b) = marker_position (b->begv_marker);
BUF_BEGV_BYTE (b) = marker_byte_position (b->begv_marker);
}
if (! NILP (b->zv_marker))
{
BUF_ZV (b) = marker_position (b->zv_marker);
BUF_ZV_BYTE (b) = marker_byte_position (b->zv_marker);
}
for (tail = b->local_var_alist; CONSP (tail); tail = XCDR (tail))
{
valcontents = SYMBOL_VALUE (XCAR (XCAR (tail)));
if ((BUFFER_LOCAL_VALUEP (valcontents)
|| SOME_BUFFER_LOCAL_VALUEP (valcontents))
&& (tem = XBUFFER_LOCAL_VALUE (valcontents)->realvalue,
(BOOLFWDP (tem) || INTFWDP (tem) || OBJFWDP (tem))))
Fsymbol_value (XCAR (XCAR (tail)));
}
if (old_buf)
for (tail = old_buf->local_var_alist; CONSP (tail); tail = XCDR (tail))
{
valcontents = SYMBOL_VALUE (XCAR (XCAR (tail)));
if ((BUFFER_LOCAL_VALUEP (valcontents)
|| SOME_BUFFER_LOCAL_VALUEP (valcontents))
&& (tem = XBUFFER_LOCAL_VALUE (valcontents)->realvalue,
(BOOLFWDP (tem) || INTFWDP (tem) || OBJFWDP (tem))))
Fsymbol_value (XCAR (XCAR (tail)));
}
}
void
set_buffer_temp (b)
struct buffer *b;
{
register struct buffer *old_buf;
if (current_buffer == b)
return;
old_buf = current_buffer;
current_buffer = b;
if (old_buf)
{
if (! NILP (old_buf->pt_marker))
{
Lisp_Object obuf;
XSETBUFFER (obuf, old_buf);
set_marker_both (old_buf->pt_marker, obuf,
BUF_PT (old_buf), BUF_PT_BYTE (old_buf));
}
if (! NILP (old_buf->begv_marker))
{
Lisp_Object obuf;
XSETBUFFER (obuf, old_buf);
set_marker_both (old_buf->begv_marker, obuf,
BUF_BEGV (old_buf), BUF_BEGV_BYTE (old_buf));
}
if (! NILP (old_buf->zv_marker))
{
Lisp_Object obuf;
XSETBUFFER (obuf, old_buf);
set_marker_both (old_buf->zv_marker, obuf,
BUF_ZV (old_buf), BUF_ZV_BYTE (old_buf));
}
}
if (! NILP (b->pt_marker))
{
BUF_PT (b) = marker_position (b->pt_marker);
BUF_PT_BYTE (b) = marker_byte_position (b->pt_marker);
}
if (! NILP (b->begv_marker))
{
BUF_BEGV (b) = marker_position (b->begv_marker);
BUF_BEGV_BYTE (b) = marker_byte_position (b->begv_marker);
}
if (! NILP (b->zv_marker))
{
BUF_ZV (b) = marker_position (b->zv_marker);
BUF_ZV_BYTE (b) = marker_byte_position (b->zv_marker);
}
}
DEFUN ("set-buffer", Fset_buffer, Sset_buffer, 1, 1, 0,
doc: )
(buffer)
register Lisp_Object buffer;
{
register Lisp_Object buf;
buf = Fget_buffer (buffer);
if (NILP (buf))
nsberror (buffer);
if (NILP (XBUFFER (buf)->name))
error ("Selecting deleted buffer");
set_buffer_internal (XBUFFER (buf));
return buf;
}
Lisp_Object
set_buffer_if_live (buffer)
Lisp_Object buffer;
{
if (! NILP (XBUFFER (buffer)->name))
Fset_buffer (buffer);
return Qnil;
}
DEFUN ("barf-if-buffer-read-only", Fbarf_if_buffer_read_only,
Sbarf_if_buffer_read_only, 0, 0, 0,
doc: )
()
{
if (!NILP (current_buffer->read_only)
&& NILP (Vinhibit_read_only))
xsignal1 (Qbuffer_read_only, Fcurrent_buffer ());
return Qnil;
}
DEFUN ("bury-buffer", Fbury_buffer, Sbury_buffer, 0, 1, "",
doc: )
(buffer)
register Lisp_Object buffer;
{
if (NILP (buffer))
{
Lisp_Object tem;
XSETBUFFER (buffer, current_buffer);
tem = Fwindow_buffer (selected_window);
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
{
Lisp_Object buf1;
buf1 = Fget_buffer (buffer);
if (NILP (buf1))
nsberror (buffer);
buffer = buf1;
}
if (!NILP (XBUFFER (buffer)->name))
{
Lisp_Object aelt, link;
aelt = Frassq (buffer, Vbuffer_alist);
link = Fmemq (aelt, Vbuffer_alist);
Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
XSETCDR (link, Qnil);
Vbuffer_alist = nconc2 (Vbuffer_alist, link);
frames_discard_buffer (buffer);
}
return Qnil;
}
DEFUN ("erase-buffer", Ferase_buffer, Serase_buffer, 0, 0, "*",
doc: )
()
{
Fwiden ();
del_range (BEG, Z);
current_buffer->last_window_start = 1;
XSETFASTINT (current_buffer->save_length, 0);
return Qnil;
}
void
validate_region (b, e)
register Lisp_Object *b, *e;
{
CHECK_NUMBER_COERCE_MARKER (*b);
CHECK_NUMBER_COERCE_MARKER (*e);
if (XINT (*b) > XINT (*e))
{
Lisp_Object tem;
tem = *b; *b = *e; *e = tem;
}
if (!(BEGV <= XINT (*b) && XINT (*b) <= XINT (*e)
&& XINT (*e) <= ZV))
args_out_of_range (*b, *e);
}
static int
advance_to_char_boundary (byte_pos)
int byte_pos;
{
int c;
if (byte_pos == BEG)
return BEG;
c = FETCH_BYTE (byte_pos);
if (! CHAR_HEAD_P (c))
{
int orig_byte_pos = byte_pos;
do
{
byte_pos--;
c = FETCH_BYTE (byte_pos);
}
while (! CHAR_HEAD_P (c) && byte_pos > BEG);
INC_POS (byte_pos);
if (byte_pos < orig_byte_pos)
byte_pos = orig_byte_pos;
}
return byte_pos;
}
DEFUN ("set-buffer-multibyte", Fset_buffer_multibyte, Sset_buffer_multibyte,
1, 1, 0,
doc: )
(flag)
Lisp_Object flag;
{
struct Lisp_Marker *tail, *markers;
struct buffer *other;
int begv, zv;
int narrowed = (BEG != BEGV || Z != ZV);
int modified_p = !NILP (Fbuffer_modified_p (Qnil));
Lisp_Object old_undo = current_buffer->undo_list;
struct gcpro gcpro1;
if (current_buffer->base_buffer)
error ("Cannot do `set-buffer-multibyte' on an indirect buffer");
if (NILP (flag) == NILP (current_buffer->enable_multibyte_characters))
return flag;
GCPRO1 (old_undo);
current_buffer->undo_list = Qt;
clear_charpos_cache (current_buffer);
if (NILP (flag))
begv = BEGV_BYTE, zv = ZV_BYTE;
else
begv = BEGV, zv = ZV;
if (narrowed)
Fwiden ();
if (NILP (flag))
{
int pos, stop;
unsigned char *p;
set_intervals_multibyte (0);
current_buffer->enable_multibyte_characters = Qnil;
Z = Z_BYTE;
BEGV = BEGV_BYTE;
ZV = ZV_BYTE;
GPT = GPT_BYTE;
TEMP_SET_PT_BOTH (PT_BYTE, PT_BYTE);
for (tail = BUF_MARKERS (current_buffer); tail; tail = tail->next)
tail->charpos = tail->bytepos;
pos = BEG;
stop = GPT;
p = BEG_ADDR;
while (1)
{
int c, bytes;
if (pos == stop)
{
if (pos == Z)
break;
p = GAP_END_ADDR;
stop = Z;
}
if (MULTIBYTE_STR_AS_UNIBYTE_P (p, bytes))
p += bytes, pos += bytes;
else
{
c = STRING_CHAR (p, stop - pos);
bytes--;
del_range_2 (pos, pos, pos + bytes, pos + bytes, 0);
p = GAP_END_ADDR;
*p++ = c;
pos++;
if (begv > pos)
begv -= bytes;
if (zv > pos)
zv -= bytes;
stop = Z;
}
}
if (narrowed)
Fnarrow_to_region (make_number (begv), make_number (zv));
}
else
{
int pt = PT;
int pos, stop;
unsigned char *p;
if (GPT_BYTE > 1 && GPT_BYTE < Z_BYTE
&& ! CHAR_HEAD_P (*(GAP_END_ADDR)))
{
unsigned char *p = GPT_ADDR - 1;
while (! CHAR_HEAD_P (*p) && p > BEG_ADDR) p--;
if (BASE_LEADING_CODE_P (*p))
{
int new_gpt = GPT_BYTE - (GPT_ADDR - p);
move_gap_both (new_gpt, new_gpt);
}
}
pos = BEG;
stop = GPT;
p = BEG_ADDR;
while (1)
{
int bytes;
if (pos == stop)
{
if (pos == Z)
break;
p = GAP_END_ADDR;
stop = Z;
}
if (UNIBYTE_STR_AS_MULTIBYTE_P (p, stop - pos, bytes))
p += bytes, pos += bytes;
else
{
unsigned char tmp[MAX_MULTIBYTE_LENGTH];
bytes = CHAR_STRING (*p, tmp);
*p = tmp[0];
TEMP_SET_PT_BOTH (pos + 1, pos + 1);
bytes--;
insert_1_both (tmp + 1, bytes, bytes, 1, 0, 0);
pos = GPT;
p = GAP_END_ADDR;
if (pos <= begv)
begv += bytes;
if (pos <= zv)
zv += bytes;
if (pos <= pt)
pt += bytes;
stop = Z;
}
}
if (pt != PT)
TEMP_SET_PT (pt);
if (narrowed)
Fnarrow_to_region (make_number (begv), make_number (zv));
current_buffer->enable_multibyte_characters = Qt;
GPT_BYTE = advance_to_char_boundary (GPT_BYTE);
GPT = chars_in_text (BEG_ADDR, GPT_BYTE - BEG_BYTE) + BEG;
Z = chars_in_text (GAP_END_ADDR, Z_BYTE - GPT_BYTE) + GPT;
BEGV_BYTE = advance_to_char_boundary (BEGV_BYTE);
if (BEGV_BYTE > GPT_BYTE)
BEGV = chars_in_text (GAP_END_ADDR, BEGV_BYTE - GPT_BYTE) + GPT;
else
BEGV = chars_in_text (BEG_ADDR, BEGV_BYTE - BEG_BYTE) + BEG;
ZV_BYTE = advance_to_char_boundary (ZV_BYTE);
if (ZV_BYTE > GPT_BYTE)
ZV = chars_in_text (GAP_END_ADDR, ZV_BYTE - GPT_BYTE) + GPT;
else
ZV = chars_in_text (BEG_ADDR, ZV_BYTE - BEG_BYTE) + BEG;
{
int pt_byte = advance_to_char_boundary (PT_BYTE);
int pt;
if (pt_byte > GPT_BYTE)
pt = chars_in_text (GAP_END_ADDR, pt_byte - GPT_BYTE) + GPT;
else
pt = chars_in_text (BEG_ADDR, pt_byte - BEG_BYTE) + BEG;
TEMP_SET_PT_BOTH (pt, pt_byte);
}
tail = markers = BUF_MARKERS (current_buffer);
BUF_MARKERS (current_buffer) = NULL;
for (; tail; tail = tail->next)
{
tail->bytepos = advance_to_char_boundary (tail->bytepos);
tail->charpos = BYTE_TO_CHAR (tail->bytepos);
}
if (BUF_MARKERS (current_buffer))
abort ();
BUF_MARKERS (current_buffer) = markers;
set_intervals_multibyte (1);
}
if (!EQ (old_undo, Qt))
{
extern Lisp_Object Qapply;
current_buffer->undo_list = Fcons (list3 (Qapply,
intern ("set-buffer-multibyte"),
NILP (flag) ? Qt : Qnil),
old_undo);
}
UNGCPRO;
current_buffer->prevent_redisplay_optimizations_p = 1;
++windows_or_buffers_changed;
for (other = all_buffers; other; other = other->next)
if (other->base_buffer == current_buffer && !NILP (other->name))
{
other->enable_multibyte_characters
= current_buffer->enable_multibyte_characters;
other->prevent_redisplay_optimizations_p = 1;
}
if (!modified_p && !NILP (Fbuffer_modified_p (Qnil)))
Fset_buffer_modified_p (Qnil);
#ifdef subprocesses
{
Lisp_Object process;
process = Fget_buffer_process (Fcurrent_buffer ());
if (PROCESSP (process))
setup_process_coding_systems (process);
}
#endif
return flag;
}
DEFUN ("kill-all-local-variables", Fkill_all_local_variables, Skill_all_local_variables,
0, 0, 0,
doc: )
()
{
register Lisp_Object alist, sym, tem;
Lisp_Object oalist;
if (!NILP (Vrun_hooks))
call1 (Vrun_hooks, Qchange_major_mode_hook);
oalist = current_buffer->local_var_alist;
swap_out_buffer_local_variables (current_buffer);
reset_buffer_local_variables (current_buffer, 0);
for (alist = oalist; !NILP (alist); alist = XCDR (alist))
{
sym = XCAR (XCAR (alist));
tem = Fget (sym, Qpermanent_local);
if (! NILP (tem))
{
Fmake_local_variable (sym);
Fset (sym, XCDR (XCAR (alist)));
}
}
update_mode_lines++;
return Qnil;
}
static void
swap_out_buffer_local_variables (b)
struct buffer *b;
{
Lisp_Object oalist, alist, sym, tem, buffer;
XSETBUFFER (buffer, b);
oalist = b->local_var_alist;
for (alist = oalist; !NILP (alist); alist = XCDR (alist))
{
sym = XCAR (XCAR (alist));
tem = XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->buffer;
if (BUFFERP (tem) && XBUFFER (tem) == current_buffer)
{
tem = XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->cdr;
XSETCDR (XCAR (tem),
do_symval_forwarding (XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->realvalue));
XSETCAR (tem, tem);
XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->buffer = buffer;
store_symval_forwarding (sym,
XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->realvalue,
XCDR (tem), NULL);
}
}
}
int
overlays_at (pos, extend, vec_ptr, len_ptr, next_ptr, prev_ptr, change_req)
EMACS_INT pos;
int extend;
Lisp_Object **vec_ptr;
int *len_ptr;
int *next_ptr;
int *prev_ptr;
int change_req;
{
Lisp_Object overlay, start, end;
struct Lisp_Overlay *tail;
int idx = 0;
int len = *len_ptr;
Lisp_Object *vec = *vec_ptr;
int next = ZV;
int prev = BEGV;
int inhibit_storing = 0;
for (tail = current_buffer->overlays_before; tail; tail = tail->next)
{
int startpos, endpos;
XSETMISC (overlay, tail);
start = OVERLAY_START (overlay);
end = OVERLAY_END (overlay);
endpos = OVERLAY_POSITION (end);
if (endpos < pos)
{
if (prev < endpos)
prev = endpos;
break;
}
startpos = OVERLAY_POSITION (start);
if (prev < startpos && startpos < pos)
prev = startpos;
if (endpos == pos)
continue;
if (startpos <= pos)
{
if (idx == len)
{
if (extend)
{
len *= 2;
if (len == 0)
len = 4;
*len_ptr = len;
vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
*vec_ptr = vec;
}
else
inhibit_storing = 1;
}
if (!inhibit_storing)
vec[idx] = overlay;
idx++;
}
else if (startpos < next)
next = startpos;
}
for (tail = current_buffer->overlays_after; tail; tail = tail->next)
{
int startpos, endpos;
XSETMISC (overlay, tail);
start = OVERLAY_START (overlay);
end = OVERLAY_END (overlay);
startpos = OVERLAY_POSITION (start);
if (pos < startpos)
{
if (startpos < next)
next = startpos;
break;
}
endpos = OVERLAY_POSITION (end);
if (pos < endpos)
{
if (idx == len)
{
if (extend)
{
len *= 2;
if (len == 0)
len = 4;
*len_ptr = len;
vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
*vec_ptr = vec;
}
else
inhibit_storing = 1;
}
if (!inhibit_storing)
vec[idx] = overlay;
idx++;
if (startpos < pos && startpos > prev)
prev = startpos;
}
else if (endpos < pos && endpos > prev)
prev = endpos;
else if (endpos == pos && startpos > prev
&& (!change_req || startpos < pos))
prev = startpos;
}
if (next_ptr)
*next_ptr = next;
if (prev_ptr)
*prev_ptr = prev;
return idx;
}
static int
overlays_in (beg, end, extend, vec_ptr, len_ptr, next_ptr, prev_ptr)
int beg, end;
int extend;
Lisp_Object **vec_ptr;
int *len_ptr;
int *next_ptr;
int *prev_ptr;
{
Lisp_Object overlay, ostart, oend;
struct Lisp_Overlay *tail;
int idx = 0;
int len = *len_ptr;
Lisp_Object *vec = *vec_ptr;
int next = ZV;
int prev = BEGV;
int inhibit_storing = 0;
for (tail = current_buffer->overlays_before; tail; tail = tail->next)
{
int startpos, endpos;
XSETMISC (overlay, tail);
ostart = OVERLAY_START (overlay);
oend = OVERLAY_END (overlay);
endpos = OVERLAY_POSITION (oend);
if (endpos < beg)
{
if (prev < endpos)
prev = endpos;
break;
}
startpos = OVERLAY_POSITION (ostart);
if ((beg < endpos && startpos < end)
|| (startpos == endpos && beg == endpos))
{
if (idx == len)
{
if (extend)
{
len *= 2;
if (len == 0)
len = 4;
*len_ptr = len;
vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
*vec_ptr = vec;
}
else
inhibit_storing = 1;
}
if (!inhibit_storing)
vec[idx] = overlay;
idx++;
}
else if (startpos < next)
next = startpos;
}
for (tail = current_buffer->overlays_after; tail; tail = tail->next)
{
int startpos, endpos;
XSETMISC (overlay, tail);
ostart = OVERLAY_START (overlay);
oend = OVERLAY_END (overlay);
startpos = OVERLAY_POSITION (ostart);
if (end < startpos)
{
if (startpos < next)
next = startpos;
break;
}
endpos = OVERLAY_POSITION (oend);
if ((beg < endpos && startpos < end)
|| (startpos == endpos && beg == endpos))
{
if (idx == len)
{
if (extend)
{
len *= 2;
if (len == 0)
len = 4;
*len_ptr = len;
vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
*vec_ptr = vec;
}
else
inhibit_storing = 1;
}
if (!inhibit_storing)
vec[idx] = overlay;
idx++;
}
else if (endpos < beg && endpos > prev)
prev = endpos;
}
if (next_ptr)
*next_ptr = next;
if (prev_ptr)
*prev_ptr = prev;
return idx;
}
int
mouse_face_overlay_overlaps (overlay)
Lisp_Object overlay;
{
int start = OVERLAY_POSITION (OVERLAY_START (overlay));
int end = OVERLAY_POSITION (OVERLAY_END (overlay));
int n, i, size;
Lisp_Object *v, tem;
size = 10;
v = (Lisp_Object *) alloca (size * sizeof *v);
n = overlays_in (start, end, 0, &v, &size, NULL, NULL);
if (n > size)
{
v = (Lisp_Object *) alloca (n * sizeof *v);
overlays_in (start, end, 0, &v, &n, NULL, NULL);
}
for (i = 0; i < n; ++i)
if (!EQ (v[i], overlay)
&& (tem = Foverlay_get (overlay, Qmouse_face),
!NILP (tem)))
break;
return i < n;
}
int
overlay_touches_p (pos)
int pos;
{
Lisp_Object overlay;
struct Lisp_Overlay *tail;
for (tail = current_buffer->overlays_before; tail; tail = tail->next)
{
int endpos;
XSETMISC (overlay ,tail);
if (!GC_OVERLAYP (overlay))
abort ();
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)
{
int startpos;
XSETMISC (overlay, tail);
if (!GC_OVERLAYP (overlay))
abort ();
startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
if (pos < startpos)
break;
if (startpos == pos || OVERLAY_POSITION (OVERLAY_END (overlay)) == pos)
return 1;
}
return 0;
}
struct sortvec
{
Lisp_Object overlay;
int beg, end;
int priority;
};
static int
compare_overlays (v1, v2)
const void *v1, *v2;
{
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;
if (s1->beg != s2->beg)
return s1->beg - s2->beg;
if (s1->end != s2->end)
return s2->end - s1->end;
return 0;
}
int
sort_overlays (overlay_vec, noverlays, w)
Lisp_Object *overlay_vec;
int noverlays;
struct window *w;
{
int i, j;
struct sortvec *sortvec;
sortvec = (struct sortvec *) alloca (noverlays * sizeof (struct sortvec));
for (i = 0, j = 0; i < noverlays; i++)
{
Lisp_Object tem;
Lisp_Object overlay;
overlay = overlay_vec[i];
if (OVERLAY_VALID (overlay)
&& OVERLAY_POSITION (OVERLAY_START (overlay)) > 0
&& OVERLAY_POSITION (OVERLAY_END (overlay)) > 0)
{
if (w)
{
Lisp_Object window;
window = Foverlay_get (overlay, Qwindow);
if (WINDOWP (window) && XWINDOW (window) != w)
continue;
}
sortvec[j].overlay = overlay;
sortvec[j].beg = OVERLAY_POSITION (OVERLAY_START (overlay));
sortvec[j].end = OVERLAY_POSITION (OVERLAY_END (overlay));
tem = Foverlay_get (overlay, Qpriority);
if (INTEGERP (tem))
sortvec[j].priority = XINT (tem);
else
sortvec[j].priority = 0;
j++;
}
}
noverlays = j;
if (noverlays > 1)
qsort (sortvec, noverlays, sizeof (struct sortvec), compare_overlays);
for (i = 0; i < noverlays; i++)
overlay_vec[i] = sortvec[i].overlay;
return (noverlays);
}
struct sortstr
{
Lisp_Object string, string2;
int size;
int priority;
};
struct sortstrlist
{
struct sortstr *buf;
int size;
int used;
int bytes;
};
static struct sortstrlist overlay_heads, overlay_tails;
static unsigned char *overlay_str_buf;
static int overlay_str_len;
static int
cmp_for_strings (as1, as2)
char *as1, *as2;
{
struct sortstr *s1 = (struct sortstr *)as1;
struct sortstr *s2 = (struct sortstr *)as2;
if (s1->size != s2->size)
return s2->size - s1->size;
if (s1->priority != s2->priority)
return s1->priority - s2->priority;
return 0;
}
static void
record_overlay_string (ssl, str, str2, pri, size)
struct sortstrlist *ssl;
Lisp_Object str, str2, pri;
int size;
{
int 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[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->used++;
if (NILP (current_buffer->enable_multibyte_characters))
nbytes = SCHARS (str);
else if (! STRING_MULTIBYTE (str))
nbytes = count_size_as_multibyte (SDATA (str),
SBYTES (str));
else
nbytes = SBYTES (str);
ssl->bytes += nbytes;
if (STRINGP (str2))
{
if (NILP (current_buffer->enable_multibyte_characters))
nbytes = SCHARS (str2);
else if (! STRING_MULTIBYTE (str2))
nbytes = count_size_as_multibyte (SDATA (str2),
SBYTES (str2));
else
nbytes = SBYTES (str2);
ssl->bytes += nbytes;
}
}
int
overlay_strings (pos, w, pstr)
EMACS_INT pos;
struct window *w;
unsigned char **pstr;
{
Lisp_Object overlay, window, str;
struct Lisp_Overlay *ov;
int startpos, endpos;
int multibyte = ! NILP (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)
{
XSETMISC (overlay, ov);
eassert (OVERLAYP (overlay));
startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
if (endpos < pos)
break;
if (endpos != pos && startpos != pos)
continue;
window = Foverlay_get (overlay, Qwindow);
if (WINDOWP (window) && XWINDOW (window) != w)
continue;
if (startpos == pos
&& (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
record_overlay_string (&overlay_heads, str,
(startpos == endpos
? Foverlay_get (overlay, Qafter_string)
: Qnil),
Foverlay_get (overlay, Qpriority),
endpos - startpos);
else if (endpos == pos
&& (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)))
record_overlay_string (&overlay_tails, str, Qnil,
Foverlay_get (overlay, Qpriority),
endpos - startpos);
}
for (ov = current_buffer->overlays_after; ov; ov = ov->next)
{
XSETMISC (overlay, ov);
eassert (OVERLAYP (overlay));
startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
if (startpos > pos)
break;
if (endpos != pos && startpos != pos)
continue;
window = Foverlay_get (overlay, Qwindow);
if (WINDOWP (window) && XWINDOW (window) != w)
continue;
if (startpos == pos
&& (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
record_overlay_string (&overlay_heads, str,
(startpos == endpos
? Foverlay_get (overlay, Qafter_string)
: Qnil),
Foverlay_get (overlay, Qpriority),
endpos - startpos);
else if (endpos == pos
&& (str = Foverlay_get (overlay, Qafter_string), STRINGP (str)))
record_overlay_string (&overlay_tails, str, Qnil,
Foverlay_get (overlay, Qpriority),
endpos - startpos);
}
if (overlay_tails.used > 1)
qsort (overlay_tails.buf, overlay_tails.used, sizeof (struct sortstr),
cmp_for_strings);
if (overlay_heads.used > 1)
qsort (overlay_heads.buf, overlay_heads.used, sizeof (struct sortstr),
cmp_for_strings);
if (overlay_heads.bytes || overlay_tails.bytes)
{
Lisp_Object tem;
int i;
unsigned char *p;
int 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);
}
p = overlay_str_buf;
for (i = overlay_tails.used; --i >= 0;)
{
int nbytes;
tem = overlay_tails.buf[i].string;
nbytes = copy_text (SDATA (tem), p,
SBYTES (tem),
STRING_MULTIBYTE (tem), multibyte);
p += nbytes;
}
for (i = 0; i < overlay_heads.used; ++i)
{
int nbytes;
tem = overlay_heads.buf[i].string;
nbytes = copy_text (SDATA (tem), p,
SBYTES (tem),
STRING_MULTIBYTE (tem), multibyte);
p += nbytes;
tem = overlay_heads.buf[i].string2;
if (STRINGP (tem))
{
nbytes = copy_text (SDATA (tem), p,
SBYTES (tem),
STRING_MULTIBYTE (tem), multibyte);
p += nbytes;
}
}
if (p != overlay_str_buf + total)
abort ();
if (pstr)
*pstr = overlay_str_buf;
return total;
}
return 0;
}
void
recenter_overlay_lists (buf, pos)
struct buffer *buf;
EMACS_INT pos;
{
Lisp_Object overlay, beg, end;
struct Lisp_Overlay *prev, *tail, *next;
prev = NULL;
for (tail = buf->overlays_before; tail; prev = tail, tail = next)
{
next = tail->next;
XSETMISC (overlay, tail);
if (!OVERLAY_VALID (overlay))
#if 1
abort ();
#else
{
if (!NILP (prev))
XCDR (prev) = next;
else
buf->overlays_before = next;
tail = prev;
continue;
}
#endif
beg = OVERLAY_START (overlay);
end = OVERLAY_END (overlay);
if (OVERLAY_POSITION (end) > pos)
{
int where = OVERLAY_POSITION (beg);
struct Lisp_Overlay *other, *other_prev;
if (prev)
prev->next = next;
else
buf->overlays_before = next;
other_prev = NULL;
for (other = buf->overlays_after; other;
other_prev = other, other = other->next)
{
Lisp_Object otherbeg, otheroverlay;
XSETMISC (otheroverlay, other);
eassert (OVERLAY_VALID (otheroverlay));
otherbeg = OVERLAY_START (otheroverlay);
if (OVERLAY_POSITION (otherbeg) >= where)
break;
}
tail->next = other;
if (other_prev)
other_prev->next = tail;
else
buf->overlays_after = tail;
tail = prev;
}
else
break;
}
prev = NULL;
for (tail = buf->overlays_after; tail; prev = tail, tail = next)
{
next = tail->next;
XSETMISC (overlay, tail);
if (!OVERLAY_VALID (overlay))
#if 1
abort ();
#else
{
if (!NILP (prev))
XCDR (prev) = next;
else
buf->overlays_after = next;
tail = prev;
continue;
}
#endif
beg = OVERLAY_START (overlay);
end = OVERLAY_END (overlay);
if (OVERLAY_POSITION (beg) > pos)
break;
if (OVERLAY_POSITION (end) <= pos)
{
int where = OVERLAY_POSITION (end);
struct Lisp_Overlay *other, *other_prev;
if (prev)
prev->next = next;
else
buf->overlays_after = next;
other_prev = NULL;
for (other = buf->overlays_before; other;
other_prev = other, other = other->next)
{
Lisp_Object otherend, otheroverlay;
XSETMISC (otheroverlay, other);
eassert (OVERLAY_VALID (otheroverlay));
otherend = OVERLAY_END (otheroverlay);
if (OVERLAY_POSITION (otherend) <= where)
break;
}
tail->next = other;
if (other_prev)
other_prev->next = tail;
else
buf->overlays_before = tail;
tail = prev;
}
}
buf->overlay_center = pos;
}
void
adjust_overlays_for_insert (pos, length)
EMACS_INT pos;
EMACS_INT length;
{
if (current_buffer->overlay_center >= pos)
current_buffer->overlay_center += length;
}
void
adjust_overlays_for_delete (pos, length)
EMACS_INT pos;
EMACS_INT length;
{
if (current_buffer->overlay_center < pos)
;
else if (current_buffer->overlay_center > pos + length)
current_buffer->overlay_center -= length;
else
recenter_overlay_lists (current_buffer, pos);
}
void
fix_start_end_in_overlays (start, end)
register int start, end;
{
Lisp_Object overlay;
struct Lisp_Overlay *before_list, *after_list;
struct Lisp_Overlay *beforep = NULL, *afterp = NULL;
struct Lisp_Overlay *tail, *parent;
int startpos, endpos;
for (parent = NULL, tail = current_buffer->overlays_before; tail;)
{
XSETMISC (overlay, tail);
endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
if (endpos < startpos)
{
startpos = endpos;
Fset_marker (OVERLAY_START (overlay), make_number (startpos),
Qnil);
}
if (endpos < start)
break;
if (endpos < end
|| (startpos >= start && startpos < end))
{
if (endpos < current_buffer->overlay_center)
{
if (!afterp)
after_list = tail;
else
afterp->next = tail;
afterp = tail;
}
else
{
if (!beforep)
before_list = tail;
else
beforep->next = tail;
beforep = tail;
}
if (!parent)
current_buffer->overlays_before = tail->next;
else
parent->next = tail->next;
tail = tail->next;
}
else
parent = tail, tail = parent->next;
}
for (parent = NULL, tail = current_buffer->overlays_after; tail;)
{
XSETMISC (overlay, tail);
startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
if (endpos < startpos)
{
startpos = endpos;
Fset_marker (OVERLAY_START (overlay), make_number (startpos),
Qnil);
}
if (startpos >= end)
break;
if (startpos >= start
|| (endpos >= start && endpos < end))
{
if (endpos < current_buffer->overlay_center)
{
if (!afterp)
after_list = tail;
else
afterp->next = tail;
afterp = tail;
}
else
{
if (!beforep)
before_list = tail;
else
beforep->next = tail;
beforep = tail;
}
if (!parent)
current_buffer->overlays_after = tail->next;
else
parent->next = tail->next;
tail = tail->next;
}
else
parent = tail, tail = parent->next;
}
if (beforep)
{
beforep->next = current_buffer->overlays_before;
current_buffer->overlays_before = before_list;
}
recenter_overlay_lists (current_buffer, current_buffer->overlay_center);
if (afterp)
{
afterp->next = current_buffer->overlays_after;
current_buffer->overlays_after = after_list;
}
recenter_overlay_lists (current_buffer, current_buffer->overlay_center);
}
void
fix_overlays_before (bp, prev, pos)
struct buffer *bp;
EMACS_INT prev, pos;
{
struct Lisp_Overlay *tail = bp->overlays_before, *parent = NULL, *right_pair;
Lisp_Object tem;
EMACS_INT end;
while (tail
&& (XSETMISC (tem, tail),
(end = OVERLAY_POSITION (OVERLAY_END (tem))) >= pos))
{
parent = tail;
tail = tail->next;
}
if (!tail || end < prev || !tail->next)
return;
right_pair = parent;
parent = tail;
tail = tail->next;
while (tail)
{
XSETMISC (tem, tail);
end = OVERLAY_POSITION (OVERLAY_END (tem));
if (end == pos)
{
struct Lisp_Overlay *found = tail;
tail = found->next;
parent->next = tail;
if (!right_pair)
{
found->next = bp->overlays_before;
bp->overlays_before = found;
}
else
{
found->next = right_pair->next;
right_pair->next = found;
}
}
else if (end == prev)
{
parent = tail;
tail = tail->next;
}
else
break;
}
}
DEFUN ("overlayp", Foverlayp, Soverlayp, 1, 1, 0,
doc: )
(object)
Lisp_Object object;
{
return (OVERLAYP (object) ? Qt : Qnil);
}
DEFUN ("make-overlay", Fmake_overlay, Smake_overlay, 2, 5, 0,
doc: )
(beg, end, buffer, front_advance, rear_advance)
Lisp_Object beg, end, buffer;
Lisp_Object front_advance, rear_advance;
{
Lisp_Object overlay;
struct buffer *b;
if (NILP (buffer))
XSETBUFFER (buffer, current_buffer);
else
CHECK_BUFFER (buffer);
if (MARKERP (beg)
&& ! EQ (Fmarker_buffer (beg), buffer))
error ("Marker points into wrong buffer");
if (MARKERP (end)
&& ! EQ (Fmarker_buffer (end), buffer))
error ("Marker points into wrong buffer");
CHECK_NUMBER_COERCE_MARKER (beg);
CHECK_NUMBER_COERCE_MARKER (end);
if (XINT (beg) > XINT (end))
{
Lisp_Object temp;
temp = beg; beg = end; end = temp;
}
b = XBUFFER (buffer);
beg = Fset_marker (Fmake_marker (), beg, buffer);
end = Fset_marker (Fmake_marker (), end, buffer);
if (!NILP (front_advance))
XMARKER (beg)->insertion_type = 1;
if (!NILP (rear_advance))
XMARKER (end)->insertion_type = 1;
overlay = allocate_misc ();
XMISCTYPE (overlay) = Lisp_Misc_Overlay;
XOVERLAY (overlay)->start = beg;
XOVERLAY (overlay)->end = end;
XOVERLAY (overlay)->plist = Qnil;
XOVERLAY (overlay)->next = NULL;
end = OVERLAY_END (overlay);
if (OVERLAY_POSITION (end) < b->overlay_center)
{
if (b->overlays_after)
XOVERLAY (overlay)->next = b->overlays_after;
b->overlays_after = XOVERLAY (overlay);
}
else
{
if (b->overlays_before)
XOVERLAY (overlay)->next = b->overlays_before;
b->overlays_before = XOVERLAY (overlay);
}
recenter_overlay_lists (b, b->overlay_center);
return overlay;
}
static void
modify_overlay (buf, start, end)
struct buffer *buf;
EMACS_INT start, end;
{
if (start > end)
{
int temp = start;
start = end;
end = temp;
}
BUF_COMPUTE_UNCHANGED (buf, start, end);
if (buf != XBUFFER (XWINDOW (selected_window)->buffer))
windows_or_buffers_changed = 1;
else if (buffer_shared > 1)
windows_or_buffers_changed = 1;
else if (end >= ZV && start <= ZV)
windows_or_buffers_changed = 1;
++BUF_OVERLAY_MODIFF (buf);
}
Lisp_Object Fdelete_overlay ();
static struct Lisp_Overlay *
unchain_overlay (list, overlay)
struct Lisp_Overlay *list, *overlay;
{
struct Lisp_Overlay *tmp, *prev;
for (tmp = list, prev = NULL; tmp; prev = tmp, tmp = tmp->next)
if (tmp == overlay)
{
if (prev)
prev->next = tmp->next;
else
list = tmp->next;
overlay->next = NULL;
break;
}
return list;
}
DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0,
doc: )
(overlay, beg, end, buffer)
Lisp_Object overlay, beg, end, buffer;
{
struct buffer *b, *ob;
Lisp_Object obuffer;
int count = SPECPDL_INDEX ();
CHECK_OVERLAY (overlay);
if (NILP (buffer))
buffer = Fmarker_buffer (OVERLAY_START (overlay));
if (NILP (buffer))
XSETBUFFER (buffer, current_buffer);
CHECK_BUFFER (buffer);
if (MARKERP (beg)
&& ! EQ (Fmarker_buffer (beg), buffer))
error ("Marker points into wrong buffer");
if (MARKERP (end)
&& ! EQ (Fmarker_buffer (end), buffer))
error ("Marker points into wrong 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;
}
specbind (Qinhibit_quit, Qt);
obuffer = Fmarker_buffer (OVERLAY_START (overlay));
b = XBUFFER (buffer);
ob = BUFFERP (obuffer) ? XBUFFER (obuffer) : (struct buffer *) 0;
if (!EQ (buffer, obuffer))
{
if (!NILP (obuffer))
{
int o_beg;
int o_end;
o_beg = OVERLAY_POSITION (OVERLAY_START (overlay));
o_end = OVERLAY_POSITION (OVERLAY_END (overlay));
modify_overlay (ob, o_beg, o_end);
}
modify_overlay (b, XINT (beg), XINT (end));
}
else
{
int o_beg, o_end;
o_beg = OVERLAY_POSITION (OVERLAY_START (overlay));
o_end = OVERLAY_POSITION (OVERLAY_END (overlay));
if (o_beg == XINT (beg))
modify_overlay (b, o_end, XINT (end));
else if (o_end == XINT (end))
modify_overlay (b, o_beg, XINT (beg));
else
{
if (XINT (beg) < o_beg) o_beg = XINT (beg);
if (XINT (end) > o_end) o_end = XINT (end);
modify_overlay (b, o_beg, o_end);
}
}
if (!NILP (obuffer))
{
ob->overlays_before
= unchain_overlay (ob->overlays_before, XOVERLAY (overlay));
ob->overlays_after
= unchain_overlay (ob->overlays_after, XOVERLAY (overlay));
eassert (XOVERLAY (overlay)->next == NULL);
}
Fset_marker (OVERLAY_START (overlay), beg, buffer);
Fset_marker (OVERLAY_END (overlay), end, buffer);
end = OVERLAY_END (overlay);
if (OVERLAY_POSITION (end) < b->overlay_center)
{
XOVERLAY (overlay)->next = b->overlays_after;
b->overlays_after = XOVERLAY (overlay);
}
else
{
XOVERLAY (overlay)->next = b->overlays_before;
b->overlays_before = XOVERLAY (overlay);
}
recenter_overlay_lists (b, b->overlay_center);
return unbind_to (count, overlay);
}
DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0,
doc: )
(overlay)
Lisp_Object overlay;
{
Lisp_Object buffer;
struct buffer *b;
int count = SPECPDL_INDEX ();
CHECK_OVERLAY (overlay);
buffer = Fmarker_buffer (OVERLAY_START (overlay));
if (NILP (buffer))
return Qnil;
b = XBUFFER (buffer);
specbind (Qinhibit_quit, Qt);
b->overlays_before = unchain_overlay (b->overlays_before,XOVERLAY (overlay));
b->overlays_after = unchain_overlay (b->overlays_after, XOVERLAY (overlay));
eassert (XOVERLAY (overlay)->next == NULL);
modify_overlay (b,
marker_position (OVERLAY_START (overlay)),
marker_position (OVERLAY_END (overlay)));
Fset_marker (OVERLAY_START (overlay), Qnil, Qnil);
Fset_marker (OVERLAY_END (overlay), Qnil, Qnil);
if (!windows_or_buffers_changed
&& (!NILP (Foverlay_get (overlay, Qbefore_string))
|| !NILP (Foverlay_get (overlay, Qafter_string))))
b->prevent_redisplay_optimizations_p = 1;
return unbind_to (count, Qnil);
}
DEFUN ("overlay-start", Foverlay_start, Soverlay_start, 1, 1, 0,
doc: )
(overlay)
Lisp_Object overlay;
{
CHECK_OVERLAY (overlay);
return (Fmarker_position (OVERLAY_START (overlay)));
}
DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0,
doc: )
(overlay)
Lisp_Object overlay;
{
CHECK_OVERLAY (overlay);
return (Fmarker_position (OVERLAY_END (overlay)));
}
DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0,
doc: )
(overlay)
Lisp_Object overlay;
{
CHECK_OVERLAY (overlay);
return Fmarker_buffer (OVERLAY_START (overlay));
}
DEFUN ("overlay-properties", Foverlay_properties, Soverlay_properties, 1, 1, 0,
doc: )
(overlay)
Lisp_Object overlay;
{
CHECK_OVERLAY (overlay);
return Fcopy_sequence (XOVERLAY (overlay)->plist);
}
DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0,
doc: )
(pos)
Lisp_Object pos;
{
int noverlays;
Lisp_Object *overlay_vec;
int len;
Lisp_Object result;
CHECK_NUMBER_COERCE_MARKER (pos);
len = 10;
overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
(int *) 0, (int *) 0, 0);
result = Flist (noverlays, overlay_vec);
xfree (overlay_vec);
return result;
}
DEFUN ("overlays-in", Foverlays_in, Soverlays_in, 2, 2, 0,
doc: )
(beg, end)
Lisp_Object beg, end;
{
int noverlays;
Lisp_Object *overlay_vec;
int len;
Lisp_Object result;
CHECK_NUMBER_COERCE_MARKER (beg);
CHECK_NUMBER_COERCE_MARKER (end);
len = 10;
overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
noverlays = overlays_in (XINT (beg), XINT (end), 1, &overlay_vec, &len,
(int *) 0, (int *) 0);
result = Flist (noverlays, overlay_vec);
xfree (overlay_vec);
return result;
}
DEFUN ("next-overlay-change", Fnext_overlay_change, Snext_overlay_change,
1, 1, 0,
doc: )
(pos)
Lisp_Object pos;
{
int noverlays;
int endpos;
Lisp_Object *overlay_vec;
int len;
int i;
CHECK_NUMBER_COERCE_MARKER (pos);
len = 10;
overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
&endpos, (int *) 0, 1);
for (i = 0; i < noverlays; i++)
{
Lisp_Object oend;
int oendpos;
oend = OVERLAY_END (overlay_vec[i]);
oendpos = OVERLAY_POSITION (oend);
if (oendpos < endpos)
endpos = oendpos;
}
xfree (overlay_vec);
return make_number (endpos);
}
DEFUN ("previous-overlay-change", Fprevious_overlay_change,
Sprevious_overlay_change, 1, 1, 0,
doc: )
(pos)
Lisp_Object pos;
{
int noverlays;
int prevpos;
Lisp_Object *overlay_vec;
int len;
CHECK_NUMBER_COERCE_MARKER (pos);
if (XINT (pos) == BEGV)
return pos;
len = 10;
overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
(int *) 0, &prevpos, 1);
xfree (overlay_vec);
return make_number (prevpos);
}
DEFUN ("overlay-lists", Foverlay_lists, Soverlay_lists, 0, 0, 0,
doc: )
()
{
struct Lisp_Overlay *ol;
Lisp_Object before = Qnil, after = Qnil, tmp;
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);
}
return Fcons (Fnreverse (before), Fnreverse (after));
}
DEFUN ("overlay-recenter", Foverlay_recenter, Soverlay_recenter, 1, 1, 0,
doc: )
(pos)
Lisp_Object pos;
{
CHECK_NUMBER_COERCE_MARKER (pos);
recenter_overlay_lists (current_buffer, XINT (pos));
return Qnil;
}
DEFUN ("overlay-get", Foverlay_get, Soverlay_get, 2, 2, 0,
doc: )
(overlay, prop)
Lisp_Object overlay, prop;
{
CHECK_OVERLAY (overlay);
return lookup_char_property (XOVERLAY (overlay)->plist, prop, 0);
}
DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 0,
doc: )
(overlay, prop, value)
Lisp_Object overlay, prop, value;
{
Lisp_Object tail, buffer;
int changed;
CHECK_OVERLAY (overlay);
buffer = Fmarker_buffer (OVERLAY_START (overlay));
for (tail = XOVERLAY (overlay)->plist;
CONSP (tail) && CONSP (XCDR (tail));
tail = XCDR (XCDR (tail)))
if (EQ (XCAR (tail), prop))
{
changed = !EQ (XCAR (XCDR (tail)), value);
XSETCAR (XCDR (tail), value);
goto found;
}
changed = !NILP (value);
XOVERLAY (overlay)->plist
= Fcons (prop, Fcons (value, XOVERLAY (overlay)->plist));
found:
if (! NILP (buffer))
{
if (changed)
modify_overlay (XBUFFER (buffer),
marker_position (OVERLAY_START (overlay)),
marker_position (OVERLAY_END (overlay)));
if (EQ (prop, Qevaporate) && ! NILP (value)
&& (OVERLAY_POSITION (OVERLAY_START (overlay))
== OVERLAY_POSITION (OVERLAY_END (overlay))))
Fdelete_overlay (overlay);
}
return value;
}
static Lisp_Object last_overlay_modification_hooks;
static int last_overlay_modification_hooks_used;
static void
add_overlay_mod_hooklist (functionlist, overlay)
Lisp_Object functionlist, overlay;
{
int oldsize = XVECTOR (last_overlay_modification_hooks)->size;
if (last_overlay_modification_hooks_used == oldsize)
{
Lisp_Object old;
old = last_overlay_modification_hooks;
last_overlay_modification_hooks
= Fmake_vector (make_number (oldsize * 2), Qnil);
bcopy (XVECTOR (old)->contents,
XVECTOR (last_overlay_modification_hooks)->contents,
sizeof (Lisp_Object) * oldsize);
}
AREF (last_overlay_modification_hooks, last_overlay_modification_hooks_used++) = functionlist;
AREF (last_overlay_modification_hooks, last_overlay_modification_hooks_used++) = overlay;
}
void
report_overlay_modification (start, end, after, arg1, arg2, arg3)
Lisp_Object start, end;
int after;
Lisp_Object arg1, arg2, arg3;
{
Lisp_Object prop, overlay;
struct Lisp_Overlay *tail;
int insertion = (after ? XFASTINT (arg3) == 0 : EQ (start, end));
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
overlay = Qnil;
tail = NULL;
if (!after)
{
last_overlay_modification_hooks_used = 0;
for (tail = current_buffer->overlays_before; tail; tail = tail->next)
{
int startpos, endpos;
Lisp_Object ostart, oend;
XSETMISC (overlay, tail);
ostart = OVERLAY_START (overlay);
oend = OVERLAY_END (overlay);
endpos = OVERLAY_POSITION (oend);
if (XFASTINT (start) > endpos)
break;
startpos = OVERLAY_POSITION (ostart);
if (insertion && (XFASTINT (start) == startpos
|| XFASTINT (end) == startpos))
{
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))
{
prop = Foverlay_get (overlay, Qinsert_behind_hooks);
if (!NILP (prop))
add_overlay_mod_hooklist (prop, overlay);
}
if (XFASTINT (end) > startpos && XFASTINT (start) < endpos)
{
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)
{
int startpos, endpos;
Lisp_Object ostart, oend;
XSETMISC (overlay, tail);
ostart = OVERLAY_START (overlay);
oend = OVERLAY_END (overlay);
startpos = OVERLAY_POSITION (ostart);
endpos = OVERLAY_POSITION (oend);
if (XFASTINT (end) < startpos)
break;
if (insertion && (XFASTINT (start) == startpos
|| XFASTINT (end) == startpos))
{
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))
{
prop = Foverlay_get (overlay, Qinsert_behind_hooks);
if (!NILP (prop))
add_overlay_mod_hooklist (prop, overlay);
}
if (XFASTINT (end) > startpos && XFASTINT (start) < endpos)
{
prop = Foverlay_get (overlay, Qmodification_hooks);
if (!NILP (prop))
add_overlay_mod_hooklist (prop, overlay);
}
}
}
GCPRO4 (overlay, arg1, arg2, arg3);
{
int size = last_overlay_modification_hooks_used;
Lisp_Object *copy = (Lisp_Object *) alloca (size * sizeof (Lisp_Object));
int i;
bcopy (XVECTOR (last_overlay_modification_hooks)->contents,
copy, size * sizeof (Lisp_Object));
gcpro1.var = copy;
gcpro1.nvars = size;
for (i = 0; i < size;)
{
Lisp_Object prop, overlay;
prop = copy[i++];
overlay = copy[i++];
call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
}
}
UNGCPRO;
}
static void
call_overlay_mod_hooks (list, overlay, after, arg1, arg2, arg3)
Lisp_Object list, overlay;
int after;
Lisp_Object arg1, arg2, arg3;
{
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
GCPRO4 (list, arg1, arg2, arg3);
while (CONSP (list))
{
if (NILP (arg3))
call4 (XCAR (list), overlay, after ? Qt : Qnil, arg1, arg2);
else
call5 (XCAR (list), overlay, after ? Qt : Qnil, arg1, arg2, arg3);
list = XCDR (list);
}
UNGCPRO;
}
void
evaporate_overlays (pos)
EMACS_INT pos;
{
Lisp_Object overlay, hit_list;
struct Lisp_Overlay *tail;
hit_list = Qnil;
if (pos <= current_buffer->overlay_center)
for (tail = current_buffer->overlays_before; tail; tail = tail->next)
{
int endpos;
XSETMISC (overlay, tail);
endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
if (endpos < pos)
break;
if (endpos == pos && OVERLAY_POSITION (OVERLAY_START (overlay)) == pos
&& ! NILP (Foverlay_get (overlay, Qevaporate)))
hit_list = Fcons (overlay, hit_list);
}
else
for (tail = current_buffer->overlays_after; tail; tail = tail->next)
{
int startpos;
XSETMISC (overlay, tail);
startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
if (startpos > pos)
break;
if (startpos == pos && OVERLAY_POSITION (OVERLAY_END (overlay)) == pos
&& ! NILP (Foverlay_get (overlay, Qevaporate)))
hit_list = Fcons (overlay, hit_list);
}
for (; CONSP (hit_list); hit_list = XCDR (hit_list))
Fdelete_overlay (XCAR (hit_list));
}
void
buffer_slot_type_mismatch (offset)
int offset;
{
Lisp_Object sym;
char *type_name;
switch (XINT (PER_BUFFER_TYPE (offset)))
{
case Lisp_Int:
type_name = "integers";
break;
case Lisp_String:
type_name = "strings";
break;
case Lisp_Symbol:
type_name = "symbols";
break;
default:
abort ();
}
sym = PER_BUFFER_SYMBOL (offset);
error ("Only %s should be stored in the buffer-local variable %s",
type_name, SDATA (SYMBOL_NAME (sym)));
}
#ifdef USE_MMAP_FOR_BUFFERS
#include <sys/types.h>
#include <sys/mman.h>
#ifndef MAP_ANON
#ifdef MAP_ANONYMOUS
#define MAP_ANON MAP_ANONYMOUS
#else
#define MAP_ANON 0
#endif
#endif
#ifndef MAP_FAILED
#define MAP_FAILED ((void *) -1)
#endif
#include <stdio.h>
#include <errno.h>
#if MAP_ANON == 0
#include <fcntl.h>
#endif
#include "coding.h"
struct mmap_region
{
size_t nbytes_specified;
size_t nbytes_mapped;
POINTER_TYPE **var;
struct mmap_region *next, *prev;
};
static struct mmap_region *mmap_regions;
static int mmap_fd;
static struct mmap_region *mmap_regions_1;
static int mmap_fd_1;
static int mmap_page_size;
static int mmap_initialized_p;
#define ROUND(X, N) (((X) + (N) - 1) / (N) * (N))
#define MMAP_REGION_STRUCT_SIZE \
ROUND (sizeof (struct mmap_region), MEM_ALIGN)
#define MMAP_REGION(P) \
((struct mmap_region *) ((char *) (P) - MMAP_REGION_STRUCT_SIZE))
#define MMAP_USER_AREA(P) \
((POINTER_TYPE *) ((char *) (P) + MMAP_REGION_STRUCT_SIZE))
#define MEM_ALIGN sizeof (double)
#ifndef MMAP_ALLOCATED_P
#define MMAP_ALLOCATED_P(start, end) 1
#endif
static int mmap_free_1 P_ ((struct mmap_region *));
static int mmap_enlarge P_ ((struct mmap_region *, int));
static struct mmap_region *mmap_find P_ ((POINTER_TYPE *, POINTER_TYPE *));
static POINTER_TYPE *mmap_alloc P_ ((POINTER_TYPE **, size_t));
static POINTER_TYPE *mmap_realloc P_ ((POINTER_TYPE **, size_t));
static void mmap_free P_ ((POINTER_TYPE **ptr));
static void mmap_init P_ ((void));
static struct mmap_region *
mmap_find (start, end)
POINTER_TYPE *start, *end;
{
struct mmap_region *r;
char *s = (char *) start, *e = (char *) end;
for (r = mmap_regions; r; r = r->next)
{
char *rstart = (char *) r;
char *rend = rstart + r->nbytes_mapped;
if (
(s >= rstart && s < rend)
|| (e > rstart && e <= rend)
|| (rstart >= s && rstart < e)
|| (rend > s && rend <= e))
break;
}
return r;
}
static int
mmap_free_1 (r)
struct mmap_region *r;
{
if (r->next)
r->next->prev = r->prev;
if (r->prev)
r->prev->next = r->next;
else
mmap_regions = r->next;
if (munmap ((POINTER_TYPE *) r, r->nbytes_mapped) == -1)
{
fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
return 0;
}
return 1;
}
static int
mmap_enlarge (r, npages)
struct mmap_region *r;
int npages;
{
char *region_end = (char *) r + r->nbytes_mapped;
size_t nbytes;
int success = 0;
if (npages < 0)
{
nbytes = - npages * mmap_page_size;
if (munmap (region_end - nbytes, nbytes) == -1)
fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
else
{
r->nbytes_mapped -= nbytes;
success = 1;
}
}
else if (npages > 0)
{
nbytes = npages * mmap_page_size;
if (!MMAP_ALLOCATED_P (region_end, region_end + nbytes))
{
POINTER_TYPE *p;
p = mmap (region_end, nbytes, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_PRIVATE | MAP_FIXED, mmap_fd, 0);
if (p == MAP_FAILED)
;
else if (p != (POINTER_TYPE *) region_end)
{
if (munmap (p, nbytes) == -1)
fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
}
else
{
r->nbytes_mapped += nbytes;
success = 1;
}
}
}
return success;
}
void
mmap_set_vars (restore_p)
int restore_p;
{
struct mmap_region *r;
if (restore_p)
{
mmap_regions = mmap_regions_1;
mmap_fd = mmap_fd_1;
for (r = mmap_regions; r; r = r->next)
*r->var = MMAP_USER_AREA (r);
}
else
{
for (r = mmap_regions; r; r = r->next)
*r->var = NULL;
mmap_regions_1 = mmap_regions;
mmap_regions = NULL;
mmap_fd_1 = mmap_fd;
mmap_fd = -1;
}
}
static POINTER_TYPE *
mmap_alloc (var, nbytes)
POINTER_TYPE **var;
size_t nbytes;
{
void *p;
size_t map;
mmap_init ();
map = ROUND (nbytes + MMAP_REGION_STRUCT_SIZE, mmap_page_size);
p = mmap (NULL, map, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,
mmap_fd, 0);
if (p == MAP_FAILED)
{
if (errno != ENOMEM)
fprintf (stderr, "mmap: %s\n", emacs_strerror (errno));
p = NULL;
}
else
{
struct mmap_region *r = (struct mmap_region *) p;
r->nbytes_specified = nbytes;
r->nbytes_mapped = map;
r->var = var;
r->prev = NULL;
r->next = mmap_regions;
if (r->next)
r->next->prev = r;
mmap_regions = r;
p = MMAP_USER_AREA (p);
}
return *var = p;
}
static POINTER_TYPE *
mmap_realloc (var, nbytes)
POINTER_TYPE **var;
size_t nbytes;
{
POINTER_TYPE *result;
mmap_init ();
if (*var == NULL)
result = mmap_alloc (var, nbytes);
else if (nbytes == 0)
{
mmap_free (var);
result = mmap_alloc (var, nbytes);
}
else
{
struct mmap_region *r = MMAP_REGION (*var);
size_t room = r->nbytes_mapped - MMAP_REGION_STRUCT_SIZE;
if (room < nbytes)
{
POINTER_TYPE *old_ptr = *var;
if (mmap_enlarge (r, (ROUND (nbytes - room, mmap_page_size)
/ mmap_page_size)))
{
r->nbytes_specified = nbytes;
*var = result = old_ptr;
}
else if (mmap_alloc (var, nbytes))
{
bcopy (old_ptr, *var, r->nbytes_specified);
mmap_free_1 (MMAP_REGION (old_ptr));
result = *var;
r = MMAP_REGION (result);
r->nbytes_specified = nbytes;
}
else
{
*var = old_ptr;
result = NULL;
}
}
else if (room - nbytes >= mmap_page_size)
{
mmap_enlarge (r, - ((room - nbytes) / mmap_page_size));
result = *var;
r->nbytes_specified = nbytes;
}
else
{
result = *var;
r->nbytes_specified = nbytes;
}
}
return result;
}
static void
mmap_free (var)
POINTER_TYPE **var;
{
mmap_init ();
if (*var)
{
mmap_free_1 (MMAP_REGION (*var));
*var = NULL;
}
}
static void
mmap_init ()
{
#if MAP_ANON == 0
if (mmap_fd <= 0)
{
mmap_fd = open ("/dev/zero", O_RDONLY);
if (mmap_fd == -1)
fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno));
}
#endif
if (mmap_initialized_p)
return;
mmap_initialized_p = 1;
#if MAP_ANON != 0
mmap_fd = -1;
#endif
mmap_page_size = getpagesize ();
}
#endif
#ifdef REL_ALLOC
extern POINTER_TYPE *r_alloc P_ ((POINTER_TYPE **, size_t));
extern POINTER_TYPE *r_re_alloc P_ ((POINTER_TYPE **, size_t));
extern void r_alloc_free P_ ((POINTER_TYPE **ptr));
#endif
static void
alloc_buffer_text (b, nbytes)
struct buffer *b;
size_t nbytes;
{
POINTER_TYPE *p;
BLOCK_INPUT;
#if defined USE_MMAP_FOR_BUFFERS
p = mmap_alloc ((POINTER_TYPE **) &b->text->beg, nbytes);
#elif defined REL_ALLOC
p = r_alloc ((POINTER_TYPE **) &b->text->beg, nbytes);
#else
p = xmalloc (nbytes);
#endif
if (p == NULL)
{
UNBLOCK_INPUT;
memory_full ();
}
b->text->beg = (unsigned char *) p;
UNBLOCK_INPUT;
}
void
enlarge_buffer_text (b, delta)
struct buffer *b;
int delta;
{
POINTER_TYPE *p;
size_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);
#elif defined REL_ALLOC
p = r_re_alloc ((POINTER_TYPE **) &b->text->beg, nbytes);
#else
p = xrealloc (b->text->beg, nbytes);
#endif
if (p == NULL)
{
UNBLOCK_INPUT;
memory_full ();
}
BUF_BEG_ADDR (b) = (unsigned char *) p;
UNBLOCK_INPUT;
}
static void
free_buffer_text (b)
struct buffer *b;
{
BLOCK_INPUT;
#if defined USE_MMAP_FOR_BUFFERS
mmap_free ((POINTER_TYPE **) &b->text->beg);
#elif defined REL_ALLOC
r_alloc_free ((POINTER_TYPE **) &b->text->beg);
#else
xfree (b->text->beg);
#endif
BUF_BEG_ADDR (b) = NULL;
UNBLOCK_INPUT;
}
void
init_buffer_once ()
{
int idx;
bzero (buffer_permanent_local_flags, sizeof buffer_permanent_local_flags);
reset_buffer (&buffer_defaults);
reset_buffer_local_variables (&buffer_defaults, 1);
reset_buffer (&buffer_local_symbols);
reset_buffer_local_variables (&buffer_local_symbols, 1);
buffer_defaults.text = &buffer_defaults.own_text;
buffer_local_symbols.text = &buffer_local_symbols.own_text;
BUF_INTERVALS (&buffer_defaults) = 0;
BUF_INTERVALS (&buffer_local_symbols) = 0;
XSETBUFFER (Vbuffer_defaults, &buffer_defaults);
XSETBUFFER (Vbuffer_local_symbols, &buffer_local_symbols);
buffer_defaults.mode_line_format = build_string ("%-");
buffer_defaults.header_line_format = Qnil;
buffer_defaults.abbrev_mode = Qnil;
buffer_defaults.overwrite_mode = Qnil;
buffer_defaults.case_fold_search = Qt;
buffer_defaults.auto_fill_function = Qnil;
buffer_defaults.selective_display = Qnil;
#ifndef old
buffer_defaults.selective_display_ellipses = Qt;
#endif
buffer_defaults.abbrev_table = Qnil;
buffer_defaults.display_table = Qnil;
buffer_defaults.undo_list = Qnil;
buffer_defaults.mark_active = Qnil;
buffer_defaults.file_format = Qnil;
buffer_defaults.auto_save_file_format = Qt;
buffer_defaults.overlays_before = NULL;
buffer_defaults.overlays_after = NULL;
buffer_defaults.overlay_center = BEG;
XSETFASTINT (buffer_defaults.tab_width, 8);
buffer_defaults.truncate_lines = Qnil;
buffer_defaults.ctl_arrow = Qt;
buffer_defaults.direction_reversed = Qnil;
buffer_defaults.cursor_type = Qt;
buffer_defaults.extra_line_spacing = Qnil;
buffer_defaults.cursor_in_non_selected_windows = Qt;
#ifdef DOS_NT
buffer_defaults.buffer_file_type = Qnil;
#endif
buffer_defaults.enable_multibyte_characters = Qt;
buffer_defaults.buffer_file_coding_system = Qnil;
XSETFASTINT (buffer_defaults.fill_column, 70);
XSETFASTINT (buffer_defaults.left_margin, 0);
buffer_defaults.cache_long_line_scans = Qnil;
buffer_defaults.file_truename = Qnil;
XSETFASTINT (buffer_defaults.display_count, 0);
XSETFASTINT (buffer_defaults.left_margin_cols, 0);
XSETFASTINT (buffer_defaults.right_margin_cols, 0);
buffer_defaults.left_fringe_width = Qnil;
buffer_defaults.right_fringe_width = Qnil;
buffer_defaults.fringes_outside_margins = Qnil;
buffer_defaults.scroll_bar_width = Qnil;
buffer_defaults.vertical_scroll_bar_type = Qt;
buffer_defaults.indicate_empty_lines = Qnil;
buffer_defaults.indicate_buffer_boundaries = Qnil;
buffer_defaults.fringe_indicator_alist = Qnil;
buffer_defaults.fringe_cursor_alist = Qnil;
buffer_defaults.scroll_up_aggressively = Qnil;
buffer_defaults.scroll_down_aggressively = Qnil;
buffer_defaults.display_time = Qnil;
if (sizeof (EMACS_INT) != sizeof (Lisp_Object)) abort ();
bzero (&buffer_local_flags, sizeof buffer_local_flags);
XSETINT (buffer_local_flags.filename, -1);
XSETINT (buffer_local_flags.directory, -1);
XSETINT (buffer_local_flags.backed_up, -1);
XSETINT (buffer_local_flags.save_length, -1);
XSETINT (buffer_local_flags.auto_save_file_name, -1);
XSETINT (buffer_local_flags.read_only, -1);
XSETINT (buffer_local_flags.major_mode, -1);
XSETINT (buffer_local_flags.mode_name, -1);
XSETINT (buffer_local_flags.undo_list, -1);
XSETINT (buffer_local_flags.mark_active, -1);
XSETINT (buffer_local_flags.point_before_scroll, -1);
XSETINT (buffer_local_flags.file_truename, -1);
XSETINT (buffer_local_flags.invisibility_spec, -1);
XSETINT (buffer_local_flags.file_format, -1);
XSETINT (buffer_local_flags.auto_save_file_format, -1);
XSETINT (buffer_local_flags.display_count, -1);
XSETINT (buffer_local_flags.display_time, -1);
XSETINT (buffer_local_flags.enable_multibyte_characters, -1);
idx = 1;
XSETFASTINT (buffer_local_flags.mode_line_format, idx); ++idx;
XSETFASTINT (buffer_local_flags.abbrev_mode, idx); ++idx;
XSETFASTINT (buffer_local_flags.overwrite_mode, idx); ++idx;
XSETFASTINT (buffer_local_flags.case_fold_search, idx); ++idx;
XSETFASTINT (buffer_local_flags.auto_fill_function, idx); ++idx;
XSETFASTINT (buffer_local_flags.selective_display, idx); ++idx;
#ifndef old
XSETFASTINT (buffer_local_flags.selective_display_ellipses, idx); ++idx;
#endif
XSETFASTINT (buffer_local_flags.tab_width, idx); ++idx;
XSETFASTINT (buffer_local_flags.truncate_lines, idx); ++idx;
XSETFASTINT (buffer_local_flags.ctl_arrow, idx); ++idx;
XSETFASTINT (buffer_local_flags.fill_column, idx); ++idx;
XSETFASTINT (buffer_local_flags.left_margin, idx); ++idx;
XSETFASTINT (buffer_local_flags.abbrev_table, idx); ++idx;
XSETFASTINT (buffer_local_flags.display_table, idx); ++idx;
#ifdef DOS_NT
XSETFASTINT (buffer_local_flags.buffer_file_type, idx);
buffer_permanent_local_flags[idx++] = 1;
#endif
XSETFASTINT (buffer_local_flags.syntax_table, idx); ++idx;
XSETFASTINT (buffer_local_flags.cache_long_line_scans, idx); ++idx;
XSETFASTINT (buffer_local_flags.category_table, idx); ++idx;
XSETFASTINT (buffer_local_flags.direction_reversed, idx); ++idx;
XSETFASTINT (buffer_local_flags.buffer_file_coding_system, idx);
buffer_permanent_local_flags[idx++] = 1;
XSETFASTINT (buffer_local_flags.left_margin_cols, idx); ++idx;
XSETFASTINT (buffer_local_flags.right_margin_cols, idx); ++idx;
XSETFASTINT (buffer_local_flags.left_fringe_width, idx); ++idx;
XSETFASTINT (buffer_local_flags.right_fringe_width, idx); ++idx;
XSETFASTINT (buffer_local_flags.fringes_outside_margins, idx); ++idx;
XSETFASTINT (buffer_local_flags.scroll_bar_width, idx); ++idx;
XSETFASTINT (buffer_local_flags.vertical_scroll_bar_type, idx); ++idx;
XSETFASTINT (buffer_local_flags.indicate_empty_lines, idx); ++idx;
XSETFASTINT (buffer_local_flags.indicate_buffer_boundaries, idx); ++idx;
XSETFASTINT (buffer_local_flags.fringe_indicator_alist, idx); ++idx;
XSETFASTINT (buffer_local_flags.fringe_cursor_alist, idx); ++idx;
XSETFASTINT (buffer_local_flags.scroll_up_aggressively, idx); ++idx;
XSETFASTINT (buffer_local_flags.scroll_down_aggressively, idx); ++idx;
XSETFASTINT (buffer_local_flags.header_line_format, idx); ++idx;
XSETFASTINT (buffer_local_flags.cursor_type, idx); ++idx;
XSETFASTINT (buffer_local_flags.extra_line_spacing, idx); ++idx;
XSETFASTINT (buffer_local_flags.cursor_in_non_selected_windows, idx); ++idx;
if (idx >= MAX_PER_BUFFER_VARS)
abort ();
last_per_buffer_idx = idx;
Vbuffer_alist = Qnil;
current_buffer = 0;
all_buffers = 0;
QSFundamental = build_string ("Fundamental");
Qfundamental_mode = intern ("fundamental-mode");
buffer_defaults.major_mode = Qfundamental_mode;
Qmode_class = intern ("mode-class");
Qprotected_field = intern ("protected-field");
Qpermanent_local = intern ("permanent-local");
Qkill_buffer_hook = intern ("kill-buffer-hook");
Fput (Qkill_buffer_hook, Qpermanent_local, Qt);
Qucs_set_table_for_input = intern ("ucs-set-table-for-input");
Vprin1_to_string_buffer = Fget_buffer_create (build_string (" prin1"));
Vbuffer_alist = Qnil;
Fset_buffer (Fget_buffer_create (build_string ("*scratch*")));
inhibit_modification_hooks = 0;
}
void
init_buffer ()
{
char *pwd;
Lisp_Object temp;
int len;
#ifdef USE_MMAP_FOR_BUFFERS
{
struct buffer *b;
for (b = all_buffers; b; b = b->next)
if (b->text->beg == NULL)
enlarge_buffer_text (b, 0);
}
#endif
Fset_buffer (Fget_buffer_create (build_string ("*scratch*")));
if (NILP (buffer_defaults.enable_multibyte_characters))
Fset_buffer_multibyte (Qnil);
pwd = get_current_dir_name ();
if (!pwd)
fatal ("`get_current_dir_name' failed: %s\n", strerror (errno));
#ifndef VMS
len = strlen (pwd);
if (!(IS_DIRECTORY_SEP (pwd[len - 1])))
{
pwd = (char *) xrealloc (pwd, len + 2);
pwd[len] = DIRECTORY_SEP;
pwd[len + 1] = '\0';
}
#endif
current_buffer->directory = make_unibyte_string (pwd, strlen (pwd));
if (! NILP (buffer_defaults.enable_multibyte_characters))
current_buffer->directory
= string_to_multibyte (current_buffer->directory);
temp = Ffind_file_name_handler (current_buffer->directory, Qt);
if (! NILP (temp)
&& strcmp ("/", SDATA (current_buffer->directory)))
current_buffer->directory
= concat2 (build_string ("/:"), current_buffer->directory);
temp = get_minibuffer (0);
XBUFFER (temp)->directory = current_buffer->directory;
free (pwd);
}
void
syms_of_buffer ()
{
staticpro (&last_overlay_modification_hooks);
last_overlay_modification_hooks
= Fmake_vector (make_number (10), Qnil);
staticpro (&Vbuffer_defaults);
staticpro (&Vbuffer_local_symbols);
staticpro (&Qfundamental_mode);
staticpro (&Qmode_class);
staticpro (&QSFundamental);
staticpro (&Vbuffer_alist);
staticpro (&Qprotected_field);
staticpro (&Qpermanent_local);
staticpro (&Qkill_buffer_hook);
Qoverlayp = intern ("overlayp");
staticpro (&Qoverlayp);
Qevaporate = intern ("evaporate");
staticpro (&Qevaporate);
Qmodification_hooks = intern ("modification-hooks");
staticpro (&Qmodification_hooks);
Qinsert_in_front_hooks = intern ("insert-in-front-hooks");
staticpro (&Qinsert_in_front_hooks);
Qinsert_behind_hooks = intern ("insert-behind-hooks");
staticpro (&Qinsert_behind_hooks);
Qget_file_buffer = intern ("get-file-buffer");
staticpro (&Qget_file_buffer);
Qpriority = intern ("priority");
staticpro (&Qpriority);
Qwindow = intern ("window");
staticpro (&Qwindow);
Qbefore_string = intern ("before-string");
staticpro (&Qbefore_string);
Qafter_string = intern ("after-string");
staticpro (&Qafter_string);
Qfirst_change_hook = intern ("first-change-hook");
staticpro (&Qfirst_change_hook);
Qbefore_change_functions = intern ("before-change-functions");
staticpro (&Qbefore_change_functions);
Qafter_change_functions = intern ("after-change-functions");
staticpro (&Qafter_change_functions);
staticpro (&Qucs_set_table_for_input);
Qkill_buffer_query_functions = intern ("kill-buffer-query-functions");
staticpro (&Qkill_buffer_query_functions);
Fput (Qprotected_field, Qerror_conditions,
Fcons (Qprotected_field, Fcons (Qerror, Qnil)));
Fput (Qprotected_field, Qerror_message,
build_string ("Attempt to modify a protected field"));
DEFVAR_LISP_NOPRO ("default-mode-line-format",
&buffer_defaults.mode_line_format,
doc: );
DEFVAR_LISP_NOPRO ("default-header-line-format",
&buffer_defaults.header_line_format,
doc: );
DEFVAR_LISP_NOPRO ("default-cursor-type", &buffer_defaults.cursor_type,
doc: );
DEFVAR_LISP_NOPRO ("default-line-spacing",
&buffer_defaults.extra_line_spacing,
doc: );
DEFVAR_LISP_NOPRO ("default-cursor-in-non-selected-windows",
&buffer_defaults.cursor_in_non_selected_windows,
doc: );
DEFVAR_LISP_NOPRO ("default-abbrev-mode",
&buffer_defaults.abbrev_mode,
doc: );
DEFVAR_LISP_NOPRO ("default-ctl-arrow",
&buffer_defaults.ctl_arrow,
doc: );
DEFVAR_LISP_NOPRO ("default-direction-reversed",
&buffer_defaults.direction_reversed,
doc: );
DEFVAR_LISP_NOPRO ("default-enable-multibyte-characters",
&buffer_defaults.enable_multibyte_characters,
doc: );
DEFVAR_LISP_NOPRO ("default-buffer-file-coding-system",
&buffer_defaults.buffer_file_coding_system,
doc: );
DEFVAR_LISP_NOPRO ("default-truncate-lines",
&buffer_defaults.truncate_lines,
doc: );
DEFVAR_LISP_NOPRO ("default-fill-column",
&buffer_defaults.fill_column,
doc: );
DEFVAR_LISP_NOPRO ("default-left-margin",
&buffer_defaults.left_margin,
doc: );
DEFVAR_LISP_NOPRO ("default-tab-width",
&buffer_defaults.tab_width,
doc: );
DEFVAR_LISP_NOPRO ("default-case-fold-search",
&buffer_defaults.case_fold_search,
doc: );
#ifdef DOS_NT
DEFVAR_LISP_NOPRO ("default-buffer-file-type",
&buffer_defaults.buffer_file_type,
doc: );
#endif
DEFVAR_LISP_NOPRO ("default-left-margin-width",
&buffer_defaults.left_margin_cols,
doc: );
DEFVAR_LISP_NOPRO ("default-right-margin-width",
&buffer_defaults.right_margin_cols,
doc: );
DEFVAR_LISP_NOPRO ("default-left-fringe-width",
&buffer_defaults.left_fringe_width,
doc: );
DEFVAR_LISP_NOPRO ("default-right-fringe-width",
&buffer_defaults.right_fringe_width,
doc: );
DEFVAR_LISP_NOPRO ("default-fringes-outside-margins",
&buffer_defaults.fringes_outside_margins,
doc: );
DEFVAR_LISP_NOPRO ("default-scroll-bar-width",
&buffer_defaults.scroll_bar_width,
doc: );
DEFVAR_LISP_NOPRO ("default-vertical-scroll-bar",
&buffer_defaults.vertical_scroll_bar_type,
doc: );
DEFVAR_LISP_NOPRO ("default-indicate-empty-lines",
&buffer_defaults.indicate_empty_lines,
doc: );
DEFVAR_LISP_NOPRO ("default-indicate-buffer-boundaries",
&buffer_defaults.indicate_buffer_boundaries,
doc: );
DEFVAR_LISP_NOPRO ("default-fringe-indicator-alist",
&buffer_defaults.fringe_indicator_alist,
doc: );
DEFVAR_LISP_NOPRO ("default-fringe-cursor-alist",
&buffer_defaults.fringe_cursor_alist,
doc: );
DEFVAR_LISP_NOPRO ("default-scroll-up-aggressively",
&buffer_defaults.scroll_up_aggressively,
doc: );
DEFVAR_LISP_NOPRO ("default-scroll-down-aggressively",
&buffer_defaults.scroll_down_aggressively,
doc: );
DEFVAR_PER_BUFFER ("header-line-format",
¤t_buffer->header_line_format,
Qnil,
doc: );
DEFVAR_PER_BUFFER ("mode-line-format", ¤t_buffer->mode_line_format,
Qnil,
doc: );
DEFVAR_LISP_NOPRO ("default-major-mode", &buffer_defaults.major_mode,
doc: );
DEFVAR_PER_BUFFER ("major-mode", ¤t_buffer->major_mode,
make_number (Lisp_Symbol),
doc: );
DEFVAR_PER_BUFFER ("mode-name", ¤t_buffer->mode_name,
Qnil,
doc: );
DEFVAR_PER_BUFFER ("abbrev-mode", ¤t_buffer->abbrev_mode, Qnil,
doc: );
DEFVAR_PER_BUFFER ("case-fold-search", ¤t_buffer->case_fold_search,
Qnil,
doc: );
DEFVAR_PER_BUFFER ("fill-column", ¤t_buffer->fill_column,
make_number (Lisp_Int),
doc: );
DEFVAR_PER_BUFFER ("left-margin", ¤t_buffer->left_margin,
make_number (Lisp_Int),
doc: );
DEFVAR_PER_BUFFER ("tab-width", ¤t_buffer->tab_width,
make_number (Lisp_Int),
doc: );
DEFVAR_PER_BUFFER ("ctl-arrow", ¤t_buffer->ctl_arrow, Qnil,
doc: );
DEFVAR_PER_BUFFER ("enable-multibyte-characters",
¤t_buffer->enable_multibyte_characters,
Qnil,
doc: );
XSYMBOL (intern ("enable-multibyte-characters"))->constant = 1;
DEFVAR_PER_BUFFER ("buffer-file-coding-system",
¤t_buffer->buffer_file_coding_system, Qnil,
doc: );
DEFVAR_PER_BUFFER ("direction-reversed", ¤t_buffer->direction_reversed,
Qnil,
doc: );
DEFVAR_PER_BUFFER ("truncate-lines", ¤t_buffer->truncate_lines, Qnil,
doc: );
#ifdef DOS_NT
DEFVAR_PER_BUFFER ("buffer-file-type", ¤t_buffer->buffer_file_type,
Qnil,
doc: );
#endif
DEFVAR_PER_BUFFER ("default-directory", ¤t_buffer->directory,
make_number (Lisp_String),
doc: );
DEFVAR_PER_BUFFER ("auto-fill-function", ¤t_buffer->auto_fill_function,
Qnil,
doc: );
DEFVAR_PER_BUFFER ("buffer-file-name", ¤t_buffer->filename,
make_number (Lisp_String),
doc: );
DEFVAR_PER_BUFFER ("buffer-file-truename", ¤t_buffer->file_truename,
make_number (Lisp_String),
doc: );
DEFVAR_PER_BUFFER ("buffer-auto-save-file-name",
¤t_buffer->auto_save_file_name,
make_number (Lisp_String),
doc: );
DEFVAR_PER_BUFFER ("buffer-read-only", ¤t_buffer->read_only, Qnil,
doc: );
DEFVAR_PER_BUFFER ("buffer-backed-up", ¤t_buffer->backed_up, Qnil,
doc: );
DEFVAR_PER_BUFFER ("buffer-saved-size", ¤t_buffer->save_length,
make_number (Lisp_Int),
doc: );
DEFVAR_PER_BUFFER ("selective-display", ¤t_buffer->selective_display,
Qnil,
doc: );
#ifndef old
DEFVAR_PER_BUFFER ("selective-display-ellipses",
¤t_buffer->selective_display_ellipses,
Qnil,
doc: );
#endif
DEFVAR_PER_BUFFER ("overwrite-mode", ¤t_buffer->overwrite_mode, Qnil,
doc: );
DEFVAR_PER_BUFFER ("buffer-display-table", ¤t_buffer->display_table,
Qnil,
doc: );
DEFVAR_PER_BUFFER ("left-margin-width", ¤t_buffer->left_margin_cols,
Qnil,
doc: );
DEFVAR_PER_BUFFER ("right-margin-width", ¤t_buffer->right_margin_cols,
Qnil,
doc: );
DEFVAR_PER_BUFFER ("left-fringe-width", ¤t_buffer->left_fringe_width,
Qnil,
doc: );
DEFVAR_PER_BUFFER ("right-fringe-width", ¤t_buffer->right_fringe_width,
Qnil,
doc: );
DEFVAR_PER_BUFFER ("fringes-outside-margins", ¤t_buffer->fringes_outside_margins,
Qnil,
doc: );
DEFVAR_PER_BUFFER ("scroll-bar-width", ¤t_buffer->scroll_bar_width,
Qnil,
doc: );
DEFVAR_PER_BUFFER ("vertical-scroll-bar", ¤t_buffer->vertical_scroll_bar_type,
Qnil,
doc: );
DEFVAR_PER_BUFFER ("indicate-empty-lines",
¤t_buffer->indicate_empty_lines, Qnil,
doc: );
DEFVAR_PER_BUFFER ("indicate-buffer-boundaries",
¤t_buffer->indicate_buffer_boundaries, Qnil,
doc: );
DEFVAR_PER_BUFFER ("fringe-indicator-alist",
¤t_buffer->fringe_indicator_alist, Qnil,
doc: );
DEFVAR_PER_BUFFER ("fringe-cursor-alist",
¤t_buffer->fringe_cursor_alist, Qnil,
doc: );
DEFVAR_PER_BUFFER ("scroll-up-aggressively",
¤t_buffer->scroll_up_aggressively, Qnil,
doc: );
DEFVAR_PER_BUFFER ("scroll-down-aggressively",
¤t_buffer->scroll_down_aggressively, Qnil,
doc: );
DEFVAR_LISP ("before-change-functions", &Vbefore_change_functions,
doc: );
Vbefore_change_functions = Qnil;
DEFVAR_LISP ("after-change-functions", &Vafter_change_functions,
doc: );
Vafter_change_functions = Qnil;
DEFVAR_LISP ("first-change-hook", &Vfirst_change_hook,
doc: );
Vfirst_change_hook = Qnil;
DEFVAR_PER_BUFFER ("buffer-undo-list", ¤t_buffer->undo_list, Qnil,
doc: );
DEFVAR_PER_BUFFER ("mark-active", ¤t_buffer->mark_active, Qnil,
doc: );
DEFVAR_PER_BUFFER ("cache-long-line-scans", ¤t_buffer->cache_long_line_scans, Qnil,
doc: );
DEFVAR_PER_BUFFER ("point-before-scroll", ¤t_buffer->point_before_scroll, Qnil,
doc: );
DEFVAR_PER_BUFFER ("buffer-file-format", ¤t_buffer->file_format, Qnil,
doc: );
DEFVAR_PER_BUFFER ("buffer-auto-save-file-format",
¤t_buffer->auto_save_file_format, Qnil,
doc: );
DEFVAR_PER_BUFFER ("buffer-invisibility-spec",
¤t_buffer->invisibility_spec, Qnil,
doc: );
DEFVAR_PER_BUFFER ("buffer-display-count",
¤t_buffer->display_count, Qnil,
doc: );
DEFVAR_PER_BUFFER ("buffer-display-time",
¤t_buffer->display_time, Qnil,
doc: );
DEFVAR_LISP ("transient-mark-mode", &Vtransient_mark_mode,
doc: );
Vtransient_mark_mode = Qnil;
DEFVAR_LISP ("inhibit-read-only", &Vinhibit_read_only,
doc: );
Vinhibit_read_only = Qnil;
DEFVAR_PER_BUFFER ("cursor-type", ¤t_buffer->cursor_type, Qnil,
doc: );
DEFVAR_PER_BUFFER ("line-spacing",
¤t_buffer->extra_line_spacing, Qnil,
doc: );
DEFVAR_PER_BUFFER ("cursor-in-non-selected-windows",
¤t_buffer->cursor_in_non_selected_windows, Qnil,
doc: );
DEFVAR_LISP ("kill-buffer-query-functions", &Vkill_buffer_query_functions,
doc: );
Vkill_buffer_query_functions = Qnil;
DEFVAR_LISP ("change-major-mode-hook", &Vchange_major_mode_hook,
doc: );
Vchange_major_mode_hook = Qnil;
Qchange_major_mode_hook = intern ("change-major-mode-hook");
staticpro (&Qchange_major_mode_hook);
defsubr (&Sbuffer_live_p);
defsubr (&Sbuffer_list);
defsubr (&Sget_buffer);
defsubr (&Sget_file_buffer);
defsubr (&Sget_buffer_create);
defsubr (&Smake_indirect_buffer);
defsubr (&Sgenerate_new_buffer_name);
defsubr (&Sbuffer_name);
defsubr (&Sbuffer_file_name);
defsubr (&Sbuffer_base_buffer);
defsubr (&Sbuffer_local_value);
defsubr (&Sbuffer_local_variables);
defsubr (&Sbuffer_modified_p);
defsubr (&Sset_buffer_modified_p);
defsubr (&Sbuffer_modified_tick);
defsubr (&Sbuffer_chars_modified_tick);
defsubr (&Srename_buffer);
defsubr (&Sother_buffer);
defsubr (&Sbuffer_enable_undo);
defsubr (&Skill_buffer);
defsubr (&Sset_buffer_major_mode);
defsubr (&Sswitch_to_buffer);
defsubr (&Spop_to_buffer);
defsubr (&Scurrent_buffer);
defsubr (&Sset_buffer);
defsubr (&Sbarf_if_buffer_read_only);
defsubr (&Sbury_buffer);
defsubr (&Serase_buffer);
defsubr (&Sset_buffer_multibyte);
defsubr (&Skill_all_local_variables);
defsubr (&Soverlayp);
defsubr (&Smake_overlay);
defsubr (&Sdelete_overlay);
defsubr (&Smove_overlay);
defsubr (&Soverlay_start);
defsubr (&Soverlay_end);
defsubr (&Soverlay_buffer);
defsubr (&Soverlay_properties);
defsubr (&Soverlays_at);
defsubr (&Soverlays_in);
defsubr (&Snext_overlay_change);
defsubr (&Sprevious_overlay_change);
defsubr (&Soverlay_recenter);
defsubr (&Soverlay_lists);
defsubr (&Soverlay_get);
defsubr (&Soverlay_put);
defsubr (&Srestore_buffer_modified_p);
}
void
keys_of_buffer ()
{
initial_define_key (control_x_map, 'b', "switch-to-buffer");
initial_define_key (control_x_map, 'k', "kill-buffer");
Fput (intern ("erase-buffer"), Qdisabled, Qt);
}