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