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