comparison src/insdel.c @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children 9ee227acff29
comparison
equal deleted inserted replaced
-1:000000000000 0:376386a54a3c
1 /* Buffer insertion/deletion and gap motion for XEmacs.
2 Copyright (C) 1985, 1986, 1991, 1992, 1993, 1994, 1995
3 Free Software Foundation, Inc.
4 Copyright (C) 1995 Sun Microsystems, Inc.
5
6 This file is part of XEmacs.
7
8 XEmacs is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
11 later version.
12
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with XEmacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
22
23 /* Synched up with: Mule 2.0, FSF 19.30. Diverges significantly. */
24
25 /* This file has been Mule-ized. */
26
27 /* Overhauled by Ben Wing, December 1994, for Mule implementation. */
28
29 /*
30 There are three possible ways to specify positions in a buffer. All
31 of these are one-based: the beginning of the buffer is position or
32 index 1, and 0 is not a valid position.
33
34 As a "buffer position" (typedef Bufpos):
35
36 This is an index specifying an offset in characters from the
37 beginning of the buffer. Note that buffer positions are
38 logically *between* characters, not on a character. The
39 difference between two buffer positions specifies the number of
40 characters between those positions. Buffer positions are the
41 only kind of position externally visible to the user.
42
43 As a "byte index" (typedef Bytind):
44
45 This is an index over the bytes used to represent the characters
46 in the buffer. If there is no Mule support, this is identical
47 to a buffer position, because each character is represented
48 using one byte. However, with Mule support, many characters
49 require two or more bytes for their representation, and so a
50 byte index may be greater than the corresponding buffer
51 position.
52
53 As a "memory index" (typedef Memind):
54
55 This is the byte index adjusted for the gap. For positions
56 before the gap, this is identical to the byte index. For
57 positions after the gap, this is the byte index plus the gap
58 size. There are two possible memory indices for the gap
59 position; the memory index at the beginning of the gap should
60 always be used, except in code that deals with manipulating the
61 gap, where both indices may be seen. The address of the
62 character "at" (i.e. following) a particular position can be
63 obtained from the formula
64
65 buffer_start_address + memory_index(position) - 1
66
67 except in the case of characters at the gap position.
68
69 Other typedefs:
70 ===============
71
72 Emchar:
73 -------
74 This typedef represents a single Emacs character, which can be
75 ASCII, ISO-8859, or some extended character, as would typically
76 be used for Kanji. Note that the representation of a character
77 as an Emchar is *not* the same as the representation of that
78 same character in a string; thus, you cannot do the standard
79 C trick of passing a pointer to a character to a function that
80 expects a string.
81
82 An Emchar takes up 19 bits of representation and (for code
83 compatibility and such) is compatible with an int. This
84 representation is visible on the Lisp level. The important
85 characteristics of the Emchar representation are
86
87 -- values 0x00 - 0x7f represent ASCII.
88 -- values 0x80 - 0xff represent the right half of ISO-8859-1.
89 -- values 0x100 and up represent all other characters.
90
91 This means that Emchar values are upwardly compatible with
92 the standard 8-bit representation of ASCII/ISO-8859-1.
93
94 Bufbyte:
95 --------
96 The data in a buffer or string is logically made up of Bufbyte
97 objects, where a Bufbyte takes up the same amount of space as a
98 char. (It is declared differently, though, to catch invalid
99 usages.) Strings stored using Bufbytes are said to be in
100 "internal format". The important characteristics of internal
101 format are
102
103 -- ASCII characters are represented as a single Bufbyte,
104 in the range 0 - 0x7f.
105 -- All other characters are represented as a Bufbyte in
106 the range 0x80 - 0x9f followed by one or more Bufbytes
107 in the range 0xa0 to 0xff.
108
109 This leads to a number of desirable properties:
110
111 -- Given the position of the beginning of a character,
112 you can find the beginning of the next or previous
113 character in constant time.
114 -- When searching for a substring or an ASCII character
115 within the string, you need merely use standard
116 searching routines.
117
118 array of char:
119 --------------
120 Strings that go in or out of Emacs are in "external format",
121 typedef'ed as an array of char or a char *. There is more
122 than one external format (JIS, EUC, etc.) but they all
123 have similar properties. They are modal encodings,
124 which is to say that the meaning of particular bytes is
125 not fixed but depends on what "mode" the string is currently
126 in (e.g. bytes in the range 0 - 0x7f might be
127 interpreted as ASCII, or as Hiragana, or as 2-byte Kanji,
128 depending on the current mode). The mode starts out in
129 ASCII/ISO-8859-1 and is switched using escape sequences --
130 for example, in the JIS encoding, 'ESC $ B' switches to a
131 mode where pairs of bytes in the range 0 - 0x7f
132 are interpreted as Kanji characters.
133
134 External-formatted data is generally desirable for passing
135 data between programs because it is upwardly compatible
136 with standard ASCII/ISO-8859-1 strings and may require
137 less space than internal encodings such as the one
138 described above. In addition, some encodings (e.g. JIS)
139 keep all characters (except the ESC used to switch modes)
140 in the printing ASCII range 0x20 - 0x7e, which results in
141 a much higher probability that the data will avoid being
142 garbled in transmission. Externally-formatted data is
143 generally not very convenient to work with, however, and
144 for this reason is usually converted to internal format
145 before any work is done on the string.
146
147 NOTE: filenames need to be in external format so that
148 ISO-8859-1 characters come out correctly.
149
150 Charcount:
151 ----------
152 This typedef represents a count of characters, such as
153 a character offset into a string or the number of
154 characters between two positions in a buffer. The
155 difference between two Bufpos's is a Charcount, and
156 character positions in a string are represented using
157 a Charcount.
158
159 Bytecount:
160 ----------
161 Similar to a Charcount but represents a count of bytes.
162 The difference between two Bytind's is a Bytecount.
163
164
165 Usage of the various representations:
166 =====================================
167
168 Memory indices are used in low-level functions in insdel.c and for
169 extent endpoints and marker positions. The reason for this is that
170 this way, the extents and markers don't need to be updated for most
171 insertions, which merely shrink the gap and don't move any
172 characters around in memory.
173
174 (The beginning-of-gap memory index simplifies insertions w.r.t.
175 markers, because text usually gets inserted after markers. For
176 extents, it is merely for consistency, because text can get
177 inserted either before or after an extent's endpoint depending on
178 the open/closedness of the endpoint.)
179
180 Byte indices are used in other code that needs to be fast,
181 such as the searching, redisplay, and extent-manipulation code.
182
183 Buffer positions are used in all other code. This is because this
184 representation is easiest to work with (especially since Lisp
185 code always uses buffer positions), necessitates the fewest
186 changes to existing code, and is the safest (e.g. if the text gets
187 shifted underneath a buffer position, it will still point to a
188 character; if text is shifted under a byte index, it might point
189 to the middle of a character, which would be bad).
190
191 Similarly, Charcounts are used in all code that deals with strings
192 except for code that needs to be fast, which used Bytecounts.
193
194 Strings are always passed around internally using internal format.
195 Conversions between external format are performed at the time
196 that the data goes in or out of Emacs.
197
198 Working with the various representations:
199 ========================================= */
200
201 #include <config.h>
202 #include "lisp.h"
203
204 #include "buffer.h"
205 #include "device.h"
206 #include "frame.h"
207 #include "extents.h"
208 #include "insdel.h"
209 #include "lstream.h"
210 #include "redisplay.h"
211
212 /* We write things this way because it's very important the
213 MAX_BYTIND_GAP_SIZE_3 is a multiple of 3. (As it happens,
214 65535 is a multiple of 3, but this may not always be the
215 case.) */
216
217 #define MAX_BUFPOS_GAP_SIZE_3 (65535/3)
218 #define MAX_BYTIND_GAP_SIZE_3 (3 * MAX_BUFPOS_GAP_SIZE_3)
219
220 short three_to_one_table[1 + MAX_BYTIND_GAP_SIZE_3];
221
222 /* Various macros modelled along the lines of those in buffer.h.
223 Purposefully omitted from buffer.h because files other than this
224 one should not be using them. */
225
226 /* Address of beginning of buffer. This is an lvalue because
227 BUFFER_ALLOC needs it to be. */
228 #define BUF_BEG_ADDR(buf) ((buf)->text->beg)
229
230 /* Set the address of beginning of buffer. */
231 #define SET_BUF_BEG_ADDR(buf, addr) do { (buf)->text->beg = (addr); } while (0)
232
233 /* Gap size. */
234 #define BUF_GAP_SIZE(buf) ((buf)->text->gap_size + 0)
235
236 /* Set gap size. */
237 #define SET_BUF_GAP_SIZE(buf, value) \
238 do { (buf)->text->gap_size = (value); } while (0)
239
240 /* Gap location. */
241 #define BI_BUF_GPT(buf) ((buf)->text->gpt + 0)
242 #define BUF_GPT_ADDR(buf) (BUF_BEG_ADDR (buf) + BI_BUF_GPT (buf) - 1)
243
244 /* Set gap location. */
245 #define SET_BI_BUF_GPT(buf, value) do { (buf)->text->gpt = (value); } while (0)
246
247 /* Set end of buffer. */
248 #define SET_BOTH_BUF_Z(buf, val, bival) \
249 do \
250 { \
251 (buf)->text->z = (bival); \
252 (buf)->text->bufz = (val); \
253 } while (0)
254
255 # define GAP_CAN_HOLD_SIZE_P(buf, len) (BUF_GAP_SIZE (buf) >= (len))
256 # define SET_GAP_SENTINEL(buf)
257 # define BUF_END_SENTINEL_SIZE 0
258 # define SET_END_SENTINEL(buf)
259
260
261 /************************************************************************/
262 /* Charcount/Bytecount conversion */
263 /************************************************************************/
264
265 /* Optimization. Do it. Live it. Love it. */
266
267 #ifdef ERROR_CHECK_BUFPOS
268
269 Bytind
270 bufpos_to_bytind (struct buffer *buf, Bufpos x)
271 {
272 Bytind retval = real_bufpos_to_bytind (buf, x);
273 ASSERT_VALID_BYTIND_UNSAFE (buf, retval);
274 return retval;
275 }
276
277 Bufpos
278 bytind_to_bufpos (struct buffer *buf, Bytind x)
279 {
280 ASSERT_VALID_BYTIND_UNSAFE (buf, x);
281 return real_bytind_to_bufpos (buf, x);
282 }
283
284 #endif /* ERROR_CHECK_BUFPOS */
285
286
287 /************************************************************************/
288 /* verifying buffer and string positions */
289 /************************************************************************/
290
291 /* Functions below are tagged with either _byte or _char indicating
292 whether they return byte or character positions. For a buffer,
293 a character position is a "Bufpos" and a byte position is a "Bytind".
294 For strings, these are sometimes typed using "Charcount" and
295 "Bytecount". */
296
297 /* Flags for the functions below are:
298
299 GB_ALLOW_PAST_ACCESSIBLE
300
301 The allowable range for the position is the entire buffer
302 (BEG and Z), rather than the accessible portion. For strings,
303 this flag has no effect.
304
305 GB_COERCE_RANGE
306
307 If the position is outside the allowable range, return
308 the lower or upper bound of the range, whichever is closer
309 to the specified position.
310
311 GB_NO_ERROR_IF_BAD
312
313 If the position is outside the allowable range, return -1.
314
315 GB_NEGATIVE_FROM_END
316
317 If a value is negative, treat it as an offset from the end.
318 Only applies to strings.
319
320 The following additional flags apply only to the functions
321 that return ranges:
322
323 GB_ALLOW_NIL
324
325 Either or both positions can be nil. If FROM is nil,
326 FROM_OUT will contain the lower bound of the allowed range.
327 If TO is nil, TO_OUT will contain the upper bound of the
328 allowed range.
329
330 GB_CHECK_ORDER
331
332 FROM must contain the lower bound and TO the upper bound
333 of the range. If the positions are reversed, an error is
334 signalled.
335
336 The following is a combination flag:
337
338 GB_HISTORICAL_STRING_BEHAVIOR
339
340 Equivalent to (GB_NEGATIVE_FROM_END | GB_ALLOW_NIL).
341 */
342
343 /* Return a buffer position stored in a Lisp_Object. Full
344 error-checking is done on the position. Flags can be specified to
345 control the behavior of out-of-range values. The default behavior
346 is to require that the position is within the accessible part of
347 the buffer (BEGV and ZV), and to signal an error if the position is
348 out of range.
349
350 */
351
352 Bufpos
353 get_buffer_pos_char (struct buffer *b, Lisp_Object pos, unsigned int flags)
354 {
355 Bufpos ind;
356 Bufpos min_allowed, max_allowed;
357
358 CHECK_INT_COERCE_MARKER (pos);
359 ind = XINT (pos);
360 min_allowed = (flags & GB_ALLOW_PAST_ACCESSIBLE) ?
361 BUF_BEG (b) : BUF_BEGV (b);
362 max_allowed = (flags & GB_ALLOW_PAST_ACCESSIBLE) ?
363 BUF_Z (b) : BUF_ZV (b);
364
365 if (ind < min_allowed || ind > max_allowed)
366 {
367 if (flags & GB_COERCE_RANGE)
368 ind = ind < min_allowed ? min_allowed : max_allowed;
369 else if (flags & GB_NO_ERROR_IF_BAD)
370 ind = -1;
371 else
372 {
373 Lisp_Object buffer;
374 XSETBUFFER (buffer, b);
375 args_out_of_range (buffer, pos);
376 }
377 }
378
379 return ind;
380 }
381
382 Bytind
383 get_buffer_pos_byte (struct buffer *b, Lisp_Object pos, unsigned int flags)
384 {
385 Bufpos bpos = get_buffer_pos_char (b, pos, flags);
386 if (bpos < 0) /* could happen with GB_NO_ERROR_IF_BAD */
387 return -1;
388 return bufpos_to_bytind (b, bpos);
389 }
390
391 /* Return a pair of buffer positions representing a range of text,
392 taken from a pair of Lisp_Objects. Full error-checking is
393 done on the positions. Flags can be specified to control the
394 behavior of out-of-range values. The default behavior is to
395 allow the range bounds to be specified in either order
396 (however, FROM_OUT will always be the lower bound of the range
397 and TO_OUT the upper bound),to require that the positions
398 are within the accessible part of the buffer (BEGV and ZV),
399 and to signal an error if the positions are out of range.
400 */
401
402 void
403 get_buffer_range_char (struct buffer *b, Lisp_Object from, Lisp_Object to,
404 Bufpos *from_out, Bufpos *to_out, unsigned int flags)
405 {
406 Bufpos min_allowed, max_allowed;
407
408 min_allowed = (flags & GB_ALLOW_PAST_ACCESSIBLE) ?
409 BUF_BEG (b) : BUF_BEGV (b);
410 max_allowed = (flags & GB_ALLOW_PAST_ACCESSIBLE) ?
411 BUF_Z (b) : BUF_ZV (b);
412
413 if (NILP (from) && (flags & GB_ALLOW_NIL))
414 *from_out = min_allowed;
415 else
416 *from_out = get_buffer_pos_char (b, from, flags | GB_NO_ERROR_IF_BAD);
417
418 if (NILP (to) && (flags & GB_ALLOW_NIL))
419 *to_out = max_allowed;
420 else
421 *to_out = get_buffer_pos_char (b, to, flags | GB_NO_ERROR_IF_BAD);
422
423 if ((*from_out < 0 || *to_out < 0) && !(flags & GB_NO_ERROR_IF_BAD))
424 {
425 Lisp_Object buffer;
426 XSETBUFFER (buffer, b);
427 args_out_of_range_3 (buffer, from, to);
428 }
429
430 if (*from_out >= 0 && *to_out >= 0 && *from_out > *to_out)
431 {
432 if (flags & GB_CHECK_ORDER)
433 signal_simple_error_2 ("start greater than end", from, to);
434 else
435 {
436 Bufpos temp;
437
438 temp = *from_out;
439 *from_out = *to_out;
440 *to_out = temp;
441 }
442 }
443 }
444
445 void
446 get_buffer_range_byte (struct buffer *b, Lisp_Object from, Lisp_Object to,
447 Bytind *from_out, Bytind *to_out, unsigned int flags)
448 {
449 Bufpos s, e;
450
451 get_buffer_range_char (b, from, to, &s, &e, flags);
452 if (s >= 0)
453 *from_out = bufpos_to_bytind (b, s);
454 else /* could happen with GB_NO_ERROR_IF_BAD */
455 *from_out = -1;
456 if (e >= 0)
457 *to_out = bufpos_to_bytind (b, e);
458 else
459 *to_out = -1;
460 }
461
462 static Charcount
463 get_string_pos_char_1 (Lisp_Object string, Lisp_Object pos, unsigned int flags,
464 Charcount known_length)
465 {
466 Charcount ccpos;
467 Charcount min_allowed = 0;
468 Charcount max_allowed = known_length;
469
470 /* Computation of KNOWN_LENGTH is potentially expensive so we pass
471 it in. */
472 CHECK_INT (pos);
473 ccpos = XINT (pos);
474 if (ccpos < 0 && flags & GB_NEGATIVE_FROM_END)
475 ccpos += max_allowed;
476
477 if (ccpos < min_allowed || ccpos > max_allowed)
478 {
479 if (flags & GB_COERCE_RANGE)
480 ccpos = ccpos < min_allowed ? min_allowed : max_allowed;
481 else if (flags & GB_NO_ERROR_IF_BAD)
482 ccpos = -1;
483 else
484 args_out_of_range (string, pos);
485 }
486
487 return ccpos;
488 }
489
490 Charcount
491 get_string_pos_char (Lisp_Object string, Lisp_Object pos, unsigned int flags)
492 {
493 return get_string_pos_char_1 (string, pos, flags,
494 string_char_length (XSTRING (string)));
495 }
496
497 Bytecount
498 get_string_pos_byte (Lisp_Object string, Lisp_Object pos, unsigned int flags)
499 {
500 Charcount ccpos = get_string_pos_char (string, pos, flags);
501 if (ccpos < 0) /* could happen with GB_NO_ERROR_IF_BAD */
502 return -1;
503 return charcount_to_bytecount (string_data (XSTRING (string)), ccpos);
504 }
505
506 void
507 get_string_range_char (Lisp_Object string, Lisp_Object from, Lisp_Object to,
508 Charcount *from_out, Charcount *to_out,
509 unsigned int flags)
510 {
511 Charcount min_allowed = 0;
512 Charcount max_allowed = string_char_length (XSTRING (string));
513
514 if (NILP (from) && (flags & GB_ALLOW_NIL))
515 *from_out = min_allowed;
516 else
517 *from_out = get_string_pos_char_1 (string, from,
518 flags | GB_NO_ERROR_IF_BAD,
519 max_allowed);
520
521 if (NILP (to) && (flags & GB_ALLOW_NIL))
522 *to_out = max_allowed;
523 else
524 *to_out = get_string_pos_char_1 (string, to,
525 flags | GB_NO_ERROR_IF_BAD,
526 max_allowed);
527
528 if ((*from_out < 0 || *to_out < 0) && !(flags & GB_NO_ERROR_IF_BAD))
529 args_out_of_range_3 (string, from, to);
530
531 if (*from_out >= 0 && *to_out >= 0 && *from_out > *to_out)
532 {
533 if (flags & GB_CHECK_ORDER)
534 signal_simple_error_2 ("start greater than end", from, to);
535 else
536 {
537 Bufpos temp;
538
539 temp = *from_out;
540 *from_out = *to_out;
541 *to_out = temp;
542 }
543 }
544 }
545
546 void
547 get_string_range_byte (Lisp_Object string, Lisp_Object from, Lisp_Object to,
548 Bytecount *from_out, Bytecount *to_out,
549 unsigned int flags)
550 {
551 Charcount s, e;
552
553 get_string_range_char (string, from, to, &s, &e, flags);
554 if (s >= 0)
555 *from_out = charcount_to_bytecount (string_data (XSTRING (string)), s);
556 else /* could happen with GB_NO_ERROR_IF_BAD */
557 *from_out = -1;
558 if (e >= 0)
559 *to_out = charcount_to_bytecount (string_data (XSTRING (string)), e);
560 else
561 *to_out = -1;
562
563 }
564
565 Bufpos
566 get_buffer_or_string_pos_char (Lisp_Object object, Lisp_Object pos,
567 unsigned int flags)
568 {
569 if (STRINGP (object))
570 return get_string_pos_char (object, pos, flags);
571 else
572 return get_buffer_pos_char (XBUFFER (object), pos, flags);
573 }
574
575 Bytind
576 get_buffer_or_string_pos_byte (Lisp_Object object, Lisp_Object pos,
577 unsigned int flags)
578 {
579 if (STRINGP (object))
580 return get_string_pos_byte (object, pos, flags);
581 else
582 return get_buffer_pos_byte (XBUFFER (object), pos, flags);
583 }
584
585 void
586 get_buffer_or_string_range_char (Lisp_Object object, Lisp_Object from,
587 Lisp_Object to, Bufpos *from_out,
588 Bufpos *to_out, unsigned int flags)
589 {
590 if (STRINGP (object))
591 get_string_range_char (object, from, to, from_out, to_out, flags);
592 else
593 get_buffer_range_char (XBUFFER (object), from, to, from_out, to_out,
594 flags);
595 }
596
597 void
598 get_buffer_or_string_range_byte (Lisp_Object object, Lisp_Object from,
599 Lisp_Object to, Bytind *from_out,
600 Bytind *to_out, unsigned int flags)
601 {
602 if (STRINGP (object))
603 get_string_range_byte (object, from, to, from_out, to_out, flags);
604 else
605 get_buffer_range_byte (XBUFFER (object), from, to, from_out, to_out,
606 flags);
607 }
608
609 Bufpos
610 buffer_or_string_accessible_begin_char (Lisp_Object object)
611 {
612 if (STRINGP (object))
613 return 0;
614 return BUF_BEGV (XBUFFER (object));
615 }
616
617 Bufpos
618 buffer_or_string_accessible_end_char (Lisp_Object object)
619 {
620 if (STRINGP (object))
621 return string_char_length (XSTRING (object));
622 return BUF_ZV (XBUFFER (object));
623 }
624
625 Bytind
626 buffer_or_string_accessible_begin_byte (Lisp_Object object)
627 {
628 if (STRINGP (object))
629 return 0;
630 return BI_BUF_BEGV (XBUFFER (object));
631 }
632
633 Bytind
634 buffer_or_string_accessible_end_byte (Lisp_Object object)
635 {
636 if (STRINGP (object))
637 return string_length (XSTRING (object));
638 return BI_BUF_ZV (XBUFFER (object));
639 }
640
641 Bufpos
642 buffer_or_string_absolute_begin_char (Lisp_Object object)
643 {
644 if (STRINGP (object))
645 return 0;
646 return BUF_BEG (XBUFFER (object));
647 }
648
649 Bufpos
650 buffer_or_string_absolute_end_char (Lisp_Object object)
651 {
652 if (STRINGP (object))
653 return string_char_length (XSTRING (object));
654 return BUF_Z (XBUFFER (object));
655 }
656
657 Bytind
658 buffer_or_string_absolute_begin_byte (Lisp_Object object)
659 {
660 if (STRINGP (object))
661 return 0;
662 return BI_BUF_BEG (XBUFFER (object));
663 }
664
665 Bytind
666 buffer_or_string_absolute_end_byte (Lisp_Object object)
667 {
668 if (STRINGP (object))
669 return string_length (XSTRING (object));
670 return BI_BUF_Z (XBUFFER (object));
671 }
672
673
674 /************************************************************************/
675 /* point and marker adjustment */
676 /************************************************************************/
677
678 /* just_set_point() is the only place `PT' is an lvalue in all of emacs.
679 This function is called from set_buffer_point(), which is the function
680 that the SET_PT and BUF_SET_PT macros expand into, and from the
681 routines below that insert and delete text. (This is in cases where
682 the point marker logically doesn't move but PT (being a byte index)
683 needs to get adjusted.) */
684
685 /* Set point to a specified value. This is used only when the value
686 of point changes due to an insert or delete; it does not represent
687 a conceptual change in point as a marker. In particular, point is
688 not crossing any interval boundaries, so there's no need to use the
689 usual SET_PT macro. In fact it would be incorrect to do so, because
690 either the old or the new value of point is out of synch with the
691 current set of intervals. */
692
693 /* This gets called more than enough to make the function call
694 overhead a significant factor so we've turned it into a macro. */
695 #define JUST_SET_POINT(buf, bufpos, ind) \
696 do \
697 { \
698 buf->bufpt = (bufpos); \
699 buf->pt = (ind); \
700 } while (0)
701
702 /* Set a buffer's point. */
703
704 void
705 set_buffer_point (struct buffer *buf, Bufpos bufpos, Bytind bytpos)
706 {
707 assert (bytpos >= BI_BUF_BEGV (buf) && bytpos <= BI_BUF_ZV (buf));
708 if (bytpos == BI_BUF_PT (buf))
709 return;
710 JUST_SET_POINT (buf, bufpos, bytpos);
711 MARK_POINT_CHANGED;
712 assert (MARKERP (buf->point_marker));
713 XMARKER (buf->point_marker)->memind =
714 bytind_to_memind (buf, bytpos);
715
716 /* FSF makes sure that PT is not being set within invisible text.
717 However, this is the wrong place for that check. The check
718 should happen only at the next redisplay. */
719
720 /* Some old coder said:
721
722 "If there were to be hooks which were run when point entered/left an
723 extent, this would be the place to put them.
724
725 However, it's probably the case that such hooks should be implemented
726 using a post-command-hook instead, to avoid running the hooks as a
727 result of intermediate motion inside of save-excursions, for example."
728
729 I definitely agree with this. PT gets moved all over the place
730 and it would be a Bad Thing for any hooks to get called, both for
731 the reason above and because many callers are not prepared for
732 a GC within this function. --ben
733 */
734 }
735
736 /* Do the correct marker-like adjustment on MPOS (see below). FROM, TO,
737 and AMOUNT are as in adjust_markers(). If MPOS doesn't need to be
738 adjusted, nothing will happen. */
739 Memind
740 do_marker_adjustment (Memind mpos, Memind from,
741 Memind to, Bytecount amount)
742 {
743 if (amount > 0)
744 {
745 if (mpos > to && mpos < to + amount)
746 mpos = to + amount;
747 }
748 else
749 {
750 if (mpos > from + amount && mpos <= from)
751 mpos = from + amount;
752 }
753 if (mpos > from && mpos <= to)
754 mpos += amount;
755 return mpos;
756 }
757
758 /* Do the following:
759
760 (1) Add `amount' to the position of every marker in the current buffer
761 whose current position is between `from' (exclusive) and `to' (inclusive).
762
763 (2) Also, any markers past the outside of that interval, in the direction
764 of adjustment, are first moved back to the near end of the interval
765 and then adjusted by `amount'.
766
767 This function is called in two different cases: when a region of
768 characters adjacent to the gap is moved, causing the gap to shift
769 to the other side of the region (in this case, `from' and `to'
770 point to the old position of the region and there should be no
771 markers affected by (2) because they would be inside the gap),
772 or when a region of characters adjacent to the gap is wiped out,
773 causing the gap to increase to include the region (in this case,
774 `from' and `to' are the same, both pointing to the boundary
775 between the gap and the deleted region, and there are no markers
776 affected by (1)).
777
778 The reason for the use of exclusive and inclusive is that markers at
779 the gap always sit at the beginning, not at the end.
780 */
781
782 static void
783 adjust_markers (struct buffer *buf, Memind from, Memind to,
784 Bytecount amount)
785 {
786 struct Lisp_Marker *m;
787
788 for (m = BUF_MARKERS (buf); m; m = marker_next (m))
789 m->memind = do_marker_adjustment (m->memind, from, to, amount);
790 }
791
792 /* Adjust markers whose insertion-type is t
793 for an insertion of AMOUNT characters at POS. */
794
795 static void
796 adjust_markers_for_insert (struct buffer *buf, Memind ind, Bytecount amount)
797 {
798 struct Lisp_Marker *m;
799
800 for (m = BUF_MARKERS (buf); m; m = marker_next (m))
801 {
802 if (m->insertion_type && m->memind == ind)
803 m->memind += amount;
804 }
805 }
806
807
808 /************************************************************************/
809 /* Routines for dealing with the gap */
810 /************************************************************************/
811
812 /* XEmacs requires an ANSI C compiler, and it damn well better have a
813 working memmove() */
814 #define GAP_USE_BCOPY
815 #ifdef BCOPY_UPWARD_SAFE
816 # undef BCOPY_UPWARD_SAFE
817 #endif
818 #ifdef BCOPY_DOWNWARD_SAFE
819 # undef BCOPY_DOWNWARD_SAFE
820 #endif
821 #define BCOPY_UPWARD_SAFE 1
822 #define BCOPY_DOWNWARD_SAFE 1
823
824 /* maximum amount of memory moved in a single chunk. Increasing this
825 value improves gap-motion efficiency but decreases QUIT responsiveness
826 time. Was 32000 but today's processors are faster and files are
827 bigger. --ben */
828 #define GAP_MOVE_CHUNK 300000
829
830 /* Move the gap to POS, which is less than the current GPT. */
831
832 static void
833 gap_left (struct buffer *buf, Bytind pos)
834 {
835 Bufbyte *to, *from;
836 Bytecount i;
837 Bytind new_s1;
838
839 from = BUF_GPT_ADDR (buf);
840 to = from + BUF_GAP_SIZE (buf);
841 new_s1 = BI_BUF_GPT (buf);
842
843 /* Now copy the characters. To move the gap down,
844 copy characters up. */
845
846 while (1)
847 {
848 /* I gets number of characters left to copy. */
849 i = new_s1 - pos;
850 if (i == 0)
851 break;
852 /* If a quit is requested, stop copying now.
853 Change POS to be where we have actually moved the gap to. */
854 if (QUITP)
855 {
856 pos = new_s1;
857 break;
858 }
859 /* Move at most GAP_MOVE_CHUNK chars before checking again for a quit. */
860 if (i > GAP_MOVE_CHUNK)
861 i = GAP_MOVE_CHUNK;
862 #ifdef GAP_USE_BCOPY
863 if (i >= 128
864 /* bcopy is safe if the two areas of memory do not overlap
865 or on systems where bcopy is always safe for moving upward. */
866 && (BCOPY_UPWARD_SAFE
867 || to - from >= 128))
868 {
869 /* If overlap is not safe, avoid it by not moving too many
870 characters at once. */
871 if (!BCOPY_UPWARD_SAFE && i > to - from)
872 i = to - from;
873 new_s1 -= i;
874 from -= i, to -= i;
875 memmove (to, from, i);
876 }
877 else
878 #endif
879 {
880 new_s1 -= i;
881 while (--i >= 0)
882 *--to = *--from;
883 }
884 }
885
886 /* Adjust markers, and buffer data structure, to put the gap at POS.
887 POS is where the loop above stopped, which may be what was specified
888 or may be where a quit was detected. */
889 adjust_markers (buf, pos, BI_BUF_GPT (buf), BUF_GAP_SIZE (buf));
890 adjust_extents (make_buffer (buf), pos, BI_BUF_GPT (buf),
891 BUF_GAP_SIZE (buf));
892 SET_BI_BUF_GPT (buf, pos);
893 SET_GAP_SENTINEL (buf);
894 #ifdef ERROR_CHECK_EXTENTS
895 sledgehammer_extent_check (make_buffer (buf));
896 #endif
897 QUIT;
898 }
899
900 static void
901 gap_right (struct buffer *buf, Bytind pos)
902 {
903 Bufbyte *to, *from;
904 Bytecount i;
905 Bytind new_s1;
906
907 to = BUF_GPT_ADDR (buf);
908 from = to + BUF_GAP_SIZE (buf);
909 new_s1 = BI_BUF_GPT (buf);
910
911 /* Now copy the characters. To move the gap up,
912 copy characters down. */
913
914 while (1)
915 {
916 /* I gets number of characters left to copy. */
917 i = pos - new_s1;
918 if (i == 0)
919 break;
920 /* If a quit is requested, stop copying now.
921 Change POS to be where we have actually moved the gap to. */
922 if (QUITP)
923 {
924 pos = new_s1;
925 break;
926 }
927 /* Move at most GAP_MOVE_CHUNK chars before checking again for a quit. */
928 if (i > GAP_MOVE_CHUNK)
929 i = GAP_MOVE_CHUNK;
930 #ifdef GAP_USE_BCOPY
931 if (i >= 128
932 /* bcopy is safe if the two areas of memory do not overlap
933 or on systems where bcopy is always safe for moving downward. */
934 && (BCOPY_DOWNWARD_SAFE
935 || from - to >= 128))
936 {
937 /* If overlap is not safe, avoid it by not moving too many
938 characters at once. */
939 if (!BCOPY_DOWNWARD_SAFE && i > from - to)
940 i = from - to;
941 new_s1 += i;
942 memmove (to, from, i);
943 from += i, to += i;
944 }
945 else
946 #endif
947 {
948 new_s1 += i;
949 while (--i >= 0)
950 *to++ = *from++;
951 }
952 }
953
954 {
955 int gsize = BUF_GAP_SIZE (buf);
956 adjust_markers (buf, BI_BUF_GPT (buf) + gsize, pos + gsize, - gsize);
957 adjust_extents (make_buffer (buf), BI_BUF_GPT (buf) + gsize, pos + gsize,
958 - gsize);
959 SET_BI_BUF_GPT (buf, pos);
960 SET_GAP_SENTINEL (buf);
961 #ifdef ERROR_CHECK_EXTENTS
962 sledgehammer_extent_check (make_buffer (buf));
963 #endif
964 }
965 QUIT;
966 }
967
968 /* Move gap to position `pos'.
969 Note that this can quit! */
970
971 static void
972 move_gap (struct buffer *buf, Bytind pos)
973 {
974 if (! BUF_BEG_ADDR (buf))
975 abort ();
976 if (pos < BI_BUF_GPT (buf))
977 gap_left (buf, pos);
978 else if (pos > BI_BUF_GPT (buf))
979 gap_right (buf, pos);
980 }
981
982 /* Make the gap INCREMENT bytes longer. */
983
984 static void
985 make_gap (struct buffer *buf, Bytecount increment)
986 {
987 Bufbyte *result;
988 Lisp_Object tem;
989 Bytind real_gap_loc;
990 Bytecount old_gap_size;
991
992 /* If we have to get more space, get enough to last a while. We use
993 a geometric progession that saves on realloc space. */
994 increment += 2000 + ((BI_BUF_Z (buf) - BI_BUF_BEG (buf)) / 8);
995
996 /* Don't allow a buffer size that won't fit in an int
997 even if it will fit in a Lisp integer.
998 That won't work because so many places use `int'. */
999
1000 if (BUF_Z (buf) - BUF_BEG (buf) + BUF_GAP_SIZE (buf) + increment
1001 >= ((unsigned) 1 << (min (INTBITS, VALBITS) - 1)))
1002 error ("Buffer exceeds maximum size");
1003
1004 result = BUFFER_REALLOC (buf->text->beg,
1005 BI_BUF_Z (buf) - BI_BUF_BEG (buf) +
1006 BUF_GAP_SIZE (buf) + increment +
1007 BUF_END_SENTINEL_SIZE);
1008 if (result == 0)
1009 memory_full ();
1010 SET_BUF_BEG_ADDR (buf, result);
1011
1012 /* Prevent quitting in move_gap. */
1013 tem = Vinhibit_quit;
1014 Vinhibit_quit = Qt;
1015
1016 real_gap_loc = BI_BUF_GPT (buf);
1017 old_gap_size = BUF_GAP_SIZE (buf);
1018
1019 /* Call the newly allocated space a gap at the end of the whole space. */
1020 SET_BI_BUF_GPT (buf, BI_BUF_Z (buf) + BUF_GAP_SIZE (buf));
1021 SET_BUF_GAP_SIZE (buf, increment);
1022
1023 /* Move the new gap down to be consecutive with the end of the old one.
1024 This adjusts the markers properly too. */
1025 gap_left (buf, real_gap_loc + old_gap_size);
1026
1027 /* Now combine the two into one large gap. */
1028 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + old_gap_size);
1029 SET_BI_BUF_GPT (buf, real_gap_loc);
1030 SET_GAP_SENTINEL (buf);
1031
1032 /* We changed the total size of the buffer (including gap),
1033 so we need to fix up the end sentinel. */
1034 SET_END_SENTINEL (buf);
1035
1036 Vinhibit_quit = tem;
1037 }
1038
1039
1040 /************************************************************************/
1041 /* Before/after-change processing */
1042 /************************************************************************/
1043
1044 /* Those magic changes ... */
1045
1046 static void
1047 buffer_signal_changed_region (struct buffer *buf, Bufpos start,
1048 Bufpos end)
1049 {
1050 /* The changed region is recorded as the number of unchanged
1051 characters from the beginning and from the end of the
1052 buffer. This obviates much of the need of shifting the
1053 region around to compensate for insertions and deletions.
1054 */
1055 if (buf->changes->begin_unchanged < 0 ||
1056 buf->changes->begin_unchanged > start - BUF_BEG (buf))
1057 buf->changes->begin_unchanged = start - BUF_BEG (buf);
1058 if (buf->changes->end_unchanged < 0 ||
1059 buf->changes->end_unchanged > BUF_Z (buf) - end)
1060 buf->changes->end_unchanged = BUF_Z (buf) - end;
1061 }
1062
1063 void
1064 buffer_extent_signal_changed_region (struct buffer *buf, Bufpos start,
1065 Bufpos end)
1066 {
1067 if (buf->changes->begin_extent_unchanged < 0 ||
1068 buf->changes->begin_extent_unchanged > start - BUF_BEG (buf))
1069 buf->changes->begin_extent_unchanged = start - BUF_BEG (buf);
1070 if (buf->changes->end_extent_unchanged < 0 ||
1071 buf->changes->end_extent_unchanged > BUF_Z (buf) - end)
1072 buf->changes->end_extent_unchanged = BUF_Z (buf) - end;
1073 }
1074
1075 void
1076 buffer_reset_changes (struct buffer *buf)
1077 {
1078 buf->changes->begin_unchanged = -1;
1079 buf->changes->end_unchanged = -1;
1080 buf->changes->begin_extent_unchanged = -1;
1081 buf->changes->end_extent_unchanged = -1;
1082 buf->changes->newline_was_deleted = 0;
1083 }
1084
1085 static void
1086 signal_after_change (struct buffer *buf, Bufpos start, Bufpos orig_end,
1087 Bufpos new_end);
1088
1089 /* Call the after-change-functions according to the changes made so far
1090 and treat all further changes as single until the outermost
1091 multiple change exits. This is called when the outermost multiple
1092 change exits and when someone is trying to make a change that violates
1093 the constraints specified in begin_multiple_change(), typically
1094 when nested multiple-change sessions occur. (There are smarter ways of
1095 dealing with nested multiple changes, but these rarely occur so there's
1096 probably no point in it.) */
1097
1098 /* #### This needs to keep track of what actually changed and only
1099 call the after-change functions on that region. */
1100
1101 static void
1102 cancel_multiple_change (struct buffer *buf)
1103 {
1104 /* This function can GC */
1105 /* Call the after-change-functions except when they've already been
1106 called or when there were no changes made to the buffer at all. */
1107 if (buf->text->changes->mc_begin != 0 &&
1108 buf->text->changes->mc_begin_signaled)
1109 {
1110 Bufpos real_mc_begin = buf->text->changes->mc_begin;
1111 buf->text->changes->mc_begin = 0;
1112
1113 signal_after_change (buf, real_mc_begin, buf->text->changes->mc_orig_end,
1114 buf->text->changes->mc_new_end);
1115 }
1116 else
1117 {
1118 buf->text->changes->mc_begin = 0;
1119 }
1120 }
1121
1122 /* this is an unwind_protect, to ensure that the after-change-functions
1123 get called even in a non-local exit. */
1124
1125 static Lisp_Object
1126 multiple_change_finish_up (Lisp_Object buffer)
1127 {
1128 struct buffer *buf = XBUFFER (buffer);
1129
1130 /* #### I don't know whether or not it should even be possible to
1131 get here with a dead buffer (though given how it is called I can
1132 see how it might be). In any case, there isn't time before 19.14
1133 to find out. */
1134 if (!BUFFER_LIVE_P (buf))
1135 return Qnil;
1136
1137 /* This function can GC */
1138 buf->text->changes->in_multiple_change = 0; /* do this first so that
1139 errors in the after-change
1140 functions don't mess things
1141 up. */
1142 cancel_multiple_change (buf);
1143 return Qnil;
1144 }
1145
1146 /* Call this function when you're about to make a number of buffer changes
1147 that should be considered a single change. (e.g. `replace-match' calls
1148 this.) You need to specify the START and END of the region that is
1149 going to be changed so that the before-change-functions are called
1150 with the correct arguments. The after-change region is calculated
1151 automatically, however, and if changes somehow or other happen outside
1152 of the specified region, that will also be handled correctly.
1153
1154 begin_multiple_change() returns a number (actually a specpdl depth)
1155 that you must pass to end_multiple_change() when you are done. */
1156
1157 int
1158 begin_multiple_change (struct buffer *buf, Bufpos start, Bufpos end)
1159 {
1160 /* This function can GC */
1161 int count = -1;
1162 if (buf->text->changes->in_multiple_change)
1163 {
1164 if (buf->text->changes->mc_begin != 0 &&
1165 (start < buf->text->changes->mc_begin ||
1166 end > buf->text->changes->mc_new_end))
1167 cancel_multiple_change (buf);
1168 }
1169 else
1170 {
1171 Lisp_Object buffer;
1172
1173 buf->text->changes->mc_begin = start;
1174 buf->text->changes->mc_orig_end = buf->text->changes->mc_new_end = end;
1175 buf->text->changes->mc_begin_signaled = 0;
1176 count = specpdl_depth ();
1177 XSETBUFFER (buffer, buf);
1178 record_unwind_protect (multiple_change_finish_up, buffer);
1179 }
1180 buf->text->changes->in_multiple_change++;
1181 /* We don't call before-change-functions until signal_before_change()
1182 is called, in case there is a read-only or other error. */
1183 return count;
1184 }
1185
1186 void
1187 end_multiple_change (struct buffer *buf, int count)
1188 {
1189 assert (buf->text->changes->in_multiple_change > 0);
1190 buf->text->changes->in_multiple_change--;
1191 if (!buf->text->changes->in_multiple_change)
1192 unbind_to (count, Qnil);
1193 }
1194
1195 static int inside_change_hook;
1196
1197 static Lisp_Object
1198 change_function_restore (Lisp_Object buffer)
1199 {
1200 Fset_buffer (buffer);
1201 inside_change_hook = 0;
1202 return Qnil;
1203 }
1204
1205 static int in_first_change;
1206
1207 static Lisp_Object
1208 first_change_hook_restore (Lisp_Object buffer)
1209 {
1210 Fset_buffer (buffer);
1211 in_first_change = 0;
1212 return Qnil;
1213 }
1214
1215 /* Signal an initial modification to the buffer. */
1216
1217 static void
1218 signal_first_change (struct buffer *buf)
1219 {
1220 /* This function can GC */
1221 Lisp_Object buffer;
1222 XSETBUFFER (buffer, buf);
1223
1224 if (!in_first_change)
1225 {
1226 if (!preparing_for_armageddon &&
1227 !NILP (symbol_value_in_buffer (Qfirst_change_hook, buffer)))
1228 {
1229 int speccount = specpdl_depth ();
1230 record_unwind_protect (first_change_hook_restore, buffer);
1231 set_buffer_internal (buf);
1232 in_first_change = 1;
1233 run_hook (Qfirst_change_hook);
1234 unbind_to (speccount, Qnil);
1235 }
1236 }
1237 }
1238
1239 /* Signal a change to the buffer immediately before it happens.
1240 START and END are the bounds of the text to be changed. */
1241
1242 static void
1243 signal_before_change (struct buffer *buf, Bufpos start, Bufpos end)
1244 {
1245 /* This function can GC */
1246 Lisp_Object buffer;
1247 XSETBUFFER (buffer, buf);
1248
1249 if (!inside_change_hook)
1250 {
1251 /* Are we in a multiple-change session? */
1252 if (buf->text->changes->in_multiple_change &&
1253 buf->text->changes->mc_begin != 0)
1254 {
1255 /* If we're violating the constraints of the session,
1256 call the after-change-functions as necessary for the
1257 changes already made and treat further changes as
1258 single. */
1259 if (start < buf->text->changes->mc_begin ||
1260 end > buf->text->changes->mc_new_end)
1261 cancel_multiple_change (buf);
1262 /* Do nothing if this is not the first change in the session. */
1263 else if (buf->text->changes->mc_begin_signaled)
1264 return;
1265 else
1266 {
1267 /* First time through; call the before-change-functions
1268 specifying the entire region to be changed. (Note that
1269 we didn't call before-change-functions in
1270 begin_multiple_change() because the buffer might be
1271 read-only, etc.) */
1272 start = buf->text->changes->mc_begin;
1273 end = buf->text->changes->mc_new_end;
1274 }
1275 }
1276
1277 /* If buffer is unmodified, run a special hook for that case. */
1278 if (BUF_SAVE_MODIFF (buf) >= BUF_MODIFF (buf))
1279 signal_first_change (buf);
1280
1281 /* Now in any case run the before-change-functions if any. */
1282
1283 if (!preparing_for_armageddon &&
1284 (!NILP (symbol_value_in_buffer (Qbefore_change_functions, buffer)) ||
1285 /* Obsolete, for compatibility */
1286 !NILP (symbol_value_in_buffer (Qbefore_change_function, buffer))))
1287 {
1288 int speccount = specpdl_depth ();
1289 record_unwind_protect (change_function_restore, Fcurrent_buffer ());
1290 set_buffer_internal (buf);
1291 inside_change_hook = 1;
1292 va_run_hook_with_args (Qbefore_change_functions, 2,
1293 make_int (start), make_int (end));
1294 /* Obsolete, for compatibility */
1295 va_run_hook_with_args (Qbefore_change_function, 2,
1296 make_int (start), make_int (end));
1297 unbind_to (speccount, Qnil);
1298 }
1299
1300 /* Only now do we indicate that the before-change-functions have
1301 been called, in case some function throws out. */
1302 buf->text->changes->mc_begin_signaled = 1;
1303 }
1304
1305 /* #### At this point we should map over extents calling
1306 modification-hooks, insert-before-hooks and insert-after-hooks
1307 of relevant extents */
1308 }
1309
1310 /* Signal a change immediately after it happens.
1311 START is the bufpos of the start of the changed text.
1312 ORIG_END is the bufpos of the end of the before-changed text.
1313 NEW_END is the bufpos of the end of the after-changed text.
1314 */
1315
1316 static void
1317 signal_after_change (struct buffer *buf, Bufpos start, Bufpos orig_end,
1318 Bufpos new_end)
1319 {
1320 /* This function can GC */
1321 Lisp_Object buffer;
1322 XSETBUFFER (buffer, buf);
1323
1324 /* always do this. */
1325 buffer_signal_changed_region (buf, start, new_end);
1326 font_lock_maybe_update_syntactic_caches (buf, start, orig_end, new_end);
1327
1328 if (!inside_change_hook)
1329 {
1330 if (buf->text->changes->in_multiple_change &&
1331 buf->text->changes->mc_begin != 0)
1332 {
1333 assert (start >= buf->text->changes->mc_begin &&
1334 start <= buf->text->changes->mc_new_end);
1335 assert (orig_end >= buf->text->changes->mc_begin &&
1336 orig_end <= buf->text->changes->mc_new_end);
1337 buf->text->changes->mc_new_end += new_end - orig_end;
1338 return; /* after-change-functions signalled when all changes done */
1339 }
1340
1341 if (!preparing_for_armageddon &&
1342 (!NILP (symbol_value_in_buffer (Qafter_change_functions, buffer)) ||
1343 /* Obsolete, for compatibility */
1344 !NILP (symbol_value_in_buffer (Qafter_change_function, buffer))))
1345 {
1346 int speccount = specpdl_depth ();
1347 record_unwind_protect (change_function_restore, Fcurrent_buffer ());
1348 set_buffer_internal (buf);
1349 inside_change_hook = 1;
1350 /* The actual after-change functions take slightly
1351 different arguments than what we were passed. */
1352 va_run_hook_with_args (Qafter_change_functions, 3,
1353 make_int (start), make_int (new_end),
1354 make_int (orig_end - start));
1355 /* Obsolete, for compatibility */
1356 va_run_hook_with_args (Qafter_change_function, 3,
1357 make_int (start), make_int (new_end),
1358 make_int (orig_end - start));
1359 unbind_to (speccount, Qnil);
1360 }
1361 }
1362
1363 /* #### At this point we should map over extents calling
1364 some sort of modification hooks of relevant extents */
1365 }
1366
1367 /* Call this if you're about to change the region of BUFFER from START
1368 to END. This checks the read-only properties of the region, calls
1369 the necessary modification hooks, and warns the next redisplay that
1370 it should pay attention to that area. */
1371
1372 static void
1373 prepare_to_modify_buffer (struct buffer *buf, Bufpos start, Bufpos end,
1374 int lockit)
1375 {
1376 /* This function can GC */
1377 barf_if_buffer_read_only (buf, start, end);
1378
1379 /* if this is the first modification, see about locking the buffer's
1380 file */
1381 if (!NILP (buf->filename) && lockit &&
1382 BUF_SAVE_MODIFF (buf) >= BUF_MODIFF (buf))
1383 {
1384 #ifdef CLASH_DETECTION
1385 if (!NILP (buf->file_truename))
1386 /* Make binding buffer-file-name to nil effective. */
1387 lock_file (buf->file_truename);
1388 #else
1389 Lisp_Object buffer;
1390 XSETBUFFER (buffer, buf);
1391 /* At least warn if this file has changed on disk since it was visited.*/
1392 if (NILP (Fverify_visited_file_modtime (buffer))
1393 && !NILP (Ffile_exists_p (buf->filename)))
1394 call1_in_buffer (buf, intern ("ask-user-about-supersession-threat"),
1395 buf->filename);
1396 #endif /* not CLASH_DETECTION */
1397 }
1398
1399 signal_before_change (buf, start, end);
1400
1401 #ifdef REGION_CACHE_NEEDS_WORK
1402 if (buf->newline_cache)
1403 invalidate_region_cache (buf,
1404 buf->newline_cache,
1405 start - BUF_BEG (buf), BUF_Z (buf) - end);
1406 if (buf->width_run_cache)
1407 invalidate_region_cache (buf,
1408 buf->width_run_cache,
1409 start - BUF_BEG (buf), BUF_Z (buf) - end);
1410 #endif
1411
1412 #if 0 /* FSFmacs */
1413 Vdeactivate_mark = Qt;
1414 #endif
1415
1416 buf->point_before_scroll = Qnil;
1417
1418 /* BUF_MODIFF (buf)++; -- should be done by callers (insert, delete range)
1419 else record_first_change isn't called */
1420 }
1421
1422
1423 /************************************************************************/
1424 /* Insertion of strings */
1425 /************************************************************************/
1426
1427 void
1428 fixup_internal_substring (CONST Bufbyte *nonreloc, Lisp_Object reloc,
1429 Bytecount offset, Bytecount *len)
1430 {
1431 assert ((nonreloc && NILP (reloc)) || (!nonreloc && STRINGP (reloc)));
1432
1433 if (*len < 0)
1434 {
1435 if (nonreloc)
1436 *len = strlen ((CONST char *) nonreloc) - offset;
1437 else
1438 *len = string_length (XSTRING (reloc)) - offset;
1439 }
1440 assert (*len >= 0);
1441 if (STRINGP (reloc))
1442 {
1443 assert (offset >= 0 && offset <= string_length (XSTRING (reloc)));
1444 assert (offset + *len <= string_length (XSTRING (reloc)));
1445 }
1446 }
1447
1448 /* Insert a string into BUF at Bufpos POS. The string data comes
1449 from one of two sources: constant, non-relocatable data (specified
1450 in NONRELOC), or a Lisp string object (specified in RELOC), which
1451 is relocatable and may have extent data that needs to be copied
1452 into the buffer. OFFSET and LENGTH specify the substring of the
1453 data that is actually to be inserted. As a special case, if POS
1454 is -1, insert the string at point and move point to the end of the
1455 string.
1456
1457 Normally, markers at the insertion point end up before the
1458 inserted string. If INSDEL_BEFORE_MARKERS is set in flags, however,
1459 they end up after the string.
1460
1461 INSDEL_NO_LOCKING is kludgy and is used when insert-file-contents is
1462 visiting a new file; it inhibits the locking checks normally done
1463 before modifying a buffer. Similar checks were already done
1464 in the higher-level Lisp functions calling insert-file-contents. */
1465
1466 Charcount
1467 buffer_insert_string_1 (struct buffer *buf, Bufpos pos,
1468 CONST Bufbyte *nonreloc, Lisp_Object reloc,
1469 Bytecount offset, Bytecount length,
1470 int flags)
1471 {
1472 /* This function can GC */
1473 struct gcpro gcpro1;
1474 Bytind ind;
1475 Charcount cclen;
1476 int move_point = 0;
1477
1478 /* Defensive steps just in case a buffer gets deleted and a calling
1479 function doesn't notice it. */
1480 if (!BUFFER_LIVE_P (buf))
1481 return 0;
1482
1483 fixup_internal_substring (nonreloc, reloc, offset, &length);
1484
1485 if (pos == -1)
1486 {
1487 pos = BUF_PT (buf);
1488 move_point = 1;
1489 }
1490
1491 #ifdef I18N3
1492 /* #### See the comment in print_internal(). If this buffer is marked
1493 as translatable, then Fgettext() should be called on obj if it
1494 is a string. */
1495 #endif
1496
1497 /* Make sure that point-max won't exceed the size of an emacs int. */
1498 {
1499 Lisp_Object temp;
1500
1501 XSETINT (temp, (int) (length + BUF_Z (buf)));
1502 if ((int) (length + BUF_Z (buf)) != XINT (temp))
1503 error ("maximum buffer size exceeded");
1504 }
1505
1506 /* theoretically not necessary -- caller should GCPRO */
1507 GCPRO1 (reloc);
1508
1509 prepare_to_modify_buffer (buf, pos, pos, !(flags & INSDEL_NO_LOCKING));
1510
1511 /* Defensive steps in case the before-change-functions fuck around */
1512 if (!BUFFER_LIVE_P (buf))
1513 {
1514 UNGCPRO;
1515 /* Bad bad pre-change function. */
1516 return 0;
1517 }
1518
1519 /* Make args be valid again. prepare_to_modify_buffer() might have
1520 modified the buffer. */
1521 if (pos < BUF_BEGV (buf))
1522 pos = BUF_BEGV (buf);
1523 if (pos > BUF_ZV (buf))
1524 pos = BUF_ZV (buf);
1525
1526 /* string may have been relocated up to this point */
1527 if (STRINGP (reloc))
1528 nonreloc = string_data (XSTRING (reloc));
1529
1530 ind = bufpos_to_bytind (buf, pos);
1531 cclen = bytecount_to_charcount (nonreloc + offset, length);
1532
1533 if (ind != BI_BUF_GPT (buf))
1534 /* #### if debug-on-quit is invoked and the user changes the
1535 buffer, bad things can happen. This is a rampant problem
1536 in Emacs. */
1537 move_gap (buf, ind); /* may QUIT */
1538 if (! GAP_CAN_HOLD_SIZE_P (buf, length))
1539 make_gap (buf, length - BUF_GAP_SIZE (buf));
1540
1541 record_insert (buf, pos, cclen);
1542 BUF_MODIFF (buf)++;
1543 MARK_BUFFERS_CHANGED;
1544
1545 /* string may have been relocated up to this point */
1546 if (STRINGP (reloc))
1547 nonreloc = string_data (XSTRING (reloc));
1548
1549 memcpy (BUF_GPT_ADDR (buf), nonreloc + offset, length);
1550
1551 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) - length);
1552 SET_BI_BUF_GPT (buf, BI_BUF_GPT (buf) + length);
1553 SET_BOTH_BUF_ZV (buf, BUF_ZV (buf) + cclen, BI_BUF_ZV (buf) + length);
1554 SET_BOTH_BUF_Z (buf, BUF_Z (buf) + cclen, BI_BUF_Z (buf) + length);
1555 SET_GAP_SENTINEL (buf);
1556
1557 process_extents_for_insertion (make_buffer (buf), ind, length);
1558 /* We know the gap is at IND so the cast is OK. */
1559 adjust_markers_for_insert (buf, (Memind) ind, length);
1560
1561 /* Point logically doesn't move, but may need to be adjusted because
1562 it's a byte index. point-marker doesn't change because it's a
1563 memory index. */
1564 if (BI_BUF_PT (buf) > ind)
1565 JUST_SET_POINT (buf, BUF_PT (buf) + cclen, BI_BUF_PT (buf) + length);
1566
1567 /* Well, point might move. */
1568 if (move_point)
1569 BI_BUF_SET_PT (buf, ind + length);
1570
1571 if (STRINGP (reloc))
1572 splice_in_string_extents (reloc, buf, ind, length, offset);
1573
1574 if (flags & INSDEL_BEFORE_MARKERS)
1575 {
1576 /* ind - 1 is correct because the FROM argument is exclusive.
1577 I formerly used DEC_BYTIND() but that caused problems at the
1578 beginning of the buffer. */
1579 adjust_markers (buf, ind - 1, ind, length);
1580 }
1581
1582 signal_after_change (buf, pos, pos, pos + cclen);
1583
1584 UNGCPRO;
1585
1586 return cclen;
1587 }
1588
1589
1590 /* The following functions are interfaces onto the above function,
1591 for inserting particular sorts of data. In all the functions,
1592 BUF and POS specify the buffer and location where the insertion is
1593 to take place. (If POS is -1, text is inserted at point and point
1594 moves forward past the text.) FLAGS is as above. */
1595
1596 Charcount
1597 buffer_insert_raw_string_1 (struct buffer *buf, Bufpos pos,
1598 CONST Bufbyte *nonreloc, Bytecount length,
1599 int flags)
1600 {
1601 /* This function can GC */
1602 return buffer_insert_string_1 (buf, pos, nonreloc, Qnil, 0, length,
1603 flags);
1604 }
1605
1606 Charcount
1607 buffer_insert_lisp_string_1 (struct buffer *buf, Bufpos pos, Lisp_Object str,
1608 int flags)
1609 {
1610 /* This function can GC */
1611 assert (STRINGP (str));
1612 return buffer_insert_string_1 (buf, pos, 0, str, 0,
1613 string_length (XSTRING (str)),
1614 flags);
1615 }
1616
1617 /* Insert the null-terminated string S (in external format). */
1618
1619 Charcount
1620 buffer_insert_c_string_1 (struct buffer *buf, Bufpos pos, CONST char *s,
1621 int flags)
1622 {
1623 /* This function can GC */
1624
1625 CONST char *translated = GETTEXT (s);
1626 return buffer_insert_string_1 (buf, pos, (CONST Bufbyte *) translated, Qnil,
1627 0, strlen (translated), flags);
1628 }
1629
1630 Charcount
1631 buffer_insert_emacs_char_1 (struct buffer *buf, Bufpos pos, Emchar ch,
1632 int flags)
1633 {
1634 /* This function can GC */
1635 Bufbyte str[MAX_EMCHAR_LEN];
1636 Bytecount len;
1637
1638 len = set_charptr_emchar (str, ch);
1639 return buffer_insert_string_1 (buf, pos, str, Qnil, 0, len, flags);
1640 }
1641
1642 Charcount
1643 buffer_insert_c_char_1 (struct buffer *buf, Bufpos pos, char c,
1644 int flags)
1645 {
1646 /* This function can GC */
1647 return buffer_insert_emacs_char_1 (buf, pos, (Emchar) (unsigned char) c,
1648 flags);
1649 }
1650
1651 Charcount
1652 buffer_insert_from_buffer_1 (struct buffer *buf, Bufpos pos,
1653 struct buffer *buf2, Bufpos pos2,
1654 Charcount length, int flags)
1655 {
1656 /* This function can GC */
1657 Lisp_Object str = make_string_from_buffer (buf2, pos2, length);
1658 return buffer_insert_string_1 (buf, pos, 0, str, 0,
1659 string_length (XSTRING (str)), flags);
1660 }
1661
1662
1663 /************************************************************************/
1664 /* Deletion of ranges */
1665 /************************************************************************/
1666
1667 /* Delete characters in buffer from FROM up to (but not including) TO. */
1668
1669 void
1670 buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags)
1671 {
1672 /* This function can GC */
1673 Charcount numdel;
1674 Bytind bi_from, bi_to;
1675 Bytecount bc_numdel;
1676 int shortage;
1677 Lisp_Object bufobj = Qnil;
1678
1679 /* Defensive steps just in case a buffer gets deleted and a calling
1680 function doesn't notice it. */
1681 if (!BUFFER_LIVE_P (buf))
1682 return;
1683
1684 /* Make args be valid */
1685 if (from < BUF_BEGV (buf))
1686 from = BUF_BEGV (buf);
1687 if (to > BUF_ZV (buf))
1688 to = BUF_ZV (buf);
1689 if ((numdel = to - from) <= 0)
1690 return;
1691
1692 prepare_to_modify_buffer (buf, from, to, !(flags & INSDEL_NO_LOCKING));
1693
1694 /* Defensive steps in case the before-change-functions fuck around */
1695 if (!BUFFER_LIVE_P (buf))
1696 /* Bad bad pre-change function. */
1697 return;
1698
1699 /* Make args be valid again. prepare_to_modify_buffer() might have
1700 modified the buffer. */
1701 if (from < BUF_BEGV (buf))
1702 from = BUF_BEGV (buf);
1703 if (to > BUF_ZV (buf))
1704 to = BUF_ZV (buf);
1705 if ((numdel = to - from) <= 0)
1706 return;
1707
1708 XSETBUFFER (bufobj, buf);
1709
1710 /* Redisplay needs to know if a newline was in the deleted region.
1711 If we've already marked the changed region as having a deleted
1712 newline there is no use in performing the check. */
1713 if (!buf->changes->newline_was_deleted)
1714 {
1715 scan_buffer (buf, '\n', from, to, 1, &shortage, 1);
1716 if (!shortage)
1717 buf->changes->newline_was_deleted = 1;
1718 }
1719
1720 bi_from = bufpos_to_bytind (buf, from);
1721 bi_to = bufpos_to_bytind (buf, to);
1722 bc_numdel = bi_to - bi_from;
1723
1724 /* Make sure the gap is somewhere in or next to what we are deleting. */
1725 if (bi_to < BI_BUF_GPT (buf))
1726 gap_left (buf, bi_to);
1727 if (bi_from > BI_BUF_GPT (buf))
1728 gap_right (buf, bi_from);
1729
1730 record_delete (buf, from, numdel);
1731 BUF_MODIFF (buf)++;
1732 MARK_BUFFERS_CHANGED;
1733
1734 /* Relocate point as if it were a marker. */
1735 if (bi_from < BI_BUF_PT (buf))
1736 {
1737 if (BI_BUF_PT (buf) < bi_to)
1738 JUST_SET_POINT (buf, from, bi_from);
1739 else
1740 JUST_SET_POINT (buf, BUF_PT (buf) - numdel,
1741 BI_BUF_PT (buf) - bc_numdel);
1742 }
1743
1744 /* Detach any extents that are completely within the range [FROM, TO],
1745 if the extents are detachable.
1746
1747 This must come AFTER record_delete(), so that the appropriate extents
1748 will be present to be recorded, and BEFORE the gap size is increased,
1749 as otherwise we will be confused about where the extents end. */
1750 process_extents_for_deletion (bufobj, bi_from, bi_to, 0);
1751
1752 /* Relocate all markers pointing into the new, larger gap
1753 to point at the end of the text before the gap. */
1754 adjust_markers (buf,
1755 (bi_to + BUF_GAP_SIZE (buf)),
1756 (bi_to + BUF_GAP_SIZE (buf)),
1757 (- bc_numdel - BUF_GAP_SIZE (buf)));
1758
1759 /* Relocate any extent endpoints just like markers. */
1760 adjust_extents_for_deletion (bufobj, bi_from, bi_to, BUF_GAP_SIZE (buf),
1761 bc_numdel);
1762
1763 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + bc_numdel);
1764 SET_BOTH_BUF_ZV (buf, BUF_ZV (buf) - numdel, BI_BUF_ZV (buf) - bc_numdel);
1765 SET_BOTH_BUF_Z (buf, BUF_Z (buf) - numdel, BI_BUF_Z (buf) - bc_numdel);
1766 SET_BI_BUF_GPT (buf, bi_from);
1767 SET_GAP_SENTINEL (buf);
1768
1769 #ifdef ERROR_CHECK_EXTENTS
1770 sledgehammer_extent_check (bufobj);
1771 #endif
1772
1773 signal_after_change (buf, from, to, from);
1774 }
1775
1776
1777 /************************************************************************/
1778 /* Replacement of characters */
1779 /************************************************************************/
1780
1781 /* Replace the character at POS in buffer B with CH. */
1782
1783 void
1784 buffer_replace_char (struct buffer *b, Bufpos pos, Emchar ch,
1785 int not_real_change, int force_lock_check)
1786 {
1787 /* This function can GC */
1788 Bufbyte curstr[MAX_EMCHAR_LEN];
1789 Bufbyte newstr[MAX_EMCHAR_LEN];
1790 Bytecount curlen, newlen;
1791
1792 /* Defensive steps just in case a buffer gets deleted and a calling
1793 function doesn't notice it. */
1794 if (!BUFFER_LIVE_P (b))
1795 return;
1796
1797 curlen = BUF_CHARPTR_COPY_CHAR (b, pos, curstr);
1798 newlen = set_charptr_emchar (newstr, ch);
1799
1800 if (curlen == newlen)
1801 {
1802 /* then we can just replace the text. */
1803 prepare_to_modify_buffer (b, pos, pos + 1,
1804 !not_real_change || force_lock_check);
1805 /* Defensive steps in case the before-change-functions fuck around */
1806 if (!BUFFER_LIVE_P (b))
1807 /* Bad bad pre-change function. */
1808 return;
1809
1810 /* Make args be valid again. prepare_to_modify_buffer() might have
1811 modified the buffer. */
1812 if (pos < BUF_BEGV (b))
1813 pos = BUF_BEGV (b);
1814 if (pos >= BUF_ZV (b))
1815 pos = BUF_ZV (b) - 1;
1816 if (pos < BUF_BEGV (b))
1817 /* no more characters in buffer! */
1818 return;
1819
1820 if (BUF_FETCH_CHAR (b, pos) == '\n')
1821 b->changes->newline_was_deleted = 1;
1822 MARK_BUFFERS_CHANGED;
1823 if (!not_real_change)
1824 {
1825 record_change (b, pos, 1);
1826 BUF_MODIFF (b)++;
1827 }
1828 memcpy (BUF_BYTE_ADDRESS (b, pos), newstr, newlen);
1829 signal_after_change (b, pos, pos + 1, pos + 1);
1830 }
1831 else
1832 {
1833 /* must implement as deletion followed by insertion. */
1834 buffer_delete_range (b, pos, pos + 1, 0);
1835 /* Defensive steps in case the before-change-functions fuck around */
1836 if (!BUFFER_LIVE_P (b))
1837 /* Bad bad pre-change function. */
1838 return;
1839
1840 /* Make args be valid again. prepare_to_modify_buffer() might have
1841 modified the buffer. */
1842 if (pos < BUF_BEGV (b))
1843 pos = BUF_BEGV (b);
1844 if (pos >= BUF_ZV (b))
1845 pos = BUF_ZV (b) - 1;
1846 if (pos < BUF_BEGV (b))
1847 /* no more characters in buffer! */
1848 return;
1849 buffer_insert_string_1 (b, pos, newstr, Qnil, 0, newlen, 0);
1850 }
1851 }
1852
1853
1854 /************************************************************************/
1855 /* Other functions */
1856 /************************************************************************/
1857
1858 /* Make a string from a buffer. This needs to take into account the gap,
1859 and add any necessary extents from the buffer. */
1860
1861 Lisp_Object
1862 make_string_from_buffer (struct buffer *buf, Bufpos pos, Charcount length)
1863 {
1864 /* This function can GC */
1865 Lisp_Object val;
1866 struct gcpro gcpro1;
1867 Bytind bi_ind;
1868 Bytecount bi_len;
1869
1870 bi_ind = bufpos_to_bytind (buf, pos);
1871 bi_len = bufpos_to_bytind (buf, pos + length) - bi_ind;
1872
1873 val = make_uninit_string (bi_len);
1874 GCPRO1 (val);
1875
1876 add_string_extents (val, buf, bi_ind, bi_len);
1877
1878 {
1879 Bytecount len1 = BI_BUF_GPT (buf) - bi_ind;
1880 Bufbyte *start1 = BI_BUF_BYTE_ADDRESS (buf, bi_ind);
1881 Bufbyte *dest = string_data (XSTRING (val));
1882
1883 if (len1 < 0)
1884 {
1885 /* Completely after gap */
1886 memcpy (dest, start1, bi_len);
1887 }
1888 else if (bi_len <= len1)
1889 {
1890 /* Completely before gap */
1891 memcpy (dest, start1, bi_len);
1892 }
1893 else
1894 {
1895 /* Spans gap */
1896 Bytind pos2 = bi_ind + len1;
1897 Bufbyte *start2 = BI_BUF_BYTE_ADDRESS (buf, pos2);
1898
1899 memcpy (dest, start1, len1);
1900 memcpy (dest + len1, start2, bi_len - len1);
1901 }
1902 }
1903
1904 UNGCPRO;
1905 return val;
1906 }
1907
1908 void
1909 barf_if_buffer_read_only (struct buffer *buf, Bufpos from, Bufpos to)
1910 {
1911 Lisp_Object buffer = Qnil;
1912 Lisp_Object iro;
1913
1914 XSETBUFFER (buffer, buf);
1915 back:
1916 iro = (buf == current_buffer ? Vinhibit_read_only :
1917 symbol_value_in_buffer (Qinhibit_read_only, buffer));
1918 if (!NILP (iro) && !CONSP (iro))
1919 return;
1920 if (NILP (iro) && !NILP (buf->read_only))
1921 {
1922 Fsignal (Qbuffer_read_only, (list1 (buffer)));
1923 goto back;
1924 }
1925 if (from > 0)
1926 {
1927 if (to < 0)
1928 to = from;
1929 verify_extent_modification (buffer,
1930 bufpos_to_bytind (buf, from),
1931 bufpos_to_bytind (buf, to),
1932 iro);
1933 }
1934 }
1935
1936 void
1937 find_charsets_in_bufbyte_string (unsigned char *charsets, CONST Bufbyte *str,
1938 Bytecount len)
1939 {
1940 /* Telescope this. */
1941 charsets[0] = 1;
1942 }
1943
1944 void
1945 find_charsets_in_emchar_string (unsigned char *charsets, CONST Emchar *str,
1946 Charcount len)
1947 {
1948 /* Telescope this. */
1949 charsets[0] = 1;
1950 }
1951
1952 int
1953 bufbyte_string_displayed_columns (CONST Bufbyte *str, Bytecount len)
1954 {
1955 int cols = 0;
1956 CONST Bufbyte *end = str + len;
1957
1958 while (str < end)
1959 {
1960 cols++;
1961 INC_CHARPTR (str);
1962 }
1963
1964 return cols;
1965 }
1966
1967 int
1968 emchar_string_displayed_columns (CONST Emchar *str, Charcount len)
1969 {
1970 int cols = 0;
1971 int i;
1972
1973 for (i = 0; i < len; i++)
1974 cols += XCHARSET_COLUMNS (CHAR_CHARSET (str[i]));
1975
1976 return cols;
1977 }
1978
1979 /* NOTE: Does not reset the Dynarr. */
1980
1981 void
1982 convert_bufbyte_string_into_emchar_dynarr (CONST Bufbyte *str, Bytecount len,
1983 emchar_dynarr *dyn)
1984 {
1985 CONST Bufbyte *strend = str + len;
1986
1987 while (str < strend)
1988 {
1989 Emchar ch = charptr_emchar (str);
1990 Dynarr_add (dyn, ch);
1991 INC_CHARPTR (str);
1992 }
1993 }
1994
1995 int
1996 convert_bufbyte_string_into_emchar_string (CONST Bufbyte *str, Bytecount len,
1997 Emchar *arr)
1998 {
1999 CONST Bufbyte *strend = str + len;
2000 Charcount newlen = 0;
2001 while (str < strend)
2002 {
2003 Emchar ch = charptr_emchar (str);
2004 arr[newlen++] = ch;
2005 INC_CHARPTR (str);
2006 }
2007 return newlen;
2008 }
2009
2010 /* Convert an array of Emchars into the equivalent string representation.
2011 Store into the given Bufbyte dynarr. Does not reset the dynarr.
2012 Does not add a terminating zero. */
2013
2014 void
2015 convert_emchar_string_into_bufbyte_dynarr (Emchar *arr, int nels,
2016 bufbyte_dynarr *dyn)
2017 {
2018 Bufbyte str[MAX_EMCHAR_LEN];
2019 Bytecount len;
2020 int i;
2021
2022 for (i = 0; i < nels; i++)
2023 {
2024 len = set_charptr_emchar (str, arr[i]);
2025 Dynarr_add_many (dyn, str, len);
2026 }
2027 }
2028
2029 /* Convert an array of Emchars into the equivalent string representation.
2030 Malloc the space needed for this and return it. If LEN_OUT is not a
2031 NULL pointer, store into LEN_OUT the number of Bufbytes in the
2032 malloc()ed string. Note that the actual number of Bufbytes allocated
2033 is one more than this: the returned string is zero-terminated. */
2034
2035 Bufbyte *
2036 convert_emchar_string_into_malloced_string (Emchar *arr, int nels,
2037 Bytecount *len_out)
2038 {
2039 /* Damn zero-termination. */
2040 Bufbyte *str = (Bufbyte *) alloca (nels * MAX_EMCHAR_LEN + 1);
2041 Bufbyte *strorig = str;
2042 Bytecount len;
2043
2044 int i;
2045
2046 for (i = 0; i < nels; i++)
2047 str += set_charptr_emchar (str, arr[i]);
2048 *str = '\0';
2049 len = str - strorig;
2050 str = xmalloc (1 + len);
2051 memcpy (str, strorig, 1 + len);
2052 if (len_out)
2053 *len_out = len;
2054 return str;
2055 }
2056
2057
2058 /************************************************************************/
2059 /* initialization */
2060 /************************************************************************/
2061
2062 void
2063 vars_of_insdel (void)
2064 {
2065 int i;
2066
2067 inside_change_hook = 0;
2068 in_first_change = 0;
2069
2070 for (i = 0; i <= MAX_BYTIND_GAP_SIZE_3; i++)
2071 three_to_one_table[i] = i / 3;
2072 }
2073
2074 void
2075 init_buffer_text (struct buffer *b, int indirect_p)
2076 {
2077 if (!indirect_p)
2078 {
2079 SET_BUF_GAP_SIZE (b, 20);
2080 (void) BUFFER_ALLOC (b->text->beg,
2081 BUF_GAP_SIZE (b) + BUF_END_SENTINEL_SIZE);
2082 if (! BUF_BEG_ADDR (b))
2083 memory_full ();
2084
2085 SET_BI_BUF_GPT (b, 1);
2086 SET_BOTH_BUF_Z (b, 1, 1);
2087 SET_GAP_SENTINEL (b);
2088 SET_END_SENTINEL (b);
2089
2090 BUF_MODIFF (b) = 1;
2091 BUF_SAVE_MODIFF (b) = 1;
2092
2093 JUST_SET_POINT (b, 1, 1);
2094 SET_BOTH_BUF_BEGV (b, 1, 1);
2095 SET_BOTH_BUF_ZV (b, 1, 1);
2096
2097 b->text->changes =
2098 (struct buffer_text_change_data *)
2099 xmalloc (sizeof (*b->text->changes));
2100 memset (b->text->changes, 0, sizeof (*b->text->changes));
2101 }
2102 else
2103 {
2104 JUST_SET_POINT (b, BUF_PT (b->base_buffer), BI_BUF_PT (b->base_buffer));
2105 SET_BOTH_BUF_BEGV (b, BUF_BEGV (b->base_buffer),
2106 BI_BUF_BEGV (b->base_buffer));
2107 SET_BOTH_BUF_ZV (b, BUF_ZV (b->base_buffer),
2108 BI_BUF_ZV (b->base_buffer));
2109 }
2110
2111 b->changes =
2112 (struct each_buffer_change_data *) xmalloc (sizeof (*b->changes));
2113 memset (b->changes, 0, sizeof (*b->changes));
2114 BUF_FACECHANGE (b) = 1;
2115
2116 #ifdef REGION_CACHE_NEEDS_WORK
2117 b->newline_cache = 0;
2118 b->width_run_cache = 0;
2119 b->width_table = Qnil;
2120 #endif
2121 }
2122
2123 void
2124 uninit_buffer_text (struct buffer *b, int indirect_p)
2125 {
2126 if (!indirect_p)
2127 {
2128 BUFFER_FREE (b->text->beg);
2129 xfree (b->text->changes);
2130 }
2131 xfree (b->changes);
2132
2133 #ifdef REGION_CACHE_NEEDS_WORK
2134 if (b->newline_cache)
2135 {
2136 free_region_cache (b->newline_cache);
2137 b->newline_cache = 0;
2138 }
2139 if (b->width_run_cache)
2140 {
2141 free_region_cache (b->width_run_cache);
2142 b->width_run_cache = 0;
2143 }
2144 b->width_table = Qnil;
2145 #endif
2146 }