(make_gap): Don't allow buffer size that won't fit in int.
[bpt/emacs.git] / src / insdel.c
1 /* Buffer insertion/deletion and gap motion for GNU Emacs.
2 Copyright (C) 1985, 1986, 1993, 1994, 1995 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
9 any later version.
10
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21 #include <config.h>
22 #include "lisp.h"
23 #include "intervals.h"
24 #include "buffer.h"
25 #include "window.h"
26 #include "blockinput.h"
27
28 static void insert_from_string_1 ();
29 static void insert_from_buffer_1 ();
30 static void gap_left ();
31 static void gap_right ();
32 static void adjust_markers ();
33 static void adjust_point ();
34
35 /* Move gap to position `pos'.
36 Note that this can quit! */
37
38 void
39 move_gap (pos)
40 int pos;
41 {
42 if (pos < GPT)
43 gap_left (pos, 0);
44 else if (pos > GPT)
45 gap_right (pos);
46 }
47
48 /* Move the gap to POS, which is less than the current GPT.
49 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
50
51 static void
52 gap_left (pos, newgap)
53 register int pos;
54 int newgap;
55 {
56 register unsigned char *to, *from;
57 register int i;
58 int new_s1;
59
60 pos--;
61
62 if (!newgap)
63 {
64 if (unchanged_modified == MODIFF)
65 {
66 beg_unchanged = pos;
67 end_unchanged = Z - pos - 1;
68 }
69 else
70 {
71 if (Z - GPT < end_unchanged)
72 end_unchanged = Z - GPT;
73 if (pos < beg_unchanged)
74 beg_unchanged = pos;
75 }
76 }
77
78 i = GPT;
79 to = GAP_END_ADDR;
80 from = GPT_ADDR;
81 new_s1 = GPT - BEG;
82
83 /* Now copy the characters. To move the gap down,
84 copy characters up. */
85
86 while (1)
87 {
88 /* I gets number of characters left to copy. */
89 i = new_s1 - pos;
90 if (i == 0)
91 break;
92 /* If a quit is requested, stop copying now.
93 Change POS to be where we have actually moved the gap to. */
94 if (QUITP)
95 {
96 pos = new_s1;
97 break;
98 }
99 /* Move at most 32000 chars before checking again for a quit. */
100 if (i > 32000)
101 i = 32000;
102 #ifdef GAP_USE_BCOPY
103 if (i >= 128
104 /* bcopy is safe if the two areas of memory do not overlap
105 or on systems where bcopy is always safe for moving upward. */
106 && (BCOPY_UPWARD_SAFE
107 || to - from >= 128))
108 {
109 /* If overlap is not safe, avoid it by not moving too many
110 characters at once. */
111 if (!BCOPY_UPWARD_SAFE && i > to - from)
112 i = to - from;
113 new_s1 -= i;
114 from -= i, to -= i;
115 bcopy (from, to, i);
116 }
117 else
118 #endif
119 {
120 new_s1 -= i;
121 while (--i >= 0)
122 *--to = *--from;
123 }
124 }
125
126 /* Adjust markers, and buffer data structure, to put the gap at POS.
127 POS is where the loop above stopped, which may be what was specified
128 or may be where a quit was detected. */
129 adjust_markers (pos + 1, GPT, GAP_SIZE);
130 GPT = pos + 1;
131 QUIT;
132 }
133
134 static void
135 gap_right (pos)
136 register int pos;
137 {
138 register unsigned char *to, *from;
139 register int i;
140 int new_s1;
141
142 pos--;
143
144 if (unchanged_modified == MODIFF)
145 {
146 beg_unchanged = pos;
147 end_unchanged = Z - pos - 1;
148 }
149 else
150 {
151 if (Z - pos - 1 < end_unchanged)
152 end_unchanged = Z - pos - 1;
153 if (GPT - BEG < beg_unchanged)
154 beg_unchanged = GPT - BEG;
155 }
156
157 i = GPT;
158 from = GAP_END_ADDR;
159 to = GPT_ADDR;
160 new_s1 = GPT - 1;
161
162 /* Now copy the characters. To move the gap up,
163 copy characters down. */
164
165 while (1)
166 {
167 /* I gets number of characters left to copy. */
168 i = pos - new_s1;
169 if (i == 0)
170 break;
171 /* If a quit is requested, stop copying now.
172 Change POS to be where we have actually moved the gap to. */
173 if (QUITP)
174 {
175 pos = new_s1;
176 break;
177 }
178 /* Move at most 32000 chars before checking again for a quit. */
179 if (i > 32000)
180 i = 32000;
181 #ifdef GAP_USE_BCOPY
182 if (i >= 128
183 /* bcopy is safe if the two areas of memory do not overlap
184 or on systems where bcopy is always safe for moving downward. */
185 && (BCOPY_DOWNWARD_SAFE
186 || from - to >= 128))
187 {
188 /* If overlap is not safe, avoid it by not moving too many
189 characters at once. */
190 if (!BCOPY_DOWNWARD_SAFE && i > from - to)
191 i = from - to;
192 new_s1 += i;
193 bcopy (from, to, i);
194 from += i, to += i;
195 }
196 else
197 #endif
198 {
199 new_s1 += i;
200 while (--i >= 0)
201 *to++ = *from++;
202 }
203 }
204
205 adjust_markers (GPT + GAP_SIZE, pos + 1 + GAP_SIZE, - GAP_SIZE);
206 GPT = pos + 1;
207 QUIT;
208 }
209
210 /* Add `amount' to the position of every marker in the current buffer
211 whose current position is between `from' (exclusive) and `to' (inclusive).
212 Also, any markers past the outside of that interval, in the direction
213 of adjustment, are first moved back to the near end of the interval
214 and then adjusted by `amount'. */
215
216 static void
217 adjust_markers (from, to, amount)
218 register int from, to, amount;
219 {
220 Lisp_Object marker;
221 register struct Lisp_Marker *m;
222 register int mpos;
223
224 marker = BUF_MARKERS (current_buffer);
225
226 while (!NILP (marker))
227 {
228 m = XMARKER (marker);
229 mpos = m->bufpos;
230 if (amount > 0)
231 {
232 if (mpos > to && mpos < to + amount)
233 mpos = to + amount;
234 }
235 else
236 {
237 if (mpos > from + amount && mpos <= from)
238 mpos = from + amount;
239 }
240 if (mpos > from && mpos <= to)
241 mpos += amount;
242 m->bufpos = mpos;
243 marker = m->chain;
244 }
245 }
246
247 /* Add the specified amount to point. This is used only when the value
248 of point changes due to an insert or delete; it does not represent
249 a conceptual change in point as a marker. In particular, point is
250 not crossing any interval boundaries, so there's no need to use the
251 usual SET_PT macro. In fact it would be incorrect to do so, because
252 either the old or the new value of point is out of synch with the
253 current set of intervals. */
254 static void
255 adjust_point (amount)
256 {
257 BUF_PT (current_buffer) += amount;
258 }
259 \f
260 /* Make the gap INCREMENT characters longer. */
261
262 void
263 make_gap (increment)
264 int increment;
265 {
266 unsigned char *result;
267 Lisp_Object tem;
268 int real_gap_loc;
269 int old_gap_size;
270
271 /* If we have to get more space, get enough to last a while. */
272 increment += 2000;
273
274 /* Don't allow a buffer size that won't fit in an int
275 even if it will fit in a Lisp integer.
276 That won't work because so many places use `int'. */
277
278 if (VALBITS > INTBITS
279 && (Z - BEG + GAP_SIZE + increment) >= ((unsigned) 1 << (INTBITS - 1)))
280 error ("Buffer too big");
281
282 BLOCK_INPUT;
283 result = BUFFER_REALLOC (BEG_ADDR, (Z - BEG + GAP_SIZE + increment));
284
285 if (result == 0)
286 {
287 UNBLOCK_INPUT;
288 memory_full ();
289 }
290
291 /* We can't unblock until the new address is properly stored. */
292 BEG_ADDR = result;
293 UNBLOCK_INPUT;
294
295 /* Prevent quitting in move_gap. */
296 tem = Vinhibit_quit;
297 Vinhibit_quit = Qt;
298
299 real_gap_loc = GPT;
300 old_gap_size = GAP_SIZE;
301
302 /* Call the newly allocated space a gap at the end of the whole space. */
303 GPT = Z + GAP_SIZE;
304 GAP_SIZE = increment;
305
306 /* Move the new gap down to be consecutive with the end of the old one.
307 This adjusts the markers properly too. */
308 gap_left (real_gap_loc + old_gap_size, 1);
309
310 /* Now combine the two into one large gap. */
311 GAP_SIZE += old_gap_size;
312 GPT = real_gap_loc;
313
314 Vinhibit_quit = tem;
315 }
316 \f
317 /* Insert a string of specified length before point.
318 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
319 prepare_to_modify_buffer could relocate the text. */
320
321 void
322 insert (string, length)
323 register unsigned char *string;
324 register length;
325 {
326 if (length > 0)
327 {
328 insert_1 (string, length, 0, 1);
329 signal_after_change (PT-length, 0, length);
330 }
331 }
332
333 void
334 insert_and_inherit (string, length)
335 register unsigned char *string;
336 register length;
337 {
338 if (length > 0)
339 {
340 insert_1 (string, length, 1, 1);
341 signal_after_change (PT-length, 0, length);
342 }
343 }
344
345 void
346 insert_1 (string, length, inherit, prepare)
347 register unsigned char *string;
348 register int length;
349 int inherit, prepare;
350 {
351 register Lisp_Object temp;
352
353 /* Make sure point-max won't overflow after this insertion. */
354 XSETINT (temp, length + Z);
355 if (length + Z != XINT (temp))
356 error ("maximum buffer size exceeded");
357
358 if (prepare)
359 prepare_to_modify_buffer (PT, PT);
360
361 if (PT != GPT)
362 move_gap (PT);
363 if (GAP_SIZE < length)
364 make_gap (length - GAP_SIZE);
365
366 record_insert (PT, length);
367 MODIFF++;
368
369 bcopy (string, GPT_ADDR, length);
370
371 #ifdef USE_TEXT_PROPERTIES
372 if (BUF_INTERVALS (current_buffer) != 0)
373 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
374 offset_intervals (current_buffer, PT, length);
375 #endif
376
377 GAP_SIZE -= length;
378 GPT += length;
379 ZV += length;
380 Z += length;
381 adjust_overlays_for_insert (PT, length);
382 adjust_point (length);
383
384 #ifdef USE_TEXT_PROPERTIES
385 if (!inherit && BUF_INTERVALS (current_buffer) != 0)
386 Fset_text_properties (make_number (PT - length), make_number (PT),
387 Qnil, Qnil);
388 #endif
389 }
390
391 /* Insert the part of the text of STRING, a Lisp object assumed to be
392 of type string, consisting of the LENGTH characters starting at
393 position POS. If the text of STRING has properties, they are absorbed
394 into the buffer.
395
396 It does not work to use `insert' for this, because a GC could happen
397 before we bcopy the stuff into the buffer, and relocate the string
398 without insert noticing. */
399
400 void
401 insert_from_string (string, pos, length, inherit)
402 Lisp_Object string;
403 register int pos, length;
404 int inherit;
405 {
406 if (length > 0)
407 {
408 insert_from_string_1 (string, pos, length, inherit);
409 signal_after_change (PT-length, 0, length);
410 }
411 }
412
413 static void
414 insert_from_string_1 (string, pos, length, inherit)
415 Lisp_Object string;
416 register int pos, length;
417 int inherit;
418 {
419 register Lisp_Object temp;
420 struct gcpro gcpro1;
421
422 /* Make sure point-max won't overflow after this insertion. */
423 XSETINT (temp, length + Z);
424 if (length + Z != XINT (temp))
425 error ("maximum buffer size exceeded");
426
427 GCPRO1 (string);
428 prepare_to_modify_buffer (PT, PT);
429
430 if (PT != GPT)
431 move_gap (PT);
432 if (GAP_SIZE < length)
433 make_gap (length - GAP_SIZE);
434
435 record_insert (PT, length);
436 MODIFF++;
437 UNGCPRO;
438
439 bcopy (XSTRING (string)->data, GPT_ADDR, length);
440
441 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
442 offset_intervals (current_buffer, PT, length);
443
444 GAP_SIZE -= length;
445 GPT += length;
446 ZV += length;
447 Z += length;
448 adjust_overlays_for_insert (PT, length);
449
450 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
451 graft_intervals_into_buffer (XSTRING (string)->intervals, PT, length,
452 current_buffer, inherit);
453
454 adjust_point (length);
455 }
456
457 /* Insert text from BUF, starting at POS and having length LENGTH, into the
458 current buffer. If the text in BUF has properties, they are absorbed
459 into the current buffer.
460
461 It does not work to use `insert' for this, because a malloc could happen
462 and relocate BUF's text before the bcopy happens. */
463
464 void
465 insert_from_buffer (buf, pos, length, inherit)
466 struct buffer *buf;
467 int pos, length;
468 int inherit;
469 {
470 if (length > 0)
471 {
472 insert_from_buffer_1 (buf, pos, length, inherit);
473 signal_after_change (PT-length, 0, length);
474 }
475 }
476
477 static void
478 insert_from_buffer_1 (buf, pos, length, inherit)
479 struct buffer *buf;
480 int pos, length;
481 int inherit;
482 {
483 register Lisp_Object temp;
484 int chunk;
485
486 /* Make sure point-max won't overflow after this insertion. */
487 XSETINT (temp, length + Z);
488 if (length + Z != XINT (temp))
489 error ("maximum buffer size exceeded");
490
491 prepare_to_modify_buffer (PT, PT);
492
493 if (PT != GPT)
494 move_gap (PT);
495 if (GAP_SIZE < length)
496 make_gap (length - GAP_SIZE);
497
498 record_insert (PT, length);
499 MODIFF++;
500
501 if (pos < BUF_GPT (buf))
502 {
503 chunk = BUF_GPT (buf) - pos;
504 if (chunk > length)
505 chunk = length;
506 bcopy (BUF_CHAR_ADDRESS (buf, pos), GPT_ADDR, chunk);
507 }
508 else
509 chunk = 0;
510 if (chunk < length)
511 bcopy (BUF_CHAR_ADDRESS (buf, pos + chunk),
512 GPT_ADDR + chunk, length - chunk);
513
514 #ifdef USE_TEXT_PROPERTIES
515 if (BUF_INTERVALS (current_buffer) != 0)
516 offset_intervals (current_buffer, PT, length);
517 #endif
518
519 GAP_SIZE -= length;
520 GPT += length;
521 ZV += length;
522 Z += length;
523 adjust_overlays_for_insert (PT, length);
524 adjust_point (length);
525
526 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
527 graft_intervals_into_buffer (copy_intervals (BUF_INTERVALS (buf),
528 pos, length),
529 PT - length, length, current_buffer, inherit);
530 }
531
532 /* Insert the character C before point */
533
534 void
535 insert_char (c)
536 unsigned char c;
537 {
538 insert (&c, 1);
539 }
540
541 /* Insert the null-terminated string S before point */
542
543 void
544 insert_string (s)
545 char *s;
546 {
547 insert (s, strlen (s));
548 }
549
550 /* Like `insert' except that all markers pointing at the place where
551 the insertion happens are adjusted to point after it.
552 Don't use this function to insert part of a Lisp string,
553 since gc could happen and relocate it. */
554
555 void
556 insert_before_markers (string, length)
557 unsigned char *string;
558 register int length;
559 {
560 if (length > 0)
561 {
562 register int opoint = PT;
563 insert_1 (string, length, 0, 1);
564 adjust_markers (opoint - 1, opoint, length);
565 signal_after_change (PT-length, 0, length);
566 }
567 }
568
569 void
570 insert_before_markers_and_inherit (string, length)
571 unsigned char *string;
572 register int length;
573 {
574 if (length > 0)
575 {
576 register int opoint = PT;
577 insert_1 (string, length, 1, 1);
578 adjust_markers (opoint - 1, opoint, length);
579 signal_after_change (PT-length, 0, length);
580 }
581 }
582
583 /* Insert part of a Lisp string, relocating markers after. */
584
585 void
586 insert_from_string_before_markers (string, pos, length, inherit)
587 Lisp_Object string;
588 register int pos, length;
589 int inherit;
590 {
591 if (length > 0)
592 {
593 register int opoint = PT;
594 insert_from_string_1 (string, pos, length, inherit);
595 adjust_markers (opoint - 1, opoint, length);
596 signal_after_change (PT-length, 0, length);
597 }
598 }
599 \f
600 /* Delete characters in current buffer
601 from FROM up to (but not including) TO. */
602
603 void
604 del_range (from, to)
605 register int from, to;
606 {
607 del_range_1 (from, to, 1);
608 }
609
610 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer. */
611
612 void
613 del_range_1 (from, to, prepare)
614 register int from, to, prepare;
615 {
616 register int numdel;
617
618 /* Make args be valid */
619 if (from < BEGV)
620 from = BEGV;
621 if (to > ZV)
622 to = ZV;
623
624 if ((numdel = to - from) <= 0)
625 return;
626
627 /* Make sure the gap is somewhere in or next to what we are deleting. */
628 if (from > GPT)
629 gap_right (from);
630 if (to < GPT)
631 gap_left (to, 0);
632
633 if (prepare)
634 prepare_to_modify_buffer (from, to);
635
636 record_delete (from, numdel);
637 MODIFF++;
638
639 /* Relocate point as if it were a marker. */
640 if (from < PT)
641 adjust_point (from - (PT < to ? PT : to));
642
643 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
644 offset_intervals (current_buffer, from, - numdel);
645
646 /* Relocate all markers pointing into the new, larger gap
647 to point at the end of the text before the gap. */
648 adjust_markers (to + GAP_SIZE, to + GAP_SIZE, - numdel - GAP_SIZE);
649
650 /* Adjust the overlay center as needed. This must be done after
651 adjusting the markers that bound the overlays. */
652 adjust_overlays_for_delete (from, numdel);
653
654 GAP_SIZE += numdel;
655 ZV -= numdel;
656 Z -= numdel;
657 GPT = from;
658
659 if (GPT - BEG < beg_unchanged)
660 beg_unchanged = GPT - BEG;
661 if (Z - GPT < end_unchanged)
662 end_unchanged = Z - GPT;
663
664 evaporate_overlays (from);
665 signal_after_change (from, numdel, 0);
666 }
667 \f
668 /* Call this if you're about to change the region of BUFFER from START
669 to END. This checks the read-only properties of the region, calls
670 the necessary modification hooks, and warns the next redisplay that
671 it should pay attention to that area. */
672 void
673 modify_region (buffer, start, end)
674 struct buffer *buffer;
675 int start, end;
676 {
677 struct buffer *old_buffer = current_buffer;
678
679 if (buffer != old_buffer)
680 set_buffer_internal (buffer);
681
682 prepare_to_modify_buffer (start, end);
683
684 if (start - 1 < beg_unchanged || unchanged_modified == MODIFF)
685 beg_unchanged = start - 1;
686 if (Z - end < end_unchanged
687 || unchanged_modified == MODIFF)
688 end_unchanged = Z - end;
689
690 if (MODIFF <= SAVE_MODIFF)
691 record_first_change ();
692 MODIFF++;
693
694 buffer->point_before_scroll = Qnil;
695
696 if (buffer != old_buffer)
697 set_buffer_internal (old_buffer);
698 }
699
700 /* Check that it is okay to modify the buffer between START and END.
701 Run the before-change-function, if any. If intervals are in use,
702 verify that the text to be modified is not read-only, and call
703 any modification properties the text may have. */
704
705 void
706 prepare_to_modify_buffer (start, end)
707 Lisp_Object start, end;
708 {
709 if (!NILP (current_buffer->read_only))
710 Fbarf_if_buffer_read_only ();
711
712 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
713 if (BUF_INTERVALS (current_buffer) != 0)
714 verify_interval_modification (current_buffer, start, end);
715
716 #ifdef CLASH_DETECTION
717 if (!NILP (current_buffer->file_truename)
718 && SAVE_MODIFF >= MODIFF)
719 lock_file (current_buffer->file_truename);
720 #else
721 /* At least warn if this file has changed on disk since it was visited. */
722 if (!NILP (current_buffer->filename)
723 && SAVE_MODIFF >= MODIFF
724 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
725 && !NILP (Ffile_exists_p (current_buffer->filename)))
726 call1 (intern ("ask-user-about-supersession-threat"),
727 current_buffer->filename);
728 #endif /* not CLASH_DETECTION */
729
730 signal_before_change (start, end);
731
732 if (current_buffer->newline_cache)
733 invalidate_region_cache (current_buffer,
734 current_buffer->newline_cache,
735 start - BEG, Z - end);
736 if (current_buffer->width_run_cache)
737 invalidate_region_cache (current_buffer,
738 current_buffer->width_run_cache,
739 start - BEG, Z - end);
740
741 Vdeactivate_mark = Qt;
742 }
743 \f
744 static Lisp_Object
745 before_change_function_restore (value)
746 Lisp_Object value;
747 {
748 Vbefore_change_function = value;
749 }
750
751 static Lisp_Object
752 after_change_function_restore (value)
753 Lisp_Object value;
754 {
755 Vafter_change_function = value;
756 }
757
758 static Lisp_Object
759 before_change_functions_restore (value)
760 Lisp_Object value;
761 {
762 Vbefore_change_functions = value;
763 }
764
765 static Lisp_Object
766 after_change_functions_restore (value)
767 Lisp_Object value;
768 {
769 Vafter_change_functions = value;
770 }
771
772 /* Signal a change to the buffer immediately before it happens.
773 START and END are the bounds of the text to be changed,
774 as Lisp objects. */
775
776 void
777 signal_before_change (start, end)
778 Lisp_Object start, end;
779 {
780 /* If buffer is unmodified, run a special hook for that case. */
781 if (SAVE_MODIFF >= MODIFF
782 && !NILP (Vfirst_change_hook)
783 && !NILP (Vrun_hooks))
784 call1 (Vrun_hooks, Qfirst_change_hook);
785
786 /* Now in any case run the before-change-function if any. */
787 if (!NILP (Vbefore_change_function))
788 {
789 int count = specpdl_ptr - specpdl;
790 Lisp_Object function;
791
792 function = Vbefore_change_function;
793
794 record_unwind_protect (after_change_function_restore,
795 Vafter_change_function);
796 record_unwind_protect (before_change_function_restore,
797 Vbefore_change_function);
798 record_unwind_protect (after_change_functions_restore,
799 Vafter_change_functions);
800 record_unwind_protect (before_change_functions_restore,
801 Vbefore_change_functions);
802 Vafter_change_function = Qnil;
803 Vbefore_change_function = Qnil;
804 Vafter_change_functions = Qnil;
805 Vbefore_change_functions = Qnil;
806
807 call2 (function, start, end);
808 unbind_to (count, Qnil);
809 }
810
811 /* Now in any case run the before-change-function if any. */
812 if (!NILP (Vbefore_change_functions))
813 {
814 int count = specpdl_ptr - specpdl;
815 Lisp_Object functions;
816
817 functions = Vbefore_change_functions;
818
819 record_unwind_protect (after_change_function_restore,
820 Vafter_change_function);
821 record_unwind_protect (before_change_function_restore,
822 Vbefore_change_function);
823 record_unwind_protect (after_change_functions_restore,
824 Vafter_change_functions);
825 record_unwind_protect (before_change_functions_restore,
826 Vbefore_change_functions);
827 Vafter_change_function = Qnil;
828 Vbefore_change_function = Qnil;
829 Vafter_change_functions = Qnil;
830 Vbefore_change_functions = Qnil;
831
832 while (CONSP (functions))
833 {
834 call2 (XCONS (functions)->car, start, end);
835 functions = XCONS (functions)->cdr;
836 }
837 unbind_to (count, Qnil);
838 }
839
840 if (!NILP (current_buffer->overlays_before)
841 || !NILP (current_buffer->overlays_after))
842 report_overlay_modification (start, end, 0, start, end, Qnil);
843 }
844
845 /* Signal a change immediately after it happens.
846 POS is the address of the start of the changed text.
847 LENDEL is the number of characters of the text before the change.
848 (Not the whole buffer; just the part that was changed.)
849 LENINS is the number of characters in the changed text.
850
851 (Hence POS + LENINS - LENDEL is the position after the changed text.) */
852
853 void
854 signal_after_change (pos, lendel, lenins)
855 int pos, lendel, lenins;
856 {
857 if (!NILP (Vafter_change_function))
858 {
859 int count = specpdl_ptr - specpdl;
860 Lisp_Object function;
861 function = Vafter_change_function;
862
863 record_unwind_protect (after_change_function_restore,
864 Vafter_change_function);
865 record_unwind_protect (before_change_function_restore,
866 Vbefore_change_function);
867 record_unwind_protect (after_change_functions_restore,
868 Vafter_change_functions);
869 record_unwind_protect (before_change_functions_restore,
870 Vbefore_change_functions);
871 Vafter_change_function = Qnil;
872 Vbefore_change_function = Qnil;
873 Vafter_change_functions = Qnil;
874 Vbefore_change_functions = Qnil;
875
876 call3 (function, make_number (pos), make_number (pos + lenins),
877 make_number (lendel));
878 unbind_to (count, Qnil);
879 }
880 if (!NILP (Vafter_change_functions))
881 {
882 int count = specpdl_ptr - specpdl;
883 Lisp_Object functions;
884 functions = Vafter_change_functions;
885
886 record_unwind_protect (after_change_function_restore,
887 Vafter_change_function);
888 record_unwind_protect (before_change_function_restore,
889 Vbefore_change_function);
890 record_unwind_protect (after_change_functions_restore,
891 Vafter_change_functions);
892 record_unwind_protect (before_change_functions_restore,
893 Vbefore_change_functions);
894 Vafter_change_function = Qnil;
895 Vbefore_change_function = Qnil;
896 Vafter_change_functions = Qnil;
897 Vbefore_change_functions = Qnil;
898
899 while (CONSP (functions))
900 {
901 call3 (XCONS (functions)->car,
902 make_number (pos), make_number (pos + lenins),
903 make_number (lendel));
904 functions = XCONS (functions)->cdr;
905 }
906 unbind_to (count, Qnil);
907 }
908
909 if (!NILP (current_buffer->overlays_before)
910 || !NILP (current_buffer->overlays_after))
911 report_overlay_modification (make_number (pos),
912 make_number (pos + lenins - lendel),
913 1,
914 make_number (pos), make_number (pos + lenins),
915 make_number (lendel));
916 }