(fix_submap_inheritance, get_keyelt, store_in_keymap,
[bpt/emacs.git] / src / marker.c
index 2bccb74..86951ed 100644 (file)
@@ -1,5 +1,5 @@
 /* Markers: examining, setting and deleting.
-   Copyright (C) 1985, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1985, 1997, 1998 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -31,6 +31,17 @@ static int cached_charpos;
 static int cached_bytepos;
 static struct buffer *cached_buffer;
 static int cached_modiff;
+
+/* Nonzero means enable debugging checks on byte/char correspondences.  */
+
+static int byte_debug_flag;
+
+clear_charpos_cache (b)
+     struct buffer *b;
+{
+  if (cached_buffer == b)
+    cached_buffer = 0;
+}
 \f
 /* Converting between character positions and byte positions.  */
 
@@ -51,7 +62,12 @@ static int cached_modiff;
   int changed = 0;                                                     \
                                                                        \
   if (this_charpos == charpos)                                         \
-    return (BYTEPOS);                                                  \
+    {                                                                  \
+      int value = (BYTEPOS);                                           \
+      if (byte_debug_flag)                                             \
+       byte_char_debug_check (b, charpos, value);                      \
+      return value;                                                    \
+    }                                                                  \
   else if (this_charpos > charpos)                                     \
     {                                                                  \
       if (this_charpos < best_above)                                   \
@@ -71,10 +87,37 @@ static int cached_modiff;
   if (changed)                                                         \
     {                                                                  \
       if (best_above - best_below == best_above_byte - best_below_byte)        \
-       return best_below_byte + (charpos - best_below);                \
+        {                                                              \
+         int value = best_below_byte + (charpos - best_below);         \
+         if (byte_debug_flag)                                          \
+           byte_char_debug_check (b, charpos, value);                  \
+         return value;                                                 \
+       }                                                               \
     }                                                                  \
 }
 
+int
+byte_char_debug_check (b, charpos, bytepos)
+     struct buffer *b;
+     int charpos, bytepos;
+{
+  int nchars = 0;
+
+  if (bytepos > BUF_GPT_BYTE (b))
+    {
+      nchars = multibyte_chars_in_text (BUF_BEG_ADDR (b),
+                                       BUF_GPT_BYTE (b) - BUF_BEG_BYTE (b));
+      nchars += multibyte_chars_in_text (BUF_GAP_END_ADDR (b),
+                                        bytepos - BUF_GPT_BYTE (b));
+    }
+  else
+    nchars = multibyte_chars_in_text (BUF_BEG_ADDR (b),
+                                     bytepos - BUF_BEG_BYTE (b));
+
+  if (charpos - 1 != nchars)
+    abort ();
+}
+
 int
 charpos_to_bytepos (charpos)
      int charpos;
@@ -127,11 +170,7 @@ buf_charpos_to_bytepos (b, charpos)
   tail = BUF_MARKERS (b);
   while (XSYMBOL (tail) != XSYMBOL (Qnil))
     {
-      int i = XMARKER (tail)->bufpos;
-      CONSIDER (XMARKER (tail)->charpos,
-               (i > gapend_byte ? i - BUF_GAP_SIZE (b)
-                : i > BUF_GPT_BYTE (b) ? BUF_GPT_BYTE (b)
-                : i));
+      CONSIDER (XMARKER (tail)->charpos, XMARKER (tail)->bytepos);
 
       /* If we are down to a range of 50 chars,
         don't bother checking any other markers;
@@ -166,6 +205,9 @@ buf_charpos_to_bytepos (b, charpos)
          set_marker_both (marker, Qnil, best_below, best_below_byte);
        }
 
+      if (byte_debug_flag)
+       byte_char_debug_check (b, charpos, best_below_byte);
+
       cached_buffer = b;
       cached_modiff = BUF_MODIFF (b);
       cached_charpos = best_below;
@@ -193,6 +235,9 @@ buf_charpos_to_bytepos (b, charpos)
          set_marker_both (marker, Qnil, best_above, best_above_byte);
        }
 
+      if (byte_debug_flag)
+       byte_char_debug_check (b, charpos, best_above_byte);
+
       cached_buffer = b;
       cached_modiff = BUF_MODIFF (b);
       cached_charpos = best_above;
@@ -215,7 +260,12 @@ buf_charpos_to_bytepos (b, charpos)
   int changed = 0;                                                     \
                                                                        \
   if (this_bytepos == bytepos)                                         \
-    return (CHARPOS);                                                  \
+    {                                                                  \
+      int value = (CHARPOS);                                           \
+      if (byte_debug_flag)                                             \
+       byte_char_debug_check (b, value, bytepos);                      \
+      return value;                                                    \
+    }                                                                  \
   else if (this_bytepos > bytepos)                                     \
     {                                                                  \
       if (this_bytepos < best_above_byte)                              \
@@ -235,7 +285,12 @@ buf_charpos_to_bytepos (b, charpos)
   if (changed)                                                         \
     {                                                                  \
       if (best_above - best_below == best_above_byte - best_below_byte)        \
-       return best_below + (bytepos - best_below_byte);                \
+       {                                                               \
+         int value = best_below + (bytepos - best_below_byte);         \
+         if (byte_debug_flag)                                          \
+           byte_char_debug_check (b, value, bytepos);                  \
+         return value;                                                 \
+       }                                                               \
     }                                                                  \
 }
 
@@ -281,14 +336,7 @@ buf_bytepos_to_charpos (b, bytepos)
   tail = BUF_MARKERS (b);
   while (XSYMBOL (tail) != XSYMBOL (Qnil))
     {
-      int marker_bytepos = XMARKER (tail)->bufpos;
-
-      if (marker_bytepos > BUF_GPT_BYTE (b) + BUF_GAP_SIZE (b))
-       marker_bytepos -= BUF_GAP_SIZE (b);
-      else if (marker_bytepos > BUF_GPT_BYTE (b))
-       marker_bytepos = BUF_GPT_BYTE (b);
-
-      CONSIDER (marker_bytepos, XMARKER (tail)->charpos);
+      CONSIDER (XMARKER (tail)->bytepos, XMARKER (tail)->charpos);
 
       /* If we are down to a range of 50 chars,
         don't bother checking any other markers;
@@ -323,6 +371,9 @@ buf_bytepos_to_charpos (b, bytepos)
          set_marker_both (marker, Qnil, best_below, best_below_byte);
        }
 
+      if (byte_debug_flag)
+       byte_char_debug_check (b, best_below, bytepos);
+
       cached_buffer = b;
       cached_modiff = BUF_MODIFF (b);
       cached_charpos = best_below;
@@ -350,6 +401,9 @@ buf_bytepos_to_charpos (b, bytepos)
          set_marker_both (marker, Qnil, best_above, best_above_byte);
        }
 
+      if (byte_debug_flag)
+       byte_char_debug_check (b, best_above, bytepos);
+
       cached_buffer = b;
       cached_modiff = BUF_MODIFF (b);
       cached_charpos = best_above;
@@ -441,7 +495,7 @@ Returns MARKER.")
   if (MARKERP (position) && b == XMARKER (position)->buffer
       && b == m->buffer)
     {
-      m->bufpos = XMARKER (position)->bufpos;
+      m->bytepos = XMARKER (position)->bytepos;
       m->charpos = XMARKER (position)->charpos;
       return marker;
     }
@@ -461,10 +515,7 @@ Returns MARKER.")
   if (charno > bytepos)
     abort ();
 
-  if (bytepos > BUF_GPT_BYTE (b))
-    bytepos += BUF_GAP_SIZE (b);
-
-  m->bufpos = bytepos;
+  m->bytepos = bytepos;
   m->charpos = charno;
 
   if (m->buffer != b)
@@ -520,7 +571,7 @@ set_marker_restricted (marker, pos, buffer)
   if (MARKERP (pos) && b == XMARKER (pos)->buffer
       && b == m->buffer)
     {
-      m->bufpos = XMARKER (pos)->bufpos;
+      m->bytepos = XMARKER (pos)->bytepos;
       m->charpos = XMARKER (pos)->charpos;
       return marker;
     }
@@ -540,10 +591,7 @@ set_marker_restricted (marker, pos, buffer)
   if (charno > bytepos)
     abort ();
 
-  if (bytepos > BUF_GPT_BYTE (b))
-    bytepos += BUF_GAP_SIZE (b);
-
-  m->bufpos = bytepos;
+  m->bytepos = bytepos;
   m->charpos = charno;
 
   if (m->buffer != b)
@@ -603,10 +651,7 @@ set_marker_both (marker, buffer, charpos, bytepos)
   if (charpos > bytepos)
     abort ();
 
-  if (bytepos > BUF_GPT_BYTE (b))
-    bytepos += BUF_GAP_SIZE (b);
-
-  m->bufpos = bytepos;
+  m->bytepos = bytepos;
   m->charpos = charpos;
 
   if (m->buffer != b)
@@ -666,10 +711,7 @@ set_marker_restricted_both (marker, buffer, charpos, bytepos)
   if (charpos > bytepos)
     abort ();
 
-  if (bytepos > BUF_GPT_BYTE (b))
-    bytepos += BUF_GAP_SIZE (b);
-
-  m->bufpos = bytepos;
+  m->bytepos = bytepos;
   m->charpos = charpos;
 
   if (m->buffer != b)
@@ -759,16 +801,11 @@ marker_byte_position (marker)
 {
   register struct Lisp_Marker *m = XMARKER (marker);
   register struct buffer *buf = m->buffer;
-  register int i = m->bufpos;
+  register int i = m->bytepos;
 
   if (!buf)
     error ("Marker does not point anywhere");
 
-  if (i > BUF_GPT_BYTE (buf) + BUF_GAP_SIZE (buf))
-    i -= BUF_GAP_SIZE (buf);
-  else if (i > BUF_GPT_BYTE (buf))
-    i = BUF_GPT_BYTE (buf);
-
   if (i < BUF_BEG_BYTE (buf) || i > BUF_Z_BYTE (buf))
     abort ();
 
@@ -859,4 +896,9 @@ syms_of_marker ()
   defsubr (&Smarker_insertion_type);
   defsubr (&Sset_marker_insertion_type);
   defsubr (&Sbuffer_has_markers_at);
+
+  DEFVAR_BOOL ("byte-debug-flag", &byte_debug_flag,
+   "Non-nil enables debugging checks in byte/char position conversions.");
+  byte_debug_flag = 0;
+
 }