diff options
Diffstat (limited to 'src/insdel.c')
-rw-r--r-- | src/insdel.c | 228 |
1 files changed, 46 insertions, 182 deletions
diff --git a/src/insdel.c b/src/insdel.c index 2de7744522e..a3eb061ee99 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -1,5 +1,5 @@ /* Buffer insertion/deletion and gap motion for GNU Emacs. - Copyright (C) 1985, 1986 Free Software Foundation, Inc. + Copyright (C) 1985, 1986, 1990 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -23,10 +23,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "buffer.h" #include "window.h" -/* Nonzero means don't allow protected fields to be modified. */ - -extern int check_protected_fields; - /* Move gap to position `pos'. Note that this can quit! */ @@ -92,28 +88,9 @@ gap_left (pos, newgap) /* Move at most 32000 chars before checking again for a quit. */ if (i > 32000) i = 32000; -#ifdef GAP_USE_BCOPY - if (i >= 128 - /* bcopy is safe if the two areas of memory do not overlap - or on systems where bcopy is always safe for moving upward. */ - && (BCOPY_UPWARD_SAFE - || to - from >= 128)) - { - /* If overlap is not safe, avoid it by not moving too many - characters at once. */ - if (!BCOPY_UPWARD_SAFE && i > to - from) - i = to - from; - new_s1 -= i; - from -= i, to -= i; - bcopy (from, to, i); - } - else -#endif - { - new_s1 -= i; - while (--i >= 0) - *--to = *--from; - } + new_s1 -= i; + while (--i >= 0) + *--to = *--from; } /* Adjust markers, and buffer data structure, to put the gap at POS. @@ -170,28 +147,9 @@ gap_right (pos) /* Move at most 32000 chars before checking again for a quit. */ if (i > 32000) i = 32000; -#ifdef GAP_USE_BCOPY - if (i >= 128 - /* bcopy is safe if the two areas of memory do not overlap - or on systems where bcopy is always safe for moving downward. */ - && (BCOPY_DOWNWARD_SAFE - || from - to >= 128)) - { - /* If overlap is not safe, avoid it by not moving too many - characters at once. */ - if (!BCOPY_DOWNWARD_SAFE && i > from - to) - i = from - to; - new_s1 += i; - bcopy (from, to, i); - from += i, to += i; - } - else -#endif - { - new_s1 += i; - while (--i >= 0) - *to++ = *from++; - } + new_s1 += i; + while (--i >= 0) + *to++ = *from++; } adjust_markers (GPT + GAP_SIZE, pos + 1 + GAP_SIZE, - GAP_SIZE); @@ -240,7 +198,7 @@ adjust_markers (from, to, amount) make_gap (increment) int increment; { - unsigned char *result; + unsigned char *memory; Lisp_Object tem; int real_gap_loc; int old_gap_size; @@ -248,10 +206,11 @@ make_gap (increment) /* If we have to get more space, get enough to last a while. */ increment += 2000; - result = BUFFER_REALLOC (BEG_ADDR, (Z - BEG + GAP_SIZE + increment)); - if (result == 0) + memory = (unsigned char *) realloc (BEG_ADDR, + Z - BEG + GAP_SIZE + increment); + if (memory == 0) memory_full (); - BEG_ADDR = result; + BEG_ADDR = memory; /* Prevent quitting in move_gap. */ tem = Vinhibit_quit; @@ -259,15 +218,12 @@ make_gap (increment) real_gap_loc = GPT; old_gap_size = GAP_SIZE; - /* Call the newly allocated space a gap at the end of the whole space. */ GPT = Z + GAP_SIZE; GAP_SIZE = increment; - /* Move the new gap down to be consecutive with the end of the old one. This adjusts the markers properly too. */ gap_left (real_gap_loc + old_gap_size, 1); - /* Now combine the two into one large gap. */ GAP_SIZE += old_gap_size; GPT = real_gap_loc; @@ -275,6 +231,22 @@ make_gap (increment) Vinhibit_quit = tem; } +/* Insert the character c before point */ + +insert_char (c) + unsigned char c; +{ + insert (&c, 1); +} + +/* Insert the null-terminated string s before point */ + +InsStr (s) + char *s; +{ + insert (s, strlen (s)); +} + /* Insert a string of specified length before point. DO NOT use this for the contents of a Lisp string! prepare_to_modify_buffer could relocate the string. */ @@ -293,7 +265,7 @@ insert (string, length) if (length + Z != XINT (temp)) error ("maximum buffer size exceeded"); - prepare_to_modify_buffer (point, point); + prepare_to_modify_buffer (); if (point != GPT) move_gap (point); @@ -309,15 +281,14 @@ insert (string, length) GPT += length; ZV += length; Z += length; - SET_PT (point + length); - - signal_after_change (point-length, 0, length); + point += length; } -/* Function to insert part of the text of a string (STRING) - consisting of LENGTH characters at position POS. - It does not work to use `insert' for this. */ - +/* Function to insert part of the text of a string (STRING) consisting + of LENGTH characters at position POS. + It does not work to use `insert' for this, becase a GC could happen + before we bcopy the stuff into the buffer, and relocate the string + without insert noticing. */ insert_from_string (string, pos, length) Lisp_Object string; register int pos, length; @@ -334,7 +305,7 @@ insert_from_string (string, pos, length) error ("maximum buffer size exceeded"); GCPRO1 (string); - prepare_to_modify_buffer (point, point); + prepare_to_modify_buffer (); if (point != GPT) move_gap (point); @@ -352,26 +323,6 @@ insert_from_string (string, pos, length) ZV += length; Z += length; point += length; - - signal_after_change (point-length, 0, length); -} - -/* Insert the character C before point */ - -void -insert_char (c) - unsigned char c; -{ - insert (&c, 1); -} - -/* Insert the null-terminated string S before point */ - -void -insert_string (s) - char *s; -{ - insert (s, strlen (s)); } /* Like `insert' except that all markers pointing at the place where @@ -400,7 +351,7 @@ insert_from_string_before_markers (string, pos, length) } /* Delete characters in current buffer - from FROM up to (but not including) TO. */ + from `from' up to (but not incl) `to' */ del_range (from, to) register int from, to; @@ -416,26 +367,25 @@ del_range (from, to) if ((numdel = to - from) <= 0) return; - /* Make sure the gap is somewhere in or next to what we are deleting. */ + /* Make sure the gap is somewhere in or next to what we are deleting */ if (from > GPT) gap_right (from); if (to < GPT) gap_left (to, 0); - prepare_to_modify_buffer (from, to); + prepare_to_modify_buffer (); + record_delete (from, numdel); + MODIFF++; /* Relocate point as if it were a marker. */ if (from < point) { if (point < to) - SET_PT (from); + point = from; else - SET_PT (point - numdel); + point -= numdel; } - record_delete (from, numdel); - MODIFF++; - /* Relocate all markers pointing into the new, larger gap to point at the end of the text before the gap. */ adjust_markers (to + GAP_SIZE, to + GAP_SIZE, - numdel - GAP_SIZE); @@ -449,15 +399,12 @@ del_range (from, to) beg_unchanged = GPT - BEG; if (Z - GPT < end_unchanged) end_unchanged = Z - GPT; - - signal_after_change (from, numdel, 0); } modify_region (start, end) int start, end; { - prepare_to_modify_buffer (start, end); - + prepare_to_modify_buffer (); if (start - 1 < beg_unchanged || unchanged_modified == MODIFF) beg_unchanged = start - 1; if (Z - end < end_unchanged @@ -466,17 +413,10 @@ modify_region (start, end) MODIFF++; } -/* Check that it is okay to modify the buffer between START and END. - Run the before-change-function, if any. */ - -prepare_to_modify_buffer (start, end) - Lisp_Object start, end; +prepare_to_modify_buffer () { if (!NULL (current_buffer->read_only)) - Fbarf_if_buffer_read_only (); - - if (check_protected_fields) - Fregion_fields (start, end, Qnil, Qt); + Fbarf_if_buffer_read_only(); #ifdef CLASH_DETECTION if (!NULL (current_buffer->filename) @@ -491,80 +431,4 @@ prepare_to_modify_buffer (start, end) call1 (intern ("ask-user-about-supersession-threat"), current_buffer->filename); #endif /* not CLASH_DETECTION */ - - signal_before_change (start, end); -} - -static Lisp_Object -before_change_function_restore (value) - Lisp_Object value; -{ - Vbefore_change_function = value; -} - -static Lisp_Object -after_change_function_restore (value) - Lisp_Object value; -{ - Vafter_change_function = value; -} - -/* Signal a change to the buffer immediatly before it happens. - START and END are the bounds of the text to be changed, - as Lisp objects. */ - -signal_before_change (start, end) - Lisp_Object start, end; -{ - /* If buffer is unmodified, run a special hook for that case. */ - if (current_buffer->save_modified >= MODIFF - && !NULL (Vfirst_change_function)) - { - call0 (Vfirst_change_function); - } - /* Now in any case run the before-change-function if any. */ - if (!NULL (Vbefore_change_function)) - { - int count = specpdl_ptr - specpdl; - Lisp_Object function; - - function = Vbefore_change_function; - record_unwind_protect (after_change_function_restore, - Vafter_change_function); - record_unwind_protect (before_change_function_restore, - Vbefore_change_function); - Vafter_change_function = Qnil; - Vbefore_change_function = Qnil; - - call2 (function, start, end); - unbind_to (count, Qnil); - } -} - -/* Signal a change immediatly after it happens. - POS is the address of the start of the changed text. - LENDEL is the number of characters of the text before the change. - (Not the whole buffer; just the part that was changed.) - LENINS is the number of characters in the changed text. */ - -signal_after_change (pos, lendel, lenins) - int pos, lendel, lenins; -{ - if (!NULL (Vafter_change_function)) - { - int count = specpdl_ptr - specpdl; - Lisp_Object function; - function = Vafter_change_function; - - record_unwind_protect (after_change_function_restore, - Vafter_change_function); - record_unwind_protect (before_change_function_restore, - Vbefore_change_function); - Vafter_change_function = Qnil; - Vbefore_change_function = Qnil; - - call3 (function, make_number (pos), make_number (pos + lenins), - make_number (lendel)); - unbind_to (count, Qnil); - } } |