#include "keymap.h"
#include "frame.h"
+#ifdef WINDOWSNT
+#include "w32heap.h" /* for mmap_* */
+#endif
+
struct buffer *current_buffer; /* The current buffer. */
/* First buffer in chain of all buffers (in reverse order of creation).
Sbuffer_local_value, 2, 2, 0,
doc: /* Return the value of VARIABLE in BUFFER.
If VARIABLE does not have a buffer-local binding in BUFFER, the value
-is the default binding of the variable. */)
+is the default binding of the variable. */)
(register Lisp_Object variable, register Lisp_Object buffer)
{
- register Lisp_Object result = buffer_local_value_1 (variable, buffer);
+ register Lisp_Object result = buffer_local_value (variable, buffer);
if (EQ (result, Qunbound))
xsignal1 (Qvoid_variable, variable);
locally unbound. */
Lisp_Object
-buffer_local_value_1 (Lisp_Object variable, Lisp_Object buffer)
+buffer_local_value (Lisp_Object variable, Lisp_Object buffer)
{
register struct buffer *buf;
register Lisp_Object result;
- struct Lisp_Symbol *sym;
+ sym_t sym;
CHECK_SYMBOL (variable);
CHECK_BUFFER (buffer);
sym = XSYMBOL (variable);
start:
- switch (sym->redirect)
+ switch (SYMBOL_REDIRECT (sym))
{
case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
case SYMBOL_PLAINVAL: result = SYMBOL_VAL (sym); break;
/* Run hooks with the buffer to be killed the current buffer. */
{
- ptrdiff_t count = SPECPDL_INDEX ();
+ dynwind_begin ();
Lisp_Object arglist[1];
record_unwind_protect (save_excursion_restore, save_excursion_save ());
don't kill the buffer. */
arglist[0] = Qkill_buffer_query_functions;
tem = Frun_hook_with_args_until_failure (1, arglist);
- if (NILP (tem))
- return unbind_to (count, Qnil);
+ if (NILP (tem)){
+
+ dynwind_end ();
+ return Qnil;
+ }
/* Query if the buffer is still modified. */
if (INTERACTIVE && !NILP (BVAR (b, filename))
tem = do_yes_or_no_p (format2 ("Buffer %s modified; kill anyway? ",
BVAR (b, name), make_number (0)));
UNGCPRO;
- if (NILP (tem))
- return unbind_to (count, Qnil);
+ if (NILP (tem)){
+
+ dynwind_end ();
+ return Qnil;
+ }
}
/* If the hooks have killed the buffer, exit now. */
- if (!BUFFER_LIVE_P (b))
- return unbind_to (count, Qt);
+ if (!BUFFER_LIVE_P (b)){
+
+ dynwind_end ();
+ return Qt;
+ }
/* Then run the hooks. */
Frun_hooks (1, &Qkill_buffer_hook);
- unbind_to (count, Qnil);
+ dynwind_end ();
}
/* If the hooks have killed the buffer, exit now. */
if (NILP (function) || EQ (function, Qfundamental_mode))
return Qnil;
- count = SPECPDL_INDEX ();
+ dynwind_begin ();
/* To select a nonfundamental mode,
select the buffer temporarily and then call the mode function. */
Fset_buffer (buffer);
call0 (function);
- return unbind_to (count, Qnil);
+ dynwind_end ();
+ return Qnil;
}
DEFUN ("current-buffer", Fcurrent_buffer, Scurrent_buffer, 0, 0, 0,
for (tail = BVAR (b, local_var_alist); CONSP (tail); tail = XCDR (tail))
{
Lisp_Object var = XCAR (XCAR (tail));
- struct Lisp_Symbol *sym = XSYMBOL (var);
- if (sym->redirect == SYMBOL_LOCALIZED /* Just to be sure. */
+ sym_t sym = XSYMBOL (var);
+ if (SYMBOL_REDIRECT (sym) == SYMBOL_LOCALIZED /* Just to be sure. */
&& SYMBOL_BLV (sym)->fwd)
/* Just reference the variable
to cause it to become set for this buffer. */
p = GAP_END_ADDR;
stop = Z;
}
- if (ASCII_BYTE_P (*p))
+ if (ASCII_CHAR_P (*p))
p++, pos++;
else if (CHAR_BYTE8_HEAD_P (*p))
{
stop = Z;
}
- if (ASCII_BYTE_P (*p))
+ if (ASCII_CHAR_P (*p))
p++, pos++;
else if (EQ (flag, Qt)
&& ! CHAR_BYTE8_HEAD_P (*p)
for (alist = oalist; CONSP (alist); alist = XCDR (alist))
{
Lisp_Object sym = XCAR (XCAR (alist));
- eassert (XSYMBOL (sym)->redirect == SYMBOL_LOCALIZED);
+ eassert (SYMBOL_REDIRECT (XSYMBOL (sym)) == SYMBOL_LOCALIZED);
/* Need not do anything if some other buffer's binding is
now cached. */
if (EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer))
Lisp_Object overlay;
ptrdiff_t beg, end;
EMACS_INT priority;
+ EMACS_INT spriority; /* Secondary priority. */
};
static int
{
const struct sortvec *s1 = v1;
const struct sortvec *s2 = v2;
+ /* Return 1 if s1 should take precedence, -1 if v2 should take precedence,
+ and 0 if they're equal. */
if (s1->priority != s2->priority)
return s1->priority < s2->priority ? -1 : 1;
- if (s1->beg != s2->beg)
- return s1->beg < s2->beg ? -1 : 1;
- if (s1->end != s2->end)
+ /* If the priority is equal, give precedence to the one not covered by the
+ other. If neither covers the other, obey spriority. */
+ else if (s1->beg < s2->beg)
+ return (s1->end < s2->end && s1->spriority > s2->spriority ? 1 : -1);
+ else if (s1->beg > s2->beg)
+ return (s1->end > s2->end && s1->spriority < s2->spriority ? -1 : 1);
+ else if (s1->end != s2->end)
return s2->end < s1->end ? -1 : 1;
- /* Avoid the non-determinism of qsort by choosing an arbitrary ordering
- between "equal" overlays. The result can still change between
- invocations of Emacs, but it won't change in the middle of
- `find_field' (bug#6830). */
- if (!EQ (s1->overlay, s2->overlay))
+ else if (s1->spriority != s2->spriority)
+ return (s1->spriority < s2->spriority ? -1 : 1);
+ else if (EQ (s1->overlay, s2->overlay))
+ return 0;
+ else
+ /* Avoid the non-determinism of qsort by choosing an arbitrary ordering
+ between "equal" overlays. The result can still change between
+ invocations of Emacs, but it won't change in the middle of
+ `find_field' (bug#6830). */
return XLI (s1->overlay) < XLI (s2->overlay) ? -1 : 1;
- return 0;
}
/* Sort an array of overlays by priority. The array is modified in place.
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;
+ if (NILP (tem))
+ {
+ sortvec[j].priority = 0;
+ sortvec[j].spriority = 0;
+ }
+ else if (INTEGERP (tem))
+ {
+ sortvec[j].priority = XINT (tem);
+ sortvec[j].spriority = 0;
+ }
+ else if (CONSP (tem))
+ {
+ Lisp_Object car = XCAR (tem);
+ Lisp_Object cdr = XCDR (tem);
+ sortvec[j].priority = INTEGERP (car) ? XINT (car) : 0;
+ sortvec[j].spriority = INTEGERP (cdr) ? XINT (cdr) : 0;
+ }
j++;
}
}
}
}
-/* Return the concatenation of the strings associated with overlays that
- begin or end at POS, ignoring overlays that are specific to a window
- other than W. The strings are concatenated in the appropriate order:
- shorter overlays nest inside longer ones, and higher priority inside
- lower. Normally all of the after-strings come first, but zero-sized
- overlays have their after-strings ride along with the before-strings
- because it would look strange to print them inside-out.
+/* Concatenate the strings associated with overlays that begin or end
+ at POS, ignoring overlays that are specific to windows other than W.
+ The strings are concatenated in the appropriate order: shorter
+ overlays nest inside longer ones, and higher priority inside lower.
+ Normally all of the after-strings come first, but zero-sized
+ overlays have their after-strings ride along with the
+ before-strings because it would look strange to print them
+ inside-out.
- Returns the string length, and stores the contents indirectly through
- PSTR, if that variable is non-null. The string may be overwritten by
- subsequent calls. */
+ Returns the concatenated string's length, and return the pointer to
+ that string via PSTR, if that variable is non-NULL. The storage of
+ the concatenated strings may be overwritten by subsequent calls. */
ptrdiff_t
overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
{
struct buffer *b, *ob = 0;
Lisp_Object obuffer;
- ptrdiff_t count = SPECPDL_INDEX ();
+ dynwind_begin ();
ptrdiff_t n_beg, n_end, o_beg IF_LINT (= 0), o_end IF_LINT (= 0);
CHECK_OVERLAY (overlay);
/* Delete the overlay if it is empty after clipping and has the
evaporate property. */
- if (n_beg == n_end && !NILP (Foverlay_get (overlay, Qevaporate)))
- return unbind_to (count, Fdelete_overlay (overlay));
+ if (n_beg == n_end && !NILP (Foverlay_get (overlay, Qevaporate))){
+
+ Lisp_Object tem0 = Fdelete_overlay (overlay);
+ dynwind_end ();
+ return tem0;
+ }
/* Put the overlay into the new buffer's overlay lists, first on the
wrong list. */
/* This puts it in the right list, and in the right order. */
recenter_overlay_lists (b, b->overlay_center);
- return unbind_to (count, overlay);
+ dynwind_end ();
+ return overlay;
}
DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0,
{
Lisp_Object buffer;
struct buffer *b;
- ptrdiff_t count = SPECPDL_INDEX ();
+ dynwind_begin ();
CHECK_OVERLAY (overlay);
buffer = Fmarker_buffer (OVERLAY_START (overlay));
- if (NILP (buffer))
+ if (NILP (buffer)) {
+ dynwind_end ();
return Qnil;
+ }
b = XBUFFER (buffer);
specbind (Qinhibit_quit, Qt);
|| !NILP (Foverlay_get (overlay, Qafter_string))))
b->prevent_redisplay_optimizations_p = 1;
- return unbind_to (count, Qnil);
+ dynwind_end ();
+ return Qnil;
}
DEFUN ("delete-all-overlays", Fdelete_all_overlays, Sdelete_all_overlays, 0, 1, 0,
}
\f
-DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0,
- doc: /* Return a list of the overlays that contain the character at POS. */)
- (Lisp_Object pos)
+DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 2, 0,
+ doc: /* Return a list of the overlays that contain the character at POS.
+If SORTED is non-nil, then sort them by decreasing priority. */)
+ (Lisp_Object pos, Lisp_Object sorted)
{
ptrdiff_t len, noverlays;
Lisp_Object *overlay_vec;
noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
NULL, NULL, 0);
+ if (!NILP (sorted))
+ noverlays = sort_overlays (overlay_vec, noverlays,
+ WINDOWP (sorted) ? XWINDOW (sorted) : NULL);
+
/* Make a list of them all. */
result = Flist (noverlays, overlay_vec);
Allocation with mmap
***********************************************************************/
-#ifdef USE_MMAP_FOR_BUFFERS
+/* Note: WINDOWSNT implements this stuff on w32heap.c. */
+#if defined USE_MMAP_FOR_BUFFERS && !defined WINDOWSNT
#include <sys/mman.h>
static int mmap_fd;
-/* Temporary storage for mmap_set_vars, see there. */
-
-static struct mmap_region *mmap_regions_1;
-static int mmap_fd_1;
-
/* Page size on this system. */
static int mmap_page_size;
mmap_page_size = getpagesize ();
}
-/* Return a region overlapping address range START...END, or null if
- none. END is not including, i.e. the last byte in the range
- is at END - 1. */
-
-static struct mmap_region *
-mmap_find (void *start, void *end)
-{
- struct mmap_region *r;
- char *s = start, *e = end;
-
- for (r = mmap_regions; r; r = r->next)
- {
- char *rstart = (char *) r;
- char *rend = rstart + r->nbytes_mapped;
-
- if (/* First byte of range, i.e. START, in this region? */
- (s >= rstart && s < rend)
- /* Last byte of range, i.e. END - 1, in this region? */
- || (e > rstart && e <= rend)
- /* First byte of this region in the range? */
- || (rstart >= s && rstart < e)
- /* Last byte of this region in the range? */
- || (rend > s && rend <= e))
- break;
- }
-
- return r;
-}
-
-
/* Unmap a region. P is a pointer to the start of the user-araa of
the region. */
}
-/* Set or reset variables holding references to mapped regions.
- If not RESTORE_P, set all variables to null. If RESTORE_P, set all
- variables to the start of the user-areas of mapped regions.
-
- This function is called from Fdump_emacs to ensure that the dumped
- Emacs doesn't contain references to memory that won't be mapped
- when Emacs starts. */
-
-void
-mmap_set_vars (bool 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;
- }
-}
-
-
/* Allocate a block of storage large enough to hold NBYTES bytes of
data. A pointer to the data is returned in *VAR. VAR is thus the
address of some variable which will use the data area.
#elif defined REL_ALLOC
p = r_alloc ((void **) &b->text->beg, nbytes);
#else
- p = xmalloc (nbytes);
+ p = xmalloc_atomic (nbytes);
#endif
if (p == NULL)
}
void
-init_buffer (void)
+init_buffer (int initialized)
{
char *pwd;
Lisp_Object temp;
ptrdiff_t len;
#ifdef USE_MMAP_FOR_BUFFERS
- {
- /* When using the ralloc implementation based on mmap(2), buffer
- text pointers will have been set to null in the dumped Emacs.
- Map new memory. */
- struct buffer *b;
-
- FOR_EACH_BUFFER (b)
- if (b->text->beg == NULL)
- enlarge_buffer_text (b, 0);
- }
+ if (initialized)
+ {
+ struct buffer *b;
+
+#ifndef WINDOWSNT
+ /* These must be reset in the dumped Emacs, to avoid stale
+ references to mmap'ed memory from before the dump.
+
+ WINDOWSNT doesn't need this because it doesn't track mmap'ed
+ regions by hand (see w32heap.c, which uses system APIs for
+ that purpose), and thus doesn't use mmap_regions. */
+ mmap_regions = NULL;
+ mmap_fd = -1;
+#endif
+
+ /* The dumped buffers reference addresses of buffer text
+ recorded by temacs, that cannot be used by the dumped Emacs.
+ We map new memory for their text here.
+
+ Implementation note: the buffers we carry from temacs are:
+ " prin1", "*scratch*", " *Minibuf-0*", "*Messages*", and
+ " *code-conversion-work*". They are created by
+ init_buffer_once and init_window_once (which are not called
+ in the dumped Emacs), and by the first call to coding.c routines. */
+ FOR_EACH_BUFFER (b)
+ {
+ b->text->beg = NULL;
+ enlarge_buffer_text (b, 0);
+ }
+ }
+ else
+ {
+ struct buffer *b;
+
+ /* Only buffers with allocated buffer text should be present at
+ this point in temacs. */
+ FOR_EACH_BUFFER (b)
+ {
+ eassert (b->text->beg != NULL);
+ }
+ }
+#else /* not USE_MMAP_FOR_BUFFERS */
+ /* Avoid compiler warnings. */
+ initialized = initialized;
#endif /* USE_MMAP_FOR_BUFFERS */
Fset_buffer (Fget_buffer_create (build_string ("*scratch*")));
defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring,
Lisp_Object *address, Lisp_Object predicate)
{
- struct Lisp_Symbol *sym;
+ sym_t sym;
int offset;
sym = XSYMBOL (intern (namestring));
bo_fwd->type = Lisp_Fwd_Buffer_Obj;
bo_fwd->offset = offset;
bo_fwd->predicate = predicate;
- sym->declared_special = 1;
- sym->redirect = SYMBOL_FORWARDED;
+ SET_SYMBOL_DECLARED_SPECIAL (sym, 1);
+ SET_SYMBOL_REDIRECT (sym, SYMBOL_FORWARDED);
SET_SYMBOL_FWD (sym, (union Lisp_Fwd *) bo_fwd);
XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym);
void
syms_of_buffer (void)
{
+#include "buffer.x"
+
staticpro (&last_overlay_modification_hooks);
last_overlay_modification_hooks
= Fmake_vector (make_number (10), Qnil);
This variable is buffer-local but you cannot set it directly;
use the function `set-buffer-multibyte' to change a buffer's representation.
See also Info node `(elisp)Text Representations'. */);
- XSYMBOL (intern_c_string ("enable-multibyte-characters"))->constant = 1;
+ SET_SYMBOL_CONSTANT (XSYMBOL (intern_c_string ("enable-multibyte-characters")), 1);
DEFVAR_PER_BUFFER ("buffer-file-coding-system",
&BVAR (current_buffer, buffer_file_coding_system), Qnil,
`bury-buffer-internal' and `select-window'. */);
Vbuffer_list_update_hook = Qnil;
DEFSYM (Qbuffer_list_update_hook, "buffer-list-update-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 (&Sforce_mode_line_update);
- 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 (&Sbury_buffer_internal);
- defsubr (&Sset_buffer_major_mode);
- defsubr (&Scurrent_buffer);
- defsubr (&Sset_buffer);
- defsubr (&Sbarf_if_buffer_read_only);
- defsubr (&Serase_buffer);
- defsubr (&Sbuffer_swap_text);
- defsubr (&Sset_buffer_multibyte);
- defsubr (&Skill_all_local_variables);
-
- defsubr (&Soverlayp);
- defsubr (&Smake_overlay);
- defsubr (&Sdelete_overlay);
- defsubr (&Sdelete_all_overlays);
- 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