From: mstanojevic@janestreet.com (Milan Stanojević)
To: 31837@debbugs.gnu.org
Subject: bug#31837: 26.1; replace-buffer-contents doesn't work if buffer has multibyte characters
Date: Thu, 14 Jun 2018 17:34:27 -0400 [thread overview]
Message-ID: <7dm4li5jbmk.fsf@janestreet.com> (raw)
Here is a small recipe that illustrates the bug.
recipe.el
---------
(setq use-multibyte (< 0 (length argv)))
(switch-to-buffer "file1")
(when use-multibyte (insert-char (char-from-name "SMILE")))
(insert "1234")
(switch-to-buffer "file2")
(when use-multibyte (insert-char (char-from-name "SMILE")))
(insert "5678")
(replace-buffer-contents "file1")
(princ (buffer-substring-no-properties (point-min) (point-max)))
(princ "\n")
-------------
Running the recipe as script
$ emacs -Q --script /tmp/recipe.el
1234
$ emacs -Q --script /tmp/recipe.el multibyte
⌣5234
In the first run, with just ascii characters, everything works as
expected.
In the second run, with multibyte characters, the function didn't
replace '5' with '1' as expected.
I looked at the code and it looks to me like there is a very obvious bug
in function buffer_chars_equal in editfns.c. It calls
BUF_FETCH_CHAR_AS_MULTIBYTE passing *character* positions, but the
macro expects *byte* positions. (it would be nice if these char vs byte
positions could be distinguished with types, but I'm not sure it is
possible in C).
The simple fix is to replace BUF_FETCH_CHAR_AS_MULTIBYTE with
STRING_CHAR (BUF_CHAR_ADDRESS (buf, pos)) and this seems to work.
I'm not sure about performance of the above fix, though, because
accessing random character position in a buffer is not constant. If
diffing algorithm is accessing buffer positions in more or less
localized manner, maybe it makes sense to move the point inside
buffer_chars_equal so the char position to byte position conversion is
fast. It probably doesn't matter for small files.
Emacs info:
In GNU Emacs 26.1 (build 4, x86_64-pc-linux-gnu, X toolkit, Xaw scroll bars)
Windowing system distributor 'The X.Org Foundation', version 11.0.11905000
System Description: Linux
Configured using:
'configure --with-x-toolkit=lucid --without-gpm --without-gconf --without-selinux --without-imagemagick --with-modules --with-gif=no'
next reply other threads:[~2018-06-14 21:34 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-14 21:34 Milan Stanojević [this message]
2018-06-15 8:34 ` bug#31837: 26.1; replace-buffer-contents doesn't work if buffer has multibyte characters Eli Zaretskii
2018-06-18 17:44 ` Milan Stanojević
2018-06-18 18:16 ` Eli Zaretskii
2018-06-18 20:29 ` Milan Stanojević
2018-06-19 2:30 ` Eli Zaretskii
2018-07-01 17:32 ` Philipp Stephani
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7dm4li5jbmk.fsf@janestreet.com \
--to=mstanojevic@janestreet.com \
--cc=31837@debbugs.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.