X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/09aba8153a8297e415477dbfa9a8c7e999fb3457..2bfa3d3e1fb347ba76bddf77f3e288049635821d:/src/buffer.c diff --git a/src/buffer.c b/src/buffer.c index a22c6d7dd5..7f0f2cc7d0 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -41,6 +41,10 @@ along with GNU Emacs. If not, see . */ #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). @@ -1158,10 +1162,10 @@ DEFUN ("buffer-local-value", Fbuffer_local_value, 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); @@ -1174,7 +1178,7 @@ is the default binding of the 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; @@ -1717,7 +1721,7 @@ cleaning up all windows currently displaying the buffer to be killed. */) /* 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 ()); @@ -1727,8 +1731,11 @@ cleaning up all windows currently displaying the buffer to be killed. */) 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)) @@ -1738,17 +1745,23 @@ cleaning up all windows currently displaying the buffer to be killed. */) 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. */ @@ -2071,7 +2084,7 @@ the current buffer's major mode. */) 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. */ @@ -2081,7 +2094,8 @@ the current buffer's major mode. */) Fset_buffer (buffer); call0 (function); - return unbind_to (count, Qnil); + dynwind_end (); + return Qnil; } DEFUN ("current-buffer", Fcurrent_buffer, Scurrent_buffer, 0, 0, 0, @@ -2526,7 +2540,7 @@ current buffer is cleared. */) 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)) { @@ -2598,7 +2612,7 @@ current buffer is cleared. */) stop = Z; } - if (ASCII_BYTE_P (*p)) + if (ASCII_CHAR_P (*p)) p++, pos++; else if (EQ (flag, Qt) && ! CHAR_BYTE8_HEAD_P (*p) @@ -3328,17 +3342,18 @@ record_overlay_string (struct sortstrlist *ssl, Lisp_Object str, } } -/* 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) @@ -3975,7 +3990,7 @@ buffer. */) { 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); @@ -4047,8 +4062,12 @@ buffer. */) /* 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. */ @@ -4066,7 +4085,8 @@ buffer. */) /* 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, @@ -4075,13 +4095,15 @@ 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); @@ -4098,7 +4120,8 @@ DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0, || !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, @@ -4163,9 +4186,10 @@ OVERLAY. */) } -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; @@ -4185,6 +4209,10 @@ DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0, 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); @@ -4626,7 +4654,8 @@ evaporate_overlays (ptrdiff_t pos) 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 @@ -4692,11 +4721,6 @@ static struct mmap_region *mmap_regions; 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; @@ -4768,36 +4792,6 @@ mmap_init (void) 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. */ @@ -4874,38 +4868,6 @@ mmap_enlarge (struct mmap_region *r, int npages) } -/* 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. @@ -5066,7 +5028,7 @@ alloc_buffer_text (struct buffer *b, ptrdiff_t nbytes) #elif defined REL_ALLOC p = r_alloc ((void **) &b->text->beg, nbytes); #else - p = xmalloc (nbytes); + p = xmalloc_atomic (nbytes); #endif if (p == NULL) @@ -5323,23 +5285,57 @@ init_buffer_once (void) } 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*"))); @@ -5432,6 +5428,8 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring, void syms_of_buffer (void) { +#include "buffer.x" + staticpro (&last_overlay_modification_hooks); last_overlay_modification_hooks = Fmake_vector (make_number (10), Qnil); @@ -6308,56 +6306,6 @@ Functions running this hook are, `get-buffer-create', `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