Contents in 1999-06-04-13 of release-21-2.
[chise/xemacs-chise.git.1] / src / insdel.c
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
3232 /************************************************************************/
3233 /*                            initialization                            */
3234 /************************************************************************/
3235
3236 void
3237 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 init_buffer_text (struct buffer *b)
3250 {
3251   if (!b->base_buffer)
3252     {
3253       SET_BUF_GAP_SIZE (b, 20);
3254       BUFFER_ALLOC (b->text->beg, BUF_GAP_SIZE (b) + BUF_END_SENTINEL_SIZE);
3255       if (! BUF_BEG_ADDR (b))
3256         memory_full ();
3257
3258       SET_BUF_END_GAP_SIZE (b, 0);
3259       SET_BI_BUF_GPT (b, 1);
3260       SET_BOTH_BUF_Z (b, 1, 1);
3261       SET_GAP_SENTINEL (b);
3262       SET_END_SENTINEL (b);
3263 #ifdef MULE
3264       {
3265         int i;
3266
3267         b->text->mule_bufmin = b->text->mule_bufmax = 1;
3268         b->text->mule_bytmin = b->text->mule_bytmax = 1;
3269         b->text->mule_shifter = 0;
3270         b->text->mule_three_p = 0;
3271
3272         for (i = 0; i < 16; i++)
3273           {
3274             b->text->mule_bufpos_cache[i] = 1;
3275             b->text->mule_bytind_cache[i] = 1;
3276           }
3277       }
3278 #endif /* MULE */
3279       b->text->line_number_cache = Qnil;
3280
3281       BUF_MODIFF (b) = 1;
3282       BUF_SAVE_MODIFF (b) = 1;
3283
3284       JUST_SET_POINT (b, 1, 1);
3285       SET_BOTH_BUF_BEGV (b, 1, 1);
3286       SET_BOTH_BUF_ZV (b, 1, 1);
3287
3288       b->text->changes = xnew_and_zero (struct buffer_text_change_data);
3289     }
3290   else
3291     {
3292       JUST_SET_POINT (b, BUF_PT (b->base_buffer), BI_BUF_PT (b->base_buffer));
3293       SET_BOTH_BUF_BEGV (b, BUF_BEGV (b->base_buffer),
3294                          BI_BUF_BEGV (b->base_buffer));
3295       SET_BOTH_BUF_ZV (b, BUF_ZV (b->base_buffer),
3296                          BI_BUF_ZV (b->base_buffer));
3297     }
3298
3299   b->changes = xnew_and_zero (struct each_buffer_change_data);
3300   BUF_FACECHANGE (b) = 1;
3301
3302 #ifdef REGION_CACHE_NEEDS_WORK
3303   b->newline_cache = 0;
3304   b->width_run_cache = 0;
3305   b->width_table = Qnil;
3306 #endif
3307 }
3308
3309 void
3310 uninit_buffer_text (struct buffer *b)
3311 {
3312   if (!b->base_buffer)
3313     {
3314       BUFFER_FREE (b->text->beg);
3315       xfree (b->text->changes);
3316     }
3317   xfree (b->changes);
3318
3319 #ifdef REGION_CACHE_NEEDS_WORK
3320   if (b->newline_cache)
3321     {
3322       free_region_cache (b->newline_cache);
3323       b->newline_cache = 0;
3324     }
3325   if (b->width_run_cache)
3326     {
3327       free_region_cache (b->width_run_cache);
3328       b->width_run_cache = 0;
3329     }
3330   b->width_table = Qnil;
3331 #endif
3332 }