emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 32cf078: * src/marker.c (buf_bytepos_to_charpos): R


From: Stefan Monnier
Subject: [Emacs-diffs] master 32cf078: * src/marker.c (buf_bytepos_to_charpos): Re-add the CHAR_HEAD_P assertion
Date: Tue, 7 May 2019 13:41:59 -0400 (EDT)

branch: master
commit 32cf07819ae8cfdbf14e00f351c7f520fff325c3
Author: Stefan Monnier <address@hidden>
Commit: Stefan Monnier <address@hidden>

    * src/marker.c (buf_bytepos_to_charpos): Re-add the CHAR_HEAD_P assertion
    
    This assertion was removed in 1c349c62305d432abf0fa2b6e3f5d754fe4cab79
    because the assumption was invalid during set_intervals_multibyte_1.
    So we change set_intervals_multibyte_1 to solve the problem in the same
    way as in the rest of Fset_buffer_multibyte, which actually simplifies
    the code.
    
    * src/buffer.c (advance_to_char_boundary): Not static any more.
    * src/buffer.h (advance_to_char_boundary): Add prototype.
    * src/intervals.c (set_intervals_multibyte_1): Use it.
---
 src/buffer.c    |  5 ++++-
 src/buffer.h    |  4 ++++
 src/intervals.c | 36 ++++++------------------------------
 src/marker.c    |  4 ++++
 4 files changed, 18 insertions(+), 31 deletions(-)

diff --git a/src/buffer.c b/src/buffer.c
index ab47748..3b5078a 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -2264,7 +2264,7 @@ validate_region (register Lisp_Object *b, register 
Lisp_Object *e)
 /* Advance BYTE_POS up to a character boundary
    and return the adjusted position.  */
 
-static ptrdiff_t
+ptrdiff_t
 advance_to_char_boundary (ptrdiff_t byte_pos)
 {
   int c;
@@ -2702,6 +2702,9 @@ current buffer is cleared.  */)
 
       /* Do this last, so it can calculate the new correspondences
         between chars and bytes.  */
+      /* FIXME: Is it worth the trouble, really?  Couldn't we just throw
+         away all the text-properties instead of trying to guess how
+         to adjust them?  AFAICT the result is not reliable anyway.  */
       set_intervals_multibyte (1);
     }
 
diff --git a/src/buffer.h b/src/buffer.h
index f42c3e9..2080a6f 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -327,6 +327,10 @@ extern void enlarge_buffer_text (struct buffer *, 
ptrdiff_t);
 #define BYTE_TO_CHAR(bytepos)                  \
   (buf_bytepos_to_charpos (current_buffer, bytepos))
 
+/* For those very rare cases where you may have a "random" pointer into
+   the middle of a multibyte char, this moves to the next boundary.  */
+extern ptrdiff_t advance_to_char_boundary (ptrdiff_t byte_pos);
+
 /* Convert PTR, the address of a byte in the buffer, into a byte position.  */
 
 #define PTR_BYTE_POS(ptr) \
diff --git a/src/intervals.c b/src/intervals.c
index 8f39c45..34829ab 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -2335,22 +2335,10 @@ set_intervals_multibyte_1 (INTERVAL i, bool multi_flag,
       if (multi_flag)
        {
          ptrdiff_t temp;
-         left_end_byte = start_byte + LEFT_TOTAL_LENGTH (i);
+         left_end_byte
+            = advance_to_char_boundary (start_byte + LEFT_TOTAL_LENGTH (i));
          left_end = BYTE_TO_CHAR (left_end_byte);
-
-         temp = CHAR_TO_BYTE (left_end);
-
-         /* If LEFT_END_BYTE is in the middle of a character,
-            adjust it and LEFT_END to a char boundary.  */
-         if (left_end_byte > temp)
-           {
-             left_end_byte = temp;
-           }
-         if (left_end_byte < temp)
-           {
-             left_end--;
-             left_end_byte = CHAR_TO_BYTE (left_end);
-           }
+         eassert (CHAR_TO_BYTE (left_end) == left_end_byte);
        }
       else
        {
@@ -2369,22 +2357,10 @@ set_intervals_multibyte_1 (INTERVAL i, bool multi_flag,
        {
          ptrdiff_t temp;
 
-         right_start_byte = end_byte - RIGHT_TOTAL_LENGTH (i);
+         right_start_byte
+            = advance_to_char_boundary (end_byte - RIGHT_TOTAL_LENGTH (i));
          right_start = BYTE_TO_CHAR (right_start_byte);
-
-         /* If RIGHT_START_BYTE is in the middle of a character,
-            adjust it and RIGHT_START to a char boundary.  */
-         temp = CHAR_TO_BYTE (right_start);
-
-         if (right_start_byte < temp)
-           {
-             right_start_byte = temp;
-           }
-         if (right_start_byte > temp)
-           {
-             right_start++;
-             right_start_byte = CHAR_TO_BYTE (right_start);
-           }
+         eassert (CHAR_TO_BYTE (right_start) == right_start_byte);
        }
       else
        {
diff --git a/src/marker.c b/src/marker.c
index b58051a..0b2e1bf 100644
--- a/src/marker.c
+++ b/src/marker.c
@@ -332,6 +332,10 @@ buf_bytepos_to_charpos (struct buffer *b, ptrdiff_t 
bytepos)
   if (best_above == best_above_byte)
     return bytepos;
 
+  /* Check bytepos is not in the middle of a character. */
+  eassert (bytepos >= BUF_Z_BYTE (b)
+           || CHAR_HEAD_P (BUF_FETCH_BYTE (b, bytepos)));
+
   best_below = BEG;
   best_below_byte = BEG_BYTE;
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]