comparison src/insdel.c @ 428:3ecd8885ac67 r21-2-22

Import from CVS: tag r21-2-22
author cvs
date Mon, 13 Aug 2007 11:28:15 +0200
parents
children 84b14dcb0985
comparison
equal deleted inserted replaced
427:0a0253eac470 428:3ecd8885ac67
1 /* Buffer insertion/deletion and gap motion for XEmacs.
2 Copyright (C) 1985, 1986, 1991, 1992, 1993, 1994, 1995
3 Free Software Foundation, Inc.
4 Copyright (C) 1995 Sun Microsystems, Inc.
5
6 This file is part of XEmacs.
7
8 XEmacs is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
11 later version.
12
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with XEmacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
22
23 /* Synched up with: Mule 2.0, FSF 19.30. Diverges significantly. */
24
25 /* This file has been Mule-ized. */
26
27 /* Overhauled by Ben Wing, December 1994, for Mule implementation. */
28
29 /*
30 There are three possible ways to specify positions in a buffer. All
31 of these are one-based: the beginning of the buffer is position or
32 index 1, and 0 is not a valid position.
33
34 As a "buffer position" (typedef Bufpos):
35
36 This is an index specifying an offset in characters from the
37 beginning of the buffer. Note that buffer positions are
38 logically *between* characters, not on a character. The
39 difference between two buffer positions specifies the number of
40 characters between those positions. Buffer positions are the
41 only kind of position externally visible to the user.
42
43 As a "byte index" (typedef Bytind):
44
45 This is an index over the bytes used to represent the characters
46 in the buffer. If there is no Mule support, this is identical
47 to a buffer position, because each character is represented
48 using one byte. However, with Mule support, many characters
49 require two or more bytes for their representation, and so a
50 byte index may be greater than the corresponding buffer
51 position.
52
53 As a "memory index" (typedef Memind):
54
55 This is the byte index adjusted for the gap. For positions
56 before the gap, this is identical to the byte index. For
57 positions after the gap, this is the byte index plus the gap
58 size. There are two possible memory indices for the gap
59 position; the memory index at the beginning of the gap should
60 always be used, except in code that deals with manipulating the
61 gap, where both indices may be seen. The address of the
62 character "at" (i.e. following) a particular position can be
63 obtained from the formula
64
65 buffer_start_address + memory_index(position) - 1
66
67 except in the case of characters at the gap position.
68
69 Other typedefs:
70 ===============
71
72 Emchar:
73 -------
74 This typedef represents a single Emacs character, which can be
75 ASCII, ISO-8859, or some extended character, as would typically
76 be used for Kanji. Note that the representation of a character
77 as an Emchar is *not* the same as the representation of that
78 same character in a string; thus, you cannot do the standard
79 C trick of passing a pointer to a character to a function that
80 expects a string.
81
82 An Emchar takes up 19 bits of representation and (for code
83 compatibility and such) is compatible with an int. This
84 representation is visible on the Lisp level. The important
85 characteristics of the Emchar representation are
86
87 -- values 0x00 - 0x7f represent ASCII.
88 -- values 0x80 - 0xff represent the right half of ISO-8859-1.
89 -- values 0x100 and up represent all other characters.
90
91 This means that Emchar values are upwardly compatible with
92 the standard 8-bit representation of ASCII/ISO-8859-1.
93
94 Bufbyte:
95 --------
96 The data in a buffer or string is logically made up of Bufbyte
97 objects, where a Bufbyte takes up the same amount of space as a
98 char. (It is declared differently, though, to catch invalid
99 usages.) Strings stored using Bufbytes are said to be in
100 "internal format". The important characteristics of internal
101 format are
102
103 -- ASCII characters are represented as a single Bufbyte,
104 in the range 0 - 0x7f.
105 -- All other characters are represented as a Bufbyte in
106 the range 0x80 - 0x9f followed by one or more Bufbytes
107 in the range 0xa0 to 0xff.
108
109 This leads to a number of desirable properties:
110
111 -- Given the position of the beginning of a character,
112 you can find the beginning of the next or previous
113 character in constant time.
114 -- When searching for a substring or an ASCII character
115 within the string, you need merely use standard
116 searching routines.
117
118 array of char:
119 --------------
120 Strings that go in or out of Emacs are in "external format",
121 typedef'ed as an array of char or a char *. There is more
122 than one external format (JIS, EUC, etc.) but they all
123 have similar properties. They are modal encodings,
124 which is to say that the meaning of particular bytes is
125 not fixed but depends on what "mode" the string is currently
126 in (e.g. bytes in the range 0 - 0x7f might be
127 interpreted as ASCII, or as Hiragana, or as 2-byte Kanji,
128 depending on the current mode). The mode starts out in
129 ASCII/ISO-8859-1 and is switched using escape sequences --
130 for example, in the JIS encoding, 'ESC $ B' switches to a
131 mode where pairs of bytes in the range 0 - 0x7f
132 are interpreted as Kanji characters.
133
134 External-formatted data is generally desirable for passing
135 data between programs because it is upwardly compatible
136 with standard ASCII/ISO-8859-1 strings and may require
137 less space than internal encodings such as the one
138 described above. In addition, some encodings (e.g. JIS)
139 keep all characters (except the ESC used to switch modes)
140 in the printing ASCII range 0x20 - 0x7e, which results in
141 a much higher probability that the data will avoid being
142 garbled in transmission. Externally-formatted data is
143 generally not very convenient to work with, however, and
144 for this reason is usually converted to internal format
145 before any work is done on the string.
146
147 NOTE: filenames need to be in external format so that
148 ISO-8859-1 characters come out correctly.
149
150 Charcount:
151 ----------
152 This typedef represents a count of characters, such as
153 a character offset into a string or the number of
154 characters between two positions in a buffer. The
155 difference between two Bufpos's is a Charcount, and
156 character positions in a string are represented using
157 a Charcount.
158
159 Bytecount:
160 ----------
161 Similar to a Charcount but represents a count of bytes.
162 The difference between two Bytind's is a Bytecount.
163
164
165 Usage of the various representations:
166 =====================================
167
168 Memory indices are used in low-level functions in insdel.c and for
169 extent endpoints and marker positions. The reason for this is that
170 this way, the extents and markers don't need to be updated for most
171 insertions, which merely shrink the gap and don't move any
172 characters around in memory.
173
174 (The beginning-of-gap memory index simplifies insertions w.r.t.
175 markers, because text usually gets inserted after markers. For
176 extents, it is merely for consistency, because text can get
177 inserted either before or after an extent's endpoint depending on
178 the open/closedness of the endpoint.)
179
180 Byte indices are used in other code that needs to be fast,
181 such as the searching, redisplay, and extent-manipulation code.
182
183 Buffer positions are used in all other code. This is because this
184 representation is easiest to work with (especially since Lisp
185 code always uses buffer positions), necessitates the fewest
186 changes to existing code, and is the safest (e.g. if the text gets
187 shifted underneath a buffer position, it will still point to a
188 character; if text is shifted under a byte index, it might point
189 to the middle of a character, which would be bad).
190
191 Similarly, Charcounts are used in all code that deals with strings
192 except for code that needs to be fast, which used Bytecounts.
193
194 Strings are always passed around internally using internal format.
195 Conversions between external format are performed at the time
196 that the data goes in or out of Emacs.
197
198 Working with the various representations:
199 ========================================= */
200
201 #include <config.h>
202 #include "lisp.h"
203 #include <limits.h>
204
205 #include "buffer.h"
206 #include "device.h"
207 #include "frame.h"
208 #include "extents.h"
209 #include "insdel.h"
210 #include "lstream.h"
211 #include "redisplay.h"
212 #include "line-number.h"
213
214 /* We write things this way because it's very important the
215 MAX_BYTIND_GAP_SIZE_3 is a multiple of 3. (As it happens,
216 65535 is a multiple of 3, but this may not always be the
217 case.) */
218
219 #define MAX_BUFPOS_GAP_SIZE_3 (65535/3)
220 #define MAX_BYTIND_GAP_SIZE_3 (3 * MAX_BUFPOS_GAP_SIZE_3)
221
222 short three_to_one_table[1 + MAX_BYTIND_GAP_SIZE_3];
223
224 /* Various macros modelled along the lines of those in buffer.h.
225 Purposefully omitted from buffer.h because files other than this
226 one should not be using them. */
227
228 /* Address of beginning of buffer. This is an lvalue because
229 BUFFER_ALLOC needs it to be. */
230 #define BUF_BEG_ADDR(buf) ((buf)->text->beg)
231
232 /* Set the address of beginning of buffer. */
233 #define SET_BUF_BEG_ADDR(buf, addr) do { (buf)->text->beg = (addr); } while (0)
234
235 /* Gap size. */
236 #define BUF_GAP_SIZE(buf) ((buf)->text->gap_size + 0)
237 #define BUF_END_GAP_SIZE(buf) ((buf)->text->end_gap_size + 0)
238 /* Set gap size. */
239 #define SET_BUF_GAP_SIZE(buf, value) \
240 do { (buf)->text->gap_size = (value); } while (0)
241 #define SET_BUF_END_GAP_SIZE(buf, value) \
242 do { (buf)->text->end_gap_size = (value); } while (0)
243
244 /* Gap location. */
245 #define BI_BUF_GPT(buf) ((buf)->text->gpt + 0)
246 #define BUF_GPT_ADDR(buf) (BUF_BEG_ADDR (buf) + BI_BUF_GPT (buf) - 1)
247
248 /* Set gap location. */
249 #define SET_BI_BUF_GPT(buf, value) do { (buf)->text->gpt = (value); } while (0)
250
251 /* Set end of buffer. */
252 #define SET_BOTH_BUF_Z(buf, val, bival) \
253 do \
254 { \
255 (buf)->text->z = (bival); \
256 (buf)->text->bufz = (val); \
257 } while (0)
258
259 /* Under Mule, we maintain two sentinels in the buffer: one at the
260 beginning of the gap, and one at the end of the buffer. This
261 allows us to move forward, examining bytes looking for the
262 end of a character, and not worry about running off the end.
263 We do not need corresponding sentinels when moving backwards
264 because we do not have to look past the beginning of a character
265 to find the beginning of the character.
266
267 Every time we change the beginning of the gap, we have to
268 call SET_GAP_SENTINEL().
269
270 Every time we change the total size (characters plus gap)
271 of the buffer, we have to call SET_END_SENTINEL().
272 */
273
274
275 #ifdef MULE
276 # define GAP_CAN_HOLD_SIZE_P(buf, len) (BUF_GAP_SIZE (buf) >= (len) + 1)
277 # define SET_GAP_SENTINEL(buf) (*BUF_GPT_ADDR (buf) = 0)
278 # define BUF_END_SENTINEL_SIZE 1
279 # define SET_END_SENTINEL(buf) \
280 (*(BUF_BEG_ADDR (buf) + BUF_GAP_SIZE (buf) + BI_BUF_Z (buf) - 1) = 0)
281 #else
282 # define GAP_CAN_HOLD_SIZE_P(buf, len) (BUF_GAP_SIZE (buf) >= (len))
283 # define SET_GAP_SENTINEL(buf)
284 # define BUF_END_SENTINEL_SIZE 0
285 # define SET_END_SENTINEL(buf)
286 #endif
287
288
289 /************************************************************************/
290 /* Charcount/Bytecount conversion */
291 /************************************************************************/
292
293 /* Optimization. Do it. Live it. Love it. */
294
295 #ifdef MULE
296
297 /* We include the basic functions here that require no specific
298 knowledge of how data is Mule-encoded into a buffer other
299 than the basic (00 - 7F), (80 - 9F), (A0 - FF) scheme.
300 Anything that requires more specific knowledge goes into
301 mule-charset.c. */
302
303 /* Given a pointer to a text string and a length in bytes, return
304 the equivalent length in characters. */
305
306 Charcount
307 bytecount_to_charcount (CONST Bufbyte *ptr, Bytecount len)
308 {
309 Charcount count = 0;
310 CONST Bufbyte *end = ptr + len;
311
312 #if (LONGBITS == 32 || LONGBITS == 64)
313
314 # if (LONGBITS == 32)
315 # define LONG_BYTES 4
316 # define ALIGN_MASK 0xFFFFFFFCU
317 # define HIGH_BIT_MASK 0x80808080U
318 # else
319 # define LONG_BYTES 8
320 # define ALIGN_MASK 0xFFFFFFFFFFFFFFF8UL
321 /* I had a dream, I was being overrun with early Intel processors ... */
322 # define HIGH_BIT_MASK 0x8080808080808080UL
323 # endif
324
325 /* When we have a large number of bytes to scan, we can be trickier
326 and significantly faster by scanning them in chunks of the CPU word
327 size (assuming that they're all ASCII -- we cut out as soon as
328 we find something non-ASCII). */
329 if (len >= 12)
330 {
331 /* Determine the section in the middle of the string that's
332 amenable to this treatment. Everything has to be aligned
333 on CPU word boundaries. */
334 CONST Bufbyte *aligned_ptr =
335 (CONST Bufbyte *) (((unsigned long) (ptr + LONG_BYTES - 1)) &
336 ALIGN_MASK);
337 CONST Bufbyte *aligned_end =
338 (CONST Bufbyte *) (((unsigned long) end) & ALIGN_MASK);
339
340 /* Handle unaligned stuff at the beginning. */
341 while (ptr < aligned_ptr)
342 {
343 if (!BYTE_ASCII_P (*ptr))
344 goto bail;
345 count++, ptr++;
346 }
347 /* Now do it. */
348 while (ptr < aligned_end)
349 {
350
351 if ((* (unsigned long *) ptr) & HIGH_BIT_MASK)
352 goto bail;
353 ptr += LONG_BYTES;
354 count += LONG_BYTES;
355 }
356 }
357
358 #endif /* LONGBITS == 32 || LONGBITS == 64 */
359
360 bail:
361 while (ptr < end)
362 {
363 count++;
364 INC_CHARPTR (ptr);
365 }
366 #ifdef ERROR_CHECK_BUFPOS
367 /* Bomb out if the specified substring ends in the middle
368 of a character. Note that we might have already gotten
369 a core dump above from an invalid reference, but at least
370 we will get no farther than here. */
371 assert (ptr == end);
372 #endif
373
374 return count;
375 }
376
377 /* Given a pointer to a text string and a length in characters, return
378 the equivalent length in bytes. */
379
380 Bytecount
381 charcount_to_bytecount (CONST Bufbyte *ptr, Charcount len)
382 {
383 CONST Bufbyte *newptr = ptr;
384
385 while (len > 0)
386 {
387 INC_CHARPTR (newptr);
388 len--;
389 }
390 return newptr - ptr;
391 }
392
393 /* The next two functions are the actual meat behind the
394 bufpos-to-bytind and bytind-to-bufpos conversions. Currently
395 the method they use is fairly unsophisticated; see buffer.h.
396
397 Note that bufpos_to_bytind_func() is probably the most-called
398 function in all of XEmacs. Therefore, it must be FAST FAST FAST.
399 This is the reason why so much of the code is duplicated.
400
401 Similar considerations apply to bytind_to_bufpos_func(), although
402 less so because the function is not called so often.
403
404 #### At some point this should use a more sophisticated method;
405 see buffer.h. */
406
407 static int not_very_random_number;
408
409 Bytind
410 bufpos_to_bytind_func (struct buffer *buf, Bufpos x)
411 {
412 Bufpos bufmin;
413 Bufpos bufmax;
414 Bytind bytmin;
415 Bytind bytmax;
416 int size;
417 int forward_p;
418 Bytind retval;
419 int diff_so_far;
420 int add_to_cache = 0;
421
422 /* Check for some cached positions, for speed. */
423 if (x == BUF_PT (buf))
424 return BI_BUF_PT (buf);
425 if (x == BUF_ZV (buf))
426 return BI_BUF_ZV (buf);
427 if (x == BUF_BEGV (buf))
428 return BI_BUF_BEGV (buf);
429
430 bufmin = buf->text->mule_bufmin;
431 bufmax = buf->text->mule_bufmax;
432 bytmin = buf->text->mule_bytmin;
433 bytmax = buf->text->mule_bytmax;
434 size = (1 << buf->text->mule_shifter) + !!buf->text->mule_three_p;
435
436 /* The basic idea here is that we shift the "known region" up or down
437 until it overlaps the specified position. We do this by moving
438 the upper bound of the known region up one character at a time,
439 and moving the lower bound of the known region up as necessary
440 when the size of the character just seen changes.
441
442 We optimize this, however, by first shifting the known region to
443 one of the cached points if it's close by. (We don't check BEG or
444 Z, even though they're cached; most of the time these will be the
445 same as BEGV and ZV, and when they're not, they're not likely
446 to be used.) */
447
448 if (x > bufmax)
449 {
450 Bufpos diffmax = x - bufmax;
451 Bufpos diffpt = x - BUF_PT (buf);
452 Bufpos diffzv = BUF_ZV (buf) - x;
453 /* #### This value could stand some more exploration. */
454 Charcount heuristic_hack = (bufmax - bufmin) >> 2;
455
456 /* Check if the position is closer to PT or ZV than to the
457 end of the known region. */
458
459 if (diffpt < 0)
460 diffpt = -diffpt;
461 if (diffzv < 0)
462 diffzv = -diffzv;
463
464 /* But also implement a heuristic that favors the known region
465 over PT or ZV. The reason for this is that switching to
466 PT or ZV will wipe out the knowledge in the known region,
467 which might be annoying if the known region is large and
468 PT or ZV is not that much closer than the end of the known
469 region. */
470
471 diffzv += heuristic_hack;
472 diffpt += heuristic_hack;
473 if (diffpt < diffmax && diffpt <= diffzv)
474 {
475 bufmax = bufmin = BUF_PT (buf);
476 bytmax = bytmin = BI_BUF_PT (buf);
477 /* We set the size to 1 even though it doesn't really
478 matter because the new known region contains no
479 characters. We do this because this is the most
480 likely size of the characters around the new known
481 region, and we avoid potential yuckiness that is
482 done when size == 3. */
483 size = 1;
484 }
485 if (diffzv < diffmax)
486 {
487 bufmax = bufmin = BUF_ZV (buf);
488 bytmax = bytmin = BI_BUF_ZV (buf);
489 size = 1;
490 }
491 }
492 #ifdef ERROR_CHECK_BUFPOS
493 else if (x >= bufmin)
494 abort ();
495 #endif
496 else
497 {
498 Bufpos diffmin = bufmin - x;
499 Bufpos diffpt = BUF_PT (buf) - x;
500 Bufpos diffbegv = x - BUF_BEGV (buf);
501 /* #### This value could stand some more exploration. */
502 Charcount heuristic_hack = (bufmax - bufmin) >> 2;
503
504 if (diffpt < 0)
505 diffpt = -diffpt;
506 if (diffbegv < 0)
507 diffbegv = -diffbegv;
508
509 /* But also implement a heuristic that favors the known region --
510 see above. */
511
512 diffbegv += heuristic_hack;
513 diffpt += heuristic_hack;
514
515 if (diffpt < diffmin && diffpt <= diffbegv)
516 {
517 bufmax = bufmin = BUF_PT (buf);
518 bytmax = bytmin = BI_BUF_PT (buf);
519 /* We set the size to 1 even though it doesn't really
520 matter because the new known region contains no
521 characters. We do this because this is the most
522 likely size of the characters around the new known
523 region, and we avoid potential yuckiness that is
524 done when size == 3. */
525 size = 1;
526 }
527 if (diffbegv < diffmin)
528 {
529 bufmax = bufmin = BUF_BEGV (buf);
530 bytmax = bytmin = BI_BUF_BEGV (buf);
531 size = 1;
532 }
533 }
534
535 diff_so_far = x > bufmax ? x - bufmax : bufmin - x;
536 if (diff_so_far > 50)
537 {
538 /* If we have to move more than a certain amount, then look
539 into our cache. */
540 int minval = INT_MAX;
541 int found = 0;
542 int i;
543
544 add_to_cache = 1;
545 /* I considered keeping the positions ordered. This would speed
546 up this loop, but updating the cache would take longer, so
547 it doesn't seem like it would really matter. */
548 for (i = 0; i < 16; i++)
549 {
550 int diff = buf->text->mule_bufpos_cache[i] - x;
551
552 if (diff < 0)
553 diff = -diff;
554 if (diff < minval)
555 {
556 minval = diff;
557 found = i;
558 }
559 }
560
561 if (minval < diff_so_far)
562 {
563 bufmax = bufmin = buf->text->mule_bufpos_cache[found];
564 bytmax = bytmin = buf->text->mule_bytind_cache[found];
565 size = 1;
566 }
567 }
568
569 /* It's conceivable that the caching above could lead to X being
570 the same as one of the range edges. */
571 if (x >= bufmax)
572 {
573 Bytind newmax;
574 Bytecount newsize;
575
576 forward_p = 1;
577 while (x > bufmax)
578 {
579 newmax = bytmax;
580
581 INC_BYTIND (buf, newmax);
582 newsize = newmax - bytmax;
583 if (newsize != size)
584 {
585 bufmin = bufmax;
586 bytmin = bytmax;
587 size = newsize;
588 }
589 bytmax = newmax;
590 bufmax++;
591 }
592 retval = bytmax;
593
594 /* #### Should go past the found location to reduce the number
595 of times that this function is called */
596 }
597 else /* x < bufmin */
598 {
599 Bytind newmin;
600 Bytecount newsize;
601
602 forward_p = 0;
603 while (x < bufmin)
604 {
605 newmin = bytmin;
606
607 DEC_BYTIND (buf, newmin);
608 newsize = bytmin - newmin;
609 if (newsize != size)
610 {
611 bufmax = bufmin;
612 bytmax = bytmin;
613 size = newsize;
614 }
615 bytmin = newmin;
616 bufmin--;
617 }
618 retval = bytmin;
619
620 /* #### Should go past the found location to reduce the number
621 of times that this function is called
622 */
623 }
624
625 /* If size is three, than we have to max sure that the range we
626 discovered isn't too large, because we use a fixed-length
627 table to divide by 3. */
628
629 if (size == 3)
630 {
631 int gap = bytmax - bytmin;
632 buf->text->mule_three_p = 1;
633 buf->text->mule_shifter = 1;
634
635 if (gap > MAX_BYTIND_GAP_SIZE_3)
636 {
637 if (forward_p)
638 {
639 bytmin = bytmax - MAX_BYTIND_GAP_SIZE_3;
640 bufmin = bufmax - MAX_BUFPOS_GAP_SIZE_3;
641 }
642 else
643 {
644 bytmax = bytmin + MAX_BYTIND_GAP_SIZE_3;
645 bufmax = bufmin + MAX_BUFPOS_GAP_SIZE_3;
646 }
647 }
648 }
649 else
650 {
651 buf->text->mule_three_p = 0;
652 if (size == 4)
653 buf->text->mule_shifter = 2;
654 else
655 buf->text->mule_shifter = size - 1;
656 }
657
658 buf->text->mule_bufmin = bufmin;
659 buf->text->mule_bufmax = bufmax;
660 buf->text->mule_bytmin = bytmin;
661 buf->text->mule_bytmax = bytmax;
662
663 if (add_to_cache)
664 {
665 int replace_loc;
666
667 /* We throw away a "random" cached value and replace it with
668 the new value. It doesn't actually have to be very random
669 at all, just evenly distributed.
670
671 #### It would be better to use a least-recently-used algorithm
672 or something that tries to space things out, but I'm not sure
673 it's worth it to go to the trouble of maintaining that. */
674 not_very_random_number += 621;
675 replace_loc = not_very_random_number & 15;
676 buf->text->mule_bufpos_cache[replace_loc] = x;
677 buf->text->mule_bytind_cache[replace_loc] = retval;
678 }
679
680 return retval;
681 }
682
683 /* The logic in this function is almost identical to the logic in
684 the previous function. */
685
686 Bufpos
687 bytind_to_bufpos_func (struct buffer *buf, Bytind x)
688 {
689 Bufpos bufmin;
690 Bufpos bufmax;
691 Bytind bytmin;
692 Bytind bytmax;
693 int size;
694 int forward_p;
695 Bufpos retval;
696 int diff_so_far;
697 int add_to_cache = 0;
698
699 /* Check for some cached positions, for speed. */
700 if (x == BI_BUF_PT (buf))
701 return BUF_PT (buf);
702 if (x == BI_BUF_ZV (buf))
703 return BUF_ZV (buf);
704 if (x == BI_BUF_BEGV (buf))
705 return BUF_BEGV (buf);
706
707 bufmin = buf->text->mule_bufmin;
708 bufmax = buf->text->mule_bufmax;
709 bytmin = buf->text->mule_bytmin;
710 bytmax = buf->text->mule_bytmax;
711 size = (1 << buf->text->mule_shifter) + !!buf->text->mule_three_p;
712
713 /* The basic idea here is that we shift the "known region" up or down
714 until it overlaps the specified position. We do this by moving
715 the upper bound of the known region up one character at a time,
716 and moving the lower bound of the known region up as necessary
717 when the size of the character just seen changes.
718
719 We optimize this, however, by first shifting the known region to
720 one of the cached points if it's close by. (We don't check BI_BEG or
721 BI_Z, even though they're cached; most of the time these will be the
722 same as BI_BEGV and BI_ZV, and when they're not, they're not likely
723 to be used.) */
724
725 if (x > bytmax)
726 {
727 Bytind diffmax = x - bytmax;
728 Bytind diffpt = x - BI_BUF_PT (buf);
729 Bytind diffzv = BI_BUF_ZV (buf) - x;
730 /* #### This value could stand some more exploration. */
731 Bytecount heuristic_hack = (bytmax - bytmin) >> 2;
732
733 /* Check if the position is closer to PT or ZV than to the
734 end of the known region. */
735
736 if (diffpt < 0)
737 diffpt = -diffpt;
738 if (diffzv < 0)
739 diffzv = -diffzv;
740
741 /* But also implement a heuristic that favors the known region
742 over BI_PT or BI_ZV. The reason for this is that switching to
743 BI_PT or BI_ZV will wipe out the knowledge in the known region,
744 which might be annoying if the known region is large and
745 BI_PT or BI_ZV is not that much closer than the end of the known
746 region. */
747
748 diffzv += heuristic_hack;
749 diffpt += heuristic_hack;
750 if (diffpt < diffmax && diffpt <= diffzv)
751 {
752 bufmax = bufmin = BUF_PT (buf);
753 bytmax = bytmin = BI_BUF_PT (buf);
754 /* We set the size to 1 even though it doesn't really
755 matter because the new known region contains no
756 characters. We do this because this is the most
757 likely size of the characters around the new known
758 region, and we avoid potential yuckiness that is
759 done when size == 3. */
760 size = 1;
761 }
762 if (diffzv < diffmax)
763 {
764 bufmax = bufmin = BUF_ZV (buf);
765 bytmax = bytmin = BI_BUF_ZV (buf);
766 size = 1;
767 }
768 }
769 #ifdef ERROR_CHECK_BUFPOS
770 else if (x >= bytmin)
771 abort ();
772 #endif
773 else
774 {
775 Bytind diffmin = bytmin - x;
776 Bytind diffpt = BI_BUF_PT (buf) - x;
777 Bytind diffbegv = x - BI_BUF_BEGV (buf);
778 /* #### This value could stand some more exploration. */
779 Bytecount heuristic_hack = (bytmax - bytmin) >> 2;
780
781 if (diffpt < 0)
782 diffpt = -diffpt;
783 if (diffbegv < 0)
784 diffbegv = -diffbegv;
785
786 /* But also implement a heuristic that favors the known region --
787 see above. */
788
789 diffbegv += heuristic_hack;
790 diffpt += heuristic_hack;
791
792 if (diffpt < diffmin && diffpt <= diffbegv)
793 {
794 bufmax = bufmin = BUF_PT (buf);
795 bytmax = bytmin = BI_BUF_PT (buf);
796 /* We set the size to 1 even though it doesn't really
797 matter because the new known region contains no
798 characters. We do this because this is the most
799 likely size of the characters around the new known
800 region, and we avoid potential yuckiness that is
801 done when size == 3. */
802 size = 1;
803 }
804 if (diffbegv < diffmin)
805 {
806 bufmax = bufmin = BUF_BEGV (buf);
807 bytmax = bytmin = BI_BUF_BEGV (buf);
808 size = 1;
809 }
810 }
811
812 diff_so_far = x > bytmax ? x - bytmax : bytmin - x;
813 if (diff_so_far > 50)
814 {
815 /* If we have to move more than a certain amount, then look
816 into our cache. */
817 int minval = INT_MAX;
818 int found = 0;
819 int i;
820
821 add_to_cache = 1;
822 /* I considered keeping the positions ordered. This would speed
823 up this loop, but updating the cache would take longer, so
824 it doesn't seem like it would really matter. */
825 for (i = 0; i < 16; i++)
826 {
827 int diff = buf->text->mule_bytind_cache[i] - x;
828
829 if (diff < 0)
830 diff = -diff;
831 if (diff < minval)
832 {
833 minval = diff;
834 found = i;
835 }
836 }
837
838 if (minval < diff_so_far)
839 {
840 bufmax = bufmin = buf->text->mule_bufpos_cache[found];
841 bytmax = bytmin = buf->text->mule_bytind_cache[found];
842 size = 1;
843 }
844 }
845
846 /* It's conceivable that the caching above could lead to X being
847 the same as one of the range edges. */
848 if (x >= bytmax)
849 {
850 Bytind newmax;
851 Bytecount newsize;
852
853 forward_p = 1;
854 while (x > bytmax)
855 {
856 newmax = bytmax;
857
858 INC_BYTIND (buf, newmax);
859 newsize = newmax - bytmax;
860 if (newsize != size)
861 {
862 bufmin = bufmax;
863 bytmin = bytmax;
864 size = newsize;
865 }
866 bytmax = newmax;
867 bufmax++;
868 }
869 retval = bufmax;
870
871 /* #### Should go past the found location to reduce the number
872 of times that this function is called */
873 }
874 else /* x <= bytmin */
875 {
876 Bytind newmin;
877 Bytecount newsize;
878
879 forward_p = 0;
880 while (x < bytmin)
881 {
882 newmin = bytmin;
883
884 DEC_BYTIND (buf, newmin);
885 newsize = bytmin - newmin;
886 if (newsize != size)
887 {
888 bufmax = bufmin;
889 bytmax = bytmin;
890 size = newsize;
891 }
892 bytmin = newmin;
893 bufmin--;
894 }
895 retval = bufmin;
896
897 /* #### Should go past the found location to reduce the number
898 of times that this function is called
899 */
900 }
901
902 /* If size is three, than we have to max sure that the range we
903 discovered isn't too large, because we use a fixed-length
904 table to divide by 3. */
905
906 if (size == 3)
907 {
908 int gap = bytmax - bytmin;
909 buf->text->mule_three_p = 1;
910 buf->text->mule_shifter = 1;
911
912 if (gap > MAX_BYTIND_GAP_SIZE_3)
913 {
914 if (forward_p)
915 {
916 bytmin = bytmax - MAX_BYTIND_GAP_SIZE_3;
917 bufmin = bufmax - MAX_BUFPOS_GAP_SIZE_3;
918 }
919 else
920 {
921 bytmax = bytmin + MAX_BYTIND_GAP_SIZE_3;
922 bufmax = bufmin + MAX_BUFPOS_GAP_SIZE_3;
923 }
924 }
925 }
926 else
927 {
928 buf->text->mule_three_p = 0;
929 if (size == 4)
930 buf->text->mule_shifter = 2;
931 else
932 buf->text->mule_shifter = size - 1;
933 }
934
935 buf->text->mule_bufmin = bufmin;
936 buf->text->mule_bufmax = bufmax;
937 buf->text->mule_bytmin = bytmin;
938 buf->text->mule_bytmax = bytmax;
939
940 if (add_to_cache)
941 {
942 int replace_loc;
943
944 /* We throw away a "random" cached value and replace it with
945 the new value. It doesn't actually have to be very random
946 at all, just evenly distributed.
947
948 #### It would be better to use a least-recently-used algorithm
949 or something that tries to space things out, but I'm not sure
950 it's worth it to go to the trouble of maintaining that. */
951 not_very_random_number += 621;
952 replace_loc = not_very_random_number & 15;
953 buf->text->mule_bufpos_cache[replace_loc] = retval;
954 buf->text->mule_bytind_cache[replace_loc] = x;
955 }
956
957 return retval;
958 }
959
960 /* Text of length BYTELENGTH and CHARLENGTH (in different units)
961 was inserted at bufpos START. */
962
963 static void
964 buffer_mule_signal_inserted_region (struct buffer *buf, Bufpos start,
965 Bytecount bytelength,
966 Charcount charlength)
967 {
968 int size = (1 << buf->text->mule_shifter) + !!buf->text->mule_three_p;
969 int i;
970
971 /* Adjust the cache of known positions. */
972 for (i = 0; i < 16; i++)
973 {
974
975 if (buf->text->mule_bufpos_cache[i] > start)
976 {
977 buf->text->mule_bufpos_cache[i] += charlength;
978 buf->text->mule_bytind_cache[i] += bytelength;
979 }
980 }
981
982 if (start >= buf->text->mule_bufmax)
983 return;
984
985 /* The insertion is either before the known region, in which case
986 it shoves it forward; or within the known region, in which case
987 it shoves the end forward. (But it may make the known region
988 inconsistent, so we may have to shorten it.) */
989
990 if (start <= buf->text->mule_bufmin)
991 {
992 buf->text->mule_bufmin += charlength;
993 buf->text->mule_bufmax += charlength;
994 buf->text->mule_bytmin += bytelength;
995 buf->text->mule_bytmax += bytelength;
996 }
997 else
998 {
999 Bufpos end = start + charlength;
1000 /* the insertion point divides the known region in two.
1001 Keep the longer half, at least, and expand into the
1002 inserted chunk as much as possible. */
1003
1004 if (start - buf->text->mule_bufmin > buf->text->mule_bufmax - start)
1005 {
1006 Bytind bytestart = (buf->text->mule_bytmin
1007 + size * (start - buf->text->mule_bufmin));
1008 Bytind bytenew;
1009
1010 while (start < end)
1011 {
1012 bytenew = bytestart;
1013 INC_BYTIND (buf, bytenew);
1014 if (bytenew - bytestart != size)
1015 break;
1016 start++;
1017 bytestart = bytenew;
1018 }
1019 if (start != end)
1020 {
1021 buf->text->mule_bufmax = start;
1022 buf->text->mule_bytmax = bytestart;
1023 }
1024 else
1025 {
1026 buf->text->mule_bufmax += charlength;
1027 buf->text->mule_bytmax += bytelength;
1028 }
1029 }
1030 else
1031 {
1032 Bytind byteend = (buf->text->mule_bytmin
1033 + size * (start - buf->text->mule_bufmin)
1034 + bytelength);
1035 Bytind bytenew;
1036
1037 buf->text->mule_bufmax += charlength;
1038 buf->text->mule_bytmax += bytelength;
1039
1040 while (end > start)
1041 {
1042 bytenew = byteend;
1043 DEC_BYTIND (buf, bytenew);
1044 if (byteend - bytenew != size)
1045 break;
1046 end--;
1047 byteend = bytenew;
1048 }
1049 if (start != end)
1050 {
1051 buf->text->mule_bufmin = end;
1052 buf->text->mule_bytmin = byteend;
1053 }
1054 }
1055 }
1056 }
1057
1058 /* Text from START to END (equivalent in Bytinds: from BI_START to
1059 BI_END) was deleted. */
1060
1061 static void
1062 buffer_mule_signal_deleted_region (struct buffer *buf, Bufpos start,
1063 Bufpos end, Bytind bi_start,
1064 Bytind bi_end)
1065 {
1066 int i;
1067
1068 /* Adjust the cache of known positions. */
1069 for (i = 0; i < 16; i++)
1070 {
1071 /* After the end; gets shoved backward */
1072 if (buf->text->mule_bufpos_cache[i] > end)
1073 {
1074 buf->text->mule_bufpos_cache[i] -= end - start;
1075 buf->text->mule_bytind_cache[i] -= bi_end - bi_start;
1076 }
1077 /* In the range; moves to start of range */
1078 else if (buf->text->mule_bufpos_cache[i] > start)
1079 {
1080 buf->text->mule_bufpos_cache[i] = start;
1081 buf->text->mule_bytind_cache[i] = bi_start;
1082 }
1083 }
1084
1085 /* We don't care about any text after the end of the known region. */
1086
1087 end = min (end, buf->text->mule_bufmax);
1088 bi_end = min (bi_end, buf->text->mule_bytmax);
1089 if (start >= end)
1090 return;
1091
1092 /* The end of the known region offsets by the total amount of deletion,
1093 since it's all before it. */
1094
1095 buf->text->mule_bufmax -= end - start;
1096 buf->text->mule_bytmax -= bi_end - bi_start;
1097
1098 /* Now we don't care about any text after the start of the known region. */
1099
1100 end = min (end, buf->text->mule_bufmin);
1101 bi_end = min (bi_end, buf->text->mule_bytmin);
1102 if (start >= end)
1103 return;
1104
1105 buf->text->mule_bufmin -= end - start;
1106 buf->text->mule_bytmin -= bi_end - bi_start;
1107 }
1108
1109 #endif /* MULE */
1110
1111 #ifdef ERROR_CHECK_BUFPOS
1112
1113 Bytind
1114 bufpos_to_bytind (struct buffer *buf, Bufpos x)
1115 {
1116 Bytind retval = real_bufpos_to_bytind (buf, x);
1117 ASSERT_VALID_BYTIND_UNSAFE (buf, retval);
1118 return retval;
1119 }
1120
1121 Bufpos
1122 bytind_to_bufpos (struct buffer *buf, Bytind x)
1123 {
1124 ASSERT_VALID_BYTIND_UNSAFE (buf, x);
1125 return real_bytind_to_bufpos (buf, x);
1126 }
1127
1128 #endif /* ERROR_CHECK_BUFPOS */
1129
1130
1131 /************************************************************************/
1132 /* verifying buffer and string positions */
1133 /************************************************************************/
1134
1135 /* Functions below are tagged with either _byte or _char indicating
1136 whether they return byte or character positions. For a buffer,
1137 a character position is a "Bufpos" and a byte position is a "Bytind".
1138 For strings, these are sometimes typed using "Charcount" and
1139 "Bytecount". */
1140
1141 /* Flags for the functions below are:
1142
1143 GB_ALLOW_PAST_ACCESSIBLE
1144
1145 Allow positions to range over the entire buffer (BUF_BEG to BUF_Z),
1146 rather than just the accessible portion (BUF_BEGV to BUF_ZV).
1147 For strings, this flag has no effect.
1148
1149 GB_COERCE_RANGE
1150
1151 If the position is outside the allowable range, return the lower
1152 or upper bound of the range, whichever is closer to the specified
1153 position.
1154
1155 GB_NO_ERROR_IF_BAD
1156
1157 If the position is outside the allowable range, return -1.
1158
1159 GB_NEGATIVE_FROM_END
1160
1161 If a value is negative, treat it as an offset from the end.
1162 Only applies to strings.
1163
1164 The following additional flags apply only to the functions
1165 that return ranges:
1166
1167 GB_ALLOW_NIL
1168
1169 Either or both positions can be nil. If FROM is nil,
1170 FROM_OUT will contain the lower bound of the allowed range.
1171 If TO is nil, TO_OUT will contain the upper bound of the
1172 allowed range.
1173
1174 GB_CHECK_ORDER
1175
1176 FROM must contain the lower bound and TO the upper bound
1177 of the range. If the positions are reversed, an error is
1178 signalled.
1179
1180 The following is a combination flag:
1181
1182 GB_HISTORICAL_STRING_BEHAVIOR
1183
1184 Equivalent to (GB_NEGATIVE_FROM_END | GB_ALLOW_NIL).
1185 */
1186
1187 /* Return a buffer position stored in a Lisp_Object. Full
1188 error-checking is done on the position. Flags can be specified to
1189 control the behavior of out-of-range values. The default behavior
1190 is to require that the position is within the accessible part of
1191 the buffer (BEGV and ZV), and to signal an error if the position is
1192 out of range.
1193
1194 */
1195
1196 Bufpos
1197 get_buffer_pos_char (struct buffer *b, Lisp_Object pos, unsigned int flags)
1198 {
1199 Bufpos ind;
1200 Bufpos min_allowed, max_allowed;
1201
1202 CHECK_INT_COERCE_MARKER (pos);
1203 ind = XINT (pos);
1204 min_allowed = flags & GB_ALLOW_PAST_ACCESSIBLE ? BUF_BEG (b) : BUF_BEGV (b);
1205 max_allowed = flags & GB_ALLOW_PAST_ACCESSIBLE ? BUF_Z (b) : BUF_ZV (b);
1206
1207 if (ind < min_allowed || ind > max_allowed)
1208 {
1209 if (flags & GB_COERCE_RANGE)
1210 ind = ind < min_allowed ? min_allowed : max_allowed;
1211 else if (flags & GB_NO_ERROR_IF_BAD)
1212 ind = -1;
1213 else
1214 {
1215 Lisp_Object buffer;
1216 XSETBUFFER (buffer, b);
1217 args_out_of_range (buffer, pos);
1218 }
1219 }
1220
1221 return ind;
1222 }
1223
1224 Bytind
1225 get_buffer_pos_byte (struct buffer *b, Lisp_Object pos, unsigned int flags)
1226 {
1227 Bufpos bpos = get_buffer_pos_char (b, pos, flags);
1228 if (bpos < 0) /* could happen with GB_NO_ERROR_IF_BAD */
1229 return -1;
1230 return bufpos_to_bytind (b, bpos);
1231 }
1232
1233 /* Return a pair of buffer positions representing a range of text,
1234 taken from a pair of Lisp_Objects. Full error-checking is
1235 done on the positions. Flags can be specified to control the
1236 behavior of out-of-range values. The default behavior is to
1237 allow the range bounds to be specified in either order
1238 (however, FROM_OUT will always be the lower bound of the range
1239 and TO_OUT the upper bound),to require that the positions
1240 are within the accessible part of the buffer (BEGV and ZV),
1241 and to signal an error if the positions are out of range.
1242 */
1243
1244 void
1245 get_buffer_range_char (struct buffer *b, Lisp_Object from, Lisp_Object to,
1246 Bufpos *from_out, Bufpos *to_out, unsigned int flags)
1247 {
1248 Bufpos min_allowed, max_allowed;
1249
1250 min_allowed = (flags & GB_ALLOW_PAST_ACCESSIBLE) ?
1251 BUF_BEG (b) : BUF_BEGV (b);
1252 max_allowed = (flags & GB_ALLOW_PAST_ACCESSIBLE) ?
1253 BUF_Z (b) : BUF_ZV (b);
1254
1255 if (NILP (from) && (flags & GB_ALLOW_NIL))
1256 *from_out = min_allowed;
1257 else
1258 *from_out = get_buffer_pos_char (b, from, flags | GB_NO_ERROR_IF_BAD);
1259
1260 if (NILP (to) && (flags & GB_ALLOW_NIL))
1261 *to_out = max_allowed;
1262 else
1263 *to_out = get_buffer_pos_char (b, to, flags | GB_NO_ERROR_IF_BAD);
1264
1265 if ((*from_out < 0 || *to_out < 0) && !(flags & GB_NO_ERROR_IF_BAD))
1266 {
1267 Lisp_Object buffer;
1268 XSETBUFFER (buffer, b);
1269 args_out_of_range_3 (buffer, from, to);
1270 }
1271
1272 if (*from_out >= 0 && *to_out >= 0 && *from_out > *to_out)
1273 {
1274 if (flags & GB_CHECK_ORDER)
1275 signal_simple_error_2 ("start greater than end", from, to);
1276 else
1277 {
1278 Bufpos temp = *from_out;
1279 *from_out = *to_out;
1280 *to_out = temp;
1281 }
1282 }
1283 }
1284
1285 void
1286 get_buffer_range_byte (struct buffer *b, Lisp_Object from, Lisp_Object to,
1287 Bytind *from_out, Bytind *to_out, unsigned int flags)
1288 {
1289 Bufpos s, e;
1290
1291 get_buffer_range_char (b, from, to, &s, &e, flags);
1292 if (s >= 0)
1293 *from_out = bufpos_to_bytind (b, s);
1294 else /* could happen with GB_NO_ERROR_IF_BAD */
1295 *from_out = -1;
1296 if (e >= 0)
1297 *to_out = bufpos_to_bytind (b, e);
1298 else
1299 *to_out = -1;
1300 }
1301
1302 static Charcount
1303 get_string_pos_char_1 (Lisp_Object string, Lisp_Object pos, unsigned int flags,
1304 Charcount known_length)
1305 {
1306 Charcount ccpos;
1307 Charcount min_allowed = 0;
1308 Charcount max_allowed = known_length;
1309
1310 /* Computation of KNOWN_LENGTH is potentially expensive so we pass
1311 it in. */
1312 CHECK_INT (pos);
1313 ccpos = XINT (pos);
1314 if (ccpos < 0 && flags & GB_NEGATIVE_FROM_END)
1315 ccpos += max_allowed;
1316
1317 if (ccpos < min_allowed || ccpos > max_allowed)
1318 {
1319 if (flags & GB_COERCE_RANGE)
1320 ccpos = ccpos < min_allowed ? min_allowed : max_allowed;
1321 else if (flags & GB_NO_ERROR_IF_BAD)
1322 ccpos = -1;
1323 else
1324 args_out_of_range (string, pos);
1325 }
1326
1327 return ccpos;
1328 }
1329
1330 Charcount
1331 get_string_pos_char (Lisp_Object string, Lisp_Object pos, unsigned int flags)
1332 {
1333 return get_string_pos_char_1 (string, pos, flags,
1334 XSTRING_CHAR_LENGTH (string));
1335 }
1336
1337 Bytecount
1338 get_string_pos_byte (Lisp_Object string, Lisp_Object pos, unsigned int flags)
1339 {
1340 Charcount ccpos = get_string_pos_char (string, pos, flags);
1341 if (ccpos < 0) /* could happen with GB_NO_ERROR_IF_BAD */
1342 return -1;
1343 return charcount_to_bytecount (XSTRING_DATA (string), ccpos);
1344 }
1345
1346 void
1347 get_string_range_char (Lisp_Object string, Lisp_Object from, Lisp_Object to,
1348 Charcount *from_out, Charcount *to_out,
1349 unsigned int flags)
1350 {
1351 Charcount min_allowed = 0;
1352 Charcount max_allowed = XSTRING_CHAR_LENGTH (string);
1353
1354 if (NILP (from) && (flags & GB_ALLOW_NIL))
1355 *from_out = min_allowed;
1356 else
1357 *from_out = get_string_pos_char_1 (string, from,
1358 flags | GB_NO_ERROR_IF_BAD,
1359 max_allowed);
1360
1361 if (NILP (to) && (flags & GB_ALLOW_NIL))
1362 *to_out = max_allowed;
1363 else
1364 *to_out = get_string_pos_char_1 (string, to,
1365 flags | GB_NO_ERROR_IF_BAD,
1366 max_allowed);
1367
1368 if ((*from_out < 0 || *to_out < 0) && !(flags & GB_NO_ERROR_IF_BAD))
1369 args_out_of_range_3 (string, from, to);
1370
1371 if (*from_out >= 0 && *to_out >= 0 && *from_out > *to_out)
1372 {
1373 if (flags & GB_CHECK_ORDER)
1374 signal_simple_error_2 ("start greater than end", from, to);
1375 else
1376 {
1377 Bufpos temp = *from_out;
1378 *from_out = *to_out;
1379 *to_out = temp;
1380 }
1381 }
1382 }
1383
1384 void
1385 get_string_range_byte (Lisp_Object string, Lisp_Object from, Lisp_Object to,
1386 Bytecount *from_out, Bytecount *to_out,
1387 unsigned int flags)
1388 {
1389 Charcount s, e;
1390
1391 get_string_range_char (string, from, to, &s, &e, flags);
1392 if (s >= 0)
1393 *from_out = charcount_to_bytecount (XSTRING_DATA (string), s);
1394 else /* could happen with GB_NO_ERROR_IF_BAD */
1395 *from_out = -1;
1396 if (e >= 0)
1397 *to_out = charcount_to_bytecount (XSTRING_DATA (string), e);
1398 else
1399 *to_out = -1;
1400
1401 }
1402
1403 Bufpos
1404 get_buffer_or_string_pos_char (Lisp_Object object, Lisp_Object pos,
1405 unsigned int flags)
1406 {
1407 return STRINGP (object) ?
1408 get_string_pos_char (object, pos, flags) :
1409 get_buffer_pos_char (XBUFFER (object), pos, flags);
1410 }
1411
1412 Bytind
1413 get_buffer_or_string_pos_byte (Lisp_Object object, Lisp_Object pos,
1414 unsigned int flags)
1415 {
1416 return STRINGP (object) ?
1417 get_string_pos_byte (object, pos, flags) :
1418 get_buffer_pos_byte (XBUFFER (object), pos, flags);
1419 }
1420
1421 void
1422 get_buffer_or_string_range_char (Lisp_Object object, Lisp_Object from,
1423 Lisp_Object to, Bufpos *from_out,
1424 Bufpos *to_out, unsigned int flags)
1425 {
1426 if (STRINGP (object))
1427 get_string_range_char (object, from, to, from_out, to_out, flags);
1428 else
1429 get_buffer_range_char (XBUFFER (object), from, to, from_out, to_out, flags);
1430 }
1431
1432 void
1433 get_buffer_or_string_range_byte (Lisp_Object object, Lisp_Object from,
1434 Lisp_Object to, Bytind *from_out,
1435 Bytind *to_out, unsigned int flags)
1436 {
1437 if (STRINGP (object))
1438 get_string_range_byte (object, from, to, from_out, to_out, flags);
1439 else
1440 get_buffer_range_byte (XBUFFER (object), from, to, from_out, to_out, flags);
1441 }
1442
1443 Bufpos
1444 buffer_or_string_accessible_begin_char (Lisp_Object object)
1445 {
1446 return STRINGP (object) ? 0 : BUF_BEGV (XBUFFER (object));
1447 }
1448
1449 Bufpos
1450 buffer_or_string_accessible_end_char (Lisp_Object object)
1451 {
1452 return STRINGP (object) ?
1453 XSTRING_CHAR_LENGTH (object) : BUF_ZV (XBUFFER (object));
1454 }
1455
1456 Bytind
1457 buffer_or_string_accessible_begin_byte (Lisp_Object object)
1458 {
1459 return STRINGP (object) ? 0 : BI_BUF_BEGV (XBUFFER (object));
1460 }
1461
1462 Bytind
1463 buffer_or_string_accessible_end_byte (Lisp_Object object)
1464 {
1465 return STRINGP (object) ?
1466 XSTRING_LENGTH (object) : BI_BUF_ZV (XBUFFER (object));
1467 }
1468
1469 Bufpos
1470 buffer_or_string_absolute_begin_char (Lisp_Object object)
1471 {
1472 return STRINGP (object) ? 0 : BUF_BEG (XBUFFER (object));
1473 }
1474
1475 Bufpos
1476 buffer_or_string_absolute_end_char (Lisp_Object object)
1477 {
1478 return STRINGP (object) ?
1479 XSTRING_CHAR_LENGTH (object) : BUF_Z (XBUFFER (object));
1480 }
1481
1482 Bytind
1483 buffer_or_string_absolute_begin_byte (Lisp_Object object)
1484 {
1485 return STRINGP (object) ? 0 : BI_BUF_BEG (XBUFFER (object));
1486 }
1487
1488 Bytind
1489 buffer_or_string_absolute_end_byte (Lisp_Object object)
1490 {
1491 return STRINGP (object) ?
1492 XSTRING_LENGTH (object) : BI_BUF_Z (XBUFFER (object));
1493 }
1494
1495
1496 /************************************************************************/
1497 /* point and marker adjustment */
1498 /************************************************************************/
1499
1500 /* just_set_point() is the only place `PT' is an lvalue in all of emacs.
1501 This function is called from set_buffer_point(), which is the function
1502 that the SET_PT and BUF_SET_PT macros expand into, and from the
1503 routines below that insert and delete text. (This is in cases where
1504 the point marker logically doesn't move but PT (being a byte index)
1505 needs to get adjusted.) */
1506
1507 /* Set point to a specified value. This is used only when the value
1508 of point changes due to an insert or delete; it does not represent
1509 a conceptual change in point as a marker. In particular, point is
1510 not crossing any interval boundaries, so there's no need to use the
1511 usual SET_PT macro. In fact it would be incorrect to do so, because
1512 either the old or the new value of point is out of synch with the
1513 current set of intervals. */
1514
1515 /* This gets called more than enough to make the function call
1516 overhead a significant factor so we've turned it into a macro. */
1517 #define JUST_SET_POINT(buf, bufpos, ind) \
1518 do \
1519 { \
1520 buf->bufpt = (bufpos); \
1521 buf->pt = (ind); \
1522 } while (0)
1523
1524 /* Set a buffer's point. */
1525
1526 void
1527 set_buffer_point (struct buffer *buf, Bufpos bufpos, Bytind bytpos)
1528 {
1529 assert (bytpos >= BI_BUF_BEGV (buf) && bytpos <= BI_BUF_ZV (buf));
1530 if (bytpos == BI_BUF_PT (buf))
1531 return;
1532 JUST_SET_POINT (buf, bufpos, bytpos);
1533 MARK_POINT_CHANGED;
1534 assert (MARKERP (buf->point_marker));
1535 XMARKER (buf->point_marker)->memind =
1536 bytind_to_memind (buf, bytpos);
1537
1538 /* FSF makes sure that PT is not being set within invisible text.
1539 However, this is the wrong place for that check. The check
1540 should happen only at the next redisplay. */
1541
1542 /* Some old coder said:
1543
1544 "If there were to be hooks which were run when point entered/left an
1545 extent, this would be the place to put them.
1546
1547 However, it's probably the case that such hooks should be implemented
1548 using a post-command-hook instead, to avoid running the hooks as a
1549 result of intermediate motion inside of save-excursions, for example."
1550
1551 I definitely agree with this. PT gets moved all over the place
1552 and it would be a Bad Thing for any hooks to get called, both for
1553 the reason above and because many callers are not prepared for
1554 a GC within this function. --ben
1555 */
1556 }
1557
1558 /* Do the correct marker-like adjustment on MPOS (see below). FROM, TO,
1559 and AMOUNT are as in adjust_markers(). If MPOS doesn't need to be
1560 adjusted, nothing will happen. */
1561 Memind
1562 do_marker_adjustment (Memind mpos, Memind from,
1563 Memind to, Bytecount amount)
1564 {
1565 if (amount > 0)
1566 {
1567 if (mpos > to && mpos < to + amount)
1568 mpos = to + amount;
1569 }
1570 else
1571 {
1572 if (mpos > from + amount && mpos <= from)
1573 mpos = from + amount;
1574 }
1575 if (mpos > from && mpos <= to)
1576 mpos += amount;
1577 return mpos;
1578 }
1579
1580 /* Do the following:
1581
1582 (1) Add `amount' to the position of every marker in the current buffer
1583 whose current position is between `from' (exclusive) and `to' (inclusive).
1584
1585 (2) Also, any markers past the outside of that interval, in the direction
1586 of adjustment, are first moved back to the near end of the interval
1587 and then adjusted by `amount'.
1588
1589 This function is called in two different cases: when a region of
1590 characters adjacent to the gap is moved, causing the gap to shift
1591 to the other side of the region (in this case, `from' and `to'
1592 point to the old position of the region and there should be no
1593 markers affected by (2) because they would be inside the gap),
1594 or when a region of characters adjacent to the gap is wiped out,
1595 causing the gap to increase to include the region (in this case,
1596 `from' and `to' are the same, both pointing to the boundary
1597 between the gap and the deleted region, and there are no markers
1598 affected by (1)).
1599
1600 The reason for the use of exclusive and inclusive is that markers at
1601 the gap always sit at the beginning, not at the end.
1602 */
1603
1604 static void
1605 adjust_markers (struct buffer *buf, Memind from, Memind to,
1606 Bytecount amount)
1607 {
1608 struct Lisp_Marker *m;
1609
1610 for (m = BUF_MARKERS (buf); m; m = marker_next (m))
1611 m->memind = do_marker_adjustment (m->memind, from, to, amount);
1612 }
1613
1614 /* Adjust markers whose insertion-type is t
1615 for an insertion of AMOUNT characters at POS. */
1616
1617 static void
1618 adjust_markers_for_insert (struct buffer *buf, Memind ind, Bytecount amount)
1619 {
1620 struct Lisp_Marker *m;
1621
1622 for (m = BUF_MARKERS (buf); m; m = marker_next (m))
1623 {
1624 if (m->insertion_type && m->memind == ind)
1625 m->memind += amount;
1626 }
1627 }
1628
1629
1630 /************************************************************************/
1631 /* Routines for dealing with the gap */
1632 /************************************************************************/
1633
1634 /* XEmacs requires an ANSI C compiler, and it damn well better have a
1635 working memmove() */
1636 #define GAP_USE_BCOPY
1637 #ifdef BCOPY_UPWARD_SAFE
1638 # undef BCOPY_UPWARD_SAFE
1639 #endif
1640 #ifdef BCOPY_DOWNWARD_SAFE
1641 # undef BCOPY_DOWNWARD_SAFE
1642 #endif
1643 #define BCOPY_UPWARD_SAFE 1
1644 #define BCOPY_DOWNWARD_SAFE 1
1645
1646 /* maximum amount of memory moved in a single chunk. Increasing this
1647 value improves gap-motion efficiency but decreases QUIT responsiveness
1648 time. Was 32000 but today's processors are faster and files are
1649 bigger. --ben */
1650 #define GAP_MOVE_CHUNK 300000
1651
1652 /* Move the gap to POS, which is less than the current GPT. */
1653
1654 static void
1655 gap_left (struct buffer *buf, Bytind pos)
1656 {
1657 Bufbyte *to, *from;
1658 Bytecount i;
1659 Bytind new_s1;
1660 struct buffer *mbuf;
1661 Lisp_Object bufcons;
1662
1663 from = BUF_GPT_ADDR (buf);
1664 to = from + BUF_GAP_SIZE (buf);
1665 new_s1 = BI_BUF_GPT (buf);
1666
1667 /* Now copy the characters. To move the gap down,
1668 copy characters up. */
1669
1670 while (1)
1671 {
1672 /* I gets number of characters left to copy. */
1673 i = new_s1 - pos;
1674 if (i == 0)
1675 break;
1676 /* If a quit is requested, stop copying now.
1677 Change POS to be where we have actually moved the gap to. */
1678 if (QUITP)
1679 {
1680 pos = new_s1;
1681 break;
1682 }
1683 /* Move at most GAP_MOVE_CHUNK chars before checking again for a quit. */
1684 if (i > GAP_MOVE_CHUNK)
1685 i = GAP_MOVE_CHUNK;
1686 #ifdef GAP_USE_BCOPY
1687 if (i >= 128
1688 /* bcopy is safe if the two areas of memory do not overlap
1689 or on systems where bcopy is always safe for moving upward. */
1690 && (BCOPY_UPWARD_SAFE
1691 || to - from >= 128))
1692 {
1693 /* If overlap is not safe, avoid it by not moving too many
1694 characters at once. */
1695 if (!BCOPY_UPWARD_SAFE && i > to - from)
1696 i = to - from;
1697 new_s1 -= i;
1698 from -= i, to -= i;
1699 memmove (to, from, i);
1700 }
1701 else
1702 #endif
1703 {
1704 new_s1 -= i;
1705 while (--i >= 0)
1706 *--to = *--from;
1707 }
1708 }
1709
1710 /* Adjust markers, and buffer data structure, to put the gap at POS.
1711 POS is where the loop above stopped, which may be what was specified
1712 or may be where a quit was detected. */
1713 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1714 {
1715 adjust_markers (mbuf, pos, BI_BUF_GPT (mbuf), BUF_GAP_SIZE (mbuf));
1716 }
1717 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1718 {
1719 adjust_extents (make_buffer (mbuf), pos, BI_BUF_GPT (mbuf),
1720 BUF_GAP_SIZE (mbuf));
1721 }
1722 SET_BI_BUF_GPT (buf, pos);
1723 SET_GAP_SENTINEL (buf);
1724 #ifdef ERROR_CHECK_EXTENTS
1725 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1726 {
1727 sledgehammer_extent_check (make_buffer (mbuf));
1728 }
1729 #endif
1730 QUIT;
1731 }
1732
1733 static void
1734 gap_right (struct buffer *buf, Bytind pos)
1735 {
1736 Bufbyte *to, *from;
1737 Bytecount i;
1738 Bytind new_s1;
1739 struct buffer *mbuf;
1740 Lisp_Object bufcons;
1741
1742 to = BUF_GPT_ADDR (buf);
1743 from = to + BUF_GAP_SIZE (buf);
1744 new_s1 = BI_BUF_GPT (buf);
1745
1746 /* Now copy the characters. To move the gap up,
1747 copy characters down. */
1748
1749 while (1)
1750 {
1751 /* I gets number of characters left to copy. */
1752 i = pos - new_s1;
1753 if (i == 0)
1754 break;
1755 /* If a quit is requested, stop copying now.
1756 Change POS to be where we have actually moved the gap to. */
1757 if (QUITP)
1758 {
1759 pos = new_s1;
1760 break;
1761 }
1762 /* Move at most GAP_MOVE_CHUNK chars before checking again for a quit. */
1763 if (i > GAP_MOVE_CHUNK)
1764 i = GAP_MOVE_CHUNK;
1765 #ifdef GAP_USE_BCOPY
1766 if (i >= 128
1767 /* bcopy is safe if the two areas of memory do not overlap
1768 or on systems where bcopy is always safe for moving downward. */
1769 && (BCOPY_DOWNWARD_SAFE
1770 || from - to >= 128))
1771 {
1772 /* If overlap is not safe, avoid it by not moving too many
1773 characters at once. */
1774 if (!BCOPY_DOWNWARD_SAFE && i > from - to)
1775 i = from - to;
1776 new_s1 += i;
1777 memmove (to, from, i);
1778 from += i, to += i;
1779 }
1780 else
1781 #endif
1782 {
1783 new_s1 += i;
1784 while (--i >= 0)
1785 *to++ = *from++;
1786 }
1787 }
1788
1789 {
1790 int gsize = BUF_GAP_SIZE (buf);
1791 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1792 {
1793 adjust_markers (mbuf, BI_BUF_GPT (mbuf) + gsize, pos + gsize, - gsize);
1794 }
1795 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1796 {
1797 adjust_extents (make_buffer (mbuf), BI_BUF_GPT (mbuf) + gsize,
1798 pos + gsize, - gsize);
1799 }
1800 SET_BI_BUF_GPT (buf, pos);
1801 SET_GAP_SENTINEL (buf);
1802 #ifdef ERROR_CHECK_EXTENTS
1803 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1804 {
1805 sledgehammer_extent_check (make_buffer (mbuf));
1806 }
1807 #endif
1808 }
1809 if (pos == BI_BUF_Z (buf))
1810 {
1811 /* merge gap with end gap */
1812
1813 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + BUF_END_GAP_SIZE (buf));
1814 SET_BUF_END_GAP_SIZE (buf, 0);
1815 SET_END_SENTINEL (buf);
1816 }
1817
1818 QUIT;
1819 }
1820
1821 /* Move gap to position `pos'.
1822 Note that this can quit! */
1823
1824 static void
1825 move_gap (struct buffer *buf, Bytind pos)
1826 {
1827 if (! BUF_BEG_ADDR (buf))
1828 abort ();
1829 if (pos < BI_BUF_GPT (buf))
1830 gap_left (buf, pos);
1831 else if (pos > BI_BUF_GPT (buf))
1832 gap_right (buf, pos);
1833 }
1834
1835 /* Merge the end gap into the gap */
1836
1837 static void
1838 merge_gap_with_end_gap (struct buffer *buf)
1839 {
1840 Lisp_Object tem;
1841 Bytind real_gap_loc;
1842 Bytecount old_gap_size;
1843 Bytecount increment;
1844
1845 increment = BUF_END_GAP_SIZE (buf);
1846 SET_BUF_END_GAP_SIZE (buf, 0);
1847
1848 if (increment > 0)
1849 {
1850 /* Prevent quitting in move_gap. */
1851 tem = Vinhibit_quit;
1852 Vinhibit_quit = Qt;
1853
1854 real_gap_loc = BI_BUF_GPT (buf);
1855 old_gap_size = BUF_GAP_SIZE (buf);
1856
1857 /* Pretend the end gap is the gap */
1858 SET_BI_BUF_GPT (buf, BI_BUF_Z (buf) + BUF_GAP_SIZE (buf));
1859 SET_BUF_GAP_SIZE (buf, increment);
1860
1861 /* Move the new gap down to be consecutive with the end of the old one.
1862 This adjusts the markers properly too. */
1863 gap_left (buf, real_gap_loc + old_gap_size);
1864
1865 /* Now combine the two into one large gap. */
1866 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + old_gap_size);
1867 SET_BI_BUF_GPT (buf, real_gap_loc);
1868 SET_GAP_SENTINEL (buf);
1869
1870 /* We changed the total size of the buffer (including gap),
1871 so we need to fix up the end sentinel. */
1872 SET_END_SENTINEL (buf);
1873
1874 Vinhibit_quit = tem;
1875 }
1876 }
1877
1878 /* Make the gap INCREMENT bytes longer. */
1879
1880 static void
1881 make_gap (struct buffer *buf, Bytecount increment)
1882 {
1883 Bufbyte *result;
1884 Lisp_Object tem;
1885 Bytind real_gap_loc;
1886 Bytecount old_gap_size;
1887
1888 /* If we have to get more space, get enough to last a while. We use
1889 a geometric progression that saves on realloc space. */
1890 increment += 2000 + ((BI_BUF_Z (buf) - BI_BUF_BEG (buf)) / 8);
1891
1892 if (increment > BUF_END_GAP_SIZE (buf))
1893 {
1894 /* Don't allow a buffer size that won't fit in an int
1895 even if it will fit in a Lisp integer.
1896 That won't work because so many places use `int'. */
1897
1898 if (BUF_Z (buf) - BUF_BEG (buf) + BUF_GAP_SIZE (buf) + increment
1899 > EMACS_INT_MAX)
1900 error ("Maximum buffer size exceeded");
1901
1902 result = BUFFER_REALLOC (buf->text->beg,
1903 BI_BUF_Z (buf) - BI_BUF_BEG (buf) +
1904 BUF_GAP_SIZE (buf) + increment +
1905 BUF_END_SENTINEL_SIZE);
1906 if (result == 0)
1907 memory_full ();
1908
1909 SET_BUF_BEG_ADDR (buf, result);
1910 }
1911 else
1912 increment = BUF_END_GAP_SIZE (buf);
1913
1914 /* Prevent quitting in move_gap. */
1915 tem = Vinhibit_quit;
1916 Vinhibit_quit = Qt;
1917
1918 real_gap_loc = BI_BUF_GPT (buf);
1919 old_gap_size = BUF_GAP_SIZE (buf);
1920
1921 /* Call the newly allocated space a gap at the end of the whole space. */
1922 SET_BI_BUF_GPT (buf, BI_BUF_Z (buf) + BUF_GAP_SIZE (buf));
1923 SET_BUF_GAP_SIZE (buf, increment);
1924
1925 SET_BUF_END_GAP_SIZE (buf, 0);
1926
1927 /* Move the new gap down to be consecutive with the end of the old one.
1928 This adjusts the markers properly too. */
1929 gap_left (buf, real_gap_loc + old_gap_size);
1930
1931 /* Now combine the two into one large gap. */
1932 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + old_gap_size);
1933 SET_BI_BUF_GPT (buf, real_gap_loc);
1934 SET_GAP_SENTINEL (buf);
1935
1936 /* We changed the total size of the buffer (including gap),
1937 so we need to fix up the end sentinel. */
1938 SET_END_SENTINEL (buf);
1939
1940 Vinhibit_quit = tem;
1941 }
1942
1943
1944 /************************************************************************/
1945 /* Before/after-change processing */
1946 /************************************************************************/
1947
1948 /* Those magic changes ... */
1949
1950 static void
1951 buffer_signal_changed_region (struct buffer *buf, Bufpos start,
1952 Bufpos end)
1953 {
1954 /* The changed region is recorded as the number of unchanged
1955 characters from the beginning and from the end of the
1956 buffer. This obviates much of the need of shifting the
1957 region around to compensate for insertions and deletions.
1958 */
1959 if (buf->changes->begin_unchanged < 0 ||
1960 buf->changes->begin_unchanged > start - BUF_BEG (buf))
1961 buf->changes->begin_unchanged = start - BUF_BEG (buf);
1962 if (buf->changes->end_unchanged < 0 ||
1963 buf->changes->end_unchanged > BUF_Z (buf) - end)
1964 buf->changes->end_unchanged = BUF_Z (buf) - end;
1965 }
1966
1967 void
1968 buffer_extent_signal_changed_region (struct buffer *buf, Bufpos start,
1969 Bufpos end)
1970 {
1971 if (buf->changes->begin_extent_unchanged < 0 ||
1972 buf->changes->begin_extent_unchanged > start - BUF_BEG (buf))
1973 buf->changes->begin_extent_unchanged = start - BUF_BEG (buf);
1974 if (buf->changes->end_extent_unchanged < 0 ||
1975 buf->changes->end_extent_unchanged > BUF_Z (buf) - end)
1976 buf->changes->end_extent_unchanged = BUF_Z (buf) - end;
1977 }
1978
1979 void
1980 buffer_reset_changes (struct buffer *buf)
1981 {
1982 buf->changes->begin_unchanged = -1;
1983 buf->changes->end_unchanged = -1;
1984 buf->changes->begin_extent_unchanged = -1;
1985 buf->changes->end_extent_unchanged = -1;
1986 buf->changes->newline_was_deleted = 0;
1987 }
1988
1989 static void
1990 signal_after_change (struct buffer *buf, Bufpos start, Bufpos orig_end,
1991 Bufpos new_end);
1992
1993
1994 /* Call the after-change-functions according to the changes made so far
1995 and treat all further changes as single until the outermost
1996 multiple change exits. This is called when the outermost multiple
1997 change exits and when someone is trying to make a change that violates
1998 the constraints specified in begin_multiple_change(), typically
1999 when nested multiple-change sessions occur. (There are smarter ways of
2000 dealing with nested multiple changes, but these rarely occur so there's
2001 probably no point in it.) */
2002
2003 /* #### This needs to keep track of what actually changed and only
2004 call the after-change functions on that region. */
2005
2006 static void
2007 cancel_multiple_change (struct buffer *buf)
2008 {
2009 /* This function can GC */
2010 /* Call the after-change-functions except when they've already been
2011 called or when there were no changes made to the buffer at all. */
2012 if (buf->text->changes->mc_begin != 0 &&
2013 buf->text->changes->mc_begin_signaled)
2014 {
2015 Bufpos real_mc_begin = buf->text->changes->mc_begin;
2016 buf->text->changes->mc_begin = 0;
2017
2018 signal_after_change (buf, real_mc_begin, buf->text->changes->mc_orig_end,
2019 buf->text->changes->mc_new_end);
2020 }
2021 else
2022 {
2023 buf->text->changes->mc_begin = 0;
2024 }
2025 }
2026
2027 /* this is an unwind_protect, to ensure that the after-change-functions
2028 get called even in a non-local exit. */
2029
2030 static Lisp_Object
2031 multiple_change_finish_up (Lisp_Object buffer)
2032 {
2033 struct buffer *buf = XBUFFER (buffer);
2034
2035 /* #### I don't know whether or not it should even be possible to
2036 get here with a dead buffer (though given how it is called I can
2037 see how it might be). In any case, there isn't time before 19.14
2038 to find out. */
2039 if (!BUFFER_LIVE_P (buf))
2040 return Qnil;
2041
2042 /* This function can GC */
2043 buf->text->changes->in_multiple_change = 0; /* do this first so that
2044 errors in the after-change
2045 functions don't mess things
2046 up. */
2047 cancel_multiple_change (buf);
2048 return Qnil;
2049 }
2050
2051 /* Call this function when you're about to make a number of buffer changes
2052 that should be considered a single change. (e.g. `replace-match' calls
2053 this.) You need to specify the START and END of the region that is
2054 going to be changed so that the before-change-functions are called
2055 with the correct arguments. The after-change region is calculated
2056 automatically, however, and if changes somehow or other happen outside
2057 of the specified region, that will also be handled correctly.
2058
2059 begin_multiple_change() returns a number (actually a specpdl depth)
2060 that you must pass to end_multiple_change() when you are done. */
2061
2062 int
2063 begin_multiple_change (struct buffer *buf, Bufpos start, Bufpos end)
2064 {
2065 /* This function can GC */
2066 int count = -1;
2067 if (buf->text->changes->in_multiple_change)
2068 {
2069 if (buf->text->changes->mc_begin != 0 &&
2070 (start < buf->text->changes->mc_begin ||
2071 end > buf->text->changes->mc_new_end))
2072 cancel_multiple_change (buf);
2073 }
2074 else
2075 {
2076 Lisp_Object buffer;
2077
2078 buf->text->changes->mc_begin = start;
2079 buf->text->changes->mc_orig_end = buf->text->changes->mc_new_end = end;
2080 buf->text->changes->mc_begin_signaled = 0;
2081 count = specpdl_depth ();
2082 XSETBUFFER (buffer, buf);
2083 record_unwind_protect (multiple_change_finish_up, buffer);
2084 }
2085 buf->text->changes->in_multiple_change++;
2086 /* We don't call before-change-functions until signal_before_change()
2087 is called, in case there is a read-only or other error. */
2088 return count;
2089 }
2090
2091 void
2092 end_multiple_change (struct buffer *buf, int count)
2093 {
2094 assert (buf->text->changes->in_multiple_change > 0);
2095 buf->text->changes->in_multiple_change--;
2096 if (!buf->text->changes->in_multiple_change)
2097 unbind_to (count, Qnil);
2098 }
2099
2100 static int inside_change_hook;
2101
2102 static Lisp_Object
2103 change_function_restore (Lisp_Object buffer)
2104 {
2105 /* We should first reset the variable and then change the buffer,
2106 because Fset_buffer() can throw. */
2107 inside_change_hook = 0;
2108 Fset_buffer (buffer);
2109 return Qnil;
2110 }
2111
2112 static int in_first_change;
2113
2114 static Lisp_Object
2115 first_change_hook_restore (Lisp_Object buffer)
2116 {
2117 in_first_change = 0;
2118 Fset_buffer (buffer);
2119 return Qnil;
2120 }
2121
2122 /* Signal an initial modification to the buffer. */
2123
2124 static void
2125 signal_first_change (struct buffer *buf)
2126 {
2127 /* This function can GC */
2128 Lisp_Object buffer;
2129 XSETBUFFER (buffer, current_buffer);
2130
2131 if (!in_first_change)
2132 {
2133 if (!NILP (symbol_value_in_buffer (Qfirst_change_hook, buffer)))
2134 {
2135 int speccount = specpdl_depth ();
2136 record_unwind_protect (first_change_hook_restore, buffer);
2137 set_buffer_internal (buf);
2138 in_first_change = 1;
2139 run_hook (Qfirst_change_hook);
2140 unbind_to (speccount, Qnil);
2141 }
2142 }
2143 }
2144
2145 /* Signal a change to the buffer immediately before it happens.
2146 START and END are the bounds of the text to be changed. */
2147
2148 static void
2149 signal_before_change (struct buffer *buf, Bufpos start, Bufpos end)
2150 {
2151 /* This function can GC */
2152 struct buffer *mbuf;
2153 Lisp_Object bufcons;
2154
2155 if (!inside_change_hook)
2156 {
2157 Lisp_Object buffer;
2158
2159 /* Are we in a multiple-change session? */
2160 if (buf->text->changes->in_multiple_change &&
2161 buf->text->changes->mc_begin != 0)
2162 {
2163 /* If we're violating the constraints of the session,
2164 call the after-change-functions as necessary for the
2165 changes already made and treat further changes as
2166 single. */
2167 if (start < buf->text->changes->mc_begin ||
2168 end > buf->text->changes->mc_new_end)
2169 cancel_multiple_change (buf);
2170 /* Do nothing if this is not the first change in the session. */
2171 else if (buf->text->changes->mc_begin_signaled)
2172 return;
2173 else
2174 {
2175 /* First time through; call the before-change-functions
2176 specifying the entire region to be changed. (Note that
2177 we didn't call before-change-functions in
2178 begin_multiple_change() because the buffer might be
2179 read-only, etc.) */
2180 start = buf->text->changes->mc_begin;
2181 end = buf->text->changes->mc_new_end;
2182 }
2183 }
2184
2185 /* If buffer is unmodified, run a special hook for that case. */
2186 if (BUF_SAVE_MODIFF (buf) >= BUF_MODIFF (buf))
2187 {
2188 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2189 {
2190 signal_first_change (mbuf);
2191 }
2192 }
2193
2194 /* Now in any case run the before-change-functions if any. */
2195
2196 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2197 {
2198 XSETBUFFER (buffer, mbuf);
2199 if (!NILP (symbol_value_in_buffer (Qbefore_change_functions, buffer))
2200 /* Obsolete, for compatibility */
2201 || !NILP (symbol_value_in_buffer (Qbefore_change_function, buffer)))
2202 {
2203 int speccount = specpdl_depth ();
2204 record_unwind_protect (change_function_restore, Fcurrent_buffer ());
2205 set_buffer_internal (buf);
2206 inside_change_hook = 1;
2207 va_run_hook_with_args (Qbefore_change_functions, 2,
2208 make_int (start), make_int (end));
2209 /* Obsolete, for compatibility */
2210 va_run_hook_with_args (Qbefore_change_function, 2,
2211 make_int (start), make_int (end));
2212 unbind_to (speccount, Qnil);
2213 }
2214 }
2215
2216 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2217 {
2218 XSETBUFFER (buffer, mbuf);
2219 report_extent_modification (buffer, start, end,
2220 &inside_change_hook, 0);
2221 }
2222
2223 /* Only now do we indicate that the before-change-functions have
2224 been called, in case some function throws out. */
2225 buf->text->changes->mc_begin_signaled = 1;
2226 }
2227 }
2228
2229 /* Signal a change immediately after it happens.
2230 START is the bufpos of the start of the changed text.
2231 ORIG_END is the bufpos of the end of the before-changed text.
2232 NEW_END is the bufpos of the end of the after-changed text.
2233 */
2234
2235 static void
2236 signal_after_change (struct buffer *buf, Bufpos start, Bufpos orig_end,
2237 Bufpos new_end)
2238 {
2239 /* This function can GC */
2240 struct buffer *mbuf;
2241 Lisp_Object bufcons;
2242
2243 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2244 {
2245 /* always do this. */
2246 buffer_signal_changed_region (mbuf, start, new_end);
2247 }
2248 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2249 {
2250 /* #### This seems inefficient. Wouldn't it be better to just
2251 keep one cache per base buffer? */
2252 font_lock_maybe_update_syntactic_caches (mbuf, start, orig_end, new_end);
2253 }
2254
2255 if (!inside_change_hook)
2256 {
2257 Lisp_Object buffer;
2258
2259 if (buf->text->changes->in_multiple_change &&
2260 buf->text->changes->mc_begin != 0)
2261 {
2262 assert (start >= buf->text->changes->mc_begin &&
2263 start <= buf->text->changes->mc_new_end);
2264 assert (orig_end >= buf->text->changes->mc_begin &&
2265 orig_end <= buf->text->changes->mc_new_end);
2266 buf->text->changes->mc_new_end += new_end - orig_end;
2267 return; /* after-change-functions signalled when all changes done */
2268 }
2269
2270 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2271 {
2272 XSETBUFFER (buffer, mbuf);
2273
2274 if (!NILP (symbol_value_in_buffer (Qafter_change_functions, buffer))
2275 /* Obsolete, for compatibility */
2276 || !NILP (symbol_value_in_buffer (Qafter_change_function, buffer)))
2277 {
2278 int speccount = specpdl_depth ();
2279 record_unwind_protect (change_function_restore, Fcurrent_buffer ());
2280 set_buffer_internal (buf);
2281 inside_change_hook = 1;
2282 /* The actual after-change functions take slightly
2283 different arguments than what we were passed. */
2284 va_run_hook_with_args (Qafter_change_functions, 3,
2285 make_int (start), make_int (new_end),
2286 make_int (orig_end - start));
2287 /* Obsolete, for compatibility */
2288 va_run_hook_with_args (Qafter_change_function, 3,
2289 make_int (start), make_int (new_end),
2290 make_int (orig_end - start));
2291 unbind_to (speccount, Qnil);
2292 }
2293 }
2294
2295 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2296 {
2297 XSETBUFFER (buffer, mbuf);
2298 report_extent_modification (buffer, start, new_end,
2299 &inside_change_hook, 1);
2300 }
2301 }
2302 }
2303
2304 /* Call this if you're about to change the region of BUFFER from START
2305 to END. This checks the read-only properties of the region, calls
2306 the necessary modification hooks, and warns the next redisplay that
2307 it should pay attention to that area. */
2308
2309 static void
2310 prepare_to_modify_buffer (struct buffer *buf, Bufpos start, Bufpos end,
2311 int lockit)
2312 {
2313 /* This function can GC */
2314 /* dmoore - This function can also kill the buffer buf, the current
2315 buffer, and do anything it pleases. So if you call it, be
2316 careful. */
2317 struct buffer *mbuf;
2318 Lisp_Object buffer, bufcons;
2319 struct gcpro gcpro1;
2320
2321 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2322 {
2323 barf_if_buffer_read_only (mbuf, start, end);
2324 }
2325
2326 /* if this is the first modification, see about locking the buffer's
2327 file */
2328 XSETBUFFER (buffer, buf);
2329 GCPRO1 (buffer);
2330 if (!NILP (buf->filename) && lockit &&
2331 BUF_SAVE_MODIFF (buf) >= BUF_MODIFF (buf))
2332 {
2333 #ifdef CLASH_DETECTION
2334 if (!NILP (buf->file_truename))
2335 /* Make binding buffer-file-name to nil effective. */
2336 lock_file (buf->file_truename);
2337 #else
2338 /* At least warn if this file has changed on disk since it was visited.*/
2339 if (NILP (Fverify_visited_file_modtime (buffer))
2340 && !NILP (Ffile_exists_p (buf->filename)))
2341 call1_in_buffer (buf, intern ("ask-user-about-supersession-threat"),
2342 buf->filename);
2343 #endif /* not CLASH_DETECTION */
2344 }
2345 UNGCPRO;
2346
2347 /* #### dmoore - is this reasonable in case of buf being killed above? */
2348 if (!BUFFER_LIVE_P (buf))
2349 return;
2350
2351 signal_before_change (buf, start, end);
2352
2353 #ifdef REGION_CACHE_NEEDS_WORK
2354 if (buf->newline_cache)
2355 invalidate_region_cache (buf,
2356 buf->newline_cache,
2357 start - BUF_BEG (buf), BUF_Z (buf) - end);
2358 if (buf->width_run_cache)
2359 invalidate_region_cache (buf,
2360 buf->width_run_cache,
2361 start - BUF_BEG (buf), BUF_Z (buf) - end);
2362 #endif
2363
2364 #if 0 /* FSFmacs */
2365 Vdeactivate_mark = Qt;
2366 #endif
2367
2368 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2369 {
2370 mbuf->point_before_scroll = Qnil;
2371 }
2372 }
2373
2374
2375 /************************************************************************/
2376 /* Insertion of strings */
2377 /************************************************************************/
2378
2379 void
2380 fixup_internal_substring (CONST Bufbyte *nonreloc, Lisp_Object reloc,
2381 Bytecount offset, Bytecount *len)
2382 {
2383 assert ((nonreloc && NILP (reloc)) || (!nonreloc && STRINGP (reloc)));
2384
2385 if (*len < 0)
2386 {
2387 if (nonreloc)
2388 *len = strlen ((CONST char *) nonreloc) - offset;
2389 else
2390 *len = XSTRING_LENGTH (reloc) - offset;
2391 }
2392 #ifdef ERROR_CHECK_BUFPOS
2393 assert (*len >= 0);
2394 if (STRINGP (reloc))
2395 {
2396 assert (offset >= 0 && offset <= XSTRING_LENGTH (reloc));
2397 assert (offset + *len <= XSTRING_LENGTH (reloc));
2398 }
2399 #endif
2400 }
2401
2402 /* Insert a string into BUF at Bufpos POS. The string data comes
2403 from one of two sources: constant, non-relocatable data (specified
2404 in NONRELOC), or a Lisp string object (specified in RELOC), which
2405 is relocatable and may have extent data that needs to be copied
2406 into the buffer. OFFSET and LENGTH specify the substring of the
2407 data that is actually to be inserted. As a special case, if POS
2408 is -1, insert the string at point and move point to the end of the
2409 string.
2410
2411 Normally, markers at the insertion point end up before the
2412 inserted string. If INSDEL_BEFORE_MARKERS is set in flags, however,
2413 they end up after the string.
2414
2415 INSDEL_NO_LOCKING is kludgy and is used when insert-file-contents is
2416 visiting a new file; it inhibits the locking checks normally done
2417 before modifying a buffer. Similar checks were already done
2418 in the higher-level Lisp functions calling insert-file-contents. */
2419
2420 Charcount
2421 buffer_insert_string_1 (struct buffer *buf, Bufpos pos,
2422 CONST Bufbyte *nonreloc, Lisp_Object reloc,
2423 Bytecount offset, Bytecount length,
2424 int flags)
2425 {
2426 /* This function can GC */
2427 struct gcpro gcpro1;
2428 Bytind ind;
2429 Charcount cclen;
2430 int move_point = 0;
2431 struct buffer *mbuf;
2432 Lisp_Object bufcons;
2433
2434 /* Defensive steps just in case a buffer gets deleted and a calling
2435 function doesn't notice it. */
2436 if (!BUFFER_LIVE_P (buf))
2437 return 0;
2438
2439 fixup_internal_substring (nonreloc, reloc, offset, &length);
2440
2441 if (pos == -1)
2442 {
2443 pos = BUF_PT (buf);
2444 move_point = 1;
2445 }
2446
2447 #ifdef I18N3
2448 /* #### See the comment in print_internal(). If this buffer is marked
2449 as translatable, then Fgettext() should be called on obj if it
2450 is a string. */
2451 #endif
2452
2453 /* Make sure that point-max won't exceed the size of an emacs int. */
2454 if ((length + BUF_Z (buf)) > EMACS_INT_MAX)
2455 error ("Maximum buffer size exceeded");
2456
2457 /* theoretically not necessary -- caller should GCPRO.
2458 #### buffer_insert_from_buffer_1() doesn't! */
2459 GCPRO1 (reloc);
2460
2461 prepare_to_modify_buffer (buf, pos, pos, !(flags & INSDEL_NO_LOCKING));
2462
2463 /* Defensive steps in case the before-change-functions fuck around */
2464 if (!BUFFER_LIVE_P (buf))
2465 {
2466 UNGCPRO;
2467 /* Bad bad pre-change function. */
2468 return 0;
2469 }
2470
2471 /* Make args be valid again. prepare_to_modify_buffer() might have
2472 modified the buffer. */
2473 if (pos < BUF_BEGV (buf))
2474 pos = BUF_BEGV (buf);
2475 if (pos > BUF_ZV (buf))
2476 pos = BUF_ZV (buf);
2477
2478 /* string may have been relocated up to this point */
2479 if (STRINGP (reloc))
2480 nonreloc = XSTRING_DATA (reloc);
2481
2482 ind = bufpos_to_bytind (buf, pos);
2483 cclen = bytecount_to_charcount (nonreloc + offset, length);
2484
2485 if (ind != BI_BUF_GPT (buf))
2486 /* #### if debug-on-quit is invoked and the user changes the
2487 buffer, bad things can happen. This is a rampant problem
2488 in Emacs. */
2489 move_gap (buf, ind); /* may QUIT */
2490 if (! GAP_CAN_HOLD_SIZE_P (buf, length))
2491 {
2492 if (BUF_END_GAP_SIZE (buf) >= length)
2493 merge_gap_with_end_gap (buf);
2494 else
2495 make_gap (buf, length - BUF_GAP_SIZE (buf));
2496 }
2497
2498 insert_invalidate_line_number_cache (buf, pos, nonreloc + offset, length);
2499
2500 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2501 {
2502 record_insert (mbuf, pos, cclen);
2503 }
2504
2505 BUF_MODIFF (buf)++;
2506 MARK_BUFFERS_CHANGED;
2507
2508 /* string may have been relocated up to this point */
2509 if (STRINGP (reloc))
2510 nonreloc = XSTRING_DATA (reloc);
2511
2512 memcpy (BUF_GPT_ADDR (buf), nonreloc + offset, length);
2513
2514 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) - length);
2515 SET_BI_BUF_GPT (buf, BI_BUF_GPT (buf) + length);
2516 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2517 {
2518 SET_BOTH_BUF_ZV (mbuf, BUF_ZV (mbuf) + cclen, BI_BUF_ZV (mbuf) + length);
2519 }
2520 SET_BOTH_BUF_Z (buf, BUF_Z (buf) + cclen, BI_BUF_Z (buf) + length);
2521 SET_GAP_SENTINEL (buf);
2522
2523 #ifdef MULE
2524 buffer_mule_signal_inserted_region (buf, pos, length, cclen);
2525 #endif
2526
2527 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2528 {
2529 process_extents_for_insertion (make_buffer (mbuf), ind, length);
2530 }
2531
2532 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2533 {
2534 /* We know the gap is at IND so the cast is OK. */
2535 adjust_markers_for_insert (mbuf, (Memind) ind, length);
2536 }
2537
2538 /* Point logically doesn't move, but may need to be adjusted because
2539 it's a byte index. point-marker doesn't change because it's a
2540 memory index. */
2541 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2542 {
2543 if (BI_BUF_PT (mbuf) > ind)
2544 JUST_SET_POINT (mbuf, BUF_PT (mbuf) + cclen,
2545 BI_BUF_PT (mbuf) + length);
2546 }
2547
2548 /* Well, point might move. */
2549 if (move_point)
2550 BI_BUF_SET_PT (buf, ind + length);
2551
2552 if (STRINGP (reloc))
2553 {
2554 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2555 {
2556 splice_in_string_extents (reloc, mbuf, ind, length, offset);
2557 }
2558 }
2559
2560 if (flags & INSDEL_BEFORE_MARKERS)
2561 {
2562 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2563 {
2564 /* ind - 1 is correct because the FROM argument is exclusive.
2565 I formerly used DEC_BYTIND() but that caused problems at the
2566 beginning of the buffer. */
2567 adjust_markers (mbuf, ind - 1, ind, length);
2568 }
2569 }
2570
2571 signal_after_change (buf, pos, pos, pos + cclen);
2572
2573 UNGCPRO;
2574
2575 return cclen;
2576 }
2577
2578
2579 /* The following functions are interfaces onto the above function,
2580 for inserting particular sorts of data. In all the functions,
2581 BUF and POS specify the buffer and location where the insertion is
2582 to take place. (If POS is -1, text is inserted at point and point
2583 moves forward past the text.) FLAGS is as above. */
2584
2585 Charcount
2586 buffer_insert_raw_string_1 (struct buffer *buf, Bufpos pos,
2587 CONST Bufbyte *nonreloc, Bytecount length,
2588 int flags)
2589 {
2590 /* This function can GC */
2591 return buffer_insert_string_1 (buf, pos, nonreloc, Qnil, 0, length,
2592 flags);
2593 }
2594
2595 Charcount
2596 buffer_insert_lisp_string_1 (struct buffer *buf, Bufpos pos, Lisp_Object str,
2597 int flags)
2598 {
2599 /* This function can GC */
2600 #ifdef ERROR_CHECK_TYPECHECK
2601 assert (STRINGP (str));
2602 #endif
2603 return buffer_insert_string_1 (buf, pos, 0, str, 0,
2604 XSTRING_LENGTH (str),
2605 flags);
2606 }
2607
2608 /* Insert the null-terminated string S (in external format). */
2609
2610 Charcount
2611 buffer_insert_c_string_1 (struct buffer *buf, Bufpos pos, CONST char *s,
2612 int flags)
2613 {
2614 /* This function can GC */
2615 CONST char *translated = GETTEXT (s);
2616 return buffer_insert_string_1 (buf, pos, (CONST Bufbyte *) translated, Qnil,
2617 0, strlen (translated), flags);
2618 }
2619
2620 Charcount
2621 buffer_insert_emacs_char_1 (struct buffer *buf, Bufpos pos, Emchar ch,
2622 int flags)
2623 {
2624 /* This function can GC */
2625 Bufbyte str[MAX_EMCHAR_LEN];
2626 Bytecount len = set_charptr_emchar (str, ch);
2627 return buffer_insert_string_1 (buf, pos, str, Qnil, 0, len, flags);
2628 }
2629
2630 Charcount
2631 buffer_insert_c_char_1 (struct buffer *buf, Bufpos pos, char c,
2632 int flags)
2633 {
2634 /* This function can GC */
2635 return buffer_insert_emacs_char_1 (buf, pos, (Emchar) (unsigned char) c,
2636 flags);
2637 }
2638
2639 Charcount
2640 buffer_insert_from_buffer_1 (struct buffer *buf, Bufpos pos,
2641 struct buffer *buf2, Bufpos pos2,
2642 Charcount length, int flags)
2643 {
2644 /* This function can GC */
2645 Lisp_Object str = make_string_from_buffer (buf2, pos2, length);
2646 return buffer_insert_string_1 (buf, pos, 0, str, 0,
2647 XSTRING_LENGTH (str), flags);
2648 }
2649
2650
2651 /************************************************************************/
2652 /* Deletion of ranges */
2653 /************************************************************************/
2654
2655 /* Delete characters in buffer from FROM up to (but not including) TO. */
2656
2657 void
2658 buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags)
2659 {
2660 /* This function can GC */
2661 Charcount numdel;
2662 Bytind bi_from, bi_to;
2663 Bytecount bc_numdel;
2664 EMACS_INT shortage;
2665 struct buffer *mbuf;
2666 Lisp_Object bufcons;
2667
2668 /* Defensive steps just in case a buffer gets deleted and a calling
2669 function doesn't notice it. */
2670 if (!BUFFER_LIVE_P (buf))
2671 return;
2672
2673 /* Make args be valid */
2674 if (from < BUF_BEGV (buf))
2675 from = BUF_BEGV (buf);
2676 if (to > BUF_ZV (buf))
2677 to = BUF_ZV (buf);
2678 if ((numdel = to - from) <= 0)
2679 return;
2680
2681 prepare_to_modify_buffer (buf, from, to, !(flags & INSDEL_NO_LOCKING));
2682
2683 /* Defensive steps in case the before-change-functions fuck around */
2684 if (!BUFFER_LIVE_P (buf))
2685 /* Bad bad pre-change function. */
2686 return;
2687
2688 /* Make args be valid again. prepare_to_modify_buffer() might have
2689 modified the buffer. */
2690 if (from < BUF_BEGV (buf))
2691 from = BUF_BEGV (buf);
2692 if (to > BUF_ZV (buf))
2693 to = BUF_ZV (buf);
2694 if ((numdel = to - from) <= 0)
2695 return;
2696
2697 /* Redisplay needs to know if a newline was in the deleted region.
2698 If we've already marked the changed region as having a deleted
2699 newline there is no use in performing the check. */
2700 if (!buf->changes->newline_was_deleted)
2701 {
2702 scan_buffer (buf, '\n', from, to, 1, &shortage, 1);
2703 if (!shortage)
2704 {
2705 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2706 {
2707 mbuf->changes->newline_was_deleted = 1;
2708 }
2709 }
2710 }
2711
2712 bi_from = bufpos_to_bytind (buf, from);
2713 bi_to = bufpos_to_bytind (buf, to);
2714 bc_numdel = bi_to - bi_from;
2715
2716 delete_invalidate_line_number_cache (buf, from, to);
2717
2718 if (to == BUF_Z (buf) &&
2719 bi_from > BI_BUF_GPT (buf))
2720 {
2721 /* avoid moving the gap just to delete from the bottom. */
2722
2723 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2724 {
2725 record_delete (mbuf, from, numdel);
2726 }
2727 BUF_MODIFF (buf)++;
2728 MARK_BUFFERS_CHANGED;
2729
2730 /* #### Point used to be modified here, but this causes problems
2731 with MULE, as point is used to calculate bytinds, and if the
2732 offset in bc_numdel causes point to move to a non first-byte
2733 location, causing some other function to throw an assertion
2734 in ASSERT_VALID_BYTIND. I've moved the code to right after
2735 the other movements and adjustments, but before the gap is
2736 moved. -- jh 970813 */
2737
2738 /* Detach any extents that are completely within the range [FROM, TO],
2739 if the extents are detachable.
2740
2741 This must come AFTER record_delete(), so that the appropriate
2742 extents will be present to be recorded, and BEFORE the gap
2743 size is increased, as otherwise we will be confused about
2744 where the extents end. */
2745 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2746 {
2747 process_extents_for_deletion (make_buffer (mbuf), bi_from, bi_to, 0);
2748 }
2749
2750 /* Relocate all markers pointing into the new, larger gap to
2751 point at the end of the text before the gap. */
2752 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2753 {
2754 adjust_markers (mbuf,
2755 (bi_to + BUF_GAP_SIZE (mbuf)),
2756 (bi_to + BUF_GAP_SIZE (mbuf)),
2757 (- bc_numdel));
2758 }
2759
2760 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2761 {
2762 /* Relocate any extent endpoints just like markers. */
2763 adjust_extents_for_deletion (make_buffer (mbuf), bi_from, bi_to,
2764 BUF_GAP_SIZE (mbuf), bc_numdel, 0);
2765 }
2766
2767 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2768 {
2769 /* Relocate point as if it were a marker. */
2770 if (bi_from < BI_BUF_PT (mbuf))
2771 {
2772 if (BI_BUF_PT (mbuf) < bi_to)
2773 JUST_SET_POINT (mbuf, from, bi_from);
2774 else
2775 JUST_SET_POINT (mbuf, BUF_PT (mbuf) - numdel,
2776 BI_BUF_PT (mbuf) - bc_numdel);
2777 }
2778 }
2779
2780 SET_BUF_END_GAP_SIZE (buf, BUF_END_GAP_SIZE (buf) + bc_numdel);
2781
2782 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2783 {
2784 SET_BOTH_BUF_ZV (mbuf, BUF_ZV (mbuf) - numdel,
2785 BI_BUF_ZV (mbuf) - bc_numdel);
2786 }
2787 SET_BOTH_BUF_Z (buf, BUF_Z (buf) - numdel, BI_BUF_Z (buf) - bc_numdel);
2788 SET_GAP_SENTINEL (buf);
2789 }
2790 else
2791 {
2792 /* Make sure the gap is somewhere in or next to what we are deleting. */
2793 if (bi_to < BI_BUF_GPT (buf))
2794 gap_left (buf, bi_to);
2795 if (bi_from > BI_BUF_GPT (buf))
2796 gap_right (buf, bi_from);
2797
2798 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2799 {
2800 record_delete (mbuf, from, numdel);
2801 }
2802 BUF_MODIFF (buf)++;
2803 MARK_BUFFERS_CHANGED;
2804
2805 /* #### Point used to be modified here, but this causes problems
2806 with MULE, as point is used to calculate bytinds, and if the
2807 offset in bc_numdel causes point to move to a non first-byte
2808 location, causing some other function to throw an assertion
2809 in ASSERT_VALID_BYTIND. I've moved the code to right after
2810 the other movements and adjustments, but before the gap is
2811 moved. -- jh 970813 */
2812
2813 /* Detach any extents that are completely within the range [FROM, TO],
2814 if the extents are detachable.
2815
2816 This must come AFTER record_delete(), so that the appropriate extents
2817 will be present to be recorded, and BEFORE the gap size is increased,
2818 as otherwise we will be confused about where the extents end. */
2819 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2820 {
2821 process_extents_for_deletion (make_buffer (mbuf), bi_from, bi_to, 0);
2822 }
2823
2824 /* Relocate all markers pointing into the new, larger gap to
2825 point at the end of the text before the gap. */
2826 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2827 {
2828 adjust_markers (mbuf,
2829 (bi_to + BUF_GAP_SIZE (mbuf)),
2830 (bi_to + BUF_GAP_SIZE (mbuf)),
2831 (- bc_numdel - BUF_GAP_SIZE (mbuf)));
2832 }
2833
2834 /* Relocate any extent endpoints just like markers. */
2835 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2836 {
2837 adjust_extents_for_deletion (make_buffer (mbuf), bi_from, bi_to,
2838 BUF_GAP_SIZE (mbuf),
2839 bc_numdel, BUF_GAP_SIZE (mbuf));
2840 }
2841
2842 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2843 {
2844 /* Relocate point as if it were a marker. */
2845 if (bi_from < BI_BUF_PT (mbuf))
2846 {
2847 if (BI_BUF_PT (mbuf) < bi_to)
2848 JUST_SET_POINT (mbuf, from, bi_from);
2849 else
2850 JUST_SET_POINT (mbuf, BUF_PT (mbuf) - numdel,
2851 BI_BUF_PT (mbuf) - bc_numdel);
2852 }
2853 }
2854
2855 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + bc_numdel);
2856 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2857 {
2858 SET_BOTH_BUF_ZV (mbuf, BUF_ZV (mbuf) - numdel,
2859 BI_BUF_ZV (mbuf) - bc_numdel);
2860 }
2861 SET_BOTH_BUF_Z (buf, BUF_Z (buf) - numdel, BI_BUF_Z (buf) - bc_numdel);
2862 SET_BI_BUF_GPT (buf, bi_from);
2863 SET_GAP_SENTINEL (buf);
2864 }
2865
2866 #ifdef MULE
2867 buffer_mule_signal_deleted_region (buf, from, to, bi_from, bi_to);
2868 #endif
2869
2870 #ifdef ERROR_CHECK_EXTENTS
2871 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2872 {
2873 sledgehammer_extent_check (make_buffer (mbuf));
2874 }
2875 #endif
2876
2877 signal_after_change (buf, from, to, from);
2878 }
2879
2880
2881 /************************************************************************/
2882 /* Replacement of characters */
2883 /************************************************************************/
2884
2885 /* Replace the character at POS in buffer B with CH. */
2886
2887 void
2888 buffer_replace_char (struct buffer *buf, Bufpos pos, Emchar ch,
2889 int not_real_change, int force_lock_check)
2890 {
2891 /* This function can GC */
2892 Bufbyte curstr[MAX_EMCHAR_LEN];
2893 Bufbyte newstr[MAX_EMCHAR_LEN];
2894 Bytecount curlen, newlen;
2895
2896 /* Defensive steps just in case a buffer gets deleted and a calling
2897 function doesn't notice it. */
2898 if (!BUFFER_LIVE_P (buf))
2899 return;
2900
2901 curlen = BUF_CHARPTR_COPY_CHAR (buf, pos, curstr);
2902 newlen = set_charptr_emchar (newstr, ch);
2903
2904 if (curlen == newlen)
2905 {
2906 struct buffer *mbuf;
2907 Lisp_Object bufcons;
2908
2909 /* then we can just replace the text. */
2910 prepare_to_modify_buffer (buf, pos, pos + 1,
2911 !not_real_change || force_lock_check);
2912 /* Defensive steps in case the before-change-functions fuck around */
2913 if (!BUFFER_LIVE_P (buf))
2914 /* Bad bad pre-change function. */
2915 return;
2916
2917 /* Make args be valid again. prepare_to_modify_buffer() might have
2918 modified the buffer. */
2919 if (pos < BUF_BEGV (buf))
2920 pos = BUF_BEGV (buf);
2921 if (pos >= BUF_ZV (buf))
2922 pos = BUF_ZV (buf) - 1;
2923 if (pos < BUF_BEGV (buf))
2924 /* no more characters in buffer! */
2925 return;
2926
2927 if (BUF_FETCH_CHAR (buf, pos) == '\n')
2928 {
2929 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2930 {
2931 mbuf->changes->newline_was_deleted = 1;
2932 }
2933 }
2934 MARK_BUFFERS_CHANGED;
2935 if (!not_real_change)
2936 {
2937 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2938 {
2939 record_change (mbuf, pos, 1);
2940 }
2941 BUF_MODIFF (buf)++;
2942 }
2943 memcpy (BUF_BYTE_ADDRESS (buf, pos), newstr, newlen);
2944
2945 signal_after_change (buf, pos, pos + 1, pos + 1);
2946
2947 /* We do not have to adjust the Mule data; we just replaced a
2948 character with another of the same number of bytes. */
2949 }
2950 else
2951 {
2952 /*
2953 * Must implement as deletion followed by insertion.
2954 *
2955 * Make a note to move point forward later in the one situation
2956 * where it is needed, a delete/insert one position behind
2957 * point. Point will drift backward by one position and stay
2958 * there otherwise.
2959 */
2960 int movepoint = (pos == BUF_PT (buf) - 1);
2961
2962 buffer_delete_range (buf, pos, pos + 1, 0);
2963 /* Defensive steps in case the before-change-functions fuck around */
2964 if (!BUFFER_LIVE_P (buf))
2965 /* Bad bad pre-change function. */
2966 return;
2967
2968 /* Make args be valid again. prepare_to_modify_buffer() might have
2969 modified the buffer. */
2970 if (pos < BUF_BEGV (buf))
2971 pos = BUF_BEGV (buf);
2972 if (pos >= BUF_ZV (buf))
2973 pos = BUF_ZV (buf) - 1;
2974 if (pos < BUF_BEGV (buf))
2975 /* no more characters in buffer! */
2976 return;
2977 /*
2978 * -1 as the pos argument means to move point forward with the
2979 * insertion, which we must do if the deletion moved point
2980 * backward so that it now equals the insertion point.
2981 */
2982 buffer_insert_string_1 (buf, (movepoint ? -1 : pos),
2983 newstr, Qnil, 0, newlen, 0);
2984 }
2985 }
2986
2987
2988 /************************************************************************/
2989 /* Other functions */
2990 /************************************************************************/
2991
2992 /* Make a string from a buffer. This needs to take into account the gap,
2993 and add any necessary extents from the buffer. */
2994
2995 static Lisp_Object
2996 make_string_from_buffer_1 (struct buffer *buf, Bufpos pos, Charcount length,
2997 int no_extents)
2998 {
2999 /* This function can GC */
3000 Bytind bi_ind = bufpos_to_bytind (buf, pos);
3001 Bytecount bi_len = bufpos_to_bytind (buf, pos + length) - bi_ind;
3002 Lisp_Object val = make_uninit_string (bi_len);
3003
3004 struct gcpro gcpro1;
3005 GCPRO1 (val);
3006
3007 if (!no_extents)
3008 add_string_extents (val, buf, bi_ind, bi_len);
3009
3010 {
3011 Bytecount len1 = BI_BUF_GPT (buf) - bi_ind;
3012 Bufbyte *start1 = BI_BUF_BYTE_ADDRESS (buf, bi_ind);
3013 Bufbyte *dest = XSTRING_DATA (val);
3014
3015 if (len1 < 0)
3016 {
3017 /* Completely after gap */
3018 memcpy (dest, start1, bi_len);
3019 }
3020 else if (bi_len <= len1)
3021 {
3022 /* Completely before gap */
3023 memcpy (dest, start1, bi_len);
3024 }
3025 else
3026 {
3027 /* Spans gap */
3028 Bytind pos2 = bi_ind + len1;
3029 Bufbyte *start2 = BI_BUF_BYTE_ADDRESS (buf, pos2);
3030
3031 memcpy (dest, start1, len1);
3032 memcpy (dest + len1, start2, bi_len - len1);
3033 }
3034 }
3035
3036 UNGCPRO;
3037 return val;
3038 }
3039
3040 Lisp_Object
3041 make_string_from_buffer (struct buffer *buf, Bufpos pos, Charcount length)
3042 {
3043 return make_string_from_buffer_1 (buf, pos, length, 0);
3044 }
3045
3046 Lisp_Object
3047 make_string_from_buffer_no_extents (struct buffer *buf, Bufpos pos,
3048 Charcount length)
3049 {
3050 return make_string_from_buffer_1 (buf, pos, length, 1);
3051 }
3052
3053 void
3054 barf_if_buffer_read_only (struct buffer *buf, Bufpos from, Bufpos to)
3055 {
3056 Lisp_Object buffer;
3057 Lisp_Object iro;
3058
3059 XSETBUFFER (buffer, buf);
3060 back:
3061 iro = (buf == current_buffer ? Vinhibit_read_only :
3062 symbol_value_in_buffer (Qinhibit_read_only, buffer));
3063 if (!LISTP (iro))
3064 return;
3065 if (NILP (iro) && !NILP (buf->read_only))
3066 {
3067 Fsignal (Qbuffer_read_only, (list1 (buffer)));
3068 goto back;
3069 }
3070 if (from > 0)
3071 {
3072 if (to < 0)
3073 to = from;
3074 verify_extent_modification (buffer,
3075 bufpos_to_bytind (buf, from),
3076 bufpos_to_bytind (buf, to),
3077 iro);
3078 }
3079 }
3080
3081 void
3082 find_charsets_in_bufbyte_string (unsigned char *charsets, CONST Bufbyte *str,
3083 Bytecount len)
3084 {
3085 #ifndef MULE
3086 /* Telescope this. */
3087 charsets[0] = 1;
3088 #else
3089 CONST Bufbyte *strend = str + len;
3090 memset (charsets, 0, NUM_LEADING_BYTES);
3091
3092 while (str < strend)
3093 {
3094 charsets[CHAR_LEADING_BYTE (charptr_emchar (str)) - 128] = 1;
3095 INC_CHARPTR (str);
3096 }
3097 #endif
3098 }
3099
3100 void
3101 find_charsets_in_emchar_string (unsigned char *charsets, CONST Emchar *str,
3102 Charcount len)
3103 {
3104 #ifndef MULE
3105 /* Telescope this. */
3106 charsets[0] = 1;
3107 #else
3108 int i;
3109
3110 memset (charsets, 0, NUM_LEADING_BYTES);
3111 for (i = 0; i < len; i++)
3112 {
3113 charsets[CHAR_LEADING_BYTE (str[i]) - 128] = 1;
3114 }
3115 #endif
3116 }
3117
3118 int
3119 bufbyte_string_displayed_columns (CONST Bufbyte *str, Bytecount len)
3120 {
3121 int cols = 0;
3122 CONST Bufbyte *end = str + len;
3123
3124 while (str < end)
3125 {
3126 #ifdef MULE
3127 Emchar ch = charptr_emchar (str);
3128 cols += XCHARSET_COLUMNS (CHAR_CHARSET (ch));
3129 #else
3130 cols++;
3131 #endif
3132 INC_CHARPTR (str);
3133 }
3134
3135 return cols;
3136 }
3137
3138 int
3139 emchar_string_displayed_columns (CONST Emchar *str, Charcount len)
3140 {
3141 #ifdef MULE
3142 int cols = 0;
3143 int i;
3144
3145 for (i = 0; i < len; i++)
3146 cols += XCHARSET_COLUMNS (CHAR_CHARSET (str[i]));
3147
3148 return cols;
3149 #else /* not MULE */
3150 return len;
3151 #endif
3152 }
3153
3154 /* NOTE: Does not reset the Dynarr. */
3155
3156 void
3157 convert_bufbyte_string_into_emchar_dynarr (CONST Bufbyte *str, Bytecount len,
3158 Emchar_dynarr *dyn)
3159 {
3160 CONST Bufbyte *strend = str + len;
3161
3162 while (str < strend)
3163 {
3164 Emchar ch = charptr_emchar (str);
3165 Dynarr_add (dyn, ch);
3166 INC_CHARPTR (str);
3167 }
3168 }
3169
3170 Charcount
3171 convert_bufbyte_string_into_emchar_string (CONST Bufbyte *str, Bytecount len,
3172 Emchar *arr)
3173 {
3174 CONST Bufbyte *strend = str + len;
3175 Charcount newlen = 0;
3176 while (str < strend)
3177 {
3178 Emchar ch = charptr_emchar (str);
3179 arr[newlen++] = ch;
3180 INC_CHARPTR (str);
3181 }
3182 return newlen;
3183 }
3184
3185 /* Convert an array of Emchars into the equivalent string representation.
3186 Store into the given Bufbyte dynarr. Does not reset the dynarr.
3187 Does not add a terminating zero. */
3188
3189 void
3190 convert_emchar_string_into_bufbyte_dynarr (Emchar *arr, int nels,
3191 Bufbyte_dynarr *dyn)
3192 {
3193 Bufbyte str[MAX_EMCHAR_LEN];
3194 int i;
3195
3196 for (i = 0; i < nels; i++)
3197 {
3198 Bytecount len = set_charptr_emchar (str, arr[i]);
3199 Dynarr_add_many (dyn, str, len);
3200 }
3201 }
3202
3203 /* Convert an array of Emchars into the equivalent string representation.
3204 Malloc the space needed for this and return it. If LEN_OUT is not a
3205 NULL pointer, store into LEN_OUT the number of Bufbytes in the
3206 malloc()ed string. Note that the actual number of Bufbytes allocated
3207 is one more than this: the returned string is zero-terminated. */
3208
3209 Bufbyte *
3210 convert_emchar_string_into_malloced_string (Emchar *arr, int nels,
3211 Bytecount *len_out)
3212 {
3213 /* Damn zero-termination. */
3214 Bufbyte *str = (Bufbyte *) alloca (nels * MAX_EMCHAR_LEN + 1);
3215 Bufbyte *strorig = str;
3216 Bytecount len;
3217
3218 int i;
3219
3220 for (i = 0; i < nels; i++)
3221 str += set_charptr_emchar (str, arr[i]);
3222 *str = '\0';
3223 len = str - strorig;
3224 str = (Bufbyte *) xmalloc (1 + len);
3225 memcpy (str, strorig, 1 + len);
3226 if (len_out)
3227 *len_out = len;
3228 return str;
3229 }
3230
3231
3232 /************************************************************************/
3233 /* initialization */
3234 /************************************************************************/
3235
3236 void
3237 reinit_vars_of_insdel (void)
3238 {
3239 int i;
3240
3241 inside_change_hook = 0;
3242 in_first_change = 0;
3243
3244 for (i = 0; i <= MAX_BYTIND_GAP_SIZE_3; i++)
3245 three_to_one_table[i] = i / 3;
3246 }
3247
3248 void
3249 vars_of_insdel (void)
3250 {
3251 reinit_vars_of_insdel ();
3252 }
3253
3254 void
3255 init_buffer_text (struct buffer *b)
3256 {
3257 if (!b->base_buffer)
3258 {
3259 SET_BUF_GAP_SIZE (b, 20);
3260 BUFFER_ALLOC (b->text->beg, BUF_GAP_SIZE (b) + BUF_END_SENTINEL_SIZE);
3261 if (! BUF_BEG_ADDR (b))
3262 memory_full ();
3263
3264 SET_BUF_END_GAP_SIZE (b, 0);
3265 SET_BI_BUF_GPT (b, 1);
3266 SET_BOTH_BUF_Z (b, 1, 1);
3267 SET_GAP_SENTINEL (b);
3268 SET_END_SENTINEL (b);
3269 #ifdef MULE
3270 {
3271 int i;
3272
3273 b->text->mule_bufmin = b->text->mule_bufmax = 1;
3274 b->text->mule_bytmin = b->text->mule_bytmax = 1;
3275 b->text->mule_shifter = 0;
3276 b->text->mule_three_p = 0;
3277
3278 for (i = 0; i < 16; i++)
3279 {
3280 b->text->mule_bufpos_cache[i] = 1;
3281 b->text->mule_bytind_cache[i] = 1;
3282 }
3283 }
3284 #endif /* MULE */
3285 b->text->line_number_cache = Qnil;
3286
3287 BUF_MODIFF (b) = 1;
3288 BUF_SAVE_MODIFF (b) = 1;
3289
3290 JUST_SET_POINT (b, 1, 1);
3291 SET_BOTH_BUF_BEGV (b, 1, 1);
3292 SET_BOTH_BUF_ZV (b, 1, 1);
3293
3294 b->text->changes = xnew_and_zero (struct buffer_text_change_data);
3295 }
3296 else
3297 {
3298 JUST_SET_POINT (b, BUF_PT (b->base_buffer), BI_BUF_PT (b->base_buffer));
3299 SET_BOTH_BUF_BEGV (b, BUF_BEGV (b->base_buffer),
3300 BI_BUF_BEGV (b->base_buffer));
3301 SET_BOTH_BUF_ZV (b, BUF_ZV (b->base_buffer),
3302 BI_BUF_ZV (b->base_buffer));
3303 }
3304
3305 b->changes = xnew_and_zero (struct each_buffer_change_data);
3306 BUF_FACECHANGE (b) = 1;
3307
3308 #ifdef REGION_CACHE_NEEDS_WORK
3309 b->newline_cache = 0;
3310 b->width_run_cache = 0;
3311 b->width_table = Qnil;
3312 #endif
3313 }
3314
3315 void
3316 uninit_buffer_text (struct buffer *b)
3317 {
3318 if (!b->base_buffer)
3319 {
3320 BUFFER_FREE (b->text->beg);
3321 xfree (b->text->changes);
3322 }
3323 xfree (b->changes);
3324
3325 #ifdef REGION_CACHE_NEEDS_WORK
3326 if (b->newline_cache)
3327 {
3328 free_region_cache (b->newline_cache);
3329 b->newline_cache = 0;
3330 }
3331 if (b->width_run_cache)
3332 {
3333 free_region_cache (b->width_run_cache);
3334 b->width_run_cache = 0;
3335 }
3336 b->width_table = Qnil;
3337 #endif
3338 }