/* 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.
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. */
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) \
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;
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;
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;
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;
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) \
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; \
+ } \
} \
}
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;
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;
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;
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;
}
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)
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;
}
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)
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)
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)
{
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 ();
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;
+
}