Avoid code repetition in marker-related functions.
[emacs.git] / src / marker.c
blob47a3e85e5829e0c9edeabe56c75eeab4fa15d164
1 /* Markers: examining, setting and deleting.
2 Copyright (C) 1985, 1997-1998, 2001-2012 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 #include <config.h>
21 #include <setjmp.h>
22 #include "lisp.h"
23 #include "character.h"
24 #include "buffer.h"
26 /* Record one cached position found recently by
27 buf_charpos_to_bytepos or buf_bytepos_to_charpos. */
29 static ptrdiff_t cached_charpos;
30 static ptrdiff_t cached_bytepos;
31 static struct buffer *cached_buffer;
32 static int cached_modiff;
34 static void byte_char_debug_check (struct buffer *, ptrdiff_t, ptrdiff_t);
36 void
37 clear_charpos_cache (struct buffer *b)
39 if (cached_buffer == b)
40 cached_buffer = 0;
43 /* Converting between character positions and byte positions. */
45 /* There are several places in the buffer where we know
46 the correspondence: BEG, BEGV, PT, GPT, ZV and Z,
47 and everywhere there is a marker. So we find the one of these places
48 that is closest to the specified position, and scan from there. */
50 /* charpos_to_bytepos returns the byte position corresponding to CHARPOS. */
52 /* This macro is a subroutine of charpos_to_bytepos.
53 Note that it is desirable that BYTEPOS is not evaluated
54 except when we really want its value. */
56 #define CONSIDER(CHARPOS, BYTEPOS) \
57 { \
58 ptrdiff_t this_charpos = (CHARPOS); \
59 int changed = 0; \
61 if (this_charpos == charpos) \
62 { \
63 ptrdiff_t value = (BYTEPOS); \
64 if (byte_debug_flag) \
65 byte_char_debug_check (b, charpos, value); \
66 return value; \
67 } \
68 else if (this_charpos > charpos) \
69 { \
70 if (this_charpos < best_above) \
71 { \
72 best_above = this_charpos; \
73 best_above_byte = (BYTEPOS); \
74 changed = 1; \
75 } \
76 } \
77 else if (this_charpos > best_below) \
78 { \
79 best_below = this_charpos; \
80 best_below_byte = (BYTEPOS); \
81 changed = 1; \
82 } \
84 if (changed) \
85 { \
86 if (best_above - best_below == best_above_byte - best_below_byte) \
87 { \
88 ptrdiff_t value = best_below_byte + (charpos - best_below); \
89 if (byte_debug_flag) \
90 byte_char_debug_check (b, charpos, value); \
91 return value; \
92 } \
93 } \
96 static void
97 byte_char_debug_check (struct buffer *b, ptrdiff_t charpos, ptrdiff_t bytepos)
99 ptrdiff_t nchars = 0;
101 if (bytepos > BUF_GPT_BYTE (b))
103 nchars = multibyte_chars_in_text (BUF_BEG_ADDR (b),
104 BUF_GPT_BYTE (b) - BUF_BEG_BYTE (b));
105 nchars += multibyte_chars_in_text (BUF_GAP_END_ADDR (b),
106 bytepos - BUF_GPT_BYTE (b));
108 else
109 nchars = multibyte_chars_in_text (BUF_BEG_ADDR (b),
110 bytepos - BUF_BEG_BYTE (b));
112 if (charpos - 1 != nchars)
113 abort ();
116 ptrdiff_t
117 charpos_to_bytepos (ptrdiff_t charpos)
119 return buf_charpos_to_bytepos (current_buffer, charpos);
122 ptrdiff_t
123 buf_charpos_to_bytepos (struct buffer *b, ptrdiff_t charpos)
125 struct Lisp_Marker *tail;
126 ptrdiff_t best_above, best_above_byte;
127 ptrdiff_t best_below, best_below_byte;
129 if (charpos < BUF_BEG (b) || charpos > BUF_Z (b))
130 abort ();
132 best_above = BUF_Z (b);
133 best_above_byte = BUF_Z_BYTE (b);
135 /* If this buffer has as many characters as bytes,
136 each character must be one byte.
137 This takes care of the case where enable-multibyte-characters is nil. */
138 if (best_above == best_above_byte)
139 return charpos;
141 best_below = BEG;
142 best_below_byte = BEG_BYTE;
144 /* We find in best_above and best_above_byte
145 the closest known point above CHARPOS,
146 and in best_below and best_below_byte
147 the closest known point below CHARPOS,
149 If at any point we can tell that the space between those
150 two best approximations is all single-byte,
151 we interpolate the result immediately. */
153 CONSIDER (BUF_PT (b), BUF_PT_BYTE (b));
154 CONSIDER (BUF_GPT (b), BUF_GPT_BYTE (b));
155 CONSIDER (BUF_BEGV (b), BUF_BEGV_BYTE (b));
156 CONSIDER (BUF_ZV (b), BUF_ZV_BYTE (b));
158 if (b == cached_buffer && BUF_MODIFF (b) == cached_modiff)
159 CONSIDER (cached_charpos, cached_bytepos);
161 for (tail = BUF_MARKERS (b); tail; tail = tail->next)
163 CONSIDER (tail->charpos, tail->bytepos);
165 /* If we are down to a range of 50 chars,
166 don't bother checking any other markers;
167 scan the intervening chars directly now. */
168 if (best_above - best_below < 50)
169 break;
172 /* We get here if we did not exactly hit one of the known places.
173 We have one known above and one known below.
174 Scan, counting characters, from whichever one is closer. */
176 if (charpos - best_below < best_above - charpos)
178 int record = charpos - best_below > 5000;
180 while (best_below != charpos)
182 best_below++;
183 BUF_INC_POS (b, best_below_byte);
186 /* If this position is quite far from the nearest known position,
187 cache the correspondence by creating a marker here.
188 It will last until the next GC. */
189 if (record)
190 build_marker (b, best_below, best_below_byte);
192 if (byte_debug_flag)
193 byte_char_debug_check (b, charpos, best_below_byte);
195 cached_buffer = b;
196 cached_modiff = BUF_MODIFF (b);
197 cached_charpos = best_below;
198 cached_bytepos = best_below_byte;
200 return best_below_byte;
202 else
204 int record = best_above - charpos > 5000;
206 while (best_above != charpos)
208 best_above--;
209 BUF_DEC_POS (b, best_above_byte);
212 /* If this position is quite far from the nearest known position,
213 cache the correspondence by creating a marker here.
214 It will last until the next GC. */
215 if (record)
216 build_marker (b, best_above, best_above_byte);
218 if (byte_debug_flag)
219 byte_char_debug_check (b, charpos, best_above_byte);
221 cached_buffer = b;
222 cached_modiff = BUF_MODIFF (b);
223 cached_charpos = best_above;
224 cached_bytepos = best_above_byte;
226 return best_above_byte;
230 #undef CONSIDER
232 /* Used for debugging: recompute the bytepos corresponding to CHARPOS
233 in the simplest, most reliable way. */
235 extern ptrdiff_t verify_bytepos (ptrdiff_t charpos) EXTERNALLY_VISIBLE;
236 ptrdiff_t
237 verify_bytepos (ptrdiff_t charpos)
239 ptrdiff_t below = 1;
240 ptrdiff_t below_byte = 1;
242 while (below != charpos)
244 below++;
245 BUF_INC_POS (current_buffer, below_byte);
248 return below_byte;
251 /* buf_bytepos_to_charpos returns the char position corresponding to
252 BYTEPOS. */
254 /* This macro is a subroutine of buf_bytepos_to_charpos.
255 It is used when BYTEPOS is actually the byte position. */
257 #define CONSIDER(BYTEPOS, CHARPOS) \
259 ptrdiff_t this_bytepos = (BYTEPOS); \
260 int changed = 0; \
262 if (this_bytepos == bytepos) \
264 ptrdiff_t value = (CHARPOS); \
265 if (byte_debug_flag) \
266 byte_char_debug_check (b, value, bytepos); \
267 return value; \
269 else if (this_bytepos > bytepos) \
271 if (this_bytepos < best_above_byte) \
273 best_above = (CHARPOS); \
274 best_above_byte = this_bytepos; \
275 changed = 1; \
278 else if (this_bytepos > best_below_byte) \
280 best_below = (CHARPOS); \
281 best_below_byte = this_bytepos; \
282 changed = 1; \
285 if (changed) \
287 if (best_above - best_below == best_above_byte - best_below_byte) \
289 ptrdiff_t value = best_below + (bytepos - best_below_byte); \
290 if (byte_debug_flag) \
291 byte_char_debug_check (b, value, bytepos); \
292 return value; \
297 ptrdiff_t
298 buf_bytepos_to_charpos (struct buffer *b, ptrdiff_t bytepos)
300 struct Lisp_Marker *tail;
301 ptrdiff_t best_above, best_above_byte;
302 ptrdiff_t best_below, best_below_byte;
304 if (bytepos < BUF_BEG_BYTE (b) || bytepos > BUF_Z_BYTE (b))
305 abort ();
307 best_above = BUF_Z (b);
308 best_above_byte = BUF_Z_BYTE (b);
310 /* If this buffer has as many characters as bytes,
311 each character must be one byte.
312 This takes care of the case where enable-multibyte-characters is nil. */
313 if (best_above == best_above_byte)
314 return bytepos;
316 best_below = BEG;
317 best_below_byte = BEG_BYTE;
319 CONSIDER (BUF_PT_BYTE (b), BUF_PT (b));
320 CONSIDER (BUF_GPT_BYTE (b), BUF_GPT (b));
321 CONSIDER (BUF_BEGV_BYTE (b), BUF_BEGV (b));
322 CONSIDER (BUF_ZV_BYTE (b), BUF_ZV (b));
324 if (b == cached_buffer && BUF_MODIFF (b) == cached_modiff)
325 CONSIDER (cached_bytepos, cached_charpos);
327 for (tail = BUF_MARKERS (b); tail; tail = tail->next)
329 CONSIDER (tail->bytepos, tail->charpos);
331 /* If we are down to a range of 50 chars,
332 don't bother checking any other markers;
333 scan the intervening chars directly now. */
334 if (best_above - best_below < 50)
335 break;
338 /* We get here if we did not exactly hit one of the known places.
339 We have one known above and one known below.
340 Scan, counting characters, from whichever one is closer. */
342 if (bytepos - best_below_byte < best_above_byte - bytepos)
344 int record = bytepos - best_below_byte > 5000;
346 while (best_below_byte < bytepos)
348 best_below++;
349 BUF_INC_POS (b, best_below_byte);
352 /* If this position is quite far from the nearest known position,
353 cache the correspondence by creating a marker here.
354 It will last until the next GC.
355 But don't do it if BUF_MARKERS is nil;
356 that is a signal from Fset_buffer_multibyte. */
357 if (record && BUF_MARKERS (b))
358 build_marker (b, best_below, best_below_byte);
360 if (byte_debug_flag)
361 byte_char_debug_check (b, best_below, bytepos);
363 cached_buffer = b;
364 cached_modiff = BUF_MODIFF (b);
365 cached_charpos = best_below;
366 cached_bytepos = best_below_byte;
368 return best_below;
370 else
372 int record = best_above_byte - bytepos > 5000;
374 while (best_above_byte > bytepos)
376 best_above--;
377 BUF_DEC_POS (b, best_above_byte);
380 /* If this position is quite far from the nearest known position,
381 cache the correspondence by creating a marker here.
382 It will last until the next GC.
383 But don't do it if BUF_MARKERS is nil;
384 that is a signal from Fset_buffer_multibyte. */
385 if (record && BUF_MARKERS (b))
386 build_marker (b, best_above, best_above_byte);
388 if (byte_debug_flag)
389 byte_char_debug_check (b, best_above, bytepos);
391 cached_buffer = b;
392 cached_modiff = BUF_MODIFF (b);
393 cached_charpos = best_above;
394 cached_bytepos = best_above_byte;
396 return best_above;
400 #undef CONSIDER
402 /* Operations on markers. */
404 DEFUN ("marker-buffer", Fmarker_buffer, Smarker_buffer, 1, 1, 0,
405 doc: /* Return the buffer that MARKER points into, or nil if none.
406 Returns nil if MARKER points into a dead buffer. */)
407 (register Lisp_Object marker)
409 register Lisp_Object buf;
410 CHECK_MARKER (marker);
411 if (XMARKER (marker)->buffer)
413 XSETBUFFER (buf, XMARKER (marker)->buffer);
414 /* If the buffer is dead, we're in trouble: the buffer pointer here
415 does not preserve the buffer from being GC'd (it's weak), so
416 markers have to be unlinked from their buffer as soon as the buffer
417 is killed. */
418 eassert (!NILP (BVAR (XBUFFER (buf), name)));
419 return buf;
421 return Qnil;
424 DEFUN ("marker-position", Fmarker_position, Smarker_position, 1, 1, 0,
425 doc: /* Return the position MARKER points at, as a character number.
426 Returns nil if MARKER points nowhere. */)
427 (Lisp_Object marker)
429 CHECK_MARKER (marker);
430 if (XMARKER (marker)->buffer)
431 return make_number (XMARKER (marker)->charpos);
433 return Qnil;
436 /* Change M so it points to B at CHARPOS and BYTEPOS. */
438 static inline void
439 attach_marker (struct Lisp_Marker *m, struct buffer *b,
440 ptrdiff_t charpos, ptrdiff_t bytepos)
442 /* Every character is at least one byte. */
443 eassert (charpos <= bytepos);
445 m->charpos = charpos;
446 m->bytepos = bytepos;
448 if (m->buffer != b)
450 unchain_marker (m);
451 m->buffer = b;
452 m->next = BUF_MARKERS (b);
453 BUF_MARKERS (b) = m;
457 DEFUN ("set-marker", Fset_marker, Sset_marker, 2, 3, 0,
458 doc: /* Position MARKER before character number POSITION in BUFFER.
459 BUFFER defaults to the current buffer.
460 If POSITION is nil, makes marker point nowhere.
461 Then it no longer slows down editing in any buffer.
462 Returns MARKER. */)
463 (Lisp_Object marker, Lisp_Object position, Lisp_Object buffer)
465 register ptrdiff_t charpos;
466 register ptrdiff_t bytepos;
467 register struct buffer *b;
468 register struct Lisp_Marker *m;
470 CHECK_MARKER (marker);
471 m = XMARKER (marker);
473 /* If position is nil or a marker that points nowhere,
474 make this marker point nowhere. */
475 if (NILP (position)
476 || (MARKERP (position) && !XMARKER (position)->buffer))
478 unchain_marker (m);
479 return marker;
482 if (NILP (buffer))
483 b = current_buffer;
484 else
486 CHECK_BUFFER (buffer);
487 b = XBUFFER (buffer);
488 /* If buffer is dead, set marker to point nowhere. */
489 if (EQ (BVAR (b, name), Qnil))
491 unchain_marker (m);
492 return marker;
496 /* Optimize the special case where we are copying the position
497 of an existing marker, and MARKER is already in the same buffer. */
498 if (MARKERP (position) && b == XMARKER (position)->buffer
499 && b == m->buffer)
501 m->bytepos = XMARKER (position)->bytepos;
502 m->charpos = XMARKER (position)->charpos;
503 return marker;
506 CHECK_NUMBER_COERCE_MARKER (position);
507 charpos = clip_to_bounds (BUF_BEG (b), XINT (position), BUF_Z (b));
508 bytepos = buf_charpos_to_bytepos (b, charpos);
510 attach_marker (m, b, charpos, bytepos);
511 return marker;
514 /* This version of Fset_marker won't let the position
515 be outside the visible part. */
517 Lisp_Object
518 set_marker_restricted (Lisp_Object marker, Lisp_Object pos, Lisp_Object buffer)
520 register ptrdiff_t charpos;
521 register ptrdiff_t bytepos;
522 register struct buffer *b;
523 register struct Lisp_Marker *m;
525 CHECK_MARKER (marker);
526 m = XMARKER (marker);
528 /* If position is nil or a marker that points nowhere,
529 make this marker point nowhere. */
530 if (NILP (pos)
531 || (MARKERP (pos) && !XMARKER (pos)->buffer))
533 unchain_marker (m);
534 return marker;
537 if (NILP (buffer))
538 b = current_buffer;
539 else
541 CHECK_BUFFER (buffer);
542 b = XBUFFER (buffer);
543 /* If buffer is dead, set marker to point nowhere. */
544 if (EQ (BVAR (b, name), Qnil))
546 unchain_marker (m);
547 return marker;
551 /* Optimize the special case where we are copying the position
552 of an existing marker, and MARKER is already in the same buffer. */
553 if (MARKERP (pos) && b == XMARKER (pos)->buffer
554 && b == m->buffer)
556 m->bytepos = XMARKER (pos)->bytepos;
557 m->charpos = XMARKER (pos)->charpos;
558 return marker;
561 CHECK_NUMBER_COERCE_MARKER (pos);
562 charpos = clip_to_bounds (BUF_BEGV (b), XINT (pos), BUF_ZV (b));
563 bytepos = buf_charpos_to_bytepos (b, charpos);
565 attach_marker (m, b, charpos, bytepos);
566 return marker;
569 /* Set the position of MARKER, specifying both the
570 character position and the corresponding byte position. */
572 Lisp_Object
573 set_marker_both (Lisp_Object marker, Lisp_Object buffer, ptrdiff_t charpos, ptrdiff_t bytepos)
575 register struct buffer *b;
576 register struct Lisp_Marker *m;
578 CHECK_MARKER (marker);
579 m = XMARKER (marker);
581 if (NILP (buffer))
582 b = current_buffer;
583 else
585 CHECK_BUFFER (buffer);
586 b = XBUFFER (buffer);
587 /* If buffer is dead, set marker to point nowhere. */
588 if (EQ (BVAR (b, name), Qnil))
590 unchain_marker (m);
591 return marker;
595 /* In a single-byte buffer, the two positions must be equal. */
596 if (BUF_Z (b) == BUF_Z_BYTE (b)
597 && charpos != bytepos)
598 abort ();
600 attach_marker (m, b, charpos, bytepos);
601 return marker;
604 /* This version of set_marker_both won't let the position
605 be outside the visible part. */
607 Lisp_Object
608 set_marker_restricted_both (Lisp_Object marker, Lisp_Object buffer, ptrdiff_t charpos, ptrdiff_t bytepos)
610 register struct buffer *b;
611 register struct Lisp_Marker *m;
613 CHECK_MARKER (marker);
614 m = XMARKER (marker);
616 if (NILP (buffer))
617 b = current_buffer;
618 else
620 CHECK_BUFFER (buffer);
621 b = XBUFFER (buffer);
622 /* If buffer is dead, set marker to point nowhere. */
623 if (EQ (BVAR (b, name), Qnil))
625 unchain_marker (m);
626 return marker;
630 charpos = clip_to_bounds (BUF_BEGV (b), charpos, BUF_ZV (b));
631 bytepos = clip_to_bounds (BUF_BEGV_BYTE (b), bytepos, BUF_ZV_BYTE (b));
633 /* In a single-byte buffer, the two positions must be equal. */
634 if (BUF_Z (b) == BUF_Z_BYTE (b)
635 && charpos != bytepos)
636 abort ();
638 attach_marker (m, b, charpos, bytepos);
639 return marker;
642 /* Remove MARKER from the chain of whatever buffer it is in,
643 leaving it points to nowhere. This is called during garbage
644 collection, so we must be careful to ignore and preserve
645 mark bits, including those in chain fields of markers. */
647 void
648 unchain_marker (register struct Lisp_Marker *marker)
650 register struct buffer *b = marker->buffer;
652 if (b)
654 register struct Lisp_Marker *tail, **prev;
656 /* No dead buffers here. */
657 eassert (!NILP (BVAR (b, name)));
659 marker->buffer = NULL;
660 prev = &BUF_MARKERS (b);
662 for (tail = BUF_MARKERS (b); tail; prev = &tail->next, tail = *prev)
663 if (marker == tail)
665 if (*prev == BUF_MARKERS (b))
667 /* Deleting first marker from the buffer's chain. Crash
668 if new first marker in chain does not say it belongs
669 to the same buffer, or at least that they have the same
670 base buffer. */
671 if (tail->next && b->text != tail->next->buffer->text)
672 abort ();
674 *prev = tail->next;
675 /* We have removed the marker from the chain;
676 no need to scan the rest of the chain. */
677 break;
680 /* Error if marker was not in it's chain. */
681 eassert (tail != NULL);
685 /* Return the char position of marker MARKER, as a C integer. */
687 ptrdiff_t
688 marker_position (Lisp_Object marker)
690 register struct Lisp_Marker *m = XMARKER (marker);
691 register struct buffer *buf = m->buffer;
693 if (!buf)
694 error ("Marker does not point anywhere");
696 eassert (BUF_BEG (buf) <= m->charpos && m->charpos <= BUF_Z (buf));
698 return m->charpos;
701 /* Return the byte position of marker MARKER, as a C integer. */
703 ptrdiff_t
704 marker_byte_position (Lisp_Object marker)
706 register struct Lisp_Marker *m = XMARKER (marker);
707 register struct buffer *buf = m->buffer;
709 if (!buf)
710 error ("Marker does not point anywhere");
712 eassert (BUF_BEG_BYTE (buf) <= m->bytepos && m->bytepos <= BUF_Z_BYTE (buf));
714 return m->bytepos;
717 DEFUN ("copy-marker", Fcopy_marker, Scopy_marker, 0, 2, 0,
718 doc: /* Return a new marker pointing at the same place as MARKER.
719 If argument is a number, makes a new marker pointing
720 at that position in the current buffer.
721 If MARKER is not specified, the new marker does not point anywhere.
722 The optional argument TYPE specifies the insertion type of the new marker;
723 see `marker-insertion-type'. */)
724 (register Lisp_Object marker, Lisp_Object type)
726 register Lisp_Object new;
728 if (!NILP (marker))
729 CHECK_TYPE (INTEGERP (marker) || MARKERP (marker), Qinteger_or_marker_p, marker);
731 new = Fmake_marker ();
732 Fset_marker (new, marker,
733 (MARKERP (marker) ? Fmarker_buffer (marker) : Qnil));
734 XMARKER (new)->insertion_type = !NILP (type);
735 return new;
738 DEFUN ("marker-insertion-type", Fmarker_insertion_type,
739 Smarker_insertion_type, 1, 1, 0,
740 doc: /* Return insertion type of MARKER: t if it stays after inserted text.
741 The value nil means the marker stays before text inserted there. */)
742 (register Lisp_Object marker)
744 CHECK_MARKER (marker);
745 return XMARKER (marker)->insertion_type ? Qt : Qnil;
748 DEFUN ("set-marker-insertion-type", Fset_marker_insertion_type,
749 Sset_marker_insertion_type, 2, 2, 0,
750 doc: /* Set the insertion-type of MARKER to TYPE.
751 If TYPE is t, it means the marker advances when you insert text at it.
752 If TYPE is nil, it means the marker stays behind when you insert text at it. */)
753 (Lisp_Object marker, Lisp_Object type)
755 CHECK_MARKER (marker);
757 XMARKER (marker)->insertion_type = ! NILP (type);
758 return type;
761 DEFUN ("buffer-has-markers-at", Fbuffer_has_markers_at, Sbuffer_has_markers_at,
762 1, 1, 0,
763 doc: /* Return t if there are markers pointing at POSITION in the current buffer. */)
764 (Lisp_Object position)
766 register struct Lisp_Marker *tail;
767 register ptrdiff_t charpos;
769 charpos = clip_to_bounds (BEG, XINT (position), Z);
771 for (tail = BUF_MARKERS (current_buffer); tail; tail = tail->next)
772 if (tail->charpos == charpos)
773 return Qt;
775 return Qnil;
778 /* For debugging -- count the markers in buffer BUF. */
780 extern int count_markers (struct buffer *) EXTERNALLY_VISIBLE;
782 count_markers (struct buffer *buf)
784 int total = 0;
785 struct Lisp_Marker *tail;
787 for (tail = BUF_MARKERS (buf); tail; tail = tail->next)
788 total++;
790 return total;
793 void
794 syms_of_marker (void)
796 defsubr (&Smarker_position);
797 defsubr (&Smarker_buffer);
798 defsubr (&Sset_marker);
799 defsubr (&Scopy_marker);
800 defsubr (&Smarker_insertion_type);
801 defsubr (&Sset_marker_insertion_type);
802 defsubr (&Sbuffer_has_markers_at);
804 DEFVAR_BOOL ("byte-debug-flag", byte_debug_flag,
805 doc: /* Non-nil enables debugging checks in byte/char position conversions. */);
806 byte_debug_flag = 0;