comparison src/insdel.c @ 826:6728e641994e

[xemacs-hg @ 2002-05-05 11:30:15 by ben] syntax cache, 8-bit-format, lots of code cleanup README.packages: Update info about --package-path. i.c: Create an inheritable event and pass it on to XEmacs, so that ^C can be handled properly. Intercept ^C and signal the event. "Stop Build" in VC++ now works. bytecomp-runtime.el: Doc string changes. compat.el: Some attempts to redo this to make it truly useful and fix the "multiple versions interacting with each other" problem. Not yet done. Currently doesn't work. files.el: Use with-obsolete-variable to avoid warnings in new revert-buffer code. xemacs.mak: Split up CFLAGS into a version without flags specifying the C library. The problem seems to be that minitar depends on zlib, which depends specifically on libc.lib, not on any of the other C libraries. Unless you compile with libc.lib, you get errors -- specifically, no _errno in the other libraries, which must make it something other than an int. (#### But this doesn't seem to obtain in XEmacs, which also uses zlib, and can be linked with any of the C libraries. Maybe zlib is used differently and doesn't need errno, or maybe XEmacs provides an int errno; ... I don't understand. Makefile.in.in: Fix so that packages are around when testing. abbrev.c, alloc.c, buffer.c, buffer.h, bytecode.c, callint.c, casefiddle.c, casetab.c, casetab.h, charset.h, chartab.c, chartab.h, cmds.c, console-msw.h, console-stream.c, console-x.c, console.c, console.h, data.c, device-msw.c, device.c, device.h, dialog-msw.c, dialog-x.c, dired-msw.c, dired.c, doc.c, doprnt.c, dumper.c, editfns.c, elhash.c, emacs.c, eval.c, event-Xt.c, event-gtk.c, event-msw.c, event-stream.c, events.c, events.h, extents.c, extents.h, faces.c, file-coding.c, file-coding.h, fileio.c, fns.c, font-lock.c, frame-gtk.c, frame-msw.c, frame-x.c, frame.c, frame.h, glade.c, glyphs-gtk.c, glyphs-msw.c, glyphs-msw.h, glyphs-x.c, glyphs.c, glyphs.h, gui-msw.c, gui-x.c, gui.h, gutter.h, hash.h, indent.c, insdel.c, intl-win32.c, intl.c, keymap.c, lisp-disunion.h, lisp-union.h, lisp.h, lread.c, lrecord.h, lstream.c, lstream.h, marker.c, menubar-gtk.c, menubar-msw.c, menubar-x.c, menubar.c, minibuf.c, mule-ccl.c, mule-charset.c, mule-coding.c, mule-wnnfns.c, nas.c, objects-msw.c, objects-x.c, opaque.c, postgresql.c, print.c, process-nt.c, process-unix.c, process.c, process.h, profile.c, rangetab.c, redisplay-gtk.c, redisplay-msw.c, redisplay-output.c, redisplay-x.c, redisplay.c, redisplay.h, regex.c, regex.h, scrollbar-msw.c, search.c, select-x.c, specifier.c, specifier.h, symbols.c, symsinit.h, syntax.c, syntax.h, syswindows.h, tests.c, text.c, text.h, tooltalk.c, ui-byhand.c, ui-gtk.c, unicode.c, win32.c, window.c: Another big Ben patch. -- FUNCTIONALITY CHANGES: add partial support for 8-bit-fixed, 16-bit-fixed, and 32-bit-fixed formats. not quite done yet. (in particular, needs functions to actually convert the buffer.) NOTE: lots of changes to regex.c here. also, many new *_fmt() inline funs that take an Internal_Format argument. redo syntax cache code. make the cache per-buffer; keep the cache valid across calls to functions that use it. also keep it valid across insertions/deletions and extent changes, as much as is possible. eliminate the junky regex-reentrancy code by passing in the relevant lisp info to the regex routines as local vars. add general mechanism in extents code for signalling extent changes. fix numerous problems with the case-table implementation; yoshiki never properly transferred many algorithms from old-style to new-style case tables. redo char tables to support a default argument, so that mapping only occurs over changed args. change many chartab functions to accept Lisp_Object instead of Lisp_Char_Table *. comment out the code in font-lock.c by default, because font-lock.el no longer uses it. we should consider eliminating it entirely. Don't output bell as ^G in console-stream when not a TTY. add -mswindows-termination-handle to interface with i.c, so we can properly kill a build. add more error-checking to buffer/string macros. add some additional buffer_or_string_() funs. -- INTERFACE CHANGES AFFECTING MORE CODE: switch the arguments of write_c_string and friends to be consistent with write_fmt_string, which must have printcharfun first. change BI_* macros to BYTE_* for increased clarity; similarly for bi_* local vars. change VOID_TO_LISP to be a one-argument function. eliminate no-longer-needed CVOID_TO_LISP. -- char/string macro changes: rename MAKE_CHAR() to make_emchar() for slightly less confusion with make_char(). (The former generates an Emchar, the latter a Lisp object. Conceivably we should rename make_char() -> wrap_char() and similarly for make_int(), make_float().) Similar changes for other *CHAR* macros -- we now consistently use names with `emchar' whenever we are working with Emchars. Any remaining name with just `char' always refers to a Lisp object. rename macros with XSTRING_* to string_* except for those that reference actual fields in the Lisp_String object, following conventions used elsewhere. rename set_string_{data,length} macros (the only ones to work with a Lisp_String_* instead of a Lisp_Object) to set_lispstringp_* to make the difference clear. try to be consistent about caps vs. lowercase in macro/inline-fun names for chars and such, which wasn't the case before. we now reserve caps either for XFOO_ macros that reference object fields (e.g. XSTRING_DATA) or for things that have non-function semantics, e.g. directly modifying an arg (BREAKUP_EMCHAR) or evaluating an arg (any arg) more than once. otherwise, use lowercase. here is a summary of most of the macros/inline funs changed by all of the above changes: BYTE_*_P -> byte_*_p XSTRING_BYTE -> string_byte set_string_data/length -> set_lispstringp_data/length XSTRING_CHAR_LENGTH -> string_char_length XSTRING_CHAR -> string_emchar INTBYTE_FIRST_BYTE_P -> intbyte_first_byte_p INTBYTE_LEADING_BYTE_P -> intbyte_leading_byte_p charptr_copy_char -> charptr_copy_emchar LEADING_BYTE_* -> leading_byte_* CHAR_* -> EMCHAR_* *_CHAR_* -> *_EMCHAR_* *_CHAR -> *_EMCHAR CHARSET_BY_ -> charset_by_* BYTE_SHIFT_JIS* -> byte_shift_jis* BYTE_BIG5* -> byte_big5* REP_BYTES_BY_FIRST_BYTE -> rep_bytes_by_first_byte char_to_unicode -> emchar_to_unicode valid_char_p -> valid_emchar_p Change intbyte_strcmp -> qxestrcmp_c (duplicated functionality). -- INTERFACE CHANGES AFFECTING LESS CODE: use DECLARE_INLINE_HEADER in various places. remove '#ifdef emacs' from XEmacs-only files. eliminate CHAR_TABLE_VALUE(), which duplicated the functionality of get_char_table(). add BUFFER_TEXT_LOOP to simplify iterations over buffer text. define typedefs for signed and unsigned types of fixed sizes (INT_32_BIT, UINT_32_BIT, etc.). create ALIGN_FOR_TYPE as a higher-level interface onto ALIGN_SIZE; fix code to use it. add charptr_emchar_len to return the text length of the character pointed to by a ptr; use it in place of charcount_to_bytecount(..., 1). add emchar_len to return the text length of a given character. add types Bytexpos and Charxpos to generalize Bytebpos/Bytecount and Charbpos/Charcount, in code (particularly, the extents code and redisplay code) that works with either kind of index. rename redisplay struct params with names such as `charbpos' to e.g. `charpos' when they are e.g. a Charxpos, not a Charbpos. eliminate xxDEFUN in place of DEFUN; no longer necessary with changes awhile back to doc.c. split up big ugly combined list of EXFUNs in lisp.h on a file-by-file basis, since other prototypes are similarly split. rewrite some "*_UNSAFE" macros as inline funs and eliminate the _UNSAFE suffix. move most string code from lisp.h to text.h; the string code and text.h code is now intertwined in such a fashion that they need to be in the same place and partially interleaved. (you can't create forward references for inline funs) automated/lisp-tests.el, automated/symbol-tests.el, automated/test-harness.el: Fix test harness to output FAIL messages to stderr when in batch mode. Fix up some problems in lisp-tests/symbol-tests that were causing spurious failures.
author ben
date Sun, 05 May 2002 11:33:57 +0000
parents a5954632b187
children 2b6fa2618f76
comparison
equal deleted inserted replaced
825:eb3bc15a6e0f 826:6728e641994e
58 do { (buf)->text->gap_size = (value); } while (0) 58 do { (buf)->text->gap_size = (value); } while (0)
59 #define SET_BUF_END_GAP_SIZE(buf, value) \ 59 #define SET_BUF_END_GAP_SIZE(buf, value) \
60 do { (buf)->text->end_gap_size = (value); } while (0) 60 do { (buf)->text->end_gap_size = (value); } while (0)
61 61
62 /* Gap location. */ 62 /* Gap location. */
63 #define BI_BUF_GPT(buf) ((buf)->text->gpt + 0) 63 #define BYTE_BUF_GPT(buf) ((buf)->text->gpt + 0)
64 #define BUF_GPT_ADDR(buf) (BUF_BEG_ADDR (buf) + BI_BUF_GPT (buf) - 1) 64 #define BUF_GPT_ADDR(buf) (BUF_BEG_ADDR (buf) + BYTE_BUF_GPT (buf) - 1)
65 65
66 /* Set gap location. */ 66 /* Set gap location. */
67 #define SET_BI_BUF_GPT(buf, value) do { (buf)->text->gpt = (value); } while (0) 67 #define SET_BYTE_BUF_GPT(buf, value) do { (buf)->text->gpt = (value); } while (0)
68 68
69 /* Set end of buffer. */ 69 /* Set end of buffer. */
70 #define SET_BOTH_BUF_Z(buf, val, bival) \ 70 #define SET_BOTH_BUF_Z(buf, val, bival) \
71 do \ 71 do \
72 { \ 72 { \
93 #ifdef MULE 93 #ifdef MULE
94 # define GAP_CAN_HOLD_SIZE_P(buf, len) (BUF_GAP_SIZE (buf) >= (len) + 1) 94 # define GAP_CAN_HOLD_SIZE_P(buf, len) (BUF_GAP_SIZE (buf) >= (len) + 1)
95 # define SET_GAP_SENTINEL(buf) (*BUF_GPT_ADDR (buf) = 0) 95 # define SET_GAP_SENTINEL(buf) (*BUF_GPT_ADDR (buf) = 0)
96 # define BUF_END_SENTINEL_SIZE 1 96 # define BUF_END_SENTINEL_SIZE 1
97 # define SET_END_SENTINEL(buf) \ 97 # define SET_END_SENTINEL(buf) \
98 (*(BUF_BEG_ADDR (buf) + BUF_GAP_SIZE (buf) + BI_BUF_Z (buf) - 1) = 0) 98 (*(BUF_BEG_ADDR (buf) + BUF_GAP_SIZE (buf) + BYTE_BUF_Z (buf) - 1) = 0)
99 #else 99 #else
100 # define GAP_CAN_HOLD_SIZE_P(buf, len) (BUF_GAP_SIZE (buf) >= (len)) 100 # define GAP_CAN_HOLD_SIZE_P(buf, len) (BUF_GAP_SIZE (buf) >= (len))
101 # define SET_GAP_SENTINEL(buf) 101 # define SET_GAP_SENTINEL(buf)
102 # define BUF_END_SENTINEL_SIZE 0 102 # define BUF_END_SENTINEL_SIZE 0
103 # define SET_END_SENTINEL(buf) 103 # define SET_END_SENTINEL(buf)
135 /* Set a buffer's point. */ 135 /* Set a buffer's point. */
136 136
137 void 137 void
138 set_buffer_point (struct buffer *buf, Charbpos charbpos, Bytebpos bytpos) 138 set_buffer_point (struct buffer *buf, Charbpos charbpos, Bytebpos bytpos)
139 { 139 {
140 assert (bytpos >= BI_BUF_BEGV (buf) && bytpos <= BI_BUF_ZV (buf)); 140 assert (bytpos >= BYTE_BUF_BEGV (buf) && bytpos <= BYTE_BUF_ZV (buf));
141 if (bytpos == BI_BUF_PT (buf)) 141 if (bytpos == BYTE_BUF_PT (buf))
142 return; 142 return;
143 JUST_SET_POINT (buf, charbpos, bytpos); 143 JUST_SET_POINT (buf, charbpos, bytpos);
144 MARK_POINT_CHANGED; 144 MARK_POINT_CHANGED;
145 assert (MARKERP (buf->point_marker)); 145 assert (MARKERP (buf->point_marker));
146 XMARKER (buf->point_marker)->membpos = 146 XMARKER (buf->point_marker)->membpos =
259 struct buffer *mbuf; 259 struct buffer *mbuf;
260 Lisp_Object bufcons; 260 Lisp_Object bufcons;
261 261
262 from = BUF_GPT_ADDR (buf); 262 from = BUF_GPT_ADDR (buf);
263 to = from + BUF_GAP_SIZE (buf); 263 to = from + BUF_GAP_SIZE (buf);
264 new_s1 = BI_BUF_GPT (buf); 264 new_s1 = BYTE_BUF_GPT (buf);
265 265
266 /* Now copy the characters. To move the gap down, 266 /* Now copy the characters. To move the gap down,
267 copy characters up. */ 267 copy characters up. */
268 268
269 while (1) 269 while (1)
301 /* Adjust markers, and buffer data structure, to put the gap at POS. 301 /* Adjust markers, and buffer data structure, to put the gap at POS.
302 POS is where the loop above stopped, which may be what was specified 302 POS is where the loop above stopped, which may be what was specified
303 or may be where a quit was detected. */ 303 or may be where a quit was detected. */
304 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 304 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
305 { 305 {
306 adjust_markers (mbuf, pos, BI_BUF_GPT (mbuf), BUF_GAP_SIZE (mbuf)); 306 adjust_markers (mbuf, pos, BYTE_BUF_GPT (mbuf), BUF_GAP_SIZE (mbuf));
307 } 307 }
308 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 308 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
309 { 309 {
310 adjust_extents (wrap_buffer (mbuf), pos, BI_BUF_GPT (mbuf), 310 adjust_extents (wrap_buffer (mbuf), pos, BYTE_BUF_GPT (mbuf),
311 BUF_GAP_SIZE (mbuf)); 311 BUF_GAP_SIZE (mbuf));
312 } 312 }
313 SET_BI_BUF_GPT (buf, pos); 313 SET_BYTE_BUF_GPT (buf, pos);
314 SET_GAP_SENTINEL (buf); 314 SET_GAP_SENTINEL (buf);
315 #ifdef ERROR_CHECK_EXTENTS 315 #ifdef ERROR_CHECK_EXTENTS
316 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 316 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
317 { 317 {
318 sledgehammer_extent_check (wrap_buffer (mbuf)); 318 sledgehammer_extent_check (wrap_buffer (mbuf));
330 struct buffer *mbuf; 330 struct buffer *mbuf;
331 Lisp_Object bufcons; 331 Lisp_Object bufcons;
332 332
333 to = BUF_GPT_ADDR (buf); 333 to = BUF_GPT_ADDR (buf);
334 from = to + BUF_GAP_SIZE (buf); 334 from = to + BUF_GAP_SIZE (buf);
335 new_s1 = BI_BUF_GPT (buf); 335 new_s1 = BYTE_BUF_GPT (buf);
336 336
337 /* Now copy the characters. To move the gap up, 337 /* Now copy the characters. To move the gap up,
338 copy characters down. */ 338 copy characters down. */
339 339
340 while (1) 340 while (1)
371 371
372 { 372 {
373 int gsize = BUF_GAP_SIZE (buf); 373 int gsize = BUF_GAP_SIZE (buf);
374 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 374 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
375 { 375 {
376 adjust_markers (mbuf, BI_BUF_GPT (mbuf) + gsize, pos + gsize, - gsize); 376 adjust_markers (mbuf, BYTE_BUF_GPT (mbuf) + gsize, pos + gsize, - gsize);
377 } 377 }
378 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 378 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
379 { 379 {
380 adjust_extents (wrap_buffer (mbuf), BI_BUF_GPT (mbuf) + gsize, 380 adjust_extents (wrap_buffer (mbuf), BYTE_BUF_GPT (mbuf) + gsize,
381 pos + gsize, - gsize); 381 pos + gsize, - gsize);
382 } 382 }
383 SET_BI_BUF_GPT (buf, pos); 383 SET_BYTE_BUF_GPT (buf, pos);
384 SET_GAP_SENTINEL (buf); 384 SET_GAP_SENTINEL (buf);
385 #ifdef ERROR_CHECK_EXTENTS 385 #ifdef ERROR_CHECK_EXTENTS
386 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 386 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
387 { 387 {
388 sledgehammer_extent_check (wrap_buffer (mbuf)); 388 sledgehammer_extent_check (wrap_buffer (mbuf));
389 } 389 }
390 #endif 390 #endif
391 } 391 }
392 if (pos == BI_BUF_Z (buf)) 392 if (pos == BYTE_BUF_Z (buf))
393 { 393 {
394 /* merge gap with end gap */ 394 /* merge gap with end gap */
395 395
396 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + BUF_END_GAP_SIZE (buf)); 396 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + BUF_END_GAP_SIZE (buf));
397 SET_BUF_END_GAP_SIZE (buf, 0); 397 SET_BUF_END_GAP_SIZE (buf, 0);
407 static void 407 static void
408 move_gap (struct buffer *buf, Bytebpos pos) 408 move_gap (struct buffer *buf, Bytebpos pos)
409 { 409 {
410 if (! BUF_BEG_ADDR (buf)) 410 if (! BUF_BEG_ADDR (buf))
411 abort (); 411 abort ();
412 if (pos < BI_BUF_GPT (buf)) 412 if (pos < BYTE_BUF_GPT (buf))
413 gap_left (buf, pos); 413 gap_left (buf, pos);
414 else if (pos > BI_BUF_GPT (buf)) 414 else if (pos > BYTE_BUF_GPT (buf))
415 gap_right (buf, pos); 415 gap_right (buf, pos);
416 } 416 }
417 417
418 /* Merge the end gap into the gap */ 418 /* Merge the end gap into the gap */
419 419
432 { 432 {
433 /* Prevent quitting in move_gap. */ 433 /* Prevent quitting in move_gap. */
434 tem = Vinhibit_quit; 434 tem = Vinhibit_quit;
435 Vinhibit_quit = Qt; 435 Vinhibit_quit = Qt;
436 436
437 real_gap_loc = BI_BUF_GPT (buf); 437 real_gap_loc = BYTE_BUF_GPT (buf);
438 old_gap_size = BUF_GAP_SIZE (buf); 438 old_gap_size = BUF_GAP_SIZE (buf);
439 439
440 /* Pretend the end gap is the gap */ 440 /* Pretend the end gap is the gap */
441 SET_BI_BUF_GPT (buf, BI_BUF_Z (buf) + BUF_GAP_SIZE (buf)); 441 SET_BYTE_BUF_GPT (buf, BYTE_BUF_Z (buf) + BUF_GAP_SIZE (buf));
442 SET_BUF_GAP_SIZE (buf, increment); 442 SET_BUF_GAP_SIZE (buf, increment);
443 443
444 /* Move the new gap down to be consecutive with the end of the old one. 444 /* Move the new gap down to be consecutive with the end of the old one.
445 This adjusts the markers properly too. */ 445 This adjusts the markers properly too. */
446 gap_left (buf, real_gap_loc + old_gap_size); 446 gap_left (buf, real_gap_loc + old_gap_size);
447 447
448 /* Now combine the two into one large gap. */ 448 /* Now combine the two into one large gap. */
449 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + old_gap_size); 449 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + old_gap_size);
450 SET_BI_BUF_GPT (buf, real_gap_loc); 450 SET_BYTE_BUF_GPT (buf, real_gap_loc);
451 SET_GAP_SENTINEL (buf); 451 SET_GAP_SENTINEL (buf);
452 452
453 /* We changed the total size of the buffer (including gap), 453 /* We changed the total size of the buffer (including gap),
454 so we need to fix up the end sentinel. */ 454 so we need to fix up the end sentinel. */
455 SET_END_SENTINEL (buf); 455 SET_END_SENTINEL (buf);
468 Bytebpos real_gap_loc; 468 Bytebpos real_gap_loc;
469 Bytecount old_gap_size; 469 Bytecount old_gap_size;
470 470
471 /* If we have to get more space, get enough to last a while. We use 471 /* If we have to get more space, get enough to last a while. We use
472 a geometric progression that saves on realloc space. */ 472 a geometric progression that saves on realloc space. */
473 increment += 2000 + ((BI_BUF_Z (buf) - BI_BUF_BEG (buf)) / 8); 473 increment += 2000 + ((BYTE_BUF_Z (buf) - BYTE_BUF_BEG (buf)) / 8);
474 /* Make sure the gap is always aligned properly in case we're using a
475 16-bit or 32-bit fixed-width format. (Other sizes should already be
476 aligned in such a case.) */
477 increment = MAX_ALIGN_SIZE (increment);
474 478
475 if (increment > BUF_END_GAP_SIZE (buf)) 479 if (increment > BUF_END_GAP_SIZE (buf))
476 { 480 {
477 /* Don't allow a buffer size that won't fit in an int 481 /* Don't allow a buffer size that won't fit in an int
478 even if it will fit in a Lisp integer. 482 even if it will fit in a Lisp integer.
481 if (BUF_Z (buf) - BUF_BEG (buf) + BUF_GAP_SIZE (buf) + increment 485 if (BUF_Z (buf) - BUF_BEG (buf) + BUF_GAP_SIZE (buf) + increment
482 > EMACS_INT_MAX) 486 > EMACS_INT_MAX)
483 out_of_memory ("Maximum buffer size exceeded", Qunbound); 487 out_of_memory ("Maximum buffer size exceeded", Qunbound);
484 488
485 result = BUFFER_REALLOC (buf->text->beg, 489 result = BUFFER_REALLOC (buf->text->beg,
486 BI_BUF_Z (buf) - BI_BUF_BEG (buf) + 490 BYTE_BUF_Z (buf) - BYTE_BUF_BEG (buf) +
487 BUF_GAP_SIZE (buf) + increment + 491 BUF_GAP_SIZE (buf) + increment +
488 BUF_END_SENTINEL_SIZE); 492 BUF_END_SENTINEL_SIZE);
489 if (result == 0) 493 if (result == 0)
490 memory_full (); 494 memory_full ();
491 495
496 500
497 /* Prevent quitting in move_gap. */ 501 /* Prevent quitting in move_gap. */
498 tem = Vinhibit_quit; 502 tem = Vinhibit_quit;
499 Vinhibit_quit = Qt; 503 Vinhibit_quit = Qt;
500 504
501 real_gap_loc = BI_BUF_GPT (buf); 505 real_gap_loc = BYTE_BUF_GPT (buf);
502 old_gap_size = BUF_GAP_SIZE (buf); 506 old_gap_size = BUF_GAP_SIZE (buf);
503 507
504 /* Call the newly allocated space a gap at the end of the whole space. */ 508 /* Call the newly allocated space a gap at the end of the whole space. */
505 SET_BI_BUF_GPT (buf, BI_BUF_Z (buf) + BUF_GAP_SIZE (buf)); 509 SET_BYTE_BUF_GPT (buf, BYTE_BUF_Z (buf) + BUF_GAP_SIZE (buf));
506 SET_BUF_GAP_SIZE (buf, increment); 510 SET_BUF_GAP_SIZE (buf, increment);
507 511
508 SET_BUF_END_GAP_SIZE (buf, 0); 512 SET_BUF_END_GAP_SIZE (buf, 0);
509 513
510 /* Move the new gap down to be consecutive with the end of the old one. 514 /* Move the new gap down to be consecutive with the end of the old one.
511 This adjusts the markers properly too. */ 515 This adjusts the markers properly too. */
512 gap_left (buf, real_gap_loc + old_gap_size); 516 gap_left (buf, real_gap_loc + old_gap_size);
513 517
514 /* Now combine the two into one large gap. */ 518 /* Now combine the two into one large gap. */
515 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + old_gap_size); 519 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + old_gap_size);
516 SET_BI_BUF_GPT (buf, real_gap_loc); 520 SET_BYTE_BUF_GPT (buf, real_gap_loc);
517 SET_GAP_SENTINEL (buf); 521 SET_GAP_SENTINEL (buf);
518 522
519 /* We changed the total size of the buffer (including gap), 523 /* We changed the total size of the buffer (including gap),
520 so we need to fix up the end sentinel. */ 524 so we need to fix up the end sentinel. */
521 SET_END_SENTINEL (buf); 525 SET_END_SENTINEL (buf);
809 if (end < BUF_BEGV (buf)) end = BUF_BEGV (buf); 813 if (end < BUF_BEGV (buf)) end = BUF_BEGV (buf);
810 if (end > BUF_ZV (buf)) end = BUF_ZV (buf); 814 if (end > BUF_ZV (buf)) end = BUF_ZV (buf);
811 815
812 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 816 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
813 { 817 {
814 buffer = wrap_buffer (mbuf); 818 report_extent_modification (wrap_buffer (mbuf), start, end, 0);
815 report_extent_modification (buffer, start, end, 0);
816 } 819 }
817 unbind_to (speccount); 820 unbind_to (speccount);
818 821
819 /* Only now do we indicate that the before-change-functions have 822 /* Only now do we indicate that the before-change-functions have
820 been called, in case some function throws out. */ 823 been called, in case some function throws out. */
839 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 842 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
840 { 843 {
841 /* always do this. */ 844 /* always do this. */
842 buffer_signal_changed_region (mbuf, start, new_end); 845 buffer_signal_changed_region (mbuf, start, new_end);
843 } 846 }
847 #ifdef USE_C_FONT_LOCK
844 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 848 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
845 { 849 {
846 /* #### This seems inefficient. Wouldn't it be better to just 850 /* #### This seems inefficient. Wouldn't it be better to just
847 keep one cache per base buffer? */ 851 keep one cache per base buffer? */
848 font_lock_maybe_update_syntactic_caches (mbuf, start, orig_end, new_end); 852 font_lock_maybe_update_syntactic_caches (mbuf, start, orig_end, new_end);
849 } 853 }
854 #endif /* USE_C_FONT_LOCK */
850 855
851 if (!inside_change_hook) 856 if (!inside_change_hook)
852 { 857 {
853 Lisp_Object buffer; 858 Lisp_Object buffer;
854 int speccount; 859 int speccount;
1028 Bytecount offset, Bytecount length, 1033 Bytecount offset, Bytecount length,
1029 int flags) 1034 int flags)
1030 { 1035 {
1031 /* This function can GC */ 1036 /* This function can GC */
1032 struct gcpro gcpro1; 1037 struct gcpro gcpro1;
1033 Bytebpos ind; 1038 Bytebpos bytepos;
1039 Bytecount length_in_buffer;
1034 Charcount cclen; 1040 Charcount cclen;
1035 int move_point = 0; 1041 int move_point = 0;
1036 struct buffer *mbuf; 1042 struct buffer *mbuf;
1037 Lisp_Object bufcons; 1043 Lisp_Object bufcons;
1038 1044
1078 if (pos < BUF_BEGV (buf)) 1084 if (pos < BUF_BEGV (buf))
1079 pos = BUF_BEGV (buf); 1085 pos = BUF_BEGV (buf);
1080 if (pos > BUF_ZV (buf)) 1086 if (pos > BUF_ZV (buf))
1081 pos = BUF_ZV (buf); 1087 pos = BUF_ZV (buf);
1082 1088
1083 ind = charbpos_to_bytebpos (buf, pos); 1089 bytepos = charbpos_to_bytebpos (buf, pos);
1084 1090
1085 /* string may have been relocated up to this point */ 1091 /* string may have been relocated up to this point */
1086 if (STRINGP (reloc)) 1092 if (STRINGP (reloc))
1087 { 1093 {
1088 cclen = string_offset_byte_to_char_len (reloc, offset, length); 1094 cclen = string_offset_byte_to_char_len (reloc, offset, length);
1089 nonreloc = XSTRING_DATA (reloc); 1095 nonreloc = XSTRING_DATA (reloc);
1090 } 1096 }
1091 else 1097 else
1092 cclen = bytecount_to_charcount (nonreloc + offset, length); 1098 cclen = bytecount_to_charcount (nonreloc + offset, length);
1093 1099 /* &&#### Here we check if the text can't fit into the format of the buffer,
1094 if (ind != BI_BUF_GPT (buf)) 1100 and if so convert it to another format (either default or 32-bit-fixed,
1101 according to some flag; if no flag, use default). */
1102
1103 length_in_buffer = copy_text_between_formats (nonreloc + offset, length,
1104 FORMAT_DEFAULT,
1105 STRINGP (reloc) ? reloc : Qnil,
1106 NULL, 0,
1107 BUF_FORMAT (buf),
1108 wrap_buffer (buf),
1109 NULL);
1110
1111 if (bytepos != BYTE_BUF_GPT (buf))
1095 /* #### if debug-on-quit is invoked and the user changes the 1112 /* #### if debug-on-quit is invoked and the user changes the
1096 buffer, bad things can happen. This is a rampant problem 1113 buffer, bad things can happen. This is a rampant problem
1097 in Emacs. */ 1114 in Emacs. */
1098 move_gap (buf, ind); /* may QUIT */ 1115 move_gap (buf, bytepos); /* may QUIT */
1099 if (! GAP_CAN_HOLD_SIZE_P (buf, length)) 1116 if (! GAP_CAN_HOLD_SIZE_P (buf, length_in_buffer))
1100 { 1117 {
1101 if (BUF_END_GAP_SIZE (buf) >= length) 1118 if (BUF_END_GAP_SIZE (buf) >= length_in_buffer)
1102 merge_gap_with_end_gap (buf); 1119 merge_gap_with_end_gap (buf);
1103 else 1120 else
1104 make_gap (buf, length - BUF_GAP_SIZE (buf)); 1121 make_gap (buf, length_in_buffer - BUF_GAP_SIZE (buf));
1105 } 1122 }
1106 1123
1124 /* At this point, no more QUITting or processing of Lisp code. Buffer is
1125 in a consistent state. Following code puts buffer in an inconsistent
1126 state and can be considered a "critical section". */
1127
1107 insert_invalidate_line_number_cache (buf, pos, nonreloc + offset, length); 1128 insert_invalidate_line_number_cache (buf, pos, nonreloc + offset, length);
1108 1129
1109 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 1130 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1110 { 1131 {
1111 record_insert (mbuf, pos, cclen); 1132 record_insert (mbuf, pos, cclen);
1112 } 1133 }
1113 1134
1114 BUF_MODIFF (buf)++; 1135 BUF_MODIFF (buf)++;
1115 MARK_BUFFERS_CHANGED; 1136 MARK_BUFFERS_CHANGED;
1116 1137
1117 /* string may have been relocated up to this point */ 1138 /* string may have been relocated up to this point #### if string is
1139 modified during quit processing, bad things can happen. */
1118 if (STRINGP (reloc)) 1140 if (STRINGP (reloc))
1119 nonreloc = XSTRING_DATA (reloc); 1141 nonreloc = XSTRING_DATA (reloc);
1120 1142
1121 memcpy (BUF_GPT_ADDR (buf), nonreloc + offset, length); 1143 copy_text_between_formats (nonreloc + offset, length, FORMAT_DEFAULT,
1122 1144 STRINGP (reloc) ? reloc : Qnil,
1123 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) - length); 1145 BUF_GPT_ADDR (buf), length_in_buffer,
1124 SET_BI_BUF_GPT (buf, BI_BUF_GPT (buf) + length); 1146 BUF_FORMAT (buf), wrap_buffer (buf), NULL);
1125 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 1147
1126 { 1148 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) - length_in_buffer);
1127 SET_BOTH_BUF_ZV (mbuf, BUF_ZV (mbuf) + cclen, BI_BUF_ZV (mbuf) + length); 1149 SET_BYTE_BUF_GPT (buf, BYTE_BUF_GPT (buf) + length_in_buffer);
1128 } 1150 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1129 SET_BOTH_BUF_Z (buf, BUF_Z (buf) + cclen, BI_BUF_Z (buf) + length); 1151 {
1152 SET_BOTH_BUF_ZV (mbuf, BUF_ZV (mbuf) + cclen,
1153 BYTE_BUF_ZV (mbuf) + length_in_buffer);
1154 }
1155 SET_BOTH_BUF_Z (buf, BUF_Z (buf) + cclen, BYTE_BUF_Z (buf) + length_in_buffer);
1130 SET_GAP_SENTINEL (buf); 1156 SET_GAP_SENTINEL (buf);
1131 1157
1132 1158
1133 #ifdef MULE 1159 #ifdef MULE
1134 buffer_mule_signal_inserted_region (buf, pos, length, cclen); 1160 buffer_mule_signal_inserted_region (buf, pos, length_in_buffer, cclen);
1161 /* Update our count of ASCII, 8-bit and 16-bit chars and the
1162 entirely-one-byte flag */
1163 {
1164 const Intbyte *ptr = nonreloc + offset;
1165 const Intbyte *ptrend = ptr + length;
1166
1167 while (ptr < ptrend)
1168 {
1169 Emchar ch = charptr_emchar (ptr);
1170 if (emchar_ascii_p (ch))
1171 buf->text->num_ascii_chars++;
1172 if (emchar_8_bit_fixed_p (ch, wrap_buffer (buf)))
1173 buf->text->num_8_bit_fixed_chars++;
1174 if (emchar_16_bit_fixed_p (ch, wrap_buffer (buf)))
1175 buf->text->num_16_bit_fixed_chars++;
1176 INC_CHARPTR (ptr);
1177 }
1178
1179 buf->text->entirely_one_byte_p =
1180 (BUF_FORMAT (buf) == FORMAT_8_BIT_FIXED ||
1181 (BUF_FORMAT (buf) == FORMAT_DEFAULT && BUF_Z (buf) == BYTE_BUF_Z (buf)));
1182 }
1135 #endif 1183 #endif
1136 1184
1137 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 1185 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1138 { 1186 {
1139 process_extents_for_insertion (wrap_buffer (mbuf), ind, length); 1187 process_extents_for_insertion (wrap_buffer (mbuf), bytepos,
1140 } 1188 length_in_buffer);
1141 1189 }
1142 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 1190
1143 { 1191 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1144 /* We know the gap is at IND so the cast is OK. */ 1192 {
1145 adjust_markers_for_insert (mbuf, (Membpos) ind, length); 1193 /* We know the gap is at BYTEPOS so the cast is OK. */
1194 adjust_markers_for_insert (mbuf, (Membpos) bytepos, length_in_buffer);
1146 } 1195 }
1147 1196
1148 /* Point logically doesn't move, but may need to be adjusted because 1197 /* Point logically doesn't move, but may need to be adjusted because
1149 it's a byte index. point-marker doesn't change because it's a 1198 it's a byte index. point-marker doesn't change because it's a
1150 memory index. */ 1199 memory index. */
1151 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 1200 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1152 { 1201 {
1153 if (BI_BUF_PT (mbuf) > ind) 1202 if (BYTE_BUF_PT (mbuf) > bytepos)
1154 JUST_SET_POINT (mbuf, BUF_PT (mbuf) + cclen, 1203 JUST_SET_POINT (mbuf, BUF_PT (mbuf) + cclen,
1155 BI_BUF_PT (mbuf) + length); 1204 BYTE_BUF_PT (mbuf) + length_in_buffer);
1156 } 1205 }
1157 1206
1158 /* Well, point might move. */ 1207 /* Well, point might move. */
1159 if (move_point) 1208 if (move_point)
1160 BI_BUF_SET_PT (buf, ind + length); 1209 BYTE_BUF_SET_PT (buf, bytepos + length_in_buffer);
1161 1210
1162 if (STRINGP (reloc)) 1211 if (STRINGP (reloc))
1163 { 1212 {
1164 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 1213 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1165 { 1214 {
1166 splice_in_string_extents (reloc, mbuf, ind, length, offset); 1215 splice_in_string_extents (reloc, mbuf, bytepos, length, offset);
1167 } 1216 }
1168 } 1217 }
1169 1218
1170 if (flags & INSDEL_BEFORE_MARKERS) 1219 if (flags & INSDEL_BEFORE_MARKERS)
1171 { 1220 {
1172 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 1221 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1173 { 1222 {
1174 /* ind - 1 is correct because the FROM argument is exclusive. 1223 /* bytepos - 1 is correct because the FROM argument is exclusive.
1175 I formerly used DEC_BYTEBPOS() but that caused problems at the 1224 I formerly used DEC_BYTEBPOS() but that caused problems at the
1176 beginning of the buffer. */ 1225 beginning of the buffer. */
1177 adjust_markers (mbuf, ind - 1, ind, length); 1226 adjust_markers (mbuf, bytepos - 1, bytepos, length_in_buffer);
1178 } 1227 }
1228 }
1229
1230 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1231 {
1232 signal_syntax_table_extent_adjust (mbuf);
1179 } 1233 }
1180 1234
1181 signal_after_change (buf, pos, pos, pos + cclen); 1235 signal_after_change (buf, pos, pos, pos + cclen);
1182 1236
1183 UNGCPRO; 1237 UNGCPRO;
1264 void 1318 void
1265 buffer_delete_range (struct buffer *buf, Charbpos from, Charbpos to, int flags) 1319 buffer_delete_range (struct buffer *buf, Charbpos from, Charbpos to, int flags)
1266 { 1320 {
1267 /* This function can GC */ 1321 /* This function can GC */
1268 Charcount numdel; 1322 Charcount numdel;
1269 Bytebpos bi_from, bi_to; 1323 Bytebpos byte_from, byte_to;
1270 Bytecount bc_numdel; 1324 Bytecount byte_numdel;
1271 EMACS_INT shortage; 1325 EMACS_INT shortage;
1272 struct buffer *mbuf; 1326 struct buffer *mbuf;
1273 Lisp_Object bufcons; 1327 Lisp_Object bufcons;
1328 int do_move_gap = 0;
1274 1329
1275 /* Defensive steps just in case a buffer gets deleted and a calling 1330 /* Defensive steps just in case a buffer gets deleted and a calling
1276 function doesn't notice it. */ 1331 function doesn't notice it. */
1277 if (!BUFFER_LIVE_P (buf)) 1332 if (!BUFFER_LIVE_P (buf))
1278 return; 1333 return;
1299 if (to > BUF_ZV (buf)) 1354 if (to > BUF_ZV (buf))
1300 to = BUF_ZV (buf); 1355 to = BUF_ZV (buf);
1301 if ((numdel = to - from) <= 0) 1356 if ((numdel = to - from) <= 0)
1302 return; 1357 return;
1303 1358
1359 byte_from = charbpos_to_bytebpos (buf, from);
1360 byte_to = charbpos_to_bytebpos (buf, to);
1361 byte_numdel = byte_to - byte_from;
1362
1363 if (to == BUF_Z (buf) &&
1364 byte_from > BYTE_BUF_GPT (buf))
1365 /* avoid moving the gap just to delete from the bottom. */
1366 do_move_gap = 0;
1367 else
1368 {
1369 /* Make sure the gap is somewhere in or next to what we are deleting. */
1370 /* NOTE: Can QUIT! */
1371 if (byte_to < BYTE_BUF_GPT (buf))
1372 gap_left (buf, byte_to);
1373 if (byte_from > BYTE_BUF_GPT (buf))
1374 gap_right (buf, byte_from);
1375 do_move_gap = 1;
1376 }
1377
1378 /* At this point, no more QUITting or processing of Lisp code. Buffer is
1379 in a consistent state. Following code puts buffer in an inconsistent
1380 state and can be considered a "critical section". */
1381
1382 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1383 {
1384 record_delete (mbuf, from, numdel);
1385 }
1386 BUF_MODIFF (buf)++;
1387 MARK_BUFFERS_CHANGED;
1388
1389 /* We used to do the following before the gap move. But that might QUIT,
1390 and (as a result of this) the gap code always leaves the buffer in
1391 a consistent state. Therefore, it's totally safe to do these operations
1392 now, and just as well not before, as we're making state changes
1393 related to the deletion. */
1394
1304 /* Redisplay needs to know if a newline was in the deleted region. 1395 /* Redisplay needs to know if a newline was in the deleted region.
1305 If we've already marked the changed region as having a deleted 1396 If we've already marked the changed region as having a deleted
1306 newline there is no use in performing the check. */ 1397 newline there is no use in performing the check. */
1307 if (!buf->changes->newline_was_deleted) 1398 if (!buf->changes->newline_was_deleted)
1308 { 1399 {
1314 mbuf->changes->newline_was_deleted = 1; 1405 mbuf->changes->newline_was_deleted = 1;
1315 } 1406 }
1316 } 1407 }
1317 } 1408 }
1318 1409
1319 bi_from = charbpos_to_bytebpos (buf, from);
1320 bi_to = charbpos_to_bytebpos (buf, to);
1321 bc_numdel = bi_to - bi_from;
1322
1323 delete_invalidate_line_number_cache (buf, from, to); 1410 delete_invalidate_line_number_cache (buf, from, to);
1324 1411
1325 if (to == BUF_Z (buf) && 1412 #ifdef MULE
1326 bi_from > BI_BUF_GPT (buf)) 1413 /* Update our count of ASCII, 8-bit and 16-bit chars and the
1327 { 1414 entirely-one-byte flag */
1328 /* avoid moving the gap just to delete from the bottom. */ 1415 {
1329 1416 Bytebpos i;
1330 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 1417
1331 { 1418 for (i = byte_from; i < byte_to; i = next_bytebpos (buf, i))
1332 record_delete (mbuf, from, numdel); 1419 {
1333 } 1420 Emchar ch = BYTE_BUF_FETCH_CHAR (buf, i);
1334 BUF_MODIFF (buf)++; 1421 if (emchar_ascii_p (ch))
1335 MARK_BUFFERS_CHANGED; 1422 buf->text->num_ascii_chars--;
1336 1423 if (emchar_8_bit_fixed_p (ch, wrap_buffer (buf)))
1337 /* #### Point used to be modified here, but this causes problems 1424 buf->text->num_8_bit_fixed_chars--;
1338 with MULE, as point is used to calculate bytebposs, and if the 1425 if (emchar_16_bit_fixed_p (ch, wrap_buffer (buf)))
1339 offset in bc_numdel causes point to move to a non first-byte 1426 buf->text->num_16_bit_fixed_chars--;
1340 location, causing some other function to throw an assertion 1427 }
1341 in ASSERT_VALID_BYTEBPOS. I've moved the code to right after 1428 }
1342 the other movements and adjustments, but before the gap is 1429 #endif /* MULE */
1343 moved. -- jh 970813 */ 1430
1344 1431 /* #### Point used to be modified here, but this causes problems
1345 /* Detach any extents that are completely within the range [FROM, TO], 1432 with MULE, as point is used to calculate bytebpos's, and if the
1346 if the extents are detachable. 1433 offset in byte_numdel causes point to move to a non first-byte
1347 1434 location, causing some other function to throw an assertion
1348 This must come AFTER record_delete(), so that the appropriate 1435 in ASSERT_VALID_BYTEBPOS. I've moved the code to right after
1349 extents will be present to be recorded, and BEFORE the gap 1436 the other movements and adjustments, but before the gap is
1350 size is increased, as otherwise we will be confused about 1437 moved. -- jh 970813 */
1351 where the extents end. */ 1438
1352 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 1439 /* Detach any extents that are completely within the range [FROM, TO],
1353 { 1440 if the extents are detachable.
1354 process_extents_for_deletion (wrap_buffer (mbuf), bi_from, bi_to, 0); 1441
1355 } 1442 This must come AFTER record_delete(), so that the appropriate extents
1356 1443 will be present to be recorded, and BEFORE the gap size is increased,
1357 /* Relocate all markers pointing into the new, larger gap to 1444 as otherwise we will be confused about where the extents end. */
1358 point at the end of the text before the gap. */ 1445 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1359 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 1446 {
1360 { 1447 process_extents_for_deletion (wrap_buffer (mbuf), byte_from, byte_to, 0);
1361 adjust_markers (mbuf, 1448 }
1362 (bi_to + BUF_GAP_SIZE (mbuf)), 1449
1363 (bi_to + BUF_GAP_SIZE (mbuf)), 1450 /* Relocate all markers pointing into the new, larger gap to
1364 (- bc_numdel)); 1451 point at the end of the text before the gap. */
1365 } 1452 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1366 1453 {
1367 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 1454 adjust_markers (mbuf,
1368 { 1455 (byte_to + BUF_GAP_SIZE (mbuf)),
1369 /* Relocate any extent endpoints just like markers. */ 1456 (byte_to + BUF_GAP_SIZE (mbuf)),
1370 adjust_extents_for_deletion (wrap_buffer (mbuf), bi_from, bi_to, 1457 (- byte_numdel -
1371 BUF_GAP_SIZE (mbuf), bc_numdel, 0); 1458 (do_move_gap ? BUF_GAP_SIZE (mbuf) : 0)));
1372 } 1459 }
1373 1460
1374 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 1461 /* Relocate any extent endpoints just like markers. */
1375 { 1462 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1376 /* Relocate point as if it were a marker. */ 1463 {
1377 if (bi_from < BI_BUF_PT (mbuf)) 1464 adjust_extents_for_deletion (wrap_buffer (mbuf), byte_from, byte_to,
1378 { 1465 BUF_GAP_SIZE (mbuf),
1379 if (BI_BUF_PT (mbuf) < bi_to) 1466 byte_numdel,
1380 JUST_SET_POINT (mbuf, from, bi_from); 1467 do_move_gap ? BUF_GAP_SIZE (mbuf) : 0);
1381 else 1468 }
1382 JUST_SET_POINT (mbuf, BUF_PT (mbuf) - numdel, 1469
1383 BI_BUF_PT (mbuf) - bc_numdel); 1470 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1384 } 1471 {
1385 } 1472 /* Relocate point as if it were a marker. */
1386 1473 if (byte_from < BYTE_BUF_PT (mbuf))
1387 SET_BUF_END_GAP_SIZE (buf, BUF_END_GAP_SIZE (buf) + bc_numdel); 1474 {
1388 1475 if (BYTE_BUF_PT (mbuf) < byte_to)
1389 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 1476 JUST_SET_POINT (mbuf, from, byte_from);
1390 { 1477 else
1391 SET_BOTH_BUF_ZV (mbuf, BUF_ZV (mbuf) - numdel, 1478 JUST_SET_POINT (mbuf, BUF_PT (mbuf) - numdel,
1392 BI_BUF_ZV (mbuf) - bc_numdel); 1479 BYTE_BUF_PT (mbuf) - byte_numdel);
1393 } 1480 }
1394 SET_BOTH_BUF_Z (buf, BUF_Z (buf) - numdel, BI_BUF_Z (buf) - bc_numdel); 1481 }
1395 SET_GAP_SENTINEL (buf); 1482
1396 } 1483 if (do_move_gap)
1484 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + byte_numdel);
1397 else 1485 else
1398 { 1486 SET_BUF_END_GAP_SIZE (buf, BUF_END_GAP_SIZE (buf) + byte_numdel);
1399 /* Make sure the gap is somewhere in or next to what we are deleting. */ 1487 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1400 if (bi_to < BI_BUF_GPT (buf)) 1488 {
1401 gap_left (buf, bi_to); 1489 SET_BOTH_BUF_ZV (mbuf, BUF_ZV (mbuf) - numdel,
1402 if (bi_from > BI_BUF_GPT (buf)) 1490 BYTE_BUF_ZV (mbuf) - byte_numdel);
1403 gap_right (buf, bi_from); 1491 }
1404 1492 SET_BOTH_BUF_Z (buf, BUF_Z (buf) - numdel, BYTE_BUF_Z (buf) - byte_numdel);
1405 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 1493 if (do_move_gap)
1406 { 1494 SET_BYTE_BUF_GPT (buf, byte_from);
1407 record_delete (mbuf, from, numdel); 1495 SET_GAP_SENTINEL (buf);
1408 }
1409 BUF_MODIFF (buf)++;
1410 MARK_BUFFERS_CHANGED;
1411
1412 /* #### Point used to be modified here, but this causes problems
1413 with MULE, as point is used to calculate bytebposs, and if the
1414 offset in bc_numdel causes point to move to a non first-byte
1415 location, causing some other function to throw an assertion
1416 in ASSERT_VALID_BYTEBPOS. I've moved the code to right after
1417 the other movements and adjustments, but before the gap is
1418 moved. -- jh 970813 */
1419
1420 /* Detach any extents that are completely within the range [FROM, TO],
1421 if the extents are detachable.
1422
1423 This must come AFTER record_delete(), so that the appropriate extents
1424 will be present to be recorded, and BEFORE the gap size is increased,
1425 as otherwise we will be confused about where the extents end. */
1426 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1427 {
1428 process_extents_for_deletion (wrap_buffer (mbuf), bi_from, bi_to, 0);
1429 }
1430
1431 /* Relocate all markers pointing into the new, larger gap to
1432 point at the end of the text before the gap. */
1433 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1434 {
1435 adjust_markers (mbuf,
1436 (bi_to + BUF_GAP_SIZE (mbuf)),
1437 (bi_to + BUF_GAP_SIZE (mbuf)),
1438 (- bc_numdel - BUF_GAP_SIZE (mbuf)));
1439 }
1440
1441 /* Relocate any extent endpoints just like markers. */
1442 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1443 {
1444 adjust_extents_for_deletion (wrap_buffer (mbuf), bi_from, bi_to,
1445 BUF_GAP_SIZE (mbuf),
1446 bc_numdel, BUF_GAP_SIZE (mbuf));
1447 }
1448
1449 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1450 {
1451 /* Relocate point as if it were a marker. */
1452 if (bi_from < BI_BUF_PT (mbuf))
1453 {
1454 if (BI_BUF_PT (mbuf) < bi_to)
1455 JUST_SET_POINT (mbuf, from, bi_from);
1456 else
1457 JUST_SET_POINT (mbuf, BUF_PT (mbuf) - numdel,
1458 BI_BUF_PT (mbuf) - bc_numdel);
1459 }
1460 }
1461
1462 SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + bc_numdel);
1463 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1464 {
1465 SET_BOTH_BUF_ZV (mbuf, BUF_ZV (mbuf) - numdel,
1466 BI_BUF_ZV (mbuf) - bc_numdel);
1467 }
1468 SET_BOTH_BUF_Z (buf, BUF_Z (buf) - numdel, BI_BUF_Z (buf) - bc_numdel);
1469 SET_BI_BUF_GPT (buf, bi_from);
1470 SET_GAP_SENTINEL (buf);
1471 }
1472 1496
1473 #ifdef MULE 1497 #ifdef MULE
1474 buffer_mule_signal_deleted_region (buf, from, to, bi_from, bi_to); 1498 buffer_mule_signal_deleted_region (buf, from, to, byte_from, byte_to);
1499 buf->text->entirely_one_byte_p =
1500 (BUF_FORMAT (buf) == FORMAT_8_BIT_FIXED ||
1501 (BUF_FORMAT (buf) == FORMAT_DEFAULT && BUF_Z (buf) == BYTE_BUF_Z (buf)));
1475 #endif 1502 #endif
1476 1503
1477 #ifdef ERROR_CHECK_EXTENTS 1504 #ifdef ERROR_CHECK_EXTENTS
1478 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 1505 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1479 { 1506 {
1480 sledgehammer_extent_check (wrap_buffer (mbuf)); 1507 sledgehammer_extent_check (wrap_buffer (mbuf));
1481 } 1508 }
1482 #endif 1509 #endif
1483 1510
1511 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
1512 {
1513 signal_syntax_table_extent_adjust (mbuf);
1514 }
1515
1516 /* &&#### Here we consider converting the buffer from default to
1517 8-bit-fixed if is entirely 8-bit-fixed chars and has been that way for
1518 a long time, e.g. 20 minutes. And if the buffer just switched to all
1519 8-bit-fixed chars, start the timer. */
1484 signal_after_change (buf, from, to, from); 1520 signal_after_change (buf, from, to, from);
1485 } 1521 }
1486 1522
1487 1523
1488 /************************************************************************/ 1524 /************************************************************************/
1494 void 1530 void
1495 buffer_replace_char (struct buffer *buf, Charbpos pos, Emchar ch, 1531 buffer_replace_char (struct buffer *buf, Charbpos pos, Emchar ch,
1496 int not_real_change, int force_lock_check) 1532 int not_real_change, int force_lock_check)
1497 { 1533 {
1498 /* This function can GC */ 1534 /* This function can GC */
1499 Intbyte curstr[MAX_EMCHAR_LEN];
1500 Intbyte newstr[MAX_EMCHAR_LEN]; 1535 Intbyte newstr[MAX_EMCHAR_LEN];
1501 Bytecount curlen, newlen; 1536 Bytecount newlen;
1537 Emchar oldch;
1502 1538
1503 /* Defensive steps just in case a buffer gets deleted and a calling 1539 /* Defensive steps just in case a buffer gets deleted and a calling
1504 function doesn't notice it. */ 1540 function doesn't notice it. */
1505 if (!BUFFER_LIVE_P (buf)) 1541 if (!BUFFER_LIVE_P (buf))
1506 return; 1542 return;
1507 1543
1508 curlen = BUF_CHARPTR_COPY_CHAR (buf, pos, curstr); 1544 newlen = set_charptr_emchar_fmt (newstr, ch, BUF_FORMAT (buf),
1509 newlen = set_charptr_emchar (newstr, ch); 1545 wrap_buffer (buf));
1510 1546 oldch = BUF_FETCH_CHAR (buf, pos);
1511 if (curlen == newlen) 1547 if (emchar_fits_in_format (ch, BUF_FORMAT (buf), wrap_buffer (buf)) &&
1548 newlen == emchar_len_fmt (oldch, BUF_FORMAT (buf)))
1512 { 1549 {
1513 struct buffer *mbuf; 1550 struct buffer *mbuf;
1514 Lisp_Object bufcons; 1551 Lisp_Object bufcons;
1515 1552
1516 /* then we can just replace the text. */ 1553 /* then we can just replace the text. */
1545 { 1582 {
1546 record_change (mbuf, pos, 1); 1583 record_change (mbuf, pos, 1);
1547 } 1584 }
1548 BUF_MODIFF (buf)++; 1585 BUF_MODIFF (buf)++;
1549 } 1586 }
1587
1588 #ifdef MULE
1589 if (emchar_ascii_p (oldch))
1590 buf->text->num_ascii_chars--;
1591 if (emchar_8_bit_fixed_p (oldch, wrap_buffer (buf)))
1592 buf->text->num_8_bit_fixed_chars--;
1593 if (emchar_16_bit_fixed_p (oldch, wrap_buffer (buf)))
1594 buf->text->num_16_bit_fixed_chars--;
1595 if (emchar_ascii_p (ch))
1596 buf->text->num_ascii_chars++;
1597 if (emchar_8_bit_fixed_p (ch, wrap_buffer (buf)))
1598 buf->text->num_8_bit_fixed_chars++;
1599 if (emchar_16_bit_fixed_p (ch, wrap_buffer (buf)))
1600 buf->text->num_16_bit_fixed_chars++;
1601 #endif /* MULE */
1602
1550 memcpy (BUF_BYTE_ADDRESS (buf, pos), newstr, newlen); 1603 memcpy (BUF_BYTE_ADDRESS (buf, pos), newstr, newlen);
1551 1604
1552 signal_after_change (buf, pos, pos + 1, pos + 1); 1605 signal_after_change (buf, pos, pos + 1, pos + 1);
1553 1606
1554 /* We do not have to adjust the Mule data; we just replaced a 1607 /* We do not have to adjust the Mule data; we just replaced a
1602 static Lisp_Object 1655 static Lisp_Object
1603 make_string_from_buffer_1 (struct buffer *buf, Charbpos pos, Charcount length, 1656 make_string_from_buffer_1 (struct buffer *buf, Charbpos pos, Charcount length,
1604 int no_extents) 1657 int no_extents)
1605 { 1658 {
1606 /* This function can GC */ 1659 /* This function can GC */
1607 Bytebpos bi_ind = charbpos_to_bytebpos (buf, pos); 1660 Bytebpos bytepos = charbpos_to_bytebpos (buf, pos);
1608 Bytecount bi_len = charbpos_to_bytebpos (buf, pos + length) - bi_ind; 1661 Bytecount bytelen = charbpos_to_bytebpos (buf, pos + length) - bytepos;
1609 Lisp_Object val = make_uninit_string (bi_len); 1662 Bytecount needed = copy_buffer_text_out (buf, bytepos, bytelen, NULL, 0,
1663 FORMAT_DEFAULT, Qnil, NULL);
1664 Lisp_Object val = make_uninit_string (needed);
1610 1665
1611 struct gcpro gcpro1; 1666 struct gcpro gcpro1;
1612 GCPRO1 (val); 1667 GCPRO1 (val);
1613 1668
1614 if (!no_extents) 1669 if (!no_extents)
1615 add_string_extents (val, buf, bi_ind, bi_len); 1670 add_string_extents (val, buf, bytepos, bytelen);
1616 1671 copy_buffer_text_out (buf, bytepos, bytelen, XSTRING_DATA (val), needed,
1617 { 1672 FORMAT_DEFAULT, Qnil, NULL);
1618 Bytecount len1 = BI_BUF_GPT (buf) - bi_ind;
1619 Intbyte *start1 = BI_BUF_BYTE_ADDRESS (buf, bi_ind);
1620 Intbyte *dest = XSTRING_DATA (val);
1621
1622 if (len1 < 0)
1623 {
1624 /* Completely after gap */
1625 memcpy (dest, start1, bi_len);
1626 }
1627 else if (bi_len <= len1)
1628 {
1629 /* Completely before gap */
1630 memcpy (dest, start1, bi_len);
1631 }
1632 else
1633 {
1634 /* Spans gap */
1635 Bytebpos pos2 = bi_ind + len1;
1636 Intbyte *start2 = BI_BUF_BYTE_ADDRESS (buf, pos2);
1637
1638 memcpy (dest, start1, len1);
1639 memcpy (dest + len1, start2, bi_len - len1);
1640 }
1641 }
1642
1643 init_string_ascii_begin (val); 1673 init_string_ascii_begin (val);
1644 sledgehammer_check_ascii_begin (val); 1674 sledgehammer_check_ascii_begin (val);
1645 1675
1646 UNGCPRO; 1676 UNGCPRO;
1647 return val; 1677 return val;
1715 BUFFER_ALLOC (b->text->beg, BUF_GAP_SIZE (b) + BUF_END_SENTINEL_SIZE); 1745 BUFFER_ALLOC (b->text->beg, BUF_GAP_SIZE (b) + BUF_END_SENTINEL_SIZE);
1716 if (! BUF_BEG_ADDR (b)) 1746 if (! BUF_BEG_ADDR (b))
1717 memory_full (); 1747 memory_full ();
1718 1748
1719 SET_BUF_END_GAP_SIZE (b, 0); 1749 SET_BUF_END_GAP_SIZE (b, 0);
1720 SET_BI_BUF_GPT (b, 1); 1750 SET_BYTE_BUF_GPT (b, 1);
1721 SET_BOTH_BUF_Z (b, 1, 1); 1751 SET_BOTH_BUF_Z (b, 1, 1);
1722 SET_GAP_SENTINEL (b); 1752 SET_GAP_SENTINEL (b);
1723 SET_END_SENTINEL (b); 1753 SET_END_SENTINEL (b);
1724 #ifdef MULE 1754 #ifdef MULE
1725 { 1755 {
1726 int i; 1756 int i;
1727 1757
1728 b->text->mule_bufmin = b->text->mule_bufmax = 1; 1758 b->text->mule_bufmin = b->text->mule_bufmax = 1;
1729 b->text->mule_bytmin = b->text->mule_bytmax = 1; 1759 b->text->mule_bytmin = b->text->mule_bytmax = 1;
1730 b->text->mule_shifter = 0; 1760 b->text->entirely_one_byte_p = 1;
1731 b->text->mule_three_p = 0;
1732 b->text->entirely_ascii_p = 1;
1733 1761
1734 for (i = 0; i < 16; i++) 1762 for (i = 0; i < 16; i++)
1735 { 1763 {
1736 b->text->mule_charbpos_cache[i] = 1; 1764 b->text->mule_charbpos_cache[i] = 1;
1737 b->text->mule_bytebpos_cache[i] = 1; 1765 b->text->mule_bytebpos_cache[i] = 1;
1738 } 1766 }
1739 } 1767 }
1768 /* &&#### Set to FORMAT_8_BIT_FIXED when that code is working */
1769 BUF_FORMAT (b) = FORMAT_DEFAULT;
1740 #endif /* MULE */ 1770 #endif /* MULE */
1741 b->text->line_number_cache = Qnil; 1771 b->text->line_number_cache = Qnil;
1742 1772
1743 BUF_MODIFF (b) = 1; 1773 BUF_MODIFF (b) = 1;
1744 BUF_SAVE_MODIFF (b) = 1; 1774 BUF_SAVE_MODIFF (b) = 1;
1749 1779
1750 b->text->changes = xnew_and_zero (struct buffer_text_change_data); 1780 b->text->changes = xnew_and_zero (struct buffer_text_change_data);
1751 } 1781 }
1752 else 1782 else
1753 { 1783 {
1754 JUST_SET_POINT (b, BUF_PT (b->base_buffer), BI_BUF_PT (b->base_buffer)); 1784 JUST_SET_POINT (b, BUF_PT (b->base_buffer), BYTE_BUF_PT (b->base_buffer));
1755 SET_BOTH_BUF_BEGV (b, BUF_BEGV (b->base_buffer), 1785 SET_BOTH_BUF_BEGV (b, BUF_BEGV (b->base_buffer),
1756 BI_BUF_BEGV (b->base_buffer)); 1786 BYTE_BUF_BEGV (b->base_buffer));
1757 SET_BOTH_BUF_ZV (b, BUF_ZV (b->base_buffer), 1787 SET_BOTH_BUF_ZV (b, BUF_ZV (b->base_buffer),
1758 BI_BUF_ZV (b->base_buffer)); 1788 BYTE_BUF_ZV (b->base_buffer));
1759 } 1789 }
1760 1790
1761 b->changes = xnew_and_zero (struct each_buffer_change_data); 1791 b->changes = xnew_and_zero (struct each_buffer_change_data);
1762 BUF_FACECHANGE (b) = 1; 1792 BUF_FACECHANGE (b) = 1;
1763 1793