lisp/progmodes/prog-mode.el: Force font-lock to deal with `composition' prop.
[bpt/emacs.git] / src / marker.c
CommitLineData
1389ad71 1/* Markers: examining, setting and deleting.
ab422c4d
PE
2 Copyright (C) 1985, 1997-1998, 2001-2013 Free Software Foundation,
3 Inc.
dcfdbac7
JB
4
5This file is part of GNU Emacs.
6
9ec0b715 7GNU Emacs is free software: you can redistribute it and/or modify
dcfdbac7 8it under the terms of the GNU General Public License as published by
9ec0b715
GM
9the Free Software Foundation, either version 3 of the License, or
10(at your option) any later version.
dcfdbac7
JB
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
9ec0b715 18along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
dcfdbac7
JB
19
20
18160b98 21#include <config.h>
0328b6de 22
dcfdbac7 23#include "lisp.h"
83be827a 24#include "character.h"
e5560ff7 25#include "buffer.h"
dcfdbac7 26
1389ad71
RS
27/* Record one cached position found recently by
28 buf_charpos_to_bytepos or buf_bytepos_to_charpos. */
29
d311d28c
PE
30static ptrdiff_t cached_charpos;
31static ptrdiff_t cached_bytepos;
1389ad71 32static struct buffer *cached_buffer;
fd2f90cf 33static EMACS_INT cached_modiff;
31f8ab72 34
f1f924b6
DA
35/* Juanma Barranquero <lekktu@gmail.com> reported ~3x increased
36 bootstrap time when byte_char_debug_check is enabled; so this
37 is never turned on by --enable-checking configure option. */
38
39#ifdef MARKER_DEBUG
80d26f99 40
90fc4786 41extern int count_markers (struct buffer *) EXTERNALLY_VISIBLE;
f1f924b6 42extern ptrdiff_t verify_bytepos (ptrdiff_t charpos) EXTERNALLY_VISIBLE;
90fc4786
DA
43
44static void
45byte_char_debug_check (struct buffer *b, ptrdiff_t charpos, ptrdiff_t bytepos)
46{
9d44f8ce
DA
47 ptrdiff_t nchars;
48
49 if (NILP (BVAR (b, enable_multibyte_characters)))
50 return;
90fc4786
DA
51
52 if (bytepos > BUF_GPT_BYTE (b))
9d44f8ce
DA
53 nchars
54 = multibyte_chars_in_text (BUF_BEG_ADDR (b),
55 BUF_GPT_BYTE (b) - BUF_BEG_BYTE (b))
56 + multibyte_chars_in_text (BUF_GAP_END_ADDR (b),
57 bytepos - BUF_GPT_BYTE (b));
90fc4786
DA
58 else
59 nchars = multibyte_chars_in_text (BUF_BEG_ADDR (b),
60 bytepos - BUF_BEG_BYTE (b));
61
62 if (charpos - 1 != nchars)
1088b922 63 emacs_abort ();
90fc4786
DA
64}
65
f1f924b6 66#else /* not MARKER_DEBUG */
90fc4786 67
e2688e4a 68#define byte_char_debug_check(b, charpos, bytepos) do { } while (0)
90fc4786 69
f1f924b6 70#endif /* MARKER_DEBUG */
1088b922 71
dfcf069d 72void
971de7fb 73clear_charpos_cache (struct buffer *b)
31f8ab72
RS
74{
75 if (cached_buffer == b)
76 cached_buffer = 0;
77}
1389ad71
RS
78\f
79/* Converting between character positions and byte positions. */
80
81/* There are several places in the buffer where we know
3f67ae94 82 the correspondence: BEG, BEGV, PT, GPT, ZV and Z,
1389ad71
RS
83 and everywhere there is a marker. So we find the one of these places
84 that is closest to the specified position, and scan from there. */
85
13002885 86/* This macro is a subroutine of buf_charpos_to_bytepos.
1389ad71
RS
87 Note that it is desirable that BYTEPOS is not evaluated
88 except when we really want its value. */
89
90#define CONSIDER(CHARPOS, BYTEPOS) \
91{ \
d311d28c 92 ptrdiff_t this_charpos = (CHARPOS); \
7cded46f 93 bool changed = 0; \
1389ad71
RS
94 \
95 if (this_charpos == charpos) \
6e57421b 96 { \
d311d28c 97 ptrdiff_t value = (BYTEPOS); \
90fc4786
DA
98 \
99 byte_char_debug_check (b, charpos, value); \
6e57421b
RS
100 return value; \
101 } \
1389ad71
RS
102 else if (this_charpos > charpos) \
103 { \
104 if (this_charpos < best_above) \
105 { \
106 best_above = this_charpos; \
107 best_above_byte = (BYTEPOS); \
108 changed = 1; \
109 } \
110 } \
111 else if (this_charpos > best_below) \
112 { \
113 best_below = this_charpos; \
114 best_below_byte = (BYTEPOS); \
115 changed = 1; \
116 } \
117 \
118 if (changed) \
119 { \
120 if (best_above - best_below == best_above_byte - best_below_byte) \
6e57421b 121 { \
d311d28c 122 ptrdiff_t value = best_below_byte + (charpos - best_below); \
90fc4786
DA
123 \
124 byte_char_debug_check (b, charpos, value); \
6e57421b
RS
125 return value; \
126 } \
1389ad71
RS
127 } \
128}
129
13002885 130/* Return the byte position corresponding to CHARPOS in B. */
1389ad71 131
d311d28c
PE
132ptrdiff_t
133buf_charpos_to_bytepos (struct buffer *b, ptrdiff_t charpos)
1389ad71 134{
5e097e00 135 struct Lisp_Marker *tail;
d311d28c
PE
136 ptrdiff_t best_above, best_above_byte;
137 ptrdiff_t best_below, best_below_byte;
1389ad71 138
13002885 139 eassert (BUF_BEG (b) <= charpos && charpos <= BUF_Z (b));
1389ad71
RS
140
141 best_above = BUF_Z (b);
142 best_above_byte = BUF_Z_BYTE (b);
143
144 /* If this buffer has as many characters as bytes,
145 each character must be one byte.
146 This takes care of the case where enable-multibyte-characters is nil. */
147 if (best_above == best_above_byte)
148 return charpos;
149
3ab364ce
SM
150 best_below = BEG;
151 best_below_byte = BEG_BYTE;
1389ad71
RS
152
153 /* We find in best_above and best_above_byte
154 the closest known point above CHARPOS,
155 and in best_below and best_below_byte
156 the closest known point below CHARPOS,
157
158 If at any point we can tell that the space between those
159 two best approximations is all single-byte,
160 we interpolate the result immediately. */
161
162 CONSIDER (BUF_PT (b), BUF_PT_BYTE (b));
163 CONSIDER (BUF_GPT (b), BUF_GPT_BYTE (b));
164 CONSIDER (BUF_BEGV (b), BUF_BEGV_BYTE (b));
165 CONSIDER (BUF_ZV (b), BUF_ZV_BYTE (b));
166
167 if (b == cached_buffer && BUF_MODIFF (b) == cached_modiff)
168 CONSIDER (cached_charpos, cached_bytepos);
169
5e097e00 170 for (tail = BUF_MARKERS (b); tail; tail = tail->next)
1389ad71 171 {
5e097e00 172 CONSIDER (tail->charpos, tail->bytepos);
1389ad71
RS
173
174 /* If we are down to a range of 50 chars,
175 don't bother checking any other markers;
176 scan the intervening chars directly now. */
177 if (best_above - best_below < 50)
178 break;
1389ad71
RS
179 }
180
181 /* We get here if we did not exactly hit one of the known places.
182 We have one known above and one known below.
183 Scan, counting characters, from whichever one is closer. */
184
185 if (charpos - best_below < best_above - charpos)
186 {
7cded46f 187 bool record = charpos - best_below > 5000;
1389ad71
RS
188
189 while (best_below != charpos)
190 {
191 best_below++;
192 BUF_INC_POS (b, best_below_byte);
193 }
194
195 /* If this position is quite far from the nearest known position,
196 cache the correspondence by creating a marker here.
197 It will last until the next GC. */
198 if (record)
657924ff 199 build_marker (b, best_below, best_below_byte);
1389ad71 200
9d44f8ce 201 byte_char_debug_check (b, best_below, best_below_byte);
6e57421b 202
1389ad71
RS
203 cached_buffer = b;
204 cached_modiff = BUF_MODIFF (b);
205 cached_charpos = best_below;
206 cached_bytepos = best_below_byte;
207
208 return best_below_byte;
209 }
210 else
211 {
7cded46f 212 bool record = best_above - charpos > 5000;
1389ad71
RS
213
214 while (best_above != charpos)
215 {
216 best_above--;
217 BUF_DEC_POS (b, best_above_byte);
218 }
219
220 /* If this position is quite far from the nearest known position,
221 cache the correspondence by creating a marker here.
222 It will last until the next GC. */
223 if (record)
657924ff 224 build_marker (b, best_above, best_above_byte);
1389ad71 225
9d44f8ce 226 byte_char_debug_check (b, best_above, best_above_byte);
6e57421b 227
1389ad71
RS
228 cached_buffer = b;
229 cached_modiff = BUF_MODIFF (b);
230 cached_charpos = best_above;
231 cached_bytepos = best_above_byte;
232
233 return best_above_byte;
234 }
235}
236
237#undef CONSIDER
55a91ea3 238
b4c3046a 239/* This macro is a subroutine of buf_bytepos_to_charpos.
1389ad71
RS
240 It is used when BYTEPOS is actually the byte position. */
241
242#define CONSIDER(BYTEPOS, CHARPOS) \
243{ \
d311d28c 244 ptrdiff_t this_bytepos = (BYTEPOS); \
1389ad71
RS
245 int changed = 0; \
246 \
247 if (this_bytepos == bytepos) \
6e57421b 248 { \
d311d28c 249 ptrdiff_t value = (CHARPOS); \
90fc4786
DA
250 \
251 byte_char_debug_check (b, value, bytepos); \
6e57421b
RS
252 return value; \
253 } \
1389ad71
RS
254 else if (this_bytepos > bytepos) \
255 { \
256 if (this_bytepos < best_above_byte) \
257 { \
258 best_above = (CHARPOS); \
259 best_above_byte = this_bytepos; \
260 changed = 1; \
261 } \
262 } \
263 else if (this_bytepos > best_below_byte) \
264 { \
265 best_below = (CHARPOS); \
266 best_below_byte = this_bytepos; \
267 changed = 1; \
268 } \
269 \
270 if (changed) \
271 { \
272 if (best_above - best_below == best_above_byte - best_below_byte) \
6e57421b 273 { \
d311d28c 274 ptrdiff_t value = best_below + (bytepos - best_below_byte); \
90fc4786
DA
275 \
276 byte_char_debug_check (b, value, bytepos); \
6e57421b
RS
277 return value; \
278 } \
1389ad71
RS
279 } \
280}
281
13002885
DA
282/* Return the character position corresponding to BYTEPOS in B. */
283
d311d28c
PE
284ptrdiff_t
285buf_bytepos_to_charpos (struct buffer *b, ptrdiff_t bytepos)
1389ad71 286{
5e097e00 287 struct Lisp_Marker *tail;
d311d28c
PE
288 ptrdiff_t best_above, best_above_byte;
289 ptrdiff_t best_below, best_below_byte;
1389ad71 290
13002885 291 eassert (BUF_BEG_BYTE (b) <= bytepos && bytepos <= BUF_Z_BYTE (b));
1389ad71
RS
292
293 best_above = BUF_Z (b);
294 best_above_byte = BUF_Z_BYTE (b);
295
296 /* If this buffer has as many characters as bytes,
297 each character must be one byte.
298 This takes care of the case where enable-multibyte-characters is nil. */
299 if (best_above == best_above_byte)
300 return bytepos;
301
3ab364ce
SM
302 best_below = BEG;
303 best_below_byte = BEG_BYTE;
1389ad71
RS
304
305 CONSIDER (BUF_PT_BYTE (b), BUF_PT (b));
306 CONSIDER (BUF_GPT_BYTE (b), BUF_GPT (b));
307 CONSIDER (BUF_BEGV_BYTE (b), BUF_BEGV (b));
308 CONSIDER (BUF_ZV_BYTE (b), BUF_ZV (b));
309
310 if (b == cached_buffer && BUF_MODIFF (b) == cached_modiff)
311 CONSIDER (cached_bytepos, cached_charpos);
312
5e097e00 313 for (tail = BUF_MARKERS (b); tail; tail = tail->next)
1389ad71 314 {
5e097e00 315 CONSIDER (tail->bytepos, tail->charpos);
1389ad71
RS
316
317 /* If we are down to a range of 50 chars,
318 don't bother checking any other markers;
319 scan the intervening chars directly now. */
320 if (best_above - best_below < 50)
321 break;
1389ad71
RS
322 }
323
324 /* We get here if we did not exactly hit one of the known places.
325 We have one known above and one known below.
326 Scan, counting characters, from whichever one is closer. */
327
328 if (bytepos - best_below_byte < best_above_byte - bytepos)
329 {
7cded46f 330 bool record = bytepos - best_below_byte > 5000;
1389ad71
RS
331
332 while (best_below_byte < bytepos)
333 {
334 best_below++;
335 BUF_INC_POS (b, best_below_byte);
336 }
337
338 /* If this position is quite far from the nearest known position,
339 cache the correspondence by creating a marker here.
7693a579
RS
340 It will last until the next GC.
341 But don't do it if BUF_MARKERS is nil;
342 that is a signal from Fset_buffer_multibyte. */
5e097e00 343 if (record && BUF_MARKERS (b))
657924ff 344 build_marker (b, best_below, best_below_byte);
1389ad71 345
9d44f8ce 346 byte_char_debug_check (b, best_below, best_below_byte);
6e57421b 347
1389ad71
RS
348 cached_buffer = b;
349 cached_modiff = BUF_MODIFF (b);
350 cached_charpos = best_below;
351 cached_bytepos = best_below_byte;
352
353 return best_below;
354 }
355 else
356 {
7cded46f 357 bool record = best_above_byte - bytepos > 5000;
1389ad71
RS
358
359 while (best_above_byte > bytepos)
360 {
361 best_above--;
362 BUF_DEC_POS (b, best_above_byte);
363 }
364
365 /* If this position is quite far from the nearest known position,
366 cache the correspondence by creating a marker here.
7693a579
RS
367 It will last until the next GC.
368 But don't do it if BUF_MARKERS is nil;
369 that is a signal from Fset_buffer_multibyte. */
5e097e00 370 if (record && BUF_MARKERS (b))
657924ff 371 build_marker (b, best_above, best_above_byte);
1389ad71 372
9d44f8ce 373 byte_char_debug_check (b, best_above, best_above_byte);
6e57421b 374
1389ad71
RS
375 cached_buffer = b;
376 cached_modiff = BUF_MODIFF (b);
377 cached_charpos = best_above;
378 cached_bytepos = best_above_byte;
379
380 return best_above;
381 }
382}
383
384#undef CONSIDER
385\f
dcfdbac7
JB
386/* Operations on markers. */
387
a7ca3326 388DEFUN ("marker-buffer", Fmarker_buffer, Smarker_buffer, 1, 1, 0,
2e1280f8
PJ
389 doc: /* Return the buffer that MARKER points into, or nil if none.
390Returns nil if MARKER points into a dead buffer. */)
5842a27b 391 (register Lisp_Object marker)
dcfdbac7
JB
392{
393 register Lisp_Object buf;
b7826503 394 CHECK_MARKER (marker);
dcfdbac7
JB
395 if (XMARKER (marker)->buffer)
396 {
0e11d869 397 XSETBUFFER (buf, XMARKER (marker)->buffer);
0754c46a
SM
398 /* If the buffer is dead, we're in trouble: the buffer pointer here
399 does not preserve the buffer from being GC'd (it's weak), so
400 markers have to be unlinked from their buffer as soon as the buffer
401 is killed. */
e578f381 402 eassert (BUFFER_LIVE_P (XBUFFER (buf)));
0754c46a 403 return buf;
dcfdbac7
JB
404 }
405 return Qnil;
406}
407
a7ca3326 408DEFUN ("marker-position", Fmarker_position, Smarker_position, 1, 1, 0,
243d70e5
JL
409 doc: /* Return the position MARKER points at, as a character number.
410Returns nil if MARKER points nowhere. */)
5842a27b 411 (Lisp_Object marker)
dcfdbac7 412{
b7826503 413 CHECK_MARKER (marker);
dcfdbac7 414 if (XMARKER (marker)->buffer)
1389ad71 415 return make_number (XMARKER (marker)->charpos);
dcfdbac7 416
dcfdbac7
JB
417 return Qnil;
418}
4e57b342
DA
419
420/* Change M so it points to B at CHARPOS and BYTEPOS. */
421
b0ab8123 422static void
4e57b342
DA
423attach_marker (struct Lisp_Marker *m, struct buffer *b,
424 ptrdiff_t charpos, ptrdiff_t bytepos)
425{
d36d71df
DA
426 /* In a single-byte buffer, two positions must be equal.
427 Otherwise, every character is at least one byte. */
428 if (BUF_Z (b) == BUF_Z_BYTE (b))
429 eassert (charpos == bytepos);
430 else
431 eassert (charpos <= bytepos);
4e57b342
DA
432
433 m->charpos = charpos;
434 m->bytepos = bytepos;
435
436 if (m->buffer != b)
437 {
438 unchain_marker (m);
439 m->buffer = b;
440 m->next = BUF_MARKERS (b);
441 BUF_MARKERS (b) = m;
442 }
443}
444
d36d71df
DA
445/* If BUFFER is nil, return current buffer pointer. Next, check
446 whether BUFFER is a buffer object and return buffer pointer
447 corresponding to BUFFER if BUFFER is live, or NULL otherwise. */
dcfdbac7 448
b0ab8123 449static struct buffer *
d36d71df
DA
450live_buffer (Lisp_Object buffer)
451{
452 struct buffer *b;
5e097e00 453
d36d71df 454 if (NILP (buffer))
dcfdbac7 455 {
d36d71df 456 b = current_buffer;
e578f381 457 eassert (BUFFER_LIVE_P (b));
dcfdbac7 458 }
dcfdbac7
JB
459 else
460 {
b7826503 461 CHECK_BUFFER (buffer);
dcfdbac7 462 b = XBUFFER (buffer);
e578f381 463 if (!BUFFER_LIVE_P (b))
d36d71df 464 b = NULL;
1389ad71 465 }
d36d71df 466 return b;
dcfdbac7
JB
467}
468
d36d71df
DA
469/* Internal function to set MARKER in BUFFER at POSITION. Non-zero
470 RESTRICTED means limit the POSITION by the visible part of BUFFER. */
dcfdbac7 471
b0ab8123 472static Lisp_Object
d36d71df 473set_marker_internal (Lisp_Object marker, Lisp_Object position,
7cded46f 474 Lisp_Object buffer, bool restricted)
dcfdbac7 475{
7cded46f
PE
476 struct Lisp_Marker *m;
477 struct buffer *b = live_buffer (buffer);
dcfdbac7 478
b7826503 479 CHECK_MARKER (marker);
5e097e00
SM
480 m = XMARKER (marker);
481
d36d71df
DA
482 /* Set MARKER to point nowhere if BUFFER is dead, or
483 POSITION is nil or a marker points to nowhere. */
484 if (NILP (position)
485 || (MARKERP (position) && !XMARKER (position)->buffer)
486 || !b)
487 unchain_marker (m);
488
489 /* Optimize the special case where we are copying the position of
490 an existing marker, and MARKER is already in the same buffer. */
491 else if (MARKERP (position) && b == XMARKER (position)->buffer
492 && b == m->buffer)
dcfdbac7 493 {
d36d71df
DA
494 m->bytepos = XMARKER (position)->bytepos;
495 m->charpos = XMARKER (position)->charpos;
dcfdbac7
JB
496 }
497
dcfdbac7
JB
498 else
499 {
d36d71df 500 register ptrdiff_t charpos, bytepos;
1088b922 501
f74de345 502 /* Do not use CHECK_NUMBER_COERCE_MARKER because we
8b17a8b9 503 don't want to call buf_charpos_to_bytepos if POSITION
f74de345
DA
504 is a marker and so we know the bytepos already. */
505 if (INTEGERP (position))
506 charpos = XINT (position), bytepos = -1;
507 else if (MARKERP (position))
508 {
509 charpos = XMARKER (position)->charpos;
510 bytepos = XMARKER (position)->bytepos;
511 }
512 else
513 wrong_type_argument (Qinteger_or_marker_p, position);
514
515 charpos = clip_to_bounds
516 (restricted ? BUF_BEGV (b) : BUF_BEG (b), charpos,
517 restricted ? BUF_ZV (b) : BUF_Z (b));
518 if (bytepos == -1)
519 bytepos = buf_charpos_to_bytepos (b, charpos);
520 else
521 bytepos = clip_to_bounds
522 (restricted ? BUF_BEGV_BYTE (b) : BUF_BEG_BYTE (b),
523 bytepos, restricted ? BUF_ZV_BYTE (b) : BUF_Z_BYTE (b));
524
d36d71df 525 attach_marker (m, b, charpos, bytepos);
dcfdbac7 526 }
d36d71df
DA
527 return marker;
528}
dcfdbac7 529
d36d71df
DA
530DEFUN ("set-marker", Fset_marker, Sset_marker, 2, 3, 0,
531 doc: /* Position MARKER before character number POSITION in BUFFER,
532which defaults to the current buffer. If POSITION is nil,
533makes marker point nowhere so it no longer slows down
534editing in any buffer. Returns MARKER. */)
535 (Lisp_Object marker, Lisp_Object position, Lisp_Object buffer)
536{
537 return set_marker_internal (marker, position, buffer, 0);
538}
1389ad71 539
d36d71df 540/* Like the above, but won't let the position be outside the visible part. */
177c0ea7 541
d36d71df
DA
542Lisp_Object
543set_marker_restricted (Lisp_Object marker, Lisp_Object position,
544 Lisp_Object buffer)
545{
546 return set_marker_internal (marker, position, buffer, 1);
dcfdbac7 547}
d36d71df 548
1389ad71
RS
549/* Set the position of MARKER, specifying both the
550 character position and the corresponding byte position. */
dcfdbac7 551
177c0ea7 552Lisp_Object
d36d71df
DA
553set_marker_both (Lisp_Object marker, Lisp_Object buffer,
554 ptrdiff_t charpos, ptrdiff_t bytepos)
1389ad71 555{
1389ad71 556 register struct Lisp_Marker *m;
d36d71df 557 register struct buffer *b = live_buffer (buffer);
1389ad71 558
b7826503 559 CHECK_MARKER (marker);
5e097e00 560 m = XMARKER (marker);
1389ad71 561
d36d71df
DA
562 if (b)
563 attach_marker (m, b, charpos, bytepos);
1389ad71 564 else
d36d71df 565 unchain_marker (m);
1389ad71
RS
566 return marker;
567}
568
d36d71df 569/* Like the above, but won't let the position be outside the visible part. */
1389ad71 570
177c0ea7 571Lisp_Object
d36d71df
DA
572set_marker_restricted_both (Lisp_Object marker, Lisp_Object buffer,
573 ptrdiff_t charpos, ptrdiff_t bytepos)
1389ad71 574{
1389ad71 575 register struct Lisp_Marker *m;
d36d71df 576 register struct buffer *b = live_buffer (buffer);
1389ad71 577
b7826503 578 CHECK_MARKER (marker);
5e097e00 579 m = XMARKER (marker);
1389ad71 580
d36d71df 581 if (b)
1389ad71 582 {
1088b922
PE
583 attach_marker
584 (m, b,
d36d71df
DA
585 clip_to_bounds (BUF_BEGV (b), charpos, BUF_ZV (b)),
586 clip_to_bounds (BUF_BEGV_BYTE (b), bytepos, BUF_ZV_BYTE (b)));
1389ad71 587 }
d36d71df
DA
588 else
589 unchain_marker (m);
1389ad71
RS
590 return marker;
591}
d36d71df 592
7b7ae965
DA
593/* Remove MARKER from the chain of whatever buffer it is in,
594 leaving it points to nowhere. This is called during garbage
595 collection, so we must be careful to ignore and preserve
596 mark bits, including those in chain fields of markers. */
dcfdbac7 597
c0323249 598void
971de7fb 599unchain_marker (register struct Lisp_Marker *marker)
dcfdbac7 600{
7b7ae965 601 register struct buffer *b = marker->buffer;
dcfdbac7 602
7b7ae965 603 if (b)
dcfdbac7 604 {
7b7ae965
DA
605 register struct Lisp_Marker *tail, **prev;
606
607 /* No dead buffers here. */
e578f381 608 eassert (BUFFER_LIVE_P (b));
7b7ae965
DA
609
610 marker->buffer = NULL;
611 prev = &BUF_MARKERS (b);
612
613 for (tail = BUF_MARKERS (b); tail; prev = &tail->next, tail = *prev)
614 if (marker == tail)
615 {
616 if (*prev == BUF_MARKERS (b))
617 {
1088b922 618 /* Deleting first marker from the buffer's chain. Crash
7b7ae965
DA
619 if new first marker in chain does not say it belongs
620 to the same buffer, or at least that they have the same
621 base buffer. */
622 if (tail->next && b->text != tail->next->buffer->text)
1088b922 623 emacs_abort ();
7b7ae965
DA
624 }
625 *prev = tail->next;
626 /* We have removed the marker from the chain;
627 no need to scan the rest of the chain. */
628 break;
629 }
630
631 /* Error if marker was not in it's chain. */
632 eassert (tail != NULL);
dcfdbac7 633 }
dcfdbac7
JB
634}
635
1389ad71 636/* Return the char position of marker MARKER, as a C integer. */
d281a86a 637
d311d28c 638ptrdiff_t
971de7fb 639marker_position (Lisp_Object marker)
dcfdbac7
JB
640{
641 register struct Lisp_Marker *m = XMARKER (marker);
642 register struct buffer *buf = m->buffer;
1389ad71
RS
643
644 if (!buf)
645 error ("Marker does not point anywhere");
646
4e57b342
DA
647 eassert (BUF_BEG (buf) <= m->charpos && m->charpos <= BUF_Z (buf));
648
1389ad71
RS
649 return m->charpos;
650}
651
652/* Return the byte position of marker MARKER, as a C integer. */
653
d311d28c 654ptrdiff_t
971de7fb 655marker_byte_position (Lisp_Object marker)
1389ad71
RS
656{
657 register struct Lisp_Marker *m = XMARKER (marker);
658 register struct buffer *buf = m->buffer;
dcfdbac7
JB
659
660 if (!buf)
661 error ("Marker does not point anywhere");
662
4e57b342 663 eassert (BUF_BEG_BYTE (buf) <= m->bytepos && m->bytepos <= BUF_Z_BYTE (buf));
dcfdbac7 664
4e57b342 665 return m->bytepos;
dcfdbac7 666}
fc299663 667\f
a7ca3326 668DEFUN ("copy-marker", Fcopy_marker, Scopy_marker, 0, 2, 0,
2e1280f8
PJ
669 doc: /* Return a new marker pointing at the same place as MARKER.
670If argument is a number, makes a new marker pointing
671at that position in the current buffer.
cd196f12 672If MARKER is not specified, the new marker does not point anywhere.
2e1280f8
PJ
673The optional argument TYPE specifies the insertion type of the new marker;
674see `marker-insertion-type'. */)
5842a27b 675 (register Lisp_Object marker, Lisp_Object type)
dcfdbac7
JB
676{
677 register Lisp_Object new;
678
cd196f12 679 if (!NILP (marker))
0b4331b7 680 CHECK_TYPE (INTEGERP (marker) || MARKERP (marker), Qinteger_or_marker_p, marker);
0469366f
KH
681
682 new = Fmake_marker ();
683 Fset_marker (new, marker,
684 (MARKERP (marker) ? Fmarker_buffer (marker) : Qnil));
685 XMARKER (new)->insertion_type = !NILP (type);
686 return new;
fc299663
RS
687}
688
689DEFUN ("marker-insertion-type", Fmarker_insertion_type,
690 Smarker_insertion_type, 1, 1, 0,
2e1280f8 691 doc: /* Return insertion type of MARKER: t if it stays after inserted text.
1961ac0f 692The value nil means the marker stays before text inserted there. */)
5842a27b 693 (register Lisp_Object marker)
fc299663 694{
b7826503 695 CHECK_MARKER (marker);
fc299663
RS
696 return XMARKER (marker)->insertion_type ? Qt : Qnil;
697}
698
699DEFUN ("set-marker-insertion-type", Fset_marker_insertion_type,
700 Sset_marker_insertion_type, 2, 2, 0,
2e1280f8
PJ
701 doc: /* Set the insertion-type of MARKER to TYPE.
702If TYPE is t, it means the marker advances when you insert text at it.
703If TYPE is nil, it means the marker stays behind when you insert text at it. */)
5842a27b 704 (Lisp_Object marker, Lisp_Object type)
fc299663 705{
b7826503 706 CHECK_MARKER (marker);
fc299663
RS
707
708 XMARKER (marker)->insertion_type = ! NILP (type);
709 return type;
dcfdbac7 710}
9e5896c6
RS
711
712DEFUN ("buffer-has-markers-at", Fbuffer_has_markers_at, Sbuffer_has_markers_at,
2e1280f8
PJ
713 1, 1, 0,
714 doc: /* Return t if there are markers pointing at POSITION in the current buffer. */)
5842a27b 715 (Lisp_Object position)
9e5896c6 716{
5e097e00 717 register struct Lisp_Marker *tail;
4e57b342 718 register ptrdiff_t charpos;
9e5896c6 719
4e57b342 720 charpos = clip_to_bounds (BEG, XINT (position), Z);
9e5896c6 721
5e097e00 722 for (tail = BUF_MARKERS (current_buffer); tail; tail = tail->next)
4e57b342 723 if (tail->charpos == charpos)
9e5896c6
RS
724 return Qt;
725
726 return Qnil;
727}
59d36066 728
f1f924b6 729#ifdef MARKER_DEBUG
90fc4786 730
59d36066
RS
731/* For debugging -- count the markers in buffer BUF. */
732
733int
971de7fb 734count_markers (struct buffer *buf)
59d36066
RS
735{
736 int total = 0;
5e097e00 737 struct Lisp_Marker *tail;
59d36066 738
5e097e00 739 for (tail = BUF_MARKERS (buf); tail; tail = tail->next)
59d36066
RS
740 total++;
741
742 return total;
743}
90fc4786 744
f1f924b6
DA
745/* For debugging -- recompute the bytepos corresponding
746 to CHARPOS in the simplest, most reliable way. */
747
748ptrdiff_t
749verify_bytepos (ptrdiff_t charpos)
750{
751 ptrdiff_t below = 1;
752 ptrdiff_t below_byte = 1;
753
754 while (below != charpos)
755 {
756 below++;
757 BUF_INC_POS (current_buffer, below_byte);
758 }
759
760 return below_byte;
761}
762
763#endif /* MARKER_DEBUG */
dcfdbac7 764\f
c0323249 765void
971de7fb 766syms_of_marker (void)
dcfdbac7
JB
767{
768 defsubr (&Smarker_position);
769 defsubr (&Smarker_buffer);
770 defsubr (&Sset_marker);
771 defsubr (&Scopy_marker);
fc299663
RS
772 defsubr (&Smarker_insertion_type);
773 defsubr (&Sset_marker_insertion_type);
9e5896c6 774 defsubr (&Sbuffer_has_markers_at);
dcfdbac7 775}