/* Buffer insertion/deletion and gap motion for GNU Emacs.
- Copyright (C) 1985, 1986, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ Copyright (C) 1985-1986, 1993-1995, 1997-2011
Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <config.h>
+#include <setjmp.h>
#include "lisp.h"
#include "intervals.h"
#include "buffer.h"
EMACS_INT, EMACS_INT, EMACS_INT);
static void adjust_point (EMACS_INT nchars, EMACS_INT nbytes);
-Lisp_Object Fcombine_after_change_execute ();
-
-/* Non-nil means don't call the after-change-functions right away,
- just record an element in Vcombine_after_change_calls_list. */
-Lisp_Object Vcombine_after_change_calls;
+Lisp_Object Fcombine_after_change_execute (void);
/* List of elements of the form (BEG-UNCHANGED END-UNCHANGED CHANGE-AMOUNT)
describing changes which happened while combine_after_change_calls
Lisp_Object combine_after_change_buffer;
Lisp_Object Qinhibit_modification_hooks;
-
\f
-/* Check all markers in the current buffer, looking for something invalid. */
-
-static int check_markers_debug_flag;
-
#define CHECK_MARKERS() \
if (check_markers_debug_flag) \
check_markers (); \
else
void
-check_markers ()
+check_markers (void)
{
register struct Lisp_Marker *tail;
int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
/* 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;
+ from -= i, to -= i;
+ memmove (to, from, i);
}
/* Adjust markers, and buffer data structure, to put the gap at BYTEPOS.
/* 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;
+ memmove (to, from, i);
+ from += i, to += i;
}
adjust_markers_gap_motion (GPT_BYTE + GAP_SIZE, bytepos + GAP_SIZE,
re-inserted text after undoing a deletion, and must be
adjusted to move them to the correct place. */
XSETMISC (marker, m);
- record_marker_adjustment (marker, from - charpos);
+ record_marker_adjustment (marker, from - charpos);
}
else if (charpos < to)
{ /* Before-insertion markers will automatically move forward
upon re-inserting the deleted text, so we have to arrange
for them to move backward to the correct position. */
XSETMISC (marker, m);
- record_marker_adjustment (marker, charpos - to);
+ record_marker_adjustment (marker, to - charpos);
}
m->charpos = from;
m->bytepos = from_byte;
}
/* Adjusting only markers whose insertion-type is t may result in
- - disordered start and end in overlays, and
+ - disordered start and end in overlays, and
- disordered overlays in the slot `overlays_before' of current_buffer. */
if (adjusted)
{
/* If we have to get more space, get enough to last a while. */
nbytes_added += 2000;
- /* Don't allow a buffer size that won't fit in an int
- even if it will fit in a Lisp integer.
- That won't work because so many places use `int'.
-
- Make sure we don't introduce overflows in the calculation. */
-
- if (Z_BYTE - BEG_BYTE + GAP_SIZE
- >= (((EMACS_INT) 1 << (min (VALBITS, BITS_PER_INT) - 1)) - 1
- - nbytes_added))
- error ("Buffer exceeds maximum size");
+ { EMACS_INT total_size = Z_BYTE - BEG_BYTE + GAP_SIZE + nbytes_added;
+ if (total_size < 0
+ /* Don't allow a buffer size that won't fit in a Lisp integer. */
+ || total_size != XINT (make_number (total_size))
+ /* Don't allow a buffer size that won't fit in an int
+ even if it will fit in a Lisp integer.
+ That won't work because so many places still use `int'. */
+ || total_size != (EMACS_INT) (int) total_size)
+ error ("Buffer exceeds maximum size");
+ }
enlarge_buffer_text (current_buffer, nbytes_added);
/* Pretend that the last unwanted part of the gap is the entire gap,
and that the first desired part of the gap is part of the buffer
text. */
- bzero (GPT_ADDR, new_gap_size);
+ memset (GPT_ADDR, 0, new_gap_size);
GPT += new_gap_size;
GPT_BYTE += new_gap_size;
Z += new_gap_size;
{
if (from_multibyte == to_multibyte)
{
- bcopy (from_addr, to_addr, nbytes);
+ memcpy (to_addr, from_addr, nbytes);
return nbytes;
}
else if (from_multibyte)
while (bytes_left > 0)
{
int thislen, c;
- c = STRING_CHAR_AND_LENGTH (from_addr, bytes_left, thislen);
+ c = STRING_CHAR_AND_LENGTH (from_addr, thislen);
if (! ASCII_CHAR_P (c))
c &= 0xFF;
*to_addr++ = c;
{
int c = *from_addr++;
- if (c >= 0200)
+ if (!ASCII_CHAR_P (c))
{
- c = unibyte_char_to_multibyte (c);
+ c = BYTE8_TO_CHAR (c);
to_addr += CHAR_STRING (c, to_addr);
nbytes--;
}
{
unsigned int c = *ptr++;
- if (c < 0200)
+ if (ASCII_CHAR_P (c))
outgoing_nbytes++;
else
{
- c = unibyte_char_to_multibyte (c);
+ c = BYTE8_TO_CHAR (c);
outgoing_nbytes += CHAR_BYTES (c);
}
}
prepare_to_modify_buffer could relocate the text. */
void
-insert (const unsigned char *string, EMACS_INT nbytes)
+insert (const char *string, EMACS_INT nbytes)
{
if (nbytes > 0)
{
- EMACS_INT len = chars_in_text (string, nbytes), opoint;
+ EMACS_INT len = chars_in_text ((unsigned char *) string, nbytes), opoint;
insert_1_both (string, len, nbytes, 0, 1, 0);
opoint = PT - len;
signal_after_change (opoint, 0, len);
/* Likewise, but inherit text properties from neighboring characters. */
void
-insert_and_inherit (const unsigned char *string, EMACS_INT nbytes)
+insert_and_inherit (const char *string, EMACS_INT nbytes)
{
if (nbytes > 0)
{
- EMACS_INT len = chars_in_text (string, nbytes), opoint;
+ EMACS_INT len = chars_in_text ((unsigned char *) string, nbytes), opoint;
insert_1_both (string, len, nbytes, 1, 1, 0);
opoint = PT - len;
signal_after_change (opoint, 0, len);
str[0] = c;
}
- insert (str, len);
+ insert ((char *) str, len);
}
/* Insert the null-terminated string S before point. */
since gc could happen and relocate it. */
void
-insert_before_markers (const unsigned char *string, EMACS_INT nbytes)
+insert_before_markers (const char *string, EMACS_INT nbytes)
{
if (nbytes > 0)
{
- EMACS_INT len = chars_in_text (string, nbytes), opoint;
+ EMACS_INT len = chars_in_text ((unsigned char *) string, nbytes), opoint;
insert_1_both (string, len, nbytes, 0, 1, 1);
opoint = PT - len;
signal_after_change (opoint, 0, len);
/* Likewise, but inherit text properties from neighboring characters. */
void
-insert_before_markers_and_inherit (const unsigned char *string,
+insert_before_markers_and_inherit (const char *string,
EMACS_INT nbytes)
{
if (nbytes > 0)
{
- EMACS_INT len = chars_in_text (string, nbytes), opoint;
+ EMACS_INT len = chars_in_text ((unsigned char *) string, nbytes), opoint;
insert_1_both (string, len, nbytes, 1, 1, 1);
opoint = PT - len;
signal_after_change (opoint, 0, len);
/* Subroutine used by the insert functions above. */
void
-insert_1 (const unsigned char *string, EMACS_INT nbytes,
+insert_1 (const char *string, EMACS_INT nbytes,
int inherit, int prepare, int before_markers)
{
- insert_1_both (string, chars_in_text (string, nbytes), nbytes,
- inherit, prepare, before_markers);
+ insert_1_both (string, chars_in_text ((unsigned char *) string, nbytes),
+ nbytes, inherit, prepare, before_markers);
}
\f
len = 1;
p = BYTE_POS_ADDR (pos_byte - 1);
while (! CHAR_HEAD_P (*p)) p--, len++;
- if (! BASE_LEADING_CODE_P (*p)) /* case (3) */
+ if (! LEADING_CODE_P (*p)) /* case (3) */
return 0;
combining_bytes = BYTES_BY_CHAR_HEAD (*p) - len;
i = pos_byte - 2;
while (i >= 0 && ! CHAR_HEAD_P (p[i]))
i--;
- if (i < 0 || !BASE_LEADING_CODE_P (p[i]))
+ if (i < 0 || !LEADING_CODE_P (p[i]))
return 0;
bytes = BYTES_BY_CHAR_HEAD (p[i]);
? 0
: bytes - (pos_byte - 1 - i + length));
}
- if (!BASE_LEADING_CODE_P (string[i]))
+ if (!LEADING_CODE_P (string[i]))
return 0;
bytes = BYTES_BY_CHAR_HEAD (string[i]) - (length - i);
are the same as in insert_1. */
void
-insert_1_both (const unsigned char *string,
+insert_1_both (const char *string,
EMACS_INT nchars, EMACS_INT nbytes,
int inherit, int prepare, int before_markers)
{
MODIFF++;
CHARS_MODIFF = MODIFF;
- bcopy (string, GPT_ADDR, nbytes);
+ memcpy (GPT_ADDR, string, nbytes);
GAP_SIZE -= nbytes;
GPT += nchars;
copy them into the buffer.
It does not work to use `insert' for this, because a GC could happen
- before we bcopy the stuff into the buffer, and relocate the string
+ before we copy the stuff into the buffer, and relocate the string
without insert noticing. */
void
into the current buffer.
It does not work to use `insert' for this, because a malloc could happen
- and relocate BUF's text before the bcopy happens. */
+ and relocate BUF's text before the copy happens. */
void
insert_from_buffer (struct buffer *buf,
void
replace_range_2 (EMACS_INT from, EMACS_INT from_byte,
EMACS_INT to, EMACS_INT to_byte,
- char *ins, EMACS_INT inschars, EMACS_INT insbytes,
+ const char *ins, EMACS_INT inschars, EMACS_INT insbytes,
int markers)
{
EMACS_INT nbytes_del, nchars_del;
make_gap (insbytes - GAP_SIZE);
/* Copy the replacement text into the buffer. */
- bcopy (ins, GPT_ADDR, insbytes);
+ memcpy (GPT_ADDR, ins, insbytes);
#ifdef BYTE_COMBINING_DEBUG
/* We have copied text into the gap, but we have not marked
base_buffer->filename);
#endif /* not CLASH_DETECTION */
+ /* If `select-active-regions' is non-nil, save the region text. */
+ if (!NILP (current_buffer->mark_active)
+ && !inhibit_modification_hooks
+ && XMARKER (current_buffer->mark)->buffer
+ && NILP (Vsaved_region_selection)
+ && (EQ (Vselect_active_regions, Qonly)
+ ? EQ (CAR_SAFE (Vtransient_mark_mode), Qonly)
+ : (!NILP (Vselect_active_regions)
+ && !NILP (Vtransient_mark_mode))))
+ {
+ EMACS_INT b = XMARKER (current_buffer->mark)->charpos;
+ EMACS_INT e = PT;
+ if (b < e)
+ Vsaved_region_selection = make_buffer_string (b, e, 0);
+ else if (b > e)
+ Vsaved_region_selection = make_buffer_string (e, b, 0);
+ }
+
signal_before_change (start, end, preserve_ptr);
if (current_buffer->newline_cache)
NO-ERROR-FLAG is nil if there was an error,
anything else meaning no error (so this function does nothing). */
Lisp_Object
-reset_var_on_error (val)
- Lisp_Object val;
+reset_var_on_error (Lisp_Object val)
{
if (NILP (XCDR (val)))
Fset (XCAR (val), Qnil);
}
Lisp_Object
-Fcombine_after_change_execute_1 (val)
- Lisp_Object val;
+Fcombine_after_change_execute_1 (Lisp_Object val)
{
Vcombine_after_change_calls = val;
return val;
DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
Scombine_after_change_execute, 0, 0, 0,
doc: /* This function is for use internally in `combine-after-change-calls'. */)
- ()
+ (void)
{
int count = SPECPDL_INDEX ();
EMACS_INT beg, end, change;
}
\f
void
-syms_of_insdel ()
+syms_of_insdel (void)
{
staticpro (&combine_after_change_list);
staticpro (&combine_after_change_buffer);
combine_after_change_list = Qnil;
combine_after_change_buffer = Qnil;
- DEFVAR_BOOL ("check-markers-debug-flag", &check_markers_debug_flag,
+ DEFVAR_BOOL ("check-markers-debug-flag", check_markers_debug_flag,
doc: /* Non-nil means enable debugging checks for invalid marker positions. */);
check_markers_debug_flag = 0;
- DEFVAR_LISP ("combine-after-change-calls", &Vcombine_after_change_calls,
+ DEFVAR_LISP ("combine-after-change-calls", Vcombine_after_change_calls,
doc: /* Used internally by the `combine-after-change-calls' macro. */);
Vcombine_after_change_calls = Qnil;
- DEFVAR_BOOL ("inhibit-modification-hooks", &inhibit_modification_hooks,
+ DEFVAR_BOOL ("inhibit-modification-hooks", inhibit_modification_hooks,
doc: /* Non-nil means don't run any of the hooks that respond to buffer changes.
This affects `before-change-functions' and `after-change-functions',
as well as hooks attached to text properties and overlays. */);
inhibit_modification_hooks = 0;
- Qinhibit_modification_hooks = intern ("inhibit-modification-hooks");
+ Qinhibit_modification_hooks = intern_c_string ("inhibit-modification-hooks");
staticpro (&Qinhibit_modification_hooks);
defsubr (&Scombine_after_change_execute);
}
-
-/* arch-tag: 9b34b886-47d7-465e-a234-299af411b23d
- (do not change this comment) */