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