X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Finsdel.c;h=a459c8a120173c8f2cc8eead7e09c561d020ea53;hb=5d0cf827247def2db200614bf5d3ab700776d641;hp=01484b7aae39f4d8988a767fb8d70cdcf49de6a4;hpb=2e3e3f9ee27fec50f45c282d71eaddf7c673bc56;p=chise%2Fxemacs-chise.git.1 diff --git a/src/insdel.c b/src/insdel.c index 01484b7..a459c8a 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -200,7 +200,6 @@ Boston, MA 02111-1307, USA. */ #include #include "lisp.h" -#include #include "buffer.h" #include "device.h" @@ -219,7 +218,9 @@ Boston, MA 02111-1307, USA. */ #define MAX_BUFPOS_GAP_SIZE_3 (65535/3) #define MAX_BYTIND_GAP_SIZE_3 (3 * MAX_BUFPOS_GAP_SIZE_3) +#ifndef UTF2000 short three_to_one_table[1 + MAX_BYTIND_GAP_SIZE_3]; +#endif /* Various macros modelled along the lines of those in buffer.h. Purposefully omitted from buffer.h because files other than this @@ -304,65 +305,64 @@ do \ the equivalent length in characters. */ Charcount -bytecount_to_charcount (CONST Bufbyte *ptr, Bytecount len) +bytecount_to_charcount (const Bufbyte *ptr, Bytecount len) { Charcount count = 0; - CONST Bufbyte *end = ptr + len; - -#if (LONGBITS == 32 || LONGBITS == 64) - -# if (LONGBITS == 32) -# define LONG_BYTES 4 -# define ALIGN_MASK 0xFFFFFFFCU -# define HIGH_BIT_MASK 0x80808080U -# else -# define LONG_BYTES 8 -# define ALIGN_MASK 0xFFFFFFFFFFFFFFF8UL - /* I had a dream, I was being overrun with early Intel processors ... */ -# define HIGH_BIT_MASK 0x8080808080808080UL -# endif - - /* When we have a large number of bytes to scan, we can be trickier - and significantly faster by scanning them in chunks of the CPU word - size (assuming that they're all ASCII -- we cut out as soon as - we find something non-ASCII). */ - if (len >= 12) - { - /* Determine the section in the middle of the string that's - amenable to this treatment. Everything has to be aligned - on CPU word boundaries. */ - CONST Bufbyte *aligned_ptr = - (CONST Bufbyte *) (((unsigned long) (ptr + LONG_BYTES - 1)) & - ALIGN_MASK); - CONST Bufbyte *aligned_end = - (CONST Bufbyte *) (((unsigned long) end) & ALIGN_MASK); - - /* Handle unaligned stuff at the beginning. */ - while (ptr < aligned_ptr) + const Bufbyte *end = ptr + len; + +#if SIZEOF_LONG == 8 +# define STRIDE_TYPE long +# define HIGH_BIT_MASK 0x8080808080808080UL +#elif SIZEOF_LONG_LONG == 8 && !(defined (i386) || defined (__i386__)) +# define STRIDE_TYPE long long +# define HIGH_BIT_MASK 0x8080808080808080ULL +#elif SIZEOF_LONG == 4 +# define STRIDE_TYPE long +# define HIGH_BIT_MASK 0x80808080UL +#else +# error Add support for 128-bit systems here +#endif + +#define ALIGN_BITS ((EMACS_UINT) (ALIGNOF (STRIDE_TYPE) - 1)) +#define ALIGN_MASK (~ ALIGN_BITS) +#define ALIGNED(ptr) ((((EMACS_UINT) ptr) & ALIGN_BITS) == 0) +#define STRIDE sizeof (STRIDE_TYPE) + + while (ptr < end) + { + if (BYTE_ASCII_P (*ptr)) { - if (!BYTE_ASCII_P (*ptr)) - goto bail; - count++, ptr++; + /* optimize for long stretches of ASCII */ + if (! ALIGNED (ptr)) + ptr++, count++; + else + { + const unsigned STRIDE_TYPE *ascii_end = + (const unsigned STRIDE_TYPE *) ptr; + /* This loop screams, because we can typically + detect ASCII characters 8 at a time. */ + while ((const Bufbyte *) ascii_end + STRIDE <= end + && !(*ascii_end & HIGH_BIT_MASK)) + ascii_end++; + if ((Bufbyte *) ascii_end == ptr) + ptr++, count++; + else + { + count += (Bufbyte *) ascii_end - ptr; + ptr = (Bufbyte *) ascii_end; + } + } } - /* Now do it. */ - while (ptr < aligned_end) + else { - - if ((* (unsigned long *) ptr) & HIGH_BIT_MASK) - goto bail; - ptr += LONG_BYTES; - count += LONG_BYTES; + /* optimize for successive characters from the same charset */ + Bufbyte leading_byte = *ptr; + size_t bytes = REP_BYTES_BY_FIRST_BYTE (leading_byte); + while ((ptr < end) && (*ptr == leading_byte)) + ptr += bytes, count++; } } -#endif /* LONGBITS == 32 || LONGBITS == 64 */ - - bail: - while (ptr < end) - { - count++; - INC_CHARPTR (ptr); - } #ifdef ERROR_CHECK_BUFPOS /* Bomb out if the specified substring ends in the middle of a character. Note that we might have already gotten @@ -378,9 +378,9 @@ bytecount_to_charcount (CONST Bufbyte *ptr, Bytecount len) the equivalent length in bytes. */ Bytecount -charcount_to_bytecount (CONST Bufbyte *ptr, Charcount len) +charcount_to_bytecount (const Bufbyte *ptr, Charcount len) { - CONST Bufbyte *newptr = ptr; + const Bufbyte *newptr = ptr; while (len > 0) { @@ -431,7 +431,11 @@ bufpos_to_bytind_func (struct buffer *buf, Bufpos x) bufmax = buf->text->mule_bufmax; bytmin = buf->text->mule_bytmin; bytmax = buf->text->mule_bytmax; +#ifdef UTF2000 + size = buf->text->mule_size; +#else size = (1 << buf->text->mule_shifter) + !!buf->text->mule_three_p; +#endif /* The basic idea here is that we shift the "known region" up or down until it overlaps the specified position. We do this by moving @@ -491,7 +495,7 @@ bufpos_to_bytind_func (struct buffer *buf, Bufpos x) } #ifdef ERROR_CHECK_BUFPOS else if (x >= bufmin) - abort (); + ABORT (); #endif else { @@ -626,11 +630,16 @@ bufpos_to_bytind_func (struct buffer *buf, Bufpos x) discovered isn't too large, because we use a fixed-length table to divide by 3. */ +#ifdef UTF2000 + buf->text->mule_size = size; +#endif if (size == 3) { int gap = bytmax - bytmin; +#ifndef UTF2000 buf->text->mule_three_p = 1; buf->text->mule_shifter = 1; +#endif if (gap > MAX_BYTIND_GAP_SIZE_3) { @@ -648,11 +657,13 @@ bufpos_to_bytind_func (struct buffer *buf, Bufpos x) } else { +#ifndef UTF2000 buf->text->mule_three_p = 0; if (size == 4) buf->text->mule_shifter = 2; else buf->text->mule_shifter = size - 1; +#endif } buf->text->mule_bufmin = bufmin; @@ -708,7 +719,11 @@ bytind_to_bufpos_func (struct buffer *buf, Bytind x) bufmax = buf->text->mule_bufmax; bytmin = buf->text->mule_bytmin; bytmax = buf->text->mule_bytmax; +#ifdef UTF2000 + size = buf->text->mule_size; +#else size = (1 << buf->text->mule_shifter) + !!buf->text->mule_three_p; +#endif /* The basic idea here is that we shift the "known region" up or down until it overlaps the specified position. We do this by moving @@ -768,7 +783,7 @@ bytind_to_bufpos_func (struct buffer *buf, Bytind x) } #ifdef ERROR_CHECK_BUFPOS else if (x >= bytmin) - abort (); + ABORT (); #endif else { @@ -903,11 +918,16 @@ bytind_to_bufpos_func (struct buffer *buf, Bytind x) discovered isn't too large, because we use a fixed-length table to divide by 3. */ +#ifdef UTF2000 + buf->text->mule_size = size; + #endif if (size == 3) { int gap = bytmax - bytmin; +#ifndef UTF2000 buf->text->mule_three_p = 1; buf->text->mule_shifter = 1; +#endif if (gap > MAX_BYTIND_GAP_SIZE_3) { @@ -925,11 +945,13 @@ bytind_to_bufpos_func (struct buffer *buf, Bytind x) } else { +#ifndef UTF2000 buf->text->mule_three_p = 0; if (size == 4) buf->text->mule_shifter = 2; else buf->text->mule_shifter = size - 1; +#endif } buf->text->mule_bufmin = bufmin; @@ -965,7 +987,11 @@ buffer_mule_signal_inserted_region (struct buffer *buf, Bufpos start, Bytecount bytelength, Charcount charlength) { +#ifdef UTF2000 + int size = buf->text->mule_size; +#else int size = (1 << buf->text->mule_shifter) + !!buf->text->mule_three_p; +#endif int i; /* Adjust the cache of known positions. */ @@ -1196,6 +1222,7 @@ bytind_to_bufpos (struct buffer *buf, Bytind x) Bufpos get_buffer_pos_char (struct buffer *b, Lisp_Object pos, unsigned int flags) { + /* Does not GC */ Bufpos ind; Bufpos min_allowed, max_allowed; @@ -1245,6 +1272,7 @@ void get_buffer_range_char (struct buffer *b, Lisp_Object from, Lisp_Object to, Bufpos *from_out, Bufpos *to_out, unsigned int flags) { + /* Does not GC */ Bufpos min_allowed, max_allowed; min_allowed = (flags & GB_ALLOW_PAST_ACCESSIBLE) ? @@ -1605,7 +1633,7 @@ static void adjust_markers (struct buffer *buf, Memind from, Memind to, Bytecount amount) { - struct Lisp_Marker *m; + Lisp_Marker *m; for (m = BUF_MARKERS (buf); m; m = marker_next (m)) m->memind = do_marker_adjustment (m->memind, from, to, amount); @@ -1617,7 +1645,7 @@ adjust_markers (struct buffer *buf, Memind from, Memind to, static void adjust_markers_for_insert (struct buffer *buf, Memind ind, Bytecount amount) { - struct Lisp_Marker *m; + Lisp_Marker *m; for (m = BUF_MARKERS (buf); m; m = marker_next (m)) { @@ -1631,18 +1659,6 @@ adjust_markers_for_insert (struct buffer *buf, Memind ind, Bytecount amount) /* Routines for dealing with the gap */ /************************************************************************/ -/* XEmacs requires an ANSI C compiler, and it damn well better have a - working memmove() */ -#define GAP_USE_BCOPY -#ifdef BCOPY_UPWARD_SAFE -# undef BCOPY_UPWARD_SAFE -#endif -#ifdef BCOPY_DOWNWARD_SAFE -# undef BCOPY_DOWNWARD_SAFE -#endif -#define BCOPY_UPWARD_SAFE 1 -#define BCOPY_DOWNWARD_SAFE 1 - /* maximum amount of memory moved in a single chunk. Increasing this value improves gap-motion efficiency but decreases QUIT responsiveness time. Was 32000 but today's processors are faster and files are @@ -1657,6 +1673,8 @@ gap_left (struct buffer *buf, Bytind pos) Bufbyte *to, *from; Bytecount i; Bytind new_s1; + struct buffer *mbuf; + Lisp_Object bufcons; from = BUF_GPT_ADDR (buf); to = from + BUF_GAP_SIZE (buf); @@ -1681,23 +1699,15 @@ gap_left (struct buffer *buf, Bytind pos) /* Move at most GAP_MOVE_CHUNK chars before checking again for a quit. */ if (i > GAP_MOVE_CHUNK) i = GAP_MOVE_CHUNK; -#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 (i >= 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; + from -= i; + to -= i; memmove (to, from, i); } else -#endif { new_s1 -= i; while (--i >= 0) @@ -1708,13 +1718,22 @@ gap_left (struct buffer *buf, Bytind pos) /* Adjust markers, and buffer data structure, to put the gap at POS. POS is where the loop above stopped, which may be what was specified or may be where a quit was detected. */ - adjust_markers (buf, pos, BI_BUF_GPT (buf), BUF_GAP_SIZE (buf)); - adjust_extents (make_buffer (buf), pos, BI_BUF_GPT (buf), - BUF_GAP_SIZE (buf)); + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + adjust_markers (mbuf, pos, BI_BUF_GPT (mbuf), BUF_GAP_SIZE (mbuf)); + } + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + adjust_extents (make_buffer (mbuf), pos, BI_BUF_GPT (mbuf), + BUF_GAP_SIZE (mbuf)); + } SET_BI_BUF_GPT (buf, pos); SET_GAP_SENTINEL (buf); #ifdef ERROR_CHECK_EXTENTS - sledgehammer_extent_check (make_buffer (buf)); + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + sledgehammer_extent_check (make_buffer (mbuf)); + } #endif QUIT; } @@ -1725,6 +1744,8 @@ gap_right (struct buffer *buf, Bytind pos) Bufbyte *to, *from; Bytecount i; Bytind new_s1; + struct buffer *mbuf; + Lisp_Object bufcons; to = BUF_GPT_ADDR (buf); from = to + BUF_GAP_SIZE (buf); @@ -1749,23 +1770,15 @@ gap_right (struct buffer *buf, Bytind pos) /* Move at most GAP_MOVE_CHUNK chars before checking again for a quit. */ if (i > GAP_MOVE_CHUNK) i = GAP_MOVE_CHUNK; -#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 (i >= 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; memmove (to, from, i); - from += i, to += i; + from += i; + to += i; } else -#endif { new_s1 += i; while (--i >= 0) @@ -1775,13 +1788,22 @@ gap_right (struct buffer *buf, Bytind pos) { int gsize = BUF_GAP_SIZE (buf); - adjust_markers (buf, BI_BUF_GPT (buf) + gsize, pos + gsize, - gsize); - adjust_extents (make_buffer (buf), BI_BUF_GPT (buf) + gsize, pos + gsize, - - gsize); + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + adjust_markers (mbuf, BI_BUF_GPT (mbuf) + gsize, pos + gsize, - gsize); + } + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + adjust_extents (make_buffer (mbuf), BI_BUF_GPT (mbuf) + gsize, + pos + gsize, - gsize); + } SET_BI_BUF_GPT (buf, pos); SET_GAP_SENTINEL (buf); #ifdef ERROR_CHECK_EXTENTS - sledgehammer_extent_check (make_buffer (buf)); + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + sledgehammer_extent_check (make_buffer (mbuf)); + } #endif } if (pos == BI_BUF_Z (buf)) @@ -1803,7 +1825,7 @@ static void move_gap (struct buffer *buf, Bytind pos) { if (! BUF_BEG_ADDR (buf)) - abort (); + ABORT (); if (pos < BI_BUF_GPT (buf)) gap_left (buf, pos); else if (pos > BI_BUF_GPT (buf)) @@ -1864,7 +1886,7 @@ make_gap (struct buffer *buf, Bytecount increment) Bytecount old_gap_size; /* If we have to get more space, get enough to last a while. We use - a geometric progession that saves on realloc space. */ + a geometric progression that saves on realloc space. */ increment += 2000 + ((BI_BUF_Z (buf) - BI_BUF_BEG (buf)) / 8); if (increment > BUF_END_GAP_SIZE (buf)) @@ -2035,7 +2057,12 @@ multiple_change_finish_up (Lisp_Object buffer) of the specified region, that will also be handled correctly. begin_multiple_change() returns a number (actually a specpdl depth) - that you must pass to end_multiple_change() when you are done. */ + that you must pass to end_multiple_change() when you are done. + + FSF Emacs 20 implements a similar feature, accessible from Lisp + through a `combine-after-change-calls' special form, which is + essentially equivalent to this function. We should consider + whether we want to introduce a similar Lisp form. */ int begin_multiple_change (struct buffer *buf, Bufpos start, Bufpos end) @@ -2080,8 +2107,11 @@ static int inside_change_hook; static Lisp_Object change_function_restore (Lisp_Object buffer) { - Fset_buffer (buffer); + /* We should first reset the variable and then change the buffer, + because Fset_buffer() can throw. */ inside_change_hook = 0; + if (XBUFFER (buffer) != current_buffer) + Fset_buffer (buffer); return Qnil; } @@ -2090,8 +2120,8 @@ static int in_first_change; static Lisp_Object first_change_hook_restore (Lisp_Object buffer) { - Fset_buffer (buffer); in_first_change = 0; + Fset_buffer (buffer); return Qnil; } @@ -2106,8 +2136,7 @@ signal_first_change (struct buffer *buf) if (!in_first_change) { - if (!preparing_for_armageddon && - !NILP (symbol_value_in_buffer (Qfirst_change_hook, buffer))) + if (!NILP (symbol_value_in_buffer (Qfirst_change_hook, buffer))) { int speccount = specpdl_depth (); record_unwind_protect (first_change_hook_restore, buffer); @@ -2126,11 +2155,14 @@ static void signal_before_change (struct buffer *buf, Bufpos start, Bufpos end) { /* This function can GC */ - Lisp_Object buffer; - XSETBUFFER (buffer, buf); + struct buffer *mbuf; + Lisp_Object bufcons; if (!inside_change_hook) { + Lisp_Object buffer; + int speccount; + /* Are we in a multiple-change session? */ if (buf->text->changes->in_multiple_change && buf->text->changes->mc_begin != 0) @@ -2159,35 +2191,52 @@ signal_before_change (struct buffer *buf, Bufpos start, Bufpos end) /* If buffer is unmodified, run a special hook for that case. */ if (BUF_SAVE_MODIFF (buf) >= BUF_MODIFF (buf)) - signal_first_change (buf); + { + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + signal_first_change (mbuf); + } + } /* Now in any case run the before-change-functions if any. */ + speccount = specpdl_depth (); + record_unwind_protect (change_function_restore, Fcurrent_buffer ()); + inside_change_hook = 1; - if (!preparing_for_armageddon && - (!NILP (symbol_value_in_buffer (Qbefore_change_functions, buffer)) || - /* Obsolete, for compatibility */ - !NILP (symbol_value_in_buffer (Qbefore_change_function, buffer)))) + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) { - int speccount = specpdl_depth (); - record_unwind_protect (change_function_restore, Fcurrent_buffer ()); - set_buffer_internal (buf); - inside_change_hook = 1; - va_run_hook_with_args (Qbefore_change_functions, 2, - make_int (start), make_int (end)); - /* Obsolete, for compatibility */ - va_run_hook_with_args (Qbefore_change_function, 2, - make_int (start), make_int (end)); - unbind_to (speccount, Qnil); + XSETBUFFER (buffer, mbuf); + if (!NILP (symbol_value_in_buffer (Qbefore_change_functions, buffer)) + /* Obsolete, for compatibility */ + || !NILP (symbol_value_in_buffer (Qbefore_change_function, buffer))) + { + set_buffer_internal (buf); + va_run_hook_with_args (Qbefore_change_functions, 2, + make_int (start), make_int (end)); + /* Obsolete, for compatibility */ + va_run_hook_with_args (Qbefore_change_function, 2, + make_int (start), make_int (end)); + } + } + + /* Make sure endpoints remain valid. before-change-functions + might have modified the buffer. */ + if (start < BUF_BEGV (buf)) start = BUF_BEGV (buf); + if (start > BUF_ZV (buf)) start = BUF_ZV (buf); + if (end < BUF_BEGV (buf)) end = BUF_BEGV (buf); + if (end > BUF_ZV (buf)) end = BUF_ZV (buf); + + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + XSETBUFFER (buffer, mbuf); + report_extent_modification (buffer, start, end, 0); } + unbind_to (speccount, Qnil); /* Only now do we indicate that the before-change-functions have been called, in case some function throws out. */ buf->text->changes->mc_begin_signaled = 1; } - - /* #### At this point we should map over extents calling - modification-hooks, insert-before-hooks and insert-after-hooks - of relevant extents */ } /* Signal a change immediately after it happens. @@ -2201,15 +2250,26 @@ signal_after_change (struct buffer *buf, Bufpos start, Bufpos orig_end, Bufpos new_end) { /* This function can GC */ - Lisp_Object buffer; - XSETBUFFER (buffer, buf); + struct buffer *mbuf; + Lisp_Object bufcons; - /* always do this. */ - buffer_signal_changed_region (buf, start, new_end); - font_lock_maybe_update_syntactic_caches (buf, start, orig_end, new_end); + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + /* always do this. */ + buffer_signal_changed_region (mbuf, start, new_end); + } + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + /* #### This seems inefficient. Wouldn't it be better to just + keep one cache per base buffer? */ + font_lock_maybe_update_syntactic_caches (mbuf, start, orig_end, new_end); + } if (!inside_change_hook) { + Lisp_Object buffer; + int speccount; + if (buf->text->changes->in_multiple_change && buf->text->changes->mc_begin != 0) { @@ -2221,30 +2281,46 @@ signal_after_change (struct buffer *buf, Bufpos start, Bufpos orig_end, return; /* after-change-functions signalled when all changes done */ } - if (!preparing_for_armageddon && - (!NILP (symbol_value_in_buffer (Qafter_change_functions, buffer)) || - /* Obsolete, for compatibility */ - !NILP (symbol_value_in_buffer (Qafter_change_function, buffer)))) + speccount = specpdl_depth (); + record_unwind_protect (change_function_restore, Fcurrent_buffer ()); + inside_change_hook = 1; + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) { - int speccount = specpdl_depth (); - record_unwind_protect (change_function_restore, Fcurrent_buffer ()); - set_buffer_internal (buf); - inside_change_hook = 1; - /* The actual after-change functions take slightly - different arguments than what we were passed. */ - va_run_hook_with_args (Qafter_change_functions, 3, - make_int (start), make_int (new_end), - make_int (orig_end - start)); - /* Obsolete, for compatibility */ - va_run_hook_with_args (Qafter_change_function, 3, - make_int (start), make_int (new_end), - make_int (orig_end - start)); - unbind_to (speccount, Qnil); + XSETBUFFER (buffer, mbuf); + + if (!NILP (symbol_value_in_buffer (Qafter_change_functions, buffer)) + /* Obsolete, for compatibility */ + || !NILP (symbol_value_in_buffer (Qafter_change_function, buffer))) + { + set_buffer_internal (buf); + /* The actual after-change functions take slightly + different arguments than what we were passed. */ + va_run_hook_with_args (Qafter_change_functions, 3, + make_int (start), make_int (new_end), + make_int (orig_end - start)); + /* Obsolete, for compatibility */ + va_run_hook_with_args (Qafter_change_function, 3, + make_int (start), make_int (new_end), + make_int (orig_end - start)); + } } - } - /* #### At this point we should map over extents calling - some sort of modification hooks of relevant extents */ + /* Make sure endpoints remain valid. after-change-functions + might have modified the buffer. */ + if (start < BUF_BEGV (buf)) start = BUF_BEGV (buf); + if (start > BUF_ZV (buf)) start = BUF_ZV (buf); + if (new_end < BUF_BEGV (buf)) new_end = BUF_BEGV (buf); + if (new_end > BUF_ZV (buf)) new_end = BUF_ZV (buf); + if (orig_end < BUF_BEGV (buf)) orig_end = BUF_BEGV (buf); + if (orig_end > BUF_ZV (buf)) orig_end = BUF_ZV (buf); + + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + XSETBUFFER (buffer, mbuf); + report_extent_modification (buffer, start, new_end, 1); + } + unbind_to (speccount, Qnil); /* sets inside_change_hook back to 0 */ + } } /* Call this if you're about to change the region of BUFFER from START @@ -2260,10 +2336,14 @@ prepare_to_modify_buffer (struct buffer *buf, Bufpos start, Bufpos end, /* dmoore - This function can also kill the buffer buf, the current buffer, and do anything it pleases. So if you call it, be careful. */ - Lisp_Object buffer; + struct buffer *mbuf; + Lisp_Object buffer, bufcons; struct gcpro gcpro1; - barf_if_buffer_read_only (buf, start, end); + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + barf_if_buffer_read_only (mbuf, start, end); + } /* if this is the first modification, see about locking the buffer's file */ @@ -2272,16 +2352,15 @@ prepare_to_modify_buffer (struct buffer *buf, Bufpos start, Bufpos end, if (!NILP (buf->filename) && lockit && BUF_SAVE_MODIFF (buf) >= BUF_MODIFF (buf)) { -#ifdef CLASH_DETECTION - if (!NILP (buf->file_truename)) - /* Make binding buffer-file-name to nil effective. */ - lock_file (buf->file_truename); -#else /* At least warn if this file has changed on disk since it was visited.*/ if (NILP (Fverify_visited_file_modtime (buffer)) && !NILP (Ffile_exists_p (buf->filename))) call1_in_buffer (buf, intern ("ask-user-about-supersession-threat"), buf->filename); +#ifdef CLASH_DETECTION + if (!NILP (buf->file_truename)) + /* Make binding buffer-file-name to nil effective. */ + lock_file (buf->file_truename); #endif /* not CLASH_DETECTION */ } UNGCPRO; @@ -2307,7 +2386,10 @@ prepare_to_modify_buffer (struct buffer *buf, Bufpos start, Bufpos end, Vdeactivate_mark = Qt; #endif - buf->point_before_scroll = Qnil; + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + mbuf->point_before_scroll = Qnil; + } } @@ -2316,7 +2398,7 @@ prepare_to_modify_buffer (struct buffer *buf, Bufpos start, Bufpos end, /************************************************************************/ void -fixup_internal_substring (CONST Bufbyte *nonreloc, Lisp_Object reloc, +fixup_internal_substring (const Bufbyte *nonreloc, Lisp_Object reloc, Bytecount offset, Bytecount *len) { assert ((nonreloc && NILP (reloc)) || (!nonreloc && STRINGP (reloc))); @@ -2324,7 +2406,7 @@ fixup_internal_substring (CONST Bufbyte *nonreloc, Lisp_Object reloc, if (*len < 0) { if (nonreloc) - *len = strlen ((CONST char *) nonreloc) - offset; + *len = strlen ((const char *) nonreloc) - offset; else *len = XSTRING_LENGTH (reloc) - offset; } @@ -2358,7 +2440,7 @@ fixup_internal_substring (CONST Bufbyte *nonreloc, Lisp_Object reloc, Charcount buffer_insert_string_1 (struct buffer *buf, Bufpos pos, - CONST Bufbyte *nonreloc, Lisp_Object reloc, + const Bufbyte *nonreloc, Lisp_Object reloc, Bytecount offset, Bytecount length, int flags) { @@ -2367,6 +2449,8 @@ buffer_insert_string_1 (struct buffer *buf, Bufpos pos, Bytind ind; Charcount cclen; int move_point = 0; + struct buffer *mbuf; + Lisp_Object bufcons; /* Defensive steps just in case a buffer gets deleted and a calling function doesn't notice it. */ @@ -2391,7 +2475,8 @@ buffer_insert_string_1 (struct buffer *buf, Bufpos pos, if ((length + BUF_Z (buf)) > EMACS_INT_MAX) error ("Maximum buffer size exceeded"); - /* theoretically not necessary -- caller should GCPRO */ + /* theoretically not necessary -- caller should GCPRO. + #### buffer_insert_from_buffer_1() doesn't! */ GCPRO1 (reloc); prepare_to_modify_buffer (buf, pos, pos, !(flags & INSDEL_NO_LOCKING)); @@ -2433,7 +2518,11 @@ buffer_insert_string_1 (struct buffer *buf, Bufpos pos, insert_invalidate_line_number_cache (buf, pos, nonreloc + offset, length); - record_insert (buf, pos, cclen); + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + record_insert (mbuf, pos, cclen); + } + BUF_MODIFF (buf)++; MARK_BUFFERS_CHANGED; @@ -2445,7 +2534,10 @@ buffer_insert_string_1 (struct buffer *buf, Bufpos pos, SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) - length); SET_BI_BUF_GPT (buf, BI_BUF_GPT (buf) + length); - SET_BOTH_BUF_ZV (buf, BUF_ZV (buf) + cclen, BI_BUF_ZV (buf) + length); + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + SET_BOTH_BUF_ZV (mbuf, BUF_ZV (mbuf) + cclen, BI_BUF_ZV (mbuf) + length); + } SET_BOTH_BUF_Z (buf, BUF_Z (buf) + cclen, BI_BUF_Z (buf) + length); SET_GAP_SENTINEL (buf); @@ -2453,29 +2545,48 @@ buffer_insert_string_1 (struct buffer *buf, Bufpos pos, buffer_mule_signal_inserted_region (buf, pos, length, cclen); #endif - process_extents_for_insertion (make_buffer (buf), ind, length); - /* We know the gap is at IND so the cast is OK. */ - adjust_markers_for_insert (buf, (Memind) ind, length); + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + process_extents_for_insertion (make_buffer (mbuf), ind, length); + } + + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + /* We know the gap is at IND so the cast is OK. */ + adjust_markers_for_insert (mbuf, (Memind) ind, length); + } /* Point logically doesn't move, but may need to be adjusted because it's a byte index. point-marker doesn't change because it's a memory index. */ - if (BI_BUF_PT (buf) > ind) - JUST_SET_POINT (buf, BUF_PT (buf) + cclen, BI_BUF_PT (buf) + length); + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + if (BI_BUF_PT (mbuf) > ind) + JUST_SET_POINT (mbuf, BUF_PT (mbuf) + cclen, + BI_BUF_PT (mbuf) + length); + } /* Well, point might move. */ if (move_point) BI_BUF_SET_PT (buf, ind + length); if (STRINGP (reloc)) - splice_in_string_extents (reloc, buf, ind, length, offset); + { + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + splice_in_string_extents (reloc, mbuf, ind, length, offset); + } + } if (flags & INSDEL_BEFORE_MARKERS) { - /* ind - 1 is correct because the FROM argument is exclusive. - I formerly used DEC_BYTIND() but that caused problems at the - beginning of the buffer. */ - adjust_markers (buf, ind - 1, ind, length); + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + /* ind - 1 is correct because the FROM argument is exclusive. + I formerly used DEC_BYTIND() but that caused problems at the + beginning of the buffer. */ + adjust_markers (mbuf, ind - 1, ind, length); + } } signal_after_change (buf, pos, pos, pos + cclen); @@ -2494,7 +2605,7 @@ buffer_insert_string_1 (struct buffer *buf, Bufpos pos, Charcount buffer_insert_raw_string_1 (struct buffer *buf, Bufpos pos, - CONST Bufbyte *nonreloc, Bytecount length, + const Bufbyte *nonreloc, Bytecount length, int flags) { /* This function can GC */ @@ -2507,7 +2618,9 @@ buffer_insert_lisp_string_1 (struct buffer *buf, Bufpos pos, Lisp_Object str, int flags) { /* This function can GC */ +#ifdef ERROR_CHECK_TYPECHECK assert (STRINGP (str)); +#endif return buffer_insert_string_1 (buf, pos, 0, str, 0, XSTRING_LENGTH (str), flags); @@ -2516,13 +2629,12 @@ buffer_insert_lisp_string_1 (struct buffer *buf, Bufpos pos, Lisp_Object str, /* Insert the null-terminated string S (in external format). */ Charcount -buffer_insert_c_string_1 (struct buffer *buf, Bufpos pos, CONST char *s, +buffer_insert_c_string_1 (struct buffer *buf, Bufpos pos, const char *s, int flags) { /* This function can GC */ - - CONST char *translated = GETTEXT (s); - return buffer_insert_string_1 (buf, pos, (CONST Bufbyte *) translated, Qnil, + const char *translated = GETTEXT (s); + return buffer_insert_string_1 (buf, pos, (const Bufbyte *) translated, Qnil, 0, strlen (translated), flags); } @@ -2532,9 +2644,7 @@ buffer_insert_emacs_char_1 (struct buffer *buf, Bufpos pos, Emchar ch, { /* This function can GC */ Bufbyte str[MAX_EMCHAR_LEN]; - Bytecount len; - - len = set_charptr_emchar (str, ch); + Bytecount len = set_charptr_emchar (str, ch); return buffer_insert_string_1 (buf, pos, str, Qnil, 0, len, flags); } @@ -2573,7 +2683,8 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags) Bytind bi_from, bi_to; Bytecount bc_numdel; EMACS_INT shortage; - Lisp_Object bufobj; + struct buffer *mbuf; + Lisp_Object bufcons; /* Defensive steps just in case a buffer gets deleted and a calling function doesn't notice it. */ @@ -2604,8 +2715,6 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags) if ((numdel = to - from) <= 0) return; - XSETBUFFER (bufobj, buf); - /* Redisplay needs to know if a newline was in the deleted region. If we've already marked the changed region as having a deleted newline there is no use in performing the check. */ @@ -2613,7 +2722,12 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags) { scan_buffer (buf, '\n', from, to, 1, &shortage, 1); if (!shortage) - buf->changes->newline_was_deleted = 1; + { + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + mbuf->changes->newline_was_deleted = 1; + } + } } bi_from = bufpos_to_bytind (buf, from); @@ -2627,49 +2741,70 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags) { /* avoid moving the gap just to delete from the bottom. */ - record_delete (buf, from, numdel); + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + record_delete (mbuf, from, numdel); + } BUF_MODIFF (buf)++; MARK_BUFFERS_CHANGED; - /* ### Point used to be modified here, but this causes problems with MULE, - as point is used to calculate bytinds, and if the offset in bc_numdel causes - point to move to a non first-byte location, causing some other function to - throw an assertion in ASSERT_VALID_BYTIND. I've moved the code to right after - the other movements and adjustments, but before the gap is moved. - -- jh 970813 */ + /* #### Point used to be modified here, but this causes problems + with MULE, as point is used to calculate bytinds, and if the + offset in bc_numdel causes point to move to a non first-byte + location, causing some other function to throw an assertion + in ASSERT_VALID_BYTIND. I've moved the code to right after + the other movements and adjustments, but before the gap is + moved. -- jh 970813 */ /* Detach any extents that are completely within the range [FROM, TO], if the extents are detachable. - This must come AFTER record_delete(), so that the appropriate extents - will be present to be recorded, and BEFORE the gap size is increased, - as otherwise we will be confused about where the extents end. */ - process_extents_for_deletion (bufobj, bi_from, bi_to, 0); + This must come AFTER record_delete(), so that the appropriate + extents will be present to be recorded, and BEFORE the gap + size is increased, as otherwise we will be confused about + where the extents end. */ + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + process_extents_for_deletion (make_buffer (mbuf), bi_from, bi_to, 0); + } - /* Relocate all markers pointing into the new, larger gap - to point at the end of the text before the gap. */ - adjust_markers (buf, - (bi_to + BUF_GAP_SIZE (buf)), - (bi_to + BUF_GAP_SIZE (buf)), - (- bc_numdel)); + /* Relocate all markers pointing into the new, larger gap to + point at the end of the text before the gap. */ + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + adjust_markers (mbuf, + (bi_to + BUF_GAP_SIZE (mbuf)), + (bi_to + BUF_GAP_SIZE (mbuf)), + (- bc_numdel)); + } - /* Relocate any extent endpoints just like markers. */ - adjust_extents_for_deletion (bufobj, bi_from, bi_to, - BUF_GAP_SIZE (buf), bc_numdel, 0); + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + /* Relocate any extent endpoints just like markers. */ + adjust_extents_for_deletion (make_buffer (mbuf), bi_from, bi_to, + BUF_GAP_SIZE (mbuf), bc_numdel, 0); + } - /* Relocate point as if it were a marker. */ - if (bi_from < BI_BUF_PT (buf)) + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) { - if (BI_BUF_PT (buf) < bi_to) - JUST_SET_POINT (buf, from, bi_from); - else - JUST_SET_POINT (buf, BUF_PT (buf) - numdel, - BI_BUF_PT (buf) - bc_numdel); + /* Relocate point as if it were a marker. */ + if (bi_from < BI_BUF_PT (mbuf)) + { + if (BI_BUF_PT (mbuf) < bi_to) + JUST_SET_POINT (mbuf, from, bi_from); + else + JUST_SET_POINT (mbuf, BUF_PT (mbuf) - numdel, + BI_BUF_PT (mbuf) - bc_numdel); + } } SET_BUF_END_GAP_SIZE (buf, BUF_END_GAP_SIZE (buf) + bc_numdel); - SET_BOTH_BUF_ZV (buf, BUF_ZV (buf) - numdel, BI_BUF_ZV (buf) - bc_numdel); + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + SET_BOTH_BUF_ZV (mbuf, BUF_ZV (mbuf) - numdel, + BI_BUF_ZV (mbuf) - bc_numdel); + } SET_BOTH_BUF_Z (buf, BUF_Z (buf) - numdel, BI_BUF_Z (buf) - bc_numdel); SET_GAP_SENTINEL (buf); } @@ -2681,16 +2816,20 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags) if (bi_from > BI_BUF_GPT (buf)) gap_right (buf, bi_from); - record_delete (buf, from, numdel); + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + record_delete (mbuf, from, numdel); + } BUF_MODIFF (buf)++; MARK_BUFFERS_CHANGED; - /* ### Point used to be modified here, but this causes problems with MULE, - as point is used to calculate bytinds, and if the offset in bc_numdel causes - point to move to a non first-byte location, causing some other function to - throw an assertion in ASSERT_VALID_BYTIND. I've moved the code to right after - the other movements and adjustments, but before the gap is moved. - -- jh 970813 */ + /* #### Point used to be modified here, but this causes problems + with MULE, as point is used to calculate bytinds, and if the + offset in bc_numdel causes point to move to a non first-byte + location, causing some other function to throw an assertion + in ASSERT_VALID_BYTIND. I've moved the code to right after + the other movements and adjustments, but before the gap is + moved. -- jh 970813 */ /* Detach any extents that are completely within the range [FROM, TO], if the extents are detachable. @@ -2698,31 +2837,48 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags) This must come AFTER record_delete(), so that the appropriate extents will be present to be recorded, and BEFORE the gap size is increased, as otherwise we will be confused about where the extents end. */ - process_extents_for_deletion (bufobj, bi_from, bi_to, 0); + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + process_extents_for_deletion (make_buffer (mbuf), bi_from, bi_to, 0); + } - /* Relocate all markers pointing into the new, larger gap - to point at the end of the text before the gap. */ - adjust_markers (buf, - (bi_to + BUF_GAP_SIZE (buf)), - (bi_to + BUF_GAP_SIZE (buf)), - (- bc_numdel - BUF_GAP_SIZE (buf))); + /* Relocate all markers pointing into the new, larger gap to + point at the end of the text before the gap. */ + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + adjust_markers (mbuf, + (bi_to + BUF_GAP_SIZE (mbuf)), + (bi_to + BUF_GAP_SIZE (mbuf)), + (- bc_numdel - BUF_GAP_SIZE (mbuf))); + } /* Relocate any extent endpoints just like markers. */ - adjust_extents_for_deletion (bufobj, bi_from, bi_to, BUF_GAP_SIZE (buf), - bc_numdel, BUF_GAP_SIZE (buf)); + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + adjust_extents_for_deletion (make_buffer (mbuf), bi_from, bi_to, + BUF_GAP_SIZE (mbuf), + bc_numdel, BUF_GAP_SIZE (mbuf)); + } - /* Relocate point as if it were a marker. */ - if (bi_from < BI_BUF_PT (buf)) + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) { - if (BI_BUF_PT (buf) < bi_to) - JUST_SET_POINT (buf, from, bi_from); - else - JUST_SET_POINT (buf, BUF_PT (buf) - numdel, - BI_BUF_PT (buf) - bc_numdel); + /* Relocate point as if it were a marker. */ + if (bi_from < BI_BUF_PT (mbuf)) + { + if (BI_BUF_PT (mbuf) < bi_to) + JUST_SET_POINT (mbuf, from, bi_from); + else + JUST_SET_POINT (mbuf, BUF_PT (mbuf) - numdel, + BI_BUF_PT (mbuf) - bc_numdel); + } } SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + bc_numdel); - SET_BOTH_BUF_ZV (buf, BUF_ZV (buf) - numdel, BI_BUF_ZV (buf) - bc_numdel); + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + SET_BOTH_BUF_ZV (mbuf, BUF_ZV (mbuf) - numdel, + BI_BUF_ZV (mbuf) - bc_numdel); + } SET_BOTH_BUF_Z (buf, BUF_Z (buf) - numdel, BI_BUF_Z (buf) - bc_numdel); SET_BI_BUF_GPT (buf, bi_from); SET_GAP_SENTINEL (buf); @@ -2733,7 +2889,10 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags) #endif #ifdef ERROR_CHECK_EXTENTS - sledgehammer_extent_check (bufobj); + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + sledgehammer_extent_check (make_buffer (mbuf)); + } #endif signal_after_change (buf, from, to, from); @@ -2747,7 +2906,7 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags) /* Replace the character at POS in buffer B with CH. */ void -buffer_replace_char (struct buffer *b, Bufpos pos, Emchar ch, +buffer_replace_char (struct buffer *buf, Bufpos pos, Emchar ch, int not_real_change, int force_lock_check) { /* This function can GC */ @@ -2757,42 +2916,54 @@ buffer_replace_char (struct buffer *b, Bufpos pos, Emchar ch, /* Defensive steps just in case a buffer gets deleted and a calling function doesn't notice it. */ - if (!BUFFER_LIVE_P (b)) + if (!BUFFER_LIVE_P (buf)) return; - curlen = BUF_CHARPTR_COPY_CHAR (b, pos, curstr); + curlen = BUF_CHARPTR_COPY_CHAR (buf, pos, curstr); newlen = set_charptr_emchar (newstr, ch); if (curlen == newlen) { + struct buffer *mbuf; + Lisp_Object bufcons; + /* then we can just replace the text. */ - prepare_to_modify_buffer (b, pos, pos + 1, + prepare_to_modify_buffer (buf, pos, pos + 1, !not_real_change || force_lock_check); /* Defensive steps in case the before-change-functions fuck around */ - if (!BUFFER_LIVE_P (b)) + if (!BUFFER_LIVE_P (buf)) /* Bad bad pre-change function. */ return; /* Make args be valid again. prepare_to_modify_buffer() might have modified the buffer. */ - if (pos < BUF_BEGV (b)) - pos = BUF_BEGV (b); - if (pos >= BUF_ZV (b)) - pos = BUF_ZV (b) - 1; - if (pos < BUF_BEGV (b)) + if (pos < BUF_BEGV (buf)) + pos = BUF_BEGV (buf); + if (pos >= BUF_ZV (buf)) + pos = BUF_ZV (buf) - 1; + if (pos < BUF_BEGV (buf)) /* no more characters in buffer! */ return; - if (BUF_FETCH_CHAR (b, pos) == '\n') - b->changes->newline_was_deleted = 1; + if (BUF_FETCH_CHAR (buf, pos) == '\n') + { + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + mbuf->changes->newline_was_deleted = 1; + } + } MARK_BUFFERS_CHANGED; if (!not_real_change) { - record_change (b, pos, 1); - BUF_MODIFF (b)++; + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) + { + record_change (mbuf, pos, 1); + } + BUF_MODIFF (buf)++; } - memcpy (BUF_BYTE_ADDRESS (b, pos), newstr, newlen); - signal_after_change (b, pos, pos + 1, pos + 1); + memcpy (BUF_BYTE_ADDRESS (buf, pos), newstr, newlen); + + signal_after_change (buf, pos, pos + 1, pos + 1); /* We do not have to adjust the Mule data; we just replaced a character with another of the same number of bytes. */ @@ -2807,21 +2978,21 @@ buffer_replace_char (struct buffer *b, Bufpos pos, Emchar ch, * point. Point will drift backward by one position and stay * there otherwise. */ - int movepoint = (pos == BUF_PT (b) - 1); + int movepoint = (pos == BUF_PT (buf) - 1); - buffer_delete_range (b, pos, pos + 1, 0); + buffer_delete_range (buf, pos, pos + 1, 0); /* Defensive steps in case the before-change-functions fuck around */ - if (!BUFFER_LIVE_P (b)) + if (!BUFFER_LIVE_P (buf)) /* Bad bad pre-change function. */ return; /* Make args be valid again. prepare_to_modify_buffer() might have modified the buffer. */ - if (pos < BUF_BEGV (b)) - pos = BUF_BEGV (b); - if (pos >= BUF_ZV (b)) - pos = BUF_ZV (b) - 1; - if (pos < BUF_BEGV (b)) + if (pos < BUF_BEGV (buf)) + pos = BUF_BEGV (buf); + if (pos >= BUF_ZV (buf)) + pos = BUF_ZV (buf) - 1; + if (pos < BUF_BEGV (buf)) /* no more characters in buffer! */ return; /* @@ -2829,7 +3000,7 @@ buffer_replace_char (struct buffer *b, Bufpos pos, Emchar ch, * insertion, which we must do if the deletion moved point * backward so that it now equals the insertion point. */ - buffer_insert_string_1 (b, (movepoint ? -1 : pos), + buffer_insert_string_1 (buf, (movepoint ? -1 : pos), newstr, Qnil, 0, newlen, 0); } } @@ -2842,22 +3013,20 @@ buffer_replace_char (struct buffer *b, Bufpos pos, Emchar ch, /* Make a string from a buffer. This needs to take into account the gap, and add any necessary extents from the buffer. */ -Lisp_Object -make_string_from_buffer (struct buffer *buf, Bufpos pos, Charcount length) +static Lisp_Object +make_string_from_buffer_1 (struct buffer *buf, Bufpos pos, Charcount length, + int no_extents) { /* This function can GC */ - Lisp_Object val; - struct gcpro gcpro1; - Bytind bi_ind; - Bytecount bi_len; + Bytind bi_ind = bufpos_to_bytind (buf, pos); + Bytecount bi_len = bufpos_to_bytind (buf, pos + length) - bi_ind; + Lisp_Object val = make_uninit_string (bi_len); - bi_ind = bufpos_to_bytind (buf, pos); - bi_len = bufpos_to_bytind (buf, pos + length) - bi_ind; - - val = make_uninit_string (bi_len); + struct gcpro gcpro1; GCPRO1 (val); - add_string_extents (val, buf, bi_ind, bi_len); + if (!no_extents) + add_string_extents (val, buf, bi_ind, bi_len); { Bytecount len1 = BI_BUF_GPT (buf) - bi_ind; @@ -2889,6 +3058,19 @@ make_string_from_buffer (struct buffer *buf, Bufpos pos, Charcount length) return val; } +Lisp_Object +make_string_from_buffer (struct buffer *buf, Bufpos pos, Charcount length) +{ + return make_string_from_buffer_1 (buf, pos, length, 0); +} + +Lisp_Object +make_string_from_buffer_no_extents (struct buffer *buf, Bufpos pos, + Charcount length) +{ + return make_string_from_buffer_1 (buf, pos, length, 1); +} + void barf_if_buffer_read_only (struct buffer *buf, Bufpos from, Bufpos to) { @@ -2918,27 +3100,41 @@ barf_if_buffer_read_only (struct buffer *buf, Bufpos from, Bufpos to) } void -find_charsets_in_bufbyte_string (unsigned char *charsets, CONST Bufbyte *str, +find_charsets_in_bufbyte_string (Charset_ID *charsets, const Bufbyte *str, Bytecount len) { #ifndef MULE /* Telescope this. */ charsets[0] = 1; #else - CONST Bufbyte *strend = str + len; - memset (charsets, 0, NUM_LEADING_BYTES); + const Bufbyte *strend = str + len; + memset (charsets, 0, NUM_LEADING_BYTES * sizeof(Charset_ID)); + + /* #### SJT doesn't like this. */ + if (len == 0) + { + charsets[XCHARSET_LEADING_BYTE (Vcharset_ascii) - MIN_LEADING_BYTE] = 1; + return; + } while (str < strend) { - charsets[CHAR_LEADING_BYTE (charptr_emchar (str)) - 128] = 1; +#ifdef UTF2000 + charsets[CHAR_CHARSET_ID (charptr_emchar (str)) + - MIN_LEADING_BYTE] = 1; +#else /* I'm not sure the definition for UTF2000 works with leading-byte + representation. */ + charsets[CHAR_LEADING_BYTE (charptr_emchar (str)) + - MIN_LEADING_BYTE] = 1; +#endif INC_CHARPTR (str); } #endif } void -find_charsets_in_emchar_string (unsigned char *charsets, CONST Emchar *str, - Charcount len) +find_charsets_in_charc_string (Charset_ID *charsets, const Charc *str, + Charcount len) { #ifndef MULE /* Telescope this. */ @@ -2946,25 +3142,33 @@ find_charsets_in_emchar_string (unsigned char *charsets, CONST Emchar *str, #else int i; - memset (charsets, 0, NUM_LEADING_BYTES); + memset (charsets, 0, NUM_LEADING_BYTES * sizeof(Charset_ID)); + + /* #### SJT doesn't like this. */ + if (len == 0) + { + charsets[XCHARSET_ID (Vcharset_ascii) - MIN_LEADING_BYTE] = 1; + return; + } + for (i = 0; i < len; i++) { - charsets[CHAR_LEADING_BYTE (str[i]) - 128] = 1; + charsets[CHARC_CHARSET_ID (str[i]) - MIN_LEADING_BYTE] = 1; } #endif } int -bufbyte_string_displayed_columns (CONST Bufbyte *str, Bytecount len) +bufbyte_string_displayed_columns (const Bufbyte *str, Bytecount len) { int cols = 0; - CONST Bufbyte *end = str + len; + const Bufbyte *end = str + len; while (str < end) { #ifdef MULE Emchar ch = charptr_emchar (str); - cols += XCHARSET_COLUMNS (CHAR_CHARSET (ch)); + cols += CHAR_COLUMNS (ch); #else cols++; #endif @@ -2975,14 +3179,14 @@ bufbyte_string_displayed_columns (CONST Bufbyte *str, Bytecount len) } int -emchar_string_displayed_columns (CONST Emchar *str, Charcount len) +charc_string_displayed_columns (const Charc *str, Charcount len) { #ifdef MULE int cols = 0; int i; for (i = 0; i < len; i++) - cols += XCHARSET_COLUMNS (CHAR_CHARSET (str[i])); + cols += CHARC_COLUMNS (str[i]); return cols; #else /* not MULE */ @@ -2993,24 +3197,23 @@ emchar_string_displayed_columns (CONST Emchar *str, Charcount len) /* NOTE: Does not reset the Dynarr. */ void -convert_bufbyte_string_into_emchar_dynarr (CONST Bufbyte *str, Bytecount len, - Emchar_dynarr *dyn) +convert_bufbyte_string_into_charc_dynarr (const Bufbyte *str, Bytecount len, + Charc_dynarr *dyn) { - CONST Bufbyte *strend = str + len; + const Bufbyte *strend = str + len; while (str < strend) { - Emchar ch = charptr_emchar (str); - Dynarr_add (dyn, ch); + Dynarr_add (dyn, CHAR_TO_CHARC (charptr_emchar (str))); INC_CHARPTR (str); } } -int -convert_bufbyte_string_into_emchar_string (CONST Bufbyte *str, Bytecount len, +Charcount +convert_bufbyte_string_into_emchar_string (const Bufbyte *str, Bytecount len, Emchar *arr) { - CONST Bufbyte *strend = str + len; + const Bufbyte *strend = str + len; Charcount newlen = 0; while (str < strend) { @@ -3026,15 +3229,15 @@ convert_bufbyte_string_into_emchar_string (CONST Bufbyte *str, Bytecount len, Does not add a terminating zero. */ void -convert_emchar_string_into_bufbyte_dynarr (Emchar *arr, int nels, - Bufbyte_dynarr *dyn) +convert_charc_string_into_bufbyte_dynarr (Charc *arr, int nels, + Bufbyte_dynarr *dyn) { Bufbyte str[MAX_EMCHAR_LEN]; int i; for (i = 0; i < nels; i++) { - Bytecount len = set_charptr_emchar (str, arr[i]); + Bytecount len = set_charptr_emchar (str, CHARC_TO_CHAR (arr[i])); Dynarr_add_many (dyn, str, len); } } @@ -3046,7 +3249,7 @@ convert_emchar_string_into_bufbyte_dynarr (Emchar *arr, int nels, is one more than this: the returned string is zero-terminated. */ Bufbyte * -convert_emchar_string_into_malloced_string (Emchar *arr, int nels, +convert_charc_string_into_malloced_string (Charc *arr, int nels, Bytecount *len_out) { /* Damn zero-termination. */ @@ -3057,7 +3260,9 @@ convert_emchar_string_into_malloced_string (Emchar *arr, int nels, int i; for (i = 0; i < nels; i++) - str += set_charptr_emchar (str, arr[i]); + { + str += set_charptr_emchar (str, CHARC_TO_CHAR (arr[i])); + } *str = '\0'; len = str - strorig; str = (Bufbyte *) xmalloc (1 + len); @@ -3073,21 +3278,31 @@ convert_emchar_string_into_malloced_string (Emchar *arr, int nels, /************************************************************************/ void -vars_of_insdel (void) +reinit_vars_of_insdel (void) { +#ifndef UTF2000 int i; +#endif inside_change_hook = 0; in_first_change = 0; +#ifndef UTF2000 for (i = 0; i <= MAX_BYTIND_GAP_SIZE_3; i++) three_to_one_table[i] = i / 3; +#endif +} + +void +vars_of_insdel (void) +{ + reinit_vars_of_insdel (); } void -init_buffer_text (struct buffer *b, int indirect_p) +init_buffer_text (struct buffer *b) { - if (!indirect_p) + if (!b->base_buffer) { SET_BUF_GAP_SIZE (b, 20); BUFFER_ALLOC (b->text->beg, BUF_GAP_SIZE (b) + BUF_END_SENTINEL_SIZE); @@ -3105,8 +3320,12 @@ init_buffer_text (struct buffer *b, int indirect_p) b->text->mule_bufmin = b->text->mule_bufmax = 1; b->text->mule_bytmin = b->text->mule_bytmax = 1; +#ifdef UTF2000 + b->text->mule_size = 0; +#else b->text->mule_shifter = 0; b->text->mule_three_p = 0; +#endif for (i = 0; i < 16; i++) { @@ -3115,6 +3334,7 @@ init_buffer_text (struct buffer *b, int indirect_p) } } #endif /* MULE */ + b->text->line_number_cache = Qnil; BUF_MODIFF (b) = 1; BUF_SAVE_MODIFF (b) = 1; @@ -3145,9 +3365,9 @@ init_buffer_text (struct buffer *b, int indirect_p) } void -uninit_buffer_text (struct buffer *b, int indirect_p) +uninit_buffer_text (struct buffer *b) { - if (!indirect_p) + if (!b->base_buffer) { BUFFER_FREE (b->text->beg); xfree (b->text->changes);