(buf_bytepos_to_charpos): Use marker bytepos, not bufpos.
[bpt/emacs.git] / src / marker.c
1 /* Markers: examining, setting and deleting.
2 Copyright (C) 1985, 1997 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
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 2, or (at your option)
9 any later version.
10
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.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21
22 #include <config.h>
23 #include "lisp.h"
24 #include "buffer.h"
25 #include "charset.h"
26
27 /* Record one cached position found recently by
28 buf_charpos_to_bytepos or buf_bytepos_to_charpos. */
29
30 static int cached_charpos;
31 static int cached_bytepos;
32 static struct buffer *cached_buffer;
33 static int cached_modiff;
34 \f
35 /* Converting between character positions and byte positions. */
36
37 /* There are several places in the buffer where we know
38 the corrspondence: BEG, BEGV, PT, GPT, ZV and Z,
39 and everywhere there is a marker. So we find the one of these places
40 that is closest to the specified position, and scan from there. */
41
42 /* charpos_to_bytepos returns the byte position corresponding to CHARPOS. */
43
44 /* This macro is a subroutine of charpos_to_bytepos.
45 Note that it is desirable that BYTEPOS is not evaluated
46 except when we really want its value. */
47
48 #define CONSIDER(CHARPOS, BYTEPOS) \
49 { \
50 int this_charpos = (CHARPOS); \
51 int changed = 0; \
52 \
53 if (this_charpos == charpos) \
54 return (BYTEPOS); \
55 else if (this_charpos > charpos) \
56 { \
57 if (this_charpos < best_above) \
58 { \
59 best_above = this_charpos; \
60 best_above_byte = (BYTEPOS); \
61 changed = 1; \
62 } \
63 } \
64 else if (this_charpos > best_below) \
65 { \
66 best_below = this_charpos; \
67 best_below_byte = (BYTEPOS); \
68 changed = 1; \
69 } \
70 \
71 if (changed) \
72 { \
73 if (best_above - best_below == best_above_byte - best_below_byte) \
74 return best_below_byte + (charpos - best_below); \
75 } \
76 }
77
78 int
79 charpos_to_bytepos (charpos)
80 int charpos;
81 {
82 return buf_charpos_to_bytepos (current_buffer, charpos);
83 }
84
85 int
86 buf_charpos_to_bytepos (b, charpos)
87 struct buffer *b;
88 int charpos;
89 {
90 Lisp_Object tail;
91 int gapend_byte = BUF_GPT_BYTE (b) + BUF_GAP_SIZE (b);
92 int best_above, best_above_byte;
93 int best_below, best_below_byte;
94
95 if (charpos < BUF_BEG (b) || charpos > BUF_Z (b))
96 abort ();
97
98 best_above = BUF_Z (b);
99 best_above_byte = BUF_Z_BYTE (b);
100
101 /* If this buffer has as many characters as bytes,
102 each character must be one byte.
103 This takes care of the case where enable-multibyte-characters is nil. */
104 if (best_above == best_above_byte)
105 return charpos;
106
107 best_below = 1;
108 best_below_byte = 1;
109
110 /* We find in best_above and best_above_byte
111 the closest known point above CHARPOS,
112 and in best_below and best_below_byte
113 the closest known point below CHARPOS,
114
115 If at any point we can tell that the space between those
116 two best approximations is all single-byte,
117 we interpolate the result immediately. */
118
119 CONSIDER (BUF_PT (b), BUF_PT_BYTE (b));
120 CONSIDER (BUF_GPT (b), BUF_GPT_BYTE (b));
121 CONSIDER (BUF_BEGV (b), BUF_BEGV_BYTE (b));
122 CONSIDER (BUF_ZV (b), BUF_ZV_BYTE (b));
123
124 if (b == cached_buffer && BUF_MODIFF (b) == cached_modiff)
125 CONSIDER (cached_charpos, cached_bytepos);
126
127 tail = BUF_MARKERS (b);
128 while (XSYMBOL (tail) != XSYMBOL (Qnil))
129 {
130 CONSIDER (XMARKER (tail)->charpos, XMARKER (tail)->bytepos);
131
132 /* If we are down to a range of 50 chars,
133 don't bother checking any other markers;
134 scan the intervening chars directly now. */
135 if (best_above - best_below < 50)
136 break;
137
138 tail = XMARKER (tail)->chain;
139 }
140
141 /* We get here if we did not exactly hit one of the known places.
142 We have one known above and one known below.
143 Scan, counting characters, from whichever one is closer. */
144
145 if (charpos - best_below < best_above - charpos)
146 {
147 int record = charpos - best_below > 5000;
148
149 while (best_below != charpos)
150 {
151 best_below++;
152 BUF_INC_POS (b, best_below_byte);
153 }
154
155 /* If this position is quite far from the nearest known position,
156 cache the correspondence by creating a marker here.
157 It will last until the next GC. */
158 if (record)
159 {
160 Lisp_Object marker;
161 marker = Fmake_marker ();
162 set_marker_both (marker, Qnil, best_below, best_below_byte);
163 }
164
165 cached_buffer = b;
166 cached_modiff = BUF_MODIFF (b);
167 cached_charpos = best_below;
168 cached_bytepos = best_below_byte;
169
170 return best_below_byte;
171 }
172 else
173 {
174 int record = best_above - charpos > 5000;
175
176 while (best_above != charpos)
177 {
178 best_above--;
179 BUF_DEC_POS (b, best_above_byte);
180 }
181
182 /* If this position is quite far from the nearest known position,
183 cache the correspondence by creating a marker here.
184 It will last until the next GC. */
185 if (record)
186 {
187 Lisp_Object marker;
188 marker = Fmake_marker ();
189 set_marker_both (marker, Qnil, best_above, best_above_byte);
190 }
191
192 cached_buffer = b;
193 cached_modiff = BUF_MODIFF (b);
194 cached_charpos = best_above;
195 cached_bytepos = best_above_byte;
196
197 return best_above_byte;
198 }
199 }
200
201 #undef CONSIDER
202 \f
203 /* bytepos_to_charpos returns the char position corresponding to BYTEPOS. */
204
205 /* This macro is a subroutine of bytepos_to_charpos.
206 It is used when BYTEPOS is actually the byte position. */
207
208 #define CONSIDER(BYTEPOS, CHARPOS) \
209 { \
210 int this_bytepos = (BYTEPOS); \
211 int changed = 0; \
212 \
213 if (this_bytepos == bytepos) \
214 return (CHARPOS); \
215 else if (this_bytepos > bytepos) \
216 { \
217 if (this_bytepos < best_above_byte) \
218 { \
219 best_above = (CHARPOS); \
220 best_above_byte = this_bytepos; \
221 changed = 1; \
222 } \
223 } \
224 else if (this_bytepos > best_below_byte) \
225 { \
226 best_below = (CHARPOS); \
227 best_below_byte = this_bytepos; \
228 changed = 1; \
229 } \
230 \
231 if (changed) \
232 { \
233 if (best_above - best_below == best_above_byte - best_below_byte) \
234 return best_below + (bytepos - best_below_byte); \
235 } \
236 }
237
238 int
239 bytepos_to_charpos (bytepos)
240 int bytepos;
241 {
242 return buf_bytepos_to_charpos (current_buffer, bytepos);
243 }
244
245 int
246 buf_bytepos_to_charpos (b, bytepos)
247 struct buffer *b;
248 int bytepos;
249 {
250 Lisp_Object tail;
251 int best_above, best_above_byte;
252 int best_below, best_below_byte;
253
254 if (bytepos < BUF_BEG_BYTE (b) || bytepos > BUF_Z_BYTE (b))
255 abort ();
256
257 best_above = BUF_Z (b);
258 best_above_byte = BUF_Z_BYTE (b);
259
260 /* If this buffer has as many characters as bytes,
261 each character must be one byte.
262 This takes care of the case where enable-multibyte-characters is nil. */
263 if (best_above == best_above_byte)
264 return bytepos;
265
266 best_below = 1;
267 best_below_byte = 1;
268
269 CONSIDER (BUF_PT_BYTE (b), BUF_PT (b));
270 CONSIDER (BUF_GPT_BYTE (b), BUF_GPT (b));
271 CONSIDER (BUF_BEGV_BYTE (b), BUF_BEGV (b));
272 CONSIDER (BUF_ZV_BYTE (b), BUF_ZV (b));
273
274 if (b == cached_buffer && BUF_MODIFF (b) == cached_modiff)
275 CONSIDER (cached_bytepos, cached_charpos);
276
277 tail = BUF_MARKERS (b);
278 while (XSYMBOL (tail) != XSYMBOL (Qnil))
279 {
280 CONSIDER (XMARKER (tail)->bytepos, XMARKER (tail)->charpos);
281
282 /* If we are down to a range of 50 chars,
283 don't bother checking any other markers;
284 scan the intervening chars directly now. */
285 if (best_above - best_below < 50)
286 break;
287
288 tail = XMARKER (tail)->chain;
289 }
290
291 /* We get here if we did not exactly hit one of the known places.
292 We have one known above and one known below.
293 Scan, counting characters, from whichever one is closer. */
294
295 if (bytepos - best_below_byte < best_above_byte - bytepos)
296 {
297 int record = best_above_byte - bytepos > 5000;
298
299 while (best_below_byte < bytepos)
300 {
301 best_below++;
302 BUF_INC_POS (b, best_below_byte);
303 }
304
305 /* If this position is quite far from the nearest known position,
306 cache the correspondence by creating a marker here.
307 It will last until the next GC. */
308 if (record)
309 {
310 Lisp_Object marker;
311 marker = Fmake_marker ();
312 set_marker_both (marker, Qnil, best_below, best_below_byte);
313 }
314
315 cached_buffer = b;
316 cached_modiff = BUF_MODIFF (b);
317 cached_charpos = best_below;
318 cached_bytepos = best_below_byte;
319
320 return best_below;
321 }
322 else
323 {
324 int record = best_above_byte - bytepos > 5000;
325
326 while (best_above_byte > bytepos)
327 {
328 best_above--;
329 BUF_DEC_POS (b, best_above_byte);
330 }
331
332 /* If this position is quite far from the nearest known position,
333 cache the correspondence by creating a marker here.
334 It will last until the next GC. */
335 if (record)
336 {
337 Lisp_Object marker;
338 marker = Fmake_marker ();
339 set_marker_both (marker, Qnil, best_above, best_above_byte);
340 }
341
342 cached_buffer = b;
343 cached_modiff = BUF_MODIFF (b);
344 cached_charpos = best_above;
345 cached_bytepos = best_above_byte;
346
347 return best_above;
348 }
349 }
350
351 #undef CONSIDER
352 \f
353 /* Operations on markers. */
354
355 DEFUN ("marker-buffer", Fmarker_buffer, Smarker_buffer, 1, 1, 0,
356 "Return the buffer that MARKER points into, or nil if none.\n\
357 Returns nil if MARKER points into a dead buffer.")
358 (marker)
359 register Lisp_Object marker;
360 {
361 register Lisp_Object buf;
362 CHECK_MARKER (marker, 0);
363 if (XMARKER (marker)->buffer)
364 {
365 XSETBUFFER (buf, XMARKER (marker)->buffer);
366 /* Return marker's buffer only if it is not dead. */
367 if (!NILP (XBUFFER (buf)->name))
368 return buf;
369 }
370 return Qnil;
371 }
372
373 DEFUN ("marker-position", Fmarker_position, Smarker_position, 1, 1, 0,
374 "Return the position MARKER points at, as a character number.")
375 (marker)
376 Lisp_Object marker;
377 {
378 register Lisp_Object pos;
379 register int i;
380 register struct buffer *buf;
381
382 CHECK_MARKER (marker, 0);
383 if (XMARKER (marker)->buffer)
384 return make_number (XMARKER (marker)->charpos);
385
386 return Qnil;
387 }
388 \f
389 DEFUN ("set-marker", Fset_marker, Sset_marker, 2, 3, 0,
390 "Position MARKER before character number POSITION in BUFFER.\n\
391 BUFFER defaults to the current buffer.\n\
392 If POSITION is nil, makes marker point nowhere.\n\
393 Then it no longer slows down editing in any buffer.\n\
394 Returns MARKER.")
395 (marker, position, buffer)
396 Lisp_Object marker, position, buffer;
397 {
398 register int charno, bytepos;
399 register struct buffer *b;
400 register struct Lisp_Marker *m;
401
402 CHECK_MARKER (marker, 0);
403 /* If position is nil or a marker that points nowhere,
404 make this marker point nowhere. */
405 if (NILP (position)
406 || (MARKERP (position) && !XMARKER (position)->buffer))
407 {
408 unchain_marker (marker);
409 return marker;
410 }
411
412 if (NILP (buffer))
413 b = current_buffer;
414 else
415 {
416 CHECK_BUFFER (buffer, 1);
417 b = XBUFFER (buffer);
418 /* If buffer is dead, set marker to point nowhere. */
419 if (EQ (b->name, Qnil))
420 {
421 unchain_marker (marker);
422 return marker;
423 }
424 }
425
426 m = XMARKER (marker);
427
428 /* Optimize the special case where we are copying the position
429 of an existing marker, and MARKER is already in the same buffer. */
430 if (MARKERP (position) && b == XMARKER (position)->buffer
431 && b == m->buffer)
432 {
433 m->bytepos = XMARKER (position)->bytepos;
434 m->charpos = XMARKER (position)->charpos;
435 return marker;
436 }
437
438 CHECK_NUMBER_COERCE_MARKER (position, 1);
439
440 charno = XINT (position);
441
442 if (charno < BUF_BEG (b))
443 charno = BUF_BEG (b);
444 if (charno > BUF_Z (b))
445 charno = BUF_Z (b);
446
447 bytepos = buf_charpos_to_bytepos (b, charno);
448
449 /* Every character is at least one byte. */
450 if (charno > bytepos)
451 abort ();
452
453 m->bytepos = bytepos;
454 m->charpos = charno;
455
456 if (m->buffer != b)
457 {
458 unchain_marker (marker);
459 m->buffer = b;
460 m->chain = BUF_MARKERS (b);
461 BUF_MARKERS (b) = marker;
462 }
463
464 return marker;
465 }
466
467 /* This version of Fset_marker won't let the position
468 be outside the visible part. */
469
470 Lisp_Object
471 set_marker_restricted (marker, pos, buffer)
472 Lisp_Object marker, pos, buffer;
473 {
474 register int charno, bytepos;
475 register struct buffer *b;
476 register struct Lisp_Marker *m;
477
478 CHECK_MARKER (marker, 0);
479 /* If position is nil or a marker that points nowhere,
480 make this marker point nowhere. */
481 if (NILP (pos)
482 || (MARKERP (pos) && !XMARKER (pos)->buffer))
483 {
484 unchain_marker (marker);
485 return marker;
486 }
487
488 if (NILP (buffer))
489 b = current_buffer;
490 else
491 {
492 CHECK_BUFFER (buffer, 1);
493 b = XBUFFER (buffer);
494 /* If buffer is dead, set marker to point nowhere. */
495 if (EQ (b->name, Qnil))
496 {
497 unchain_marker (marker);
498 return marker;
499 }
500 }
501
502 m = XMARKER (marker);
503
504 /* Optimize the special case where we are copying the position
505 of an existing marker, and MARKER is already in the same buffer. */
506 if (MARKERP (pos) && b == XMARKER (pos)->buffer
507 && b == m->buffer)
508 {
509 m->bytepos = XMARKER (pos)->bytepos;
510 m->charpos = XMARKER (pos)->charpos;
511 return marker;
512 }
513
514 CHECK_NUMBER_COERCE_MARKER (pos, 1);
515
516 charno = XINT (pos);
517
518 if (charno < BUF_BEGV (b))
519 charno = BUF_BEGV (b);
520 if (charno > BUF_ZV (b))
521 charno = BUF_ZV (b);
522
523 bytepos = buf_charpos_to_bytepos (b, charno);
524
525 /* Every character is at least one byte. */
526 if (charno > bytepos)
527 abort ();
528
529 m->bytepos = bytepos;
530 m->charpos = charno;
531
532 if (m->buffer != b)
533 {
534 unchain_marker (marker);
535 m->buffer = b;
536 m->chain = BUF_MARKERS (b);
537 BUF_MARKERS (b) = marker;
538 }
539
540 return marker;
541 }
542 \f
543 /* Set the position of MARKER, specifying both the
544 character position and the corresponding byte position. */
545
546 Lisp_Object
547 set_marker_both (marker, buffer, charpos, bytepos)
548 Lisp_Object marker, buffer;
549 int charpos, bytepos;
550 {
551 register struct buffer *b;
552 register struct Lisp_Marker *m;
553
554 CHECK_MARKER (marker, 0);
555 /* If position is nil or a marker that points nowhere,
556 make this marker point nowhere. */
557 if (NILP (charpos)
558 || (MARKERP (charpos) && !XMARKER (charpos)->buffer))
559 {
560 unchain_marker (marker);
561 return marker;
562 }
563
564 CHECK_NUMBER_COERCE_MARKER (charpos, 1);
565 if (NILP (buffer))
566 b = current_buffer;
567 else
568 {
569 CHECK_BUFFER (buffer, 1);
570 b = XBUFFER (buffer);
571 /* If buffer is dead, set marker to point nowhere. */
572 if (EQ (b->name, Qnil))
573 {
574 unchain_marker (marker);
575 return marker;
576 }
577 }
578
579 m = XMARKER (marker);
580
581 /* In a single-byte buffer, the two positions must be equal. */
582 if (BUF_Z (b) == BUF_Z_BYTE (b)
583 && charpos != bytepos)
584 abort ();
585 /* Every character is at least one byte. */
586 if (charpos > bytepos)
587 abort ();
588
589 m->bytepos = bytepos;
590 m->charpos = charpos;
591
592 if (m->buffer != b)
593 {
594 unchain_marker (marker);
595 m->buffer = b;
596 m->chain = BUF_MARKERS (b);
597 BUF_MARKERS (b) = marker;
598 }
599
600 return marker;
601 }
602
603 /* This version of set_marker_both won't let the position
604 be outside the visible part. */
605
606 Lisp_Object
607 set_marker_restricted_both (marker, buffer, charpos, bytepos)
608 Lisp_Object marker, buffer;
609 int charpos, bytepos;
610 {
611 register struct buffer *b;
612 register struct Lisp_Marker *m;
613
614 CHECK_MARKER (marker, 0);
615
616 if (NILP (buffer))
617 b = current_buffer;
618 else
619 {
620 CHECK_BUFFER (buffer, 1);
621 b = XBUFFER (buffer);
622 /* If buffer is dead, set marker to point nowhere. */
623 if (EQ (b->name, Qnil))
624 {
625 unchain_marker (marker);
626 return marker;
627 }
628 }
629
630 m = XMARKER (marker);
631
632 if (charpos < BUF_BEGV (b))
633 charpos = BUF_BEGV (b);
634 if (charpos > BUF_ZV (b))
635 charpos = BUF_ZV (b);
636 if (bytepos < BUF_BEGV_BYTE (b))
637 bytepos = BUF_BEGV_BYTE (b);
638 if (bytepos > BUF_ZV_BYTE (b))
639 bytepos = BUF_ZV_BYTE (b);
640
641 /* In a single-byte buffer, the two positions must be equal. */
642 if (BUF_Z (b) == BUF_Z_BYTE (b)
643 && charpos != bytepos)
644 abort ();
645 /* Every character is at least one byte. */
646 if (charpos > bytepos)
647 abort ();
648
649 m->bytepos = bytepos;
650 m->charpos = charpos;
651
652 if (m->buffer != b)
653 {
654 unchain_marker (marker);
655 m->buffer = b;
656 m->chain = BUF_MARKERS (b);
657 BUF_MARKERS (b) = marker;
658 }
659
660 return marker;
661 }
662 \f
663 /* This is called during garbage collection,
664 so we must be careful to ignore and preserve mark bits,
665 including those in chain fields of markers. */
666
667 void
668 unchain_marker (marker)
669 register Lisp_Object marker;
670 {
671 register Lisp_Object tail, prev, next;
672 register EMACS_INT omark;
673 register struct buffer *b;
674
675 b = XMARKER (marker)->buffer;
676 if (b == 0)
677 return;
678
679 if (EQ (b->name, Qnil))
680 abort ();
681
682 tail = BUF_MARKERS (b);
683 prev = Qnil;
684 while (XSYMBOL (tail) != XSYMBOL (Qnil))
685 {
686 next = XMARKER (tail)->chain;
687 XUNMARK (next);
688
689 if (XMARKER (marker) == XMARKER (tail))
690 {
691 if (NILP (prev))
692 {
693 BUF_MARKERS (b) = next;
694 /* Deleting first marker from the buffer's chain. Crash
695 if new first marker in chain does not say it belongs
696 to the same buffer, or at least that they have the same
697 base buffer. */
698 if (!NILP (next) && b->text != XMARKER (next)->buffer->text)
699 abort ();
700 }
701 else
702 {
703 omark = XMARKBIT (XMARKER (prev)->chain);
704 XMARKER (prev)->chain = next;
705 XSETMARKBIT (XMARKER (prev)->chain, omark);
706 }
707 break;
708 }
709 else
710 prev = tail;
711 tail = next;
712 }
713 XMARKER (marker)->buffer = 0;
714 }
715
716 /* Return the char position of marker MARKER, as a C integer. */
717
718 int
719 marker_position (marker)
720 Lisp_Object marker;
721 {
722 register struct Lisp_Marker *m = XMARKER (marker);
723 register struct buffer *buf = m->buffer;
724
725 if (!buf)
726 error ("Marker does not point anywhere");
727
728 return m->charpos;
729 }
730
731 /* Return the byte position of marker MARKER, as a C integer. */
732
733 int
734 marker_byte_position (marker)
735 Lisp_Object marker;
736 {
737 register struct Lisp_Marker *m = XMARKER (marker);
738 register struct buffer *buf = m->buffer;
739 register int i = m->bytepos;
740
741 if (!buf)
742 error ("Marker does not point anywhere");
743
744 if (i < BUF_BEG_BYTE (buf) || i > BUF_Z_BYTE (buf))
745 abort ();
746
747 return i;
748 }
749 \f
750 DEFUN ("copy-marker", Fcopy_marker, Scopy_marker, 1, 2, 0,
751 "Return a new marker pointing at the same place as MARKER.\n\
752 If argument is a number, makes a new marker pointing\n\
753 at that position in the current buffer.\n\
754 The optional argument TYPE specifies the insertion type of the new marker;\n\
755 see `marker-insertion-type'.")
756 (marker, type)
757 register Lisp_Object marker, type;
758 {
759 register Lisp_Object new;
760
761 if (INTEGERP (marker) || MARKERP (marker))
762 {
763 new = Fmake_marker ();
764 Fset_marker (new, marker,
765 (MARKERP (marker) ? Fmarker_buffer (marker) : Qnil));
766 XMARKER (new)->insertion_type = !NILP (type);
767 return new;
768 }
769 else
770 marker = wrong_type_argument (Qinteger_or_marker_p, marker);
771 }
772
773 DEFUN ("marker-insertion-type", Fmarker_insertion_type,
774 Smarker_insertion_type, 1, 1, 0,
775 "Return insertion type of MARKER: t if it stays after inserted text.\n\
776 nil means the marker stays before text inserted there.")
777 (marker)
778 register Lisp_Object marker;
779 {
780 register Lisp_Object buf;
781 CHECK_MARKER (marker, 0);
782 return XMARKER (marker)->insertion_type ? Qt : Qnil;
783 }
784
785 DEFUN ("set-marker-insertion-type", Fset_marker_insertion_type,
786 Sset_marker_insertion_type, 2, 2, 0,
787 "Set the insertion-type of MARKER to TYPE.\n\
788 If TYPE is t, it means the marker advances when you insert text at it.\n\
789 If TYPE is nil, it means the marker stays behind when you insert text at it.")
790 (marker, type)
791 Lisp_Object marker, type;
792 {
793 CHECK_MARKER (marker, 0);
794
795 XMARKER (marker)->insertion_type = ! NILP (type);
796 return type;
797 }
798
799 DEFUN ("buffer-has-markers-at", Fbuffer_has_markers_at, Sbuffer_has_markers_at,
800 1, 1, 0,
801 "Return t if there are markers pointing at POSITION in the current buffer.")
802 (position)
803 Lisp_Object position;
804 {
805 register Lisp_Object tail;
806 register int charno;
807
808 charno = XINT (position);
809
810 if (charno < BEG)
811 charno = BEG;
812 if (charno > Z)
813 charno = Z;
814
815 for (tail = BUF_MARKERS (current_buffer);
816 XSYMBOL (tail) != XSYMBOL (Qnil);
817 tail = XMARKER (tail)->chain)
818 if (XMARKER (tail)->charpos == charno)
819 return Qt;
820
821 return Qnil;
822 }
823 \f
824 void
825 syms_of_marker ()
826 {
827 defsubr (&Smarker_position);
828 defsubr (&Smarker_buffer);
829 defsubr (&Sset_marker);
830 defsubr (&Scopy_marker);
831 defsubr (&Smarker_insertion_type);
832 defsubr (&Sset_marker_insertion_type);
833 defsubr (&Sbuffer_has_markers_at);
834 }