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