From 20f5695598d3137257e24802479d003ea82eb5f9 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Sat, 19 Mar 2011 12:42:53 -0400 Subject: [PATCH] Backport fix for Bug#8219 from trunk. * buffer.h (BUF_BEGV, BUF_BEGV_BYTE, BUF_ZV, BUF_ZV_BYTE, BUF_PT) (BUF_PT_BYTE): Rewrite to handle indirect buffers (Bug#8219). These macros can no longer be used for assignment. * buffer.c (Fget_buffer_create, Fmake_indirect_buffer): Assign struct members directly, instead of using BUF_BEGV etc. (record_buffer_markers, fetch_buffer_markers): New functions for recording and fetching special buffer markers. (set_buffer_internal_1, set_buffer_temp): Use them. * lread.c (unreadchar): Use SET_BUF_PT_BOTH. * insdel.c (adjust_point): Use SET_BUF_PT_BOTH. * intervals.c (temp_set_point_both): Use SET_BUF_PT_BOTH. (get_local_map): Use SET_BUF_BEGV_BOTH and SET_BUF_ZV_BOTH. * xdisp.c (hscroll_window_tree): (reconsider_clip_changes): Use PT instead of BUF_PT. --- src/ChangeLog | 22 ++++++ src/buffer.c | 187 +++++++++++++++++++++--------------------------- src/buffer.h | 42 ++++++++--- src/insdel.c | 4 +- src/intervals.c | 16 ++--- src/lread.c | 6 +- src/xdisp.c | 4 +- 7 files changed, 148 insertions(+), 133 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 49b37a843b6..be81dd27584 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,25 @@ +2011-03-19 Chong Yidong + + * buffer.h (BUF_BEGV, BUF_BEGV_BYTE, BUF_ZV, BUF_ZV_BYTE, BUF_PT) + (BUF_PT_BYTE): Rewrite to handle indirect buffers (Bug#8219). + These macros can no longer be used for assignment. + + * buffer.c (Fget_buffer_create, Fmake_indirect_buffer): Assign + struct members directly, instead of using BUF_BEGV etc. + (record_buffer_markers, fetch_buffer_markers): New functions for + recording and fetching special buffer markers. + (set_buffer_internal_1, set_buffer_temp): Use them. + + * lread.c (unreadchar): Use SET_BUF_PT_BOTH. + + * insdel.c (adjust_point): Use SET_BUF_PT_BOTH. + + * intervals.c (temp_set_point_both): Use SET_BUF_PT_BOTH. + (get_local_map): Use SET_BUF_BEGV_BOTH and SET_BUF_ZV_BOTH. + + * xdisp.c (hscroll_window_tree): + (reconsider_clip_changes): Use PT instead of BUF_PT. + 2011-03-17 Juanma Barranquero * xfaces.c (Fx_load_color_file): diff --git a/src/buffer.c b/src/buffer.c index 9220527313d..e7759cb5255 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -371,15 +371,17 @@ even if it is dead. The return value is never nil. */) if (! BUF_BEG_ADDR (b)) buffer_memory_full (); - BUF_PT (b) = BEG; + b->pt = BEG; + b->begv = BEG; + b->zv = BEG; + b->pt_byte = BEG_BYTE; + b->begv_byte = BEG_BYTE; + b->zv_byte = BEG_BYTE; + BUF_GPT (b) = BEG; - BUF_BEGV (b) = BEG; - BUF_ZV (b) = BEG; - BUF_Z (b) = BEG; - BUF_PT_BYTE (b) = BEG_BYTE; BUF_GPT_BYTE (b) = BEG_BYTE; - BUF_BEGV_BYTE (b) = BEG_BYTE; - BUF_ZV_BYTE (b) = BEG_BYTE; + + BUF_Z (b) = BEG; BUF_Z_BYTE (b) = BEG_BYTE; BUF_MODIFF (b) = 1; BUF_CHARS_MODIFF (b) = 1; @@ -533,6 +535,53 @@ clone_per_buffer_values (from, to) to->local_var_alist = buffer_lisp_local_variables (from); } + +/* If buffer B has markers to record PT, BEGV and ZV when it is not + current, update these markers. */ + +static void +record_buffer_markers (struct buffer *b) +{ + if (! NILP (b->pt_marker)) + { + Lisp_Object buffer; + + eassert (!NILP (b->begv_marker)); + eassert (!NILP (b->zv_marker)); + + XSETBUFFER (buffer, b); + set_marker_both (b->pt_marker, buffer, b->pt, b->pt_byte); + set_marker_both (b->begv_marker, buffer, b->begv, b->begv_byte); + set_marker_both (b->zv_marker, buffer, b->zv, b->zv_byte); + } +} + + +/* If buffer B has markers to record PT, BEGV and ZV when it is not + current, fetch these values into B->begv etc. */ + +static void +fetch_buffer_markers (struct buffer *b) +{ + if (! NILP (b->pt_marker)) + { + Lisp_Object m; + + eassert (!NILP (b->begv_marker)); + eassert (!NILP (b->zv_marker)); + + m = b->pt_marker; + SET_BUF_PT_BOTH (b, marker_position (m), marker_byte_position (m)); + + m = b->begv_marker; + SET_BUF_BEGV_BOTH (b, marker_position (m), marker_byte_position (m)); + + m = b->zv_marker; + SET_BUF_ZV_BOTH (b, marker_position (m), marker_byte_position (m)); + } +} + + DEFUN ("make-indirect-buffer", Fmake_indirect_buffer, Smake_indirect_buffer, 2, 3, "bMake indirect buffer (to buffer): \nBName of indirect buffer: ", @@ -572,12 +621,12 @@ CLONE nil means the indirect buffer's state is reset to default values. */) /* Use the base buffer's text object. */ b->text = b->base_buffer->text; - BUF_BEGV (b) = BUF_BEGV (b->base_buffer); - BUF_ZV (b) = BUF_ZV (b->base_buffer); - BUF_PT (b) = BUF_PT (b->base_buffer); - BUF_BEGV_BYTE (b) = BUF_BEGV_BYTE (b->base_buffer); - BUF_ZV_BYTE (b) = BUF_ZV_BYTE (b->base_buffer); - BUF_PT_BYTE (b) = BUF_PT_BYTE (b->base_buffer); + b->pt = b->base_buffer->pt; + b->begv = b->base_buffer->begv; + b->zv = b->base_buffer->zv; + b->pt_byte = b->base_buffer->pt_byte; + b->begv_byte = b->base_buffer->begv_byte; + b->zv_byte = b->base_buffer->zv_byte; b->newline_cache = 0; b->width_run_cache = 0; @@ -607,24 +656,23 @@ CLONE nil means the indirect buffer's state is reset to default values. */) /* Make sure the base buffer has markers for its narrowing. */ if (NILP (b->base_buffer->pt_marker)) { + eassert (NILP (b->base_buffer->begv_marker)); + eassert (NILP (b->base_buffer->zv_marker)); + b->base_buffer->pt_marker = Fmake_marker (); set_marker_both (b->base_buffer->pt_marker, base_buffer, - BUF_PT (b->base_buffer), - BUF_PT_BYTE (b->base_buffer)); - } - if (NILP (b->base_buffer->begv_marker)) - { + b->base_buffer->pt, + b->base_buffer->pt_byte); + b->base_buffer->begv_marker = Fmake_marker (); set_marker_both (b->base_buffer->begv_marker, base_buffer, - BUF_BEGV (b->base_buffer), - BUF_BEGV_BYTE (b->base_buffer)); - } - if (NILP (b->base_buffer->zv_marker)) - { + b->base_buffer->begv, + b->base_buffer->begv_byte); + b->base_buffer->zv_marker = Fmake_marker (); set_marker_both (b->base_buffer->zv_marker, base_buffer, - BUF_ZV (b->base_buffer), - BUF_ZV_BYTE (b->base_buffer)); + b->base_buffer->zv, + b->base_buffer->zv_byte); XMARKER (b->base_buffer->zv_marker)->insertion_type = 1; } @@ -632,11 +680,11 @@ CLONE nil means the indirect buffer's state is reset to default values. */) { /* Give the indirect buffer markers for its narrowing. */ b->pt_marker = Fmake_marker (); - set_marker_both (b->pt_marker, buf, BUF_PT (b), BUF_PT_BYTE (b)); + set_marker_both (b->pt_marker, buf, b->pt, b->pt_byte); b->begv_marker = Fmake_marker (); - set_marker_both (b->begv_marker, buf, BUF_BEGV (b), BUF_BEGV_BYTE (b)); + set_marker_both (b->begv_marker, buf, b->begv, b->begv_byte); b->zv_marker = Fmake_marker (); - set_marker_both (b->zv_marker, buf, BUF_ZV (b), BUF_ZV_BYTE (b)); + set_marker_both (b->zv_marker, buf, b->zv, b->zv_byte); XMARKER (b->zv_marker)->insertion_type = 1; } else @@ -1890,27 +1938,7 @@ set_buffer_internal_1 (b) /* If the old current buffer has markers to record PT, BEGV and ZV when it is not current, update them now. */ - if (! NILP (old_buf->pt_marker)) - { - Lisp_Object obuf; - XSETBUFFER (obuf, old_buf); - set_marker_both (old_buf->pt_marker, obuf, - BUF_PT (old_buf), BUF_PT_BYTE (old_buf)); - } - if (! NILP (old_buf->begv_marker)) - { - Lisp_Object obuf; - XSETBUFFER (obuf, old_buf); - set_marker_both (old_buf->begv_marker, obuf, - BUF_BEGV (old_buf), BUF_BEGV_BYTE (old_buf)); - } - if (! NILP (old_buf->zv_marker)) - { - Lisp_Object obuf; - XSETBUFFER (obuf, old_buf); - set_marker_both (old_buf->zv_marker, obuf, - BUF_ZV (old_buf), BUF_ZV_BYTE (old_buf)); - } + record_buffer_markers (old_buf); } /* Get the undo list from the base buffer, so that it appears @@ -1920,21 +1948,7 @@ set_buffer_internal_1 (b) /* If the new current buffer has markers to record PT, BEGV and ZV when it is not current, fetch them now. */ - if (! NILP (b->pt_marker)) - { - BUF_PT (b) = marker_position (b->pt_marker); - BUF_PT_BYTE (b) = marker_byte_position (b->pt_marker); - } - if (! NILP (b->begv_marker)) - { - BUF_BEGV (b) = marker_position (b->begv_marker); - BUF_BEGV_BYTE (b) = marker_byte_position (b->begv_marker); - } - if (! NILP (b->zv_marker)) - { - BUF_ZV (b) = marker_position (b->zv_marker); - BUF_ZV_BYTE (b) = marker_byte_position (b->zv_marker); - } + fetch_buffer_markers (b); /* Look down buffer's list of local Lisp variables to find and update any that forward into C variables. */ @@ -1984,50 +1998,13 @@ set_buffer_temp (b) old_buf = current_buffer; current_buffer = b; - if (old_buf) - { - /* If the old current buffer has markers to record PT, BEGV and ZV - when it is not current, update them now. */ - if (! NILP (old_buf->pt_marker)) - { - Lisp_Object obuf; - XSETBUFFER (obuf, old_buf); - set_marker_both (old_buf->pt_marker, obuf, - BUF_PT (old_buf), BUF_PT_BYTE (old_buf)); - } - if (! NILP (old_buf->begv_marker)) - { - Lisp_Object obuf; - XSETBUFFER (obuf, old_buf); - set_marker_both (old_buf->begv_marker, obuf, - BUF_BEGV (old_buf), BUF_BEGV_BYTE (old_buf)); - } - if (! NILP (old_buf->zv_marker)) - { - Lisp_Object obuf; - XSETBUFFER (obuf, old_buf); - set_marker_both (old_buf->zv_marker, obuf, - BUF_ZV (old_buf), BUF_ZV_BYTE (old_buf)); - } - } + /* If the old current buffer has markers to record PT, BEGV and ZV + when it is not current, update them now. */ + record_buffer_markers (old_buf); /* If the new current buffer has markers to record PT, BEGV and ZV when it is not current, fetch them now. */ - if (! NILP (b->pt_marker)) - { - BUF_PT (b) = marker_position (b->pt_marker); - BUF_PT_BYTE (b) = marker_byte_position (b->pt_marker); - } - if (! NILP (b->begv_marker)) - { - BUF_BEGV (b) = marker_position (b->begv_marker); - BUF_BEGV_BYTE (b) = marker_byte_position (b->begv_marker); - } - if (! NILP (b->zv_marker)) - { - BUF_ZV (b) = marker_position (b->zv_marker); - BUF_ZV_BYTE (b) = marker_byte_position (b->zv_marker); - } + fetch_buffer_markers (b); } DEFUN ("set-buffer", Fset_buffer, Sset_buffer, 1, 1, 0, diff --git a/src/buffer.h b/src/buffer.h index 21854571670..56d0422b7e3 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -107,22 +107,46 @@ along with GNU Emacs. If not, see . */ #define BUF_BEG(buf) (BEG) #define BUF_BEG_BYTE(buf) (BEG_BYTE) +/* The BUF_BEGV[_BYTE], BUF_ZV[_BYTE], and BUF_PT[_BYTE] macros cannot + be used for assignment; use SET_BUF_* macros below for that. */ + /* Position of beginning of accessible range of buffer. */ -#define BUF_BEGV(buf) ((buf)->begv) -#define BUF_BEGV_BYTE(buf) ((buf)->begv_byte) +#define BUF_BEGV(buf) \ + (buf == current_buffer ? BEGV \ + : NILP (buf->begv_marker) ? buf->begv \ + : marker_position (buf->begv_marker)) + +#define BUF_BEGV_BYTE(buf) \ + (buf == current_buffer ? BEGV_BYTE \ + : NILP (buf->begv_marker) ? buf->begv_byte \ + : marker_byte_position (buf->begv_marker)) /* Position of point in buffer. */ -#define BUF_PT(buf) ((buf)->pt) -#define BUF_PT_BYTE(buf) ((buf)->pt_byte) +#define BUF_PT(buf) \ + (buf == current_buffer ? PT \ + : NILP (buf->pt_marker) ? buf->pt \ + : marker_position (buf->pt_marker)) + +#define BUF_PT_BYTE(buf) \ + (buf == current_buffer ? PT_BYTE \ + : NILP (buf->pt_marker) ? buf->pt_byte \ + : marker_byte_position (buf->pt_marker)) + +/* Position of end of accessible range of buffer. */ +#define BUF_ZV(buf) \ + (buf == current_buffer ? ZV \ + : NILP (buf->zv_marker) ? buf->zv \ + : marker_position (buf->zv_marker)) + +#define BUF_ZV_BYTE(buf) \ + (buf == current_buffer ? ZV_BYTE \ + : NILP (buf->zv_marker) ? buf->zv_byte \ + : marker_byte_position (buf->zv_marker)) /* Position of gap in buffer. */ #define BUF_GPT(buf) ((buf)->text->gpt) #define BUF_GPT_BYTE(buf) ((buf)->text->gpt_byte) -/* Position of end of accessible range of buffer. */ -#define BUF_ZV(buf) ((buf)->zv) -#define BUF_ZV_BYTE(buf) ((buf)->zv_byte) - /* Position of end of buffer. */ #define BUF_Z(buf) ((buf)->text->z) #define BUF_Z_BYTE(buf) ((buf)->text->z_byte) @@ -230,8 +254,6 @@ extern void enlarge_buffer_text P_ ((struct buffer *, EMACS_INT)); /* Macros for setting the BEGV, ZV or PT of a given buffer. - SET_BUF_PT* seet to be redundant. Get rid of them? - The ..._BOTH macros take both a charpos and a bytepos, which must correspond to each other. diff --git a/src/insdel.c b/src/insdel.c index 7e0ba797fa8..b76a2d2271a 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -459,9 +459,7 @@ adjust_markers_for_insert (EMACS_INT from, EMACS_INT from_byte, static void adjust_point (EMACS_INT nchars, EMACS_INT nbytes) { - BUF_PT (current_buffer) += nchars; - BUF_PT_BYTE (current_buffer) += nbytes; - + SET_BUF_PT_BOTH (current_buffer, PT + nchars, PT_BYTE + nbytes); /* In a single-byte buffer, the two positions must be equal. */ eassert (PT_BYTE >= PT && PT_BYTE - PT <= ZV_BYTE - ZV); } diff --git a/src/intervals.c b/src/intervals.c index d47888b237c..fd8f3f55479 100644 --- a/src/intervals.c +++ b/src/intervals.c @@ -1949,8 +1949,7 @@ temp_set_point_both (struct buffer *buffer, if (charpos > BUF_ZV (buffer) || charpos < BUF_BEGV (buffer)) abort (); - BUF_PT_BYTE (buffer) = bytepos; - BUF_PT (buffer) = charpos; + SET_BUF_PT_BOTH (buffer, charpos, bytepos); } /* Set point in BUFFER to CHARPOS. If the target position is @@ -2366,10 +2365,9 @@ get_local_map (position, buffer, type) old_zv = BUF_ZV (buffer); old_begv_byte = BUF_BEGV_BYTE (buffer); old_zv_byte = BUF_ZV_BYTE (buffer); - BUF_BEGV (buffer) = BUF_BEG (buffer); - BUF_ZV (buffer) = BUF_Z (buffer); - BUF_BEGV_BYTE (buffer) = BUF_BEG_BYTE (buffer); - BUF_ZV_BYTE (buffer) = BUF_Z_BYTE (buffer); + + SET_BUF_BEGV_BOTH (buffer, BUF_BEG (buffer), BUF_BEG_BYTE (buffer)); + SET_BUF_ZV_BOTH (buffer, BUF_Z (buffer), BUF_Z_BYTE (buffer)); XSETFASTINT (lispy_position, position); XSETBUFFER (lispy_buffer, buffer); @@ -2383,10 +2381,8 @@ get_local_map (position, buffer, type) if (NILP (prop)) prop = get_pos_property (lispy_position, type, lispy_buffer); - BUF_BEGV (buffer) = old_begv; - BUF_ZV (buffer) = old_zv; - BUF_BEGV_BYTE (buffer) = old_begv_byte; - BUF_ZV_BYTE (buffer) = old_zv_byte; + SET_BUF_BEGV_BOTH (buffer, old_begv, old_begv_byte); + SET_BUF_ZV_BOTH (buffer, old_zv, old_zv_byte); /* Use the local map only if it is valid. */ prop = get_keymap (prop, 0, 0); diff --git a/src/lread.c b/src/lread.c index 8f1d4af8f36..2da64632417 100644 --- a/src/lread.c +++ b/src/lread.c @@ -458,15 +458,15 @@ unreadchar (readcharfun, c) else if (BUFFERP (readcharfun)) { struct buffer *b = XBUFFER (readcharfun); - int bytepos = BUF_PT_BYTE (b); + EMACS_INT charpos = BUF_PT (b); + EMACS_INT bytepos = BUF_PT_BYTE (b); - BUF_PT (b)--; if (! NILP (b->enable_multibyte_characters)) BUF_DEC_POS (b, bytepos); else bytepos--; - BUF_PT_BYTE (b) = bytepos; + SET_BUF_PT_BOTH (b, charpos - 1, bytepos); } else if (MARKERP (readcharfun)) { diff --git a/src/xdisp.c b/src/xdisp.c index c2af4d68b6e..ade95cf3d62 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10760,7 +10760,7 @@ hscroll_window_tree (window) current_buffer = XBUFFER (w->buffer); if (w == XWINDOW (selected_window)) - pt = BUF_PT (current_buffer); + pt = PT; else { pt = marker_position (w->pointm); @@ -11194,7 +11194,7 @@ reconsider_clip_changes (w, b) int pt; if (w == XWINDOW (selected_window)) - pt = BUF_PT (current_buffer); + pt = PT; else pt = marker_position (w->pointm); -- 2.39.2