From: Stefan Monnier Date: Tue, 2 Jul 2019 20:04:16 +0000 (-0400) Subject: * src/insdel.c (insert_from_gap_1): New fun, extracted from insert_from_gap. X-Git-Tag: emacs-27.0.90~2120 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=dc3093904d74a7c51d452439888c4f36e4274e9f;p=emacs.git * src/insdel.c (insert_from_gap_1): New fun, extracted from insert_from_gap. (insert_from_gap): Use it. * src/lisp.h (insert_from_gap_1): Declare it. * src/json.c (Fjson_insert): * src/fileio.c (Finsert_file_contents): Use it. --- diff --git a/src/fileio.c b/src/fileio.c index 7f4478a9448..fc938ebe1fa 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -4436,17 +4436,7 @@ by calling `format-decode', which see. */) report_file_error ("Read error", orig_filename); /* Make the text read part of the buffer. */ - GAP_SIZE -= inserted; - GPT += inserted; - GPT_BYTE += inserted; - ZV += inserted; - ZV_BYTE += inserted; - Z += inserted; - Z_BYTE += inserted; - - if (GAP_SIZE > 0) - /* Put an anchor to ensure multi-byte form ends at gap. */ - *GPT_ADDR = 0; + insert_from_gap_1 (inserted, inserted, false); notfound: diff --git a/src/insdel.c b/src/insdel.c index 85fffd8fd16..1da8d551c73 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -115,7 +115,7 @@ gap_left (ptrdiff_t charpos, ptrdiff_t bytepos, bool newgap) i = GPT_BYTE; to = GAP_END_ADDR; from = GPT_ADDR; - new_s1 = GPT_BYTE; + new_s1 = GPT_BYTE; /* May point in the middle of multibyte sequences. */ /* Now copy the characters. To move the gap down, copy characters up. */ @@ -133,11 +133,17 @@ gap_left (ptrdiff_t charpos, ptrdiff_t bytepos, bool newgap) make_gap_smaller set inhibit-quit. */ if (QUITP) { + /* FIXME: This can point in the middle of a multibyte character. */ bytepos = new_s1; charpos = BYTE_TO_CHAR (bytepos); break; } /* Move at most 32000 chars before checking again for a quit. */ + /* FIXME: This 32KB chunk size dates back to before 1991. + Maybe we should bump it to reflect the >1000x increase + in memory size and bandwidth since that time. + Is it even worthwhile checking `quit` within this loop? + Especially since make_gap_smaller/larger binds inhibit-quit anyway! */ if (i > 32000) i = 32000; new_s1 -= i; @@ -164,7 +170,7 @@ gap_right (ptrdiff_t charpos, ptrdiff_t bytepos) { register unsigned char *to, *from; register ptrdiff_t i; - ptrdiff_t new_s1; + ptrdiff_t new_s1; /* May point in the middle of multibyte sequences. */ BUF_COMPUTE_UNCHANGED (current_buffer, charpos, GPT); @@ -189,6 +195,7 @@ gap_right (ptrdiff_t charpos, ptrdiff_t bytepos) make_gap_smaller set inhibit-quit. */ if (QUITP) { + /* FIXME: This can point in the middle of a multibyte character. */ bytepos = new_s1; charpos = BYTE_TO_CHAR (bytepos); break; @@ -1070,6 +1077,34 @@ insert_from_string_1 (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, check_markers (); } +/* Insert a sequence of NCHARS chars which occupy NBYTES bytes + starting at GAP_END_ADDR - NBYTES (if text_at_gap_tail) and at + GPT_ADDR (if not text_at_gap_tail). + Contrary to insert_from_gap, this does not invalidate any cache, + nor update any markers, nor record any buffer modification information + of any sort. */ +void +insert_from_gap_1 (ptrdiff_t nchars, ptrdiff_t nbytes, bool text_at_gap_tail) +{ + eassert (NILP (BVAR (current_buffer, enable_multibyte_characters)) + ? nchars == nbytes : nchars <= nbytes); + + GAP_SIZE -= nbytes; + if (! text_at_gap_tail) + { + GPT += nchars; + GPT_BYTE += nbytes; + } + ZV += nchars; + Z += nchars; + ZV_BYTE += nbytes; + Z_BYTE += nbytes; + + /* Put an anchor to ensure multi-byte form ends at gap. */ + if (GAP_SIZE > 0) *(GPT_ADDR) = 0; + eassert (GPT <= GPT_BYTE); +} + /* Insert a sequence of NCHARS chars which occupy NBYTES bytes starting at GAP_END_ADDR - NBYTES (if text_at_gap_tail) and at GPT_ADDR (if not text_at_gap_tail). */ @@ -1090,19 +1125,7 @@ insert_from_gap (ptrdiff_t nchars, ptrdiff_t nbytes, bool text_at_gap_tail) record_insert (GPT, nchars); modiff_incr (&MODIFF); - GAP_SIZE -= nbytes; - if (! text_at_gap_tail) - { - GPT += nchars; - GPT_BYTE += nbytes; - } - ZV += nchars; - Z += nchars; - ZV_BYTE += nbytes; - Z_BYTE += nbytes; - if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ - - eassert (GPT <= GPT_BYTE); + insert_from_gap_1 (nchars, nbytes, text_at_gap_tail); adjust_overlays_for_insert (ins_charpos, nchars); adjust_markers_for_insert (ins_charpos, ins_bytepos, diff --git a/src/json.c b/src/json.c index 4c897d4be04..607b8d32646 100644 --- a/src/json.c +++ b/src/json.c @@ -740,17 +740,7 @@ usage: (json-insert OBJECT &rest ARGS) */) if (inserted_bytes > 0) { /* Make the inserted text part of the buffer, as unibyte text. */ - GAP_SIZE -= inserted_bytes; - GPT += inserted_bytes; - GPT_BYTE += inserted_bytes; - ZV += inserted_bytes; - ZV_BYTE += inserted_bytes; - Z += inserted_bytes; - Z_BYTE += inserted_bytes; - - if (GAP_SIZE > 0) - /* Put an anchor to ensure multi-byte form ends at gap. */ - *GPT_ADDR = 0; + insert_from_gap_1 (inserted_bytes, inserted_bytes, false); /* If required, decode the stuff we've read into the gap. */ struct coding_system coding; diff --git a/src/lisp.h b/src/lisp.h index a0619e64f20..1a1d8ee7e48 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3667,6 +3667,7 @@ extern void insert (const char *, ptrdiff_t); extern void insert_and_inherit (const char *, ptrdiff_t); extern void insert_1_both (const char *, ptrdiff_t, ptrdiff_t, bool, bool, bool); +extern void insert_from_gap_1 (ptrdiff_t, ptrdiff_t, bool text_at_gap_tail); extern void insert_from_gap (ptrdiff_t, ptrdiff_t, bool text_at_gap_tail); extern void insert_from_string (Lisp_Object, ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool);