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