comparison src/marker.c @ 20537:cc87b03bad13

(marker_byte_position): Renamed from marker_position. (marker_position): New function returns the charpos. (Fbuffer_has_markers_at): Test the marker's charpos. (set_marker_restricted, Fset_marker): Set both kinds of position. Optimize case where POSITION is a marker. (set_marker_both, set_marker_restricted_both): New functions. (Fmarker_position): Use the charpos. (charpos_to_bytepos, bytepos_to_charpos): New functions. (buf_charpos_to_bytepos, buf_bytepos_to_charpos): New functions.
author Richard M. Stallman <rms@gnu.org>
date Thu, 01 Jan 1998 02:35:09 +0000
parents 6e2ea54ad704
children d4de7ffb567d
comparison
equal deleted inserted replaced
20536:8f88438d9f61 20537:cc87b03bad13
1 /* Markers: examining, setting and killing. 1 /* Markers: examining, setting and deleting.
2 Copyright (C) 1985 Free Software Foundation, Inc. 2 Copyright (C) 1985, 1997 Free Software Foundation, Inc.
3 3
4 This file is part of GNU Emacs. 4 This file is part of GNU Emacs.
5 5
6 GNU Emacs is free software; you can redistribute it and/or modify 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 7 it under the terms of the GNU General Public License as published by
20 20
21 21
22 #include <config.h> 22 #include <config.h>
23 #include "lisp.h" 23 #include "lisp.h"
24 #include "buffer.h" 24 #include "buffer.h"
25 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
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 int i = XMARKER (tail)->bufpos;
131 CONSIDER (XMARKER (tail)->charpos,
132 (i > gapend_byte ? i - BUF_GAP_SIZE (b)
133 : i > BUF_GPT_BYTE (b) ? BUF_GPT_BYTE (b)
134 : i));
135
136 /* If we are down to a range of 50 chars,
137 don't bother checking any other markers;
138 scan the intervening chars directly now. */
139 if (best_above - best_below < 50)
140 break;
141
142 tail = XMARKER (tail)->chain;
143 }
144
145 /* We get here if we did not exactly hit one of the known places.
146 We have one known above and one known below.
147 Scan, counting characters, from whichever one is closer. */
148
149 if (charpos - best_below < best_above - charpos)
150 {
151 int record = charpos - best_below > 5000;
152
153 while (best_below != charpos)
154 {
155 best_below++;
156 BUF_INC_POS (b, best_below_byte);
157 }
158
159 /* If this position is quite far from the nearest known position,
160 cache the correspondence by creating a marker here.
161 It will last until the next GC. */
162 if (record)
163 {
164 Lisp_Object marker;
165 marker = Fmake_marker ();
166 set_marker_both (marker, Qnil, best_below, best_below_byte);
167 }
168
169 cached_buffer = b;
170 cached_modiff = BUF_MODIFF (b);
171 cached_charpos = best_below;
172 cached_bytepos = best_below_byte;
173
174 return best_below_byte;
175 }
176 else
177 {
178 int record = best_above - charpos > 5000;
179
180 while (best_above != charpos)
181 {
182 best_above--;
183 BUF_DEC_POS (b, best_above_byte);
184 }
185
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 {
191 Lisp_Object marker;
192 marker = Fmake_marker ();
193 set_marker_both (marker, Qnil, best_above, best_above_byte);
194 }
195
196 cached_buffer = b;
197 cached_modiff = BUF_MODIFF (b);
198 cached_charpos = best_above;
199 cached_bytepos = best_above_byte;
200
201 return best_above_byte;
202 }
203 }
204
205 #undef CONSIDER
206
207 /* bytepos_to_charpos returns the char position corresponding to BYTEPOS. */
208
209 /* This macro is a subroutine of bytepos_to_charpos.
210 It is used when BYTEPOS is actually the byte position. */
211
212 #define CONSIDER(BYTEPOS, CHARPOS) \
213 { \
214 int this_bytepos = (BYTEPOS); \
215 int changed = 0; \
216 \
217 if (this_bytepos == bytepos) \
218 return (CHARPOS); \
219 else if (this_bytepos > bytepos) \
220 { \
221 if (this_bytepos < best_above_byte) \
222 { \
223 best_above = (CHARPOS); \
224 best_above_byte = this_bytepos; \
225 changed = 1; \
226 } \
227 } \
228 else if (this_bytepos > best_below_byte) \
229 { \
230 best_below = (CHARPOS); \
231 best_below_byte = this_bytepos; \
232 changed = 1; \
233 } \
234 \
235 if (changed) \
236 { \
237 if (best_above - best_below == best_above_byte - best_below_byte) \
238 return best_below + (bytepos - best_below_byte); \
239 } \
240 }
241
242 int
243 bytepos_to_charpos (bytepos)
244 int bytepos;
245 {
246 return buf_bytepos_to_charpos (current_buffer, bytepos);
247 }
248
249 int
250 buf_bytepos_to_charpos (b, bytepos)
251 struct buffer *b;
252 int bytepos;
253 {
254 Lisp_Object tail;
255 int best_above, best_above_byte;
256 int best_below, best_below_byte;
257
258 if (bytepos < BUF_BEG_BYTE (b) || bytepos > BUF_Z_BYTE (b))
259 abort ();
260
261 best_above = BUF_Z (b);
262 best_above_byte = BUF_Z_BYTE (b);
263
264 /* If this buffer has as many characters as bytes,
265 each character must be one byte.
266 This takes care of the case where enable-multibyte-characters is nil. */
267 if (best_above == best_above_byte)
268 return bytepos;
269
270 best_below = 1;
271 best_below_byte = 1;
272
273 CONSIDER (BUF_PT_BYTE (b), BUF_PT (b));
274 CONSIDER (BUF_GPT_BYTE (b), BUF_GPT (b));
275 CONSIDER (BUF_BEGV_BYTE (b), BUF_BEGV (b));
276 CONSIDER (BUF_ZV_BYTE (b), BUF_ZV (b));
277
278 if (b == cached_buffer && BUF_MODIFF (b) == cached_modiff)
279 CONSIDER (cached_bytepos, cached_charpos);
280
281 tail = BUF_MARKERS (b);
282 while (XSYMBOL (tail) != XSYMBOL (Qnil))
283 {
284 int marker_bytepos = XMARKER (tail)->bufpos;
285
286 if (marker_bytepos > BUF_GPT_BYTE (b) + BUF_GAP_SIZE (b))
287 marker_bytepos -= BUF_GAP_SIZE (b);
288 else if (marker_bytepos > BUF_GPT_BYTE (b))
289 marker_bytepos = BUF_GPT_BYTE (b);
290
291 CONSIDER (marker_bytepos, XMARKER (tail)->charpos);
292
293 /* If we are down to a range of 50 chars,
294 don't bother checking any other markers;
295 scan the intervening chars directly now. */
296 if (best_above - best_below < 50)
297 break;
298
299 tail = XMARKER (tail)->chain;
300 }
301
302 /* We get here if we did not exactly hit one of the known places.
303 We have one known above and one known below.
304 Scan, counting characters, from whichever one is closer. */
305
306 if (bytepos - best_below_byte < best_above_byte - bytepos)
307 {
308 int record = best_above_byte - bytepos > 5000;
309
310 while (best_below_byte < bytepos)
311 {
312 best_below++;
313 BUF_INC_POS (b, best_below_byte);
314 }
315
316 /* If this position is quite far from the nearest known position,
317 cache the correspondence by creating a marker here.
318 It will last until the next GC. */
319 if (record)
320 {
321 Lisp_Object marker;
322 marker = Fmake_marker ();
323 set_marker_both (marker, Qnil, best_below, best_below_byte);
324 }
325
326 cached_buffer = b;
327 cached_modiff = BUF_MODIFF (b);
328 cached_charpos = best_below;
329 cached_bytepos = best_below_byte;
330
331 return best_below;
332 }
333 else
334 {
335 int record = best_above_byte - bytepos > 5000;
336
337 while (best_above_byte > bytepos)
338 {
339 best_above--;
340 BUF_DEC_POS (b, best_above_byte);
341 }
342
343 /* If this position is quite far from the nearest known position,
344 cache the correspondence by creating a marker here.
345 It will last until the next GC. */
346 if (record)
347 {
348 Lisp_Object marker;
349 marker = Fmake_marker ();
350 set_marker_both (marker, Qnil, best_above, best_above_byte);
351 }
352
353 cached_buffer = b;
354 cached_modiff = BUF_MODIFF (b);
355 cached_charpos = best_above;
356 cached_bytepos = best_above_byte;
357
358 return best_above;
359 }
360 }
361
362 #undef CONSIDER
363
26 /* Operations on markers. */ 364 /* Operations on markers. */
27 365
28 DEFUN ("marker-buffer", Fmarker_buffer, Smarker_buffer, 1, 1, 0, 366 DEFUN ("marker-buffer", Fmarker_buffer, Smarker_buffer, 1, 1, 0,
29 "Return the buffer that MARKER points into, or nil if none.\n\ 367 "Return the buffer that MARKER points into, or nil if none.\n\
30 Returns nil if MARKER points into a dead buffer.") 368 Returns nil if MARKER points into a dead buffer.")
52 register int i; 390 register int i;
53 register struct buffer *buf; 391 register struct buffer *buf;
54 392
55 CHECK_MARKER (marker, 0); 393 CHECK_MARKER (marker, 0);
56 if (XMARKER (marker)->buffer) 394 if (XMARKER (marker)->buffer)
57 { 395 return make_number (XMARKER (marker)->charpos);
58 buf = XMARKER (marker)->buffer; 396
59 i = XMARKER (marker)->bufpos;
60
61 if (i > BUF_GPT (buf) + BUF_GAP_SIZE (buf))
62 i -= BUF_GAP_SIZE (buf);
63 else if (i > BUF_GPT (buf))
64 i = BUF_GPT (buf);
65
66 if (i < BUF_BEG (buf) || i > BUF_Z (buf))
67 abort ();
68
69 XSETFASTINT (pos, i);
70 return pos;
71 }
72 return Qnil; 397 return Qnil;
73 } 398 }
74 399
75 DEFUN ("set-marker", Fset_marker, Sset_marker, 2, 3, 0, 400 DEFUN ("set-marker", Fset_marker, Sset_marker, 2, 3, 0,
76 "Position MARKER before character number POSITION in BUFFER.\n\ 401 "Position MARKER before character number POSITION in BUFFER.\n\
79 Then it no longer slows down editing in any buffer.\n\ 404 Then it no longer slows down editing in any buffer.\n\
80 Returns MARKER.") 405 Returns MARKER.")
81 (marker, position, buffer) 406 (marker, position, buffer)
82 Lisp_Object marker, position, buffer; 407 Lisp_Object marker, position, buffer;
83 { 408 {
84 register int charno; 409 register int charno, bytepos;
85 register struct buffer *b; 410 register struct buffer *b;
86 register struct Lisp_Marker *m; 411 register struct Lisp_Marker *m;
87 412
88 CHECK_MARKER (marker, 0); 413 CHECK_MARKER (marker, 0);
89 /* If position is nil or a marker that points nowhere, 414 /* If position is nil or a marker that points nowhere,
93 { 418 {
94 unchain_marker (marker); 419 unchain_marker (marker);
95 return marker; 420 return marker;
96 } 421 }
97 422
98 CHECK_NUMBER_COERCE_MARKER (position, 1);
99 if (NILP (buffer)) 423 if (NILP (buffer))
100 b = current_buffer; 424 b = current_buffer;
101 else 425 else
102 { 426 {
103 CHECK_BUFFER (buffer, 1); 427 CHECK_BUFFER (buffer, 1);
108 unchain_marker (marker); 432 unchain_marker (marker);
109 return marker; 433 return marker;
110 } 434 }
111 } 435 }
112 436
437 m = XMARKER (marker);
438
439 /* Optimize the special case where we are copying the position
440 of an existing marker, and MARKER is already in the same buffer. */
441 if (MARKERP (position) && b == XMARKER (position)->buffer
442 && b == m->buffer)
443 {
444 m->bufpos = XMARKER (position)->bufpos;
445 m->charpos = XMARKER (position)->charpos;
446 return marker;
447 }
448
449 CHECK_NUMBER_COERCE_MARKER (position, 1);
450
113 charno = XINT (position); 451 charno = XINT (position);
114 m = XMARKER (marker);
115 452
116 if (charno < BUF_BEG (b)) 453 if (charno < BUF_BEG (b))
117 charno = BUF_BEG (b); 454 charno = BUF_BEG (b);
118 if (charno > BUF_Z (b)) 455 if (charno > BUF_Z (b))
119 charno = BUF_Z (b); 456 charno = BUF_Z (b);
120 if (charno > BUF_GPT (b)) charno += BUF_GAP_SIZE (b); 457
121 m->bufpos = charno; 458 bytepos = buf_charpos_to_bytepos (b, charno);
459
460 /* Every character is at least one byte. */
461 if (charno > bytepos)
462 abort ();
463
464 if (bytepos > BUF_GPT_BYTE (b))
465 bytepos += BUF_GAP_SIZE (b);
466
467 m->bufpos = bytepos;
468 m->charpos = charno;
122 469
123 if (m->buffer != b) 470 if (m->buffer != b)
124 { 471 {
125 unchain_marker (marker); 472 unchain_marker (marker);
126 m->buffer = b; 473 m->buffer = b;
136 483
137 Lisp_Object 484 Lisp_Object
138 set_marker_restricted (marker, pos, buffer) 485 set_marker_restricted (marker, pos, buffer)
139 Lisp_Object marker, pos, buffer; 486 Lisp_Object marker, pos, buffer;
140 { 487 {
141 register int charno; 488 register int charno, bytepos;
142 register struct buffer *b; 489 register struct buffer *b;
143 register struct Lisp_Marker *m; 490 register struct Lisp_Marker *m;
144 491
145 CHECK_MARKER (marker, 0); 492 CHECK_MARKER (marker, 0);
146 /* If position is nil or a marker that points nowhere, 493 /* If position is nil or a marker that points nowhere,
147 make this marker point nowhere. */ 494 make this marker point nowhere. */
148 if (NILP (pos) || 495 if (NILP (pos)
149 (MARKERP (pos) && !XMARKER (pos)->buffer)) 496 || (MARKERP (pos) && !XMARKER (pos)->buffer))
150 { 497 {
151 unchain_marker (marker); 498 unchain_marker (marker);
152 return marker; 499 return marker;
153 } 500 }
154 501
155 CHECK_NUMBER_COERCE_MARKER (pos, 1);
156 if (NILP (buffer)) 502 if (NILP (buffer))
157 b = current_buffer; 503 b = current_buffer;
158 else 504 else
159 { 505 {
160 CHECK_BUFFER (buffer, 1); 506 CHECK_BUFFER (buffer, 1);
165 unchain_marker (marker); 511 unchain_marker (marker);
166 return marker; 512 return marker;
167 } 513 }
168 } 514 }
169 515
516 m = XMARKER (marker);
517
518 /* Optimize the special case where we are copying the position
519 of an existing marker, and MARKER is already in the same buffer. */
520 if (MARKERP (pos) && b == XMARKER (pos)->buffer
521 && b == m->buffer)
522 {
523 m->bufpos = XMARKER (pos)->bufpos;
524 m->charpos = XMARKER (pos)->charpos;
525 return marker;
526 }
527
528 CHECK_NUMBER_COERCE_MARKER (pos, 1);
529
170 charno = XINT (pos); 530 charno = XINT (pos);
171 m = XMARKER (marker);
172 531
173 if (charno < BUF_BEGV (b)) 532 if (charno < BUF_BEGV (b))
174 charno = BUF_BEGV (b); 533 charno = BUF_BEGV (b);
175 if (charno > BUF_ZV (b)) 534 if (charno > BUF_ZV (b))
176 charno = BUF_ZV (b); 535 charno = BUF_ZV (b);
177 if (charno > BUF_GPT (b)) 536
178 charno += BUF_GAP_SIZE (b); 537 bytepos = buf_charpos_to_bytepos (b, charno);
179 m->bufpos = charno; 538
539 /* Every character is at least one byte. */
540 if (charno > bytepos)
541 abort ();
542
543 if (bytepos > BUF_GPT_BYTE (b))
544 bytepos += BUF_GAP_SIZE (b);
545
546 m->bufpos = bytepos;
547 m->charpos = charno;
180 548
181 if (m->buffer != b) 549 if (m->buffer != b)
182 { 550 {
183 unchain_marker (marker); 551 unchain_marker (marker);
184 m->buffer = b; 552 m->buffer = b;
186 BUF_MARKERS (b) = marker; 554 BUF_MARKERS (b) = marker;
187 } 555 }
188 556
189 return marker; 557 return marker;
190 } 558 }
191 559
560 /* Set the position of MARKER, specifying both the
561 character position and the corresponding byte position. */
562
563 Lisp_Object
564 set_marker_both (marker, buffer, charpos, bytepos)
565 Lisp_Object marker, buffer;
566 int charpos, bytepos;
567 {
568 register struct buffer *b;
569 register struct Lisp_Marker *m;
570
571 CHECK_MARKER (marker, 0);
572 /* If position is nil or a marker that points nowhere,
573 make this marker point nowhere. */
574 if (NILP (charpos)
575 || (MARKERP (charpos) && !XMARKER (charpos)->buffer))
576 {
577 unchain_marker (marker);
578 return marker;
579 }
580
581 CHECK_NUMBER_COERCE_MARKER (charpos, 1);
582 if (NILP (buffer))
583 b = current_buffer;
584 else
585 {
586 CHECK_BUFFER (buffer, 1);
587 b = XBUFFER (buffer);
588 /* If buffer is dead, set marker to point nowhere. */
589 if (EQ (b->name, Qnil))
590 {
591 unchain_marker (marker);
592 return marker;
593 }
594 }
595
596 m = XMARKER (marker);
597
598 /* In a single-byte buffer, the two positions must be equal. */
599 if (BUF_Z (b) == BUF_Z_BYTE (b)
600 && charpos != bytepos)
601 abort ();
602 /* Every character is at least one byte. */
603 if (charpos > bytepos)
604 abort ();
605
606 if (bytepos > BUF_GPT_BYTE (b))
607 bytepos += BUF_GAP_SIZE (b);
608
609 m->bufpos = bytepos;
610 m->charpos = charpos;
611
612 if (m->buffer != b)
613 {
614 unchain_marker (marker);
615 m->buffer = b;
616 m->chain = BUF_MARKERS (b);
617 BUF_MARKERS (b) = marker;
618 }
619
620 return marker;
621 }
622
623 /* This version of set_marker_both won't let the position
624 be outside the visible part. */
625
626 Lisp_Object
627 set_marker_restricted_both (marker, buffer, charpos, bytepos)
628 Lisp_Object marker, buffer;
629 int charpos, bytepos;
630 {
631 register struct buffer *b;
632 register struct Lisp_Marker *m;
633
634 CHECK_MARKER (marker, 0);
635
636 if (NILP (buffer))
637 b = current_buffer;
638 else
639 {
640 CHECK_BUFFER (buffer, 1);
641 b = XBUFFER (buffer);
642 /* If buffer is dead, set marker to point nowhere. */
643 if (EQ (b->name, Qnil))
644 {
645 unchain_marker (marker);
646 return marker;
647 }
648 }
649
650 m = XMARKER (marker);
651
652 if (charpos < BUF_BEGV (b))
653 charpos = BUF_BEGV (b);
654 if (charpos > BUF_ZV (b))
655 charpos = BUF_ZV (b);
656 if (bytepos < BUF_BEGV_BYTE (b))
657 bytepos = BUF_BEGV_BYTE (b);
658 if (bytepos > BUF_ZV_BYTE (b))
659 bytepos = BUF_ZV_BYTE (b);
660
661 /* In a single-byte buffer, the two positions must be equal. */
662 if (BUF_Z (b) == BUF_Z_BYTE (b)
663 && charpos != bytepos)
664 abort ();
665 /* Every character is at least one byte. */
666 if (charpos > bytepos)
667 abort ();
668
669 if (bytepos > BUF_GPT_BYTE (b))
670 bytepos += BUF_GAP_SIZE (b);
671
672 m->bufpos = bytepos;
673 m->charpos = charpos;
674
675 if (m->buffer != b)
676 {
677 unchain_marker (marker);
678 m->buffer = b;
679 m->chain = BUF_MARKERS (b);
680 BUF_MARKERS (b) = marker;
681 }
682
683 return marker;
684 }
685
192 /* This is called during garbage collection, 686 /* This is called during garbage collection,
193 so we must be careful to ignore and preserve mark bits, 687 so we must be careful to ignore and preserve mark bits,
194 including those in chain fields of markers. */ 688 including those in chain fields of markers. */
195 689
196 void 690 void
240 tail = next; 734 tail = next;
241 } 735 }
242 XMARKER (marker)->buffer = 0; 736 XMARKER (marker)->buffer = 0;
243 } 737 }
244 738
245 /* Return the buffer position of marker MARKER, as a C integer. */ 739 /* Return the char position of marker MARKER, as a C integer. */
246 740
247 int 741 int
248 marker_position (marker) 742 marker_position (marker)
249 Lisp_Object marker; 743 Lisp_Object marker;
250 { 744 {
251 register struct Lisp_Marker *m = XMARKER (marker); 745 register struct Lisp_Marker *m = XMARKER (marker);
252 register struct buffer *buf = m->buffer; 746 register struct buffer *buf = m->buffer;
253 register int i = m->bufpos;
254 747
255 if (!buf) 748 if (!buf)
256 error ("Marker does not point anywhere"); 749 error ("Marker does not point anywhere");
257 750
258 if (i > BUF_GPT (buf) + BUF_GAP_SIZE (buf)) 751 return m->charpos;
752 }
753
754 /* Return the byte position of marker MARKER, as a C integer. */
755
756 int
757 marker_byte_position (marker)
758 Lisp_Object marker;
759 {
760 register struct Lisp_Marker *m = XMARKER (marker);
761 register struct buffer *buf = m->buffer;
762 register int i = m->bufpos;
763
764 if (!buf)
765 error ("Marker does not point anywhere");
766
767 if (i > BUF_GPT_BYTE (buf) + BUF_GAP_SIZE (buf))
259 i -= BUF_GAP_SIZE (buf); 768 i -= BUF_GAP_SIZE (buf);
260 else if (i > BUF_GPT (buf)) 769 else if (i > BUF_GPT_BYTE (buf))
261 i = BUF_GPT (buf); 770 i = BUF_GPT_BYTE (buf);
262 771
263 if (i < BUF_BEG (buf) || i > BUF_Z (buf)) 772 if (i < BUF_BEG_BYTE (buf) || i > BUF_Z_BYTE (buf))
264 abort (); 773 abort ();
265 774
266 return i; 775 return i;
267 } 776 }
268 777
315 return type; 824 return type;
316 } 825 }
317 826
318 DEFUN ("buffer-has-markers-at", Fbuffer_has_markers_at, Sbuffer_has_markers_at, 827 DEFUN ("buffer-has-markers-at", Fbuffer_has_markers_at, Sbuffer_has_markers_at,
319 1, 1, 0, 828 1, 1, 0,
320 "Return t if there are markers pointing at POSITION in the currentbuffer.") 829 "Return t if there are markers pointing at POSITION in the current buffer.")
321 (position) 830 (position)
322 Lisp_Object position; 831 Lisp_Object position;
323 { 832 {
324 register Lisp_Object tail; 833 register Lisp_Object tail;
325 register int charno; 834 register int charno;
328 837
329 if (charno < BEG) 838 if (charno < BEG)
330 charno = BEG; 839 charno = BEG;
331 if (charno > Z) 840 if (charno > Z)
332 charno = Z; 841 charno = Z;
333 if (charno > GPT) charno += GAP_SIZE;
334 842
335 for (tail = BUF_MARKERS (current_buffer); 843 for (tail = BUF_MARKERS (current_buffer);
336 XSYMBOL (tail) != XSYMBOL (Qnil); 844 XSYMBOL (tail) != XSYMBOL (Qnil);
337 tail = XMARKER (tail)->chain) 845 tail = XMARKER (tail)->chain)
338 if (XMARKER (tail)->bufpos == charno) 846 if (XMARKER (tail)->charpos == charno)
339 return Qt; 847 return Qt;
340 848
341 return Qnil; 849 return Qnil;
342 } 850 }
343 851