From: Eli Zaretskii Date: Mon, 18 Nov 2013 16:29:49 +0000 (+0200) Subject: Fix bug #15841 with assertion violations due to newline cache. X-Git-Tag: emacs-24.3.90~173^2^2~42^2~45^2~387^2~793 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=37c790b38599cc80a16c6a76152abbf8160fe2a1;p=emacs.git Fix bug #15841 with assertion violations due to newline cache. src/insdel.c (invalidate_buffer_caches): New function, consolidated from part of prepare_to_modify_buffer. (insert_from_gap, prepare_to_modify_buffer): src/coding.c (code_convert_region, code_convert_string): Call invalidate_buffer_caches. src/lisp.h (invalidate_buffer_caches): Add prototype. --- diff --git a/src/ChangeLog b/src/ChangeLog index 2b88d076b8c..a2dfa5bf613 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,13 @@ +2013-11-18 Eli Zaretskii + + * insdel.c (invalidate_buffer_caches): New function, consolidated + from part of prepare_to_modify_buffer. + (insert_from_gap, prepare_to_modify_buffer): + * coding.c (code_convert_region, code_convert_string): Call + invalidate_buffer_caches. (Bug#15841) + + * lisp.h (invalidate_buffer_caches): Add prototype. + 2013-11-17 Eli Zaretskii * w32term.c (x_update_window_end): Don't invalidate the entire diff --git a/src/coding.c b/src/coding.c index ac828a48683..6c0633f2d93 100644 --- a/src/coding.c +++ b/src/coding.c @@ -9358,6 +9358,14 @@ code_convert_region (Lisp_Object start, Lisp_Object end, setup_coding_system (coding_system, &coding); coding.mode |= CODING_MODE_LAST_BLOCK; + if (BUFFERP (dst_object) && !EQ (dst_object, src_object)) + { + struct buffer *buf = XBUFFER (dst_object); + ptrdiff_t buf_pt = BUF_PT (buf); + + invalidate_buffer_caches (buf, buf_pt, buf_pt); + } + if (encodep) encode_coding_object (&coding, src_object, from, from_byte, to, to_byte, dst_object); @@ -9447,6 +9455,15 @@ code_convert_string (Lisp_Object string, Lisp_Object coding_system, coding.mode |= CODING_MODE_LAST_BLOCK; chars = SCHARS (string); bytes = SBYTES (string); + + if (BUFFERP (dst_object)) + { + struct buffer *buf = XBUFFER (dst_object); + ptrdiff_t buf_pt = BUF_PT (buf); + + invalidate_buffer_caches (buf, buf_pt, buf_pt); + } + if (encodep) encode_coding_object (&coding, string, 0, 0, chars, bytes, dst_object); else diff --git a/src/insdel.c b/src/insdel.c index 5515b641d66..8de4f095396 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -993,6 +993,11 @@ insert_from_gap (ptrdiff_t nchars, ptrdiff_t nbytes, bool text_at_gap_tail) if (NILP (BVAR (current_buffer, enable_multibyte_characters))) nchars = nbytes; + /* No need to call prepare_to_modify_buffer, since this is called + from places that replace some region with a different text, so + prepare_to_modify_buffer was already called by the deletion part + of this dance. */ + invalidate_buffer_caches (current_buffer, GPT, GPT); record_insert (GPT, nchars); MODIFF++; @@ -1869,19 +1874,26 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end, ptrdiff_t *preserve_ptr) { prepare_to_modify_buffer_1 (start, end, preserve_ptr); + invalidate_buffer_caches (current_buffer, start, end); +} - if (current_buffer->newline_cache) - invalidate_region_cache (current_buffer, - current_buffer->newline_cache, - start - BEG, Z - end); - if (current_buffer->width_run_cache) - invalidate_region_cache (current_buffer, - current_buffer->width_run_cache, - start - BEG, Z - end); - if (current_buffer->bidi_paragraph_cache) - invalidate_region_cache (current_buffer, - current_buffer->bidi_paragraph_cache, - start - BEG, Z - end); +/* Invalidate the caches maintained by the buffer BUF, if any, for the + region between buffer positions START and END. */ +void +invalidate_buffer_caches (struct buffer *buf, ptrdiff_t start, ptrdiff_t end) +{ + if (buf->newline_cache) + invalidate_region_cache (buf, + buf->newline_cache, + start - BUF_BEG (buf), BUF_Z (buf) - end); + if (buf->width_run_cache) + invalidate_region_cache (buf, + buf->width_run_cache, + start - BUF_BEG (buf), BUF_Z (buf) - end); + if (buf->bidi_paragraph_cache) + invalidate_region_cache (buf, + buf->bidi_paragraph_cache, + start - BUF_BEG (buf), BUF_Z (buf) - end); } /* These macros work with an argument named `preserve_ptr' diff --git a/src/lisp.h b/src/lisp.h index 926b83d7ce0..a5aec41be38 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3479,6 +3479,7 @@ extern Lisp_Object del_range_2 (ptrdiff_t, ptrdiff_t, extern void modify_text (ptrdiff_t, ptrdiff_t); extern void prepare_to_modify_buffer (ptrdiff_t, ptrdiff_t, ptrdiff_t *); extern void prepare_to_modify_buffer_1 (ptrdiff_t, ptrdiff_t, ptrdiff_t *); +extern void invalidate_buffer_caches (struct buffer *, ptrdiff_t, ptrdiff_t); extern void signal_after_change (ptrdiff_t, ptrdiff_t, ptrdiff_t); extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t);