unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Lisp primitives and their calling of the change hooks
@ 2018-01-03 12:45 Alan Mackenzie
  2018-01-03 21:51 ` Stefan Monnier
  0 siblings, 1 reply; 66+ messages in thread
From: Alan Mackenzie @ 2018-01-03 12:45 UTC (permalink / raw)
  To: emacs-devel

Hello, Emacs.

I've just had an interesting few days investigating our privitives'
calling of before-change-functions and after-change-functions.

In an ideal world, each primitive would call each of those hooks exactly
once.  However, we're not in an ideal world, and there are primitives
which perform several (or many) distinct changes (e.g. transpose-regions
or subst-char-in-region) where a single pair of hook calls wouldn't make
sense.

TL;DR: There are several, but not many, primitives where
before-change-functions doesn't match after-change-functions.

Here is how I went about this:
1. Extract a list of external functions in insdel.c from the section in
lisp.h which declares them.  Form a regexp from this list, and convert it
into a grep regexp (by replacing '?' by '\?'.

2. grep -l *.c with this regexp.  This gave these files:
    buffer.c
    callproc.c
    casefiddle.c
    cmds.c
    coding.c
    decompress.c
    editfns.c
    emacs.c
    fileio.c
    fns.c
    indent.c
    insdel.c
    print.c
    process.c
    search.c
    textprop.c
    xdisp.c
    xml.c

3. Using GNU cflow, a utility which creates call graphs for C files,
create a reverse call graph (i.e. an "is called by" graph) for the 18 C
files.

4. Analyse this graph with an elisp script to find all functions which,
directly or indirectly, call signal_before_change or signal_after_change.

5. Filter this list of functions to leave only the lisp primitives (i.e.
functions starting with "F"), and convert to Lisp names.  Edit this list
by hand to remove those primitives which don't change the buffer (most of
them were removed).  This left the following list:
    (add-face-text-property)
    (add-text-properties)
    (base64-decode-region)
    (base64-encode-region)
    (capitalize-region)

    (capitalize-word)
    (delete-and-extract-region)
    (delete-char)
    (delete-field)
    (delete-region)

    (downcase-region)
    (downcase-word)
    (erase-buffer)
    (indent-to)
    (insert)

    (insert-and-inherit)
    (insert-before-markers)
    (insert-buffer-substring)
    (insert-byte)
    (insert-char)

    (insert-file-contents)
    (move-to-column)
    (princ)
    (print)
    (put-text-property)

    (remove-list-of-text-properties)
    (remove-text-properties)
    (replace-buffer-contents)
    (replace-match)
    (self-insert-command)

    (set-buffer-multibyte)
    (set-text-properties)
    (subst-char-in-region)
    (terpri)
    (translate-region-internal)

    (transpose-regions)
    (upcase-initials-region)
    (upcase-region)
    (upcase-word)
    (write-char)

    (zlib-decompress-region)

6. Write and run a script which executes each of these primitives whilst
counting the number of times it invokes before-change-hooks and
after-change-hooks.  Output messages where these numbers aren't 1 and 1.
This gave the following:
    Primitive              b-c-f calls         a-c-f calls
base64-encode-region          2                    2
base64-decode-region          2                    1
insert-file-contents          2                    2
move-to-column-1              3                    3   ; with the &optional
                                                       ; which untabifies.
replace-buffer-contents      123                  123
set-buffer-multibyte          0                    0   ; May have done nothing
tranlate-region-internal      1                   146
tranpose-regions              2                    1
upcase-initials-region        1                    0[*]
upcase-region                 1                    0[*]
zlib-decompress-region        0                    0
erase-buffer                  0                    0

[*] In upcase-... there weren't any lower case characters in the buffer
at the time.

This list is incomplete.  There were one or two other primitives which
triggered messages which I didn't write down, and now cannot reproduce.

7. Surpising is that insert-file-contents (which gave so much trouble in
summer 2016) returned balanced counts.  It seems to be mostly the special
purpose primitives, those not widely used in Lisp, which are most likely
to have strange b-c-f and a-c-f counts.  But the case-switching
primitives might be troublesome.  So might transpose-regions.

8. Possibly these things could be more accurately documented in
elisp.info.

-- 
Alan Mackenzie (Nuremberg, Germany).



^ permalink raw reply	[flat|nested] 66+ messages in thread

end of thread, other threads:[~2018-01-12 16:40 UTC | newest]

Thread overview: 66+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-01-03 12:45 Lisp primitives and their calling of the change hooks Alan Mackenzie
2018-01-03 21:51 ` Stefan Monnier
2018-01-04 15:51   ` Alan Mackenzie
2018-01-04 18:16     ` Stefan Monnier
2018-01-04 21:11       ` Alan Mackenzie
2018-01-04 21:36         ` Stefan Monnier
2018-01-06 15:18           ` Alan Mackenzie
2018-01-06 15:51             ` Stefan Monnier
2018-01-06 16:18               ` Eli Zaretskii
2018-01-06 19:06                 ` Alan Mackenzie
2018-01-06 20:24               ` Alan Mackenzie
2018-01-07 11:36                 ` Alan Mackenzie
2018-01-07 11:49                   ` Eli Zaretskii
2018-01-07 12:08                     ` Alan Mackenzie
2018-01-07 13:56                       ` Alan Mackenzie
2018-01-07 15:21                         ` [SUSPECTED SPAM] " Stefan Monnier
2018-01-07 16:47                         ` Eli Zaretskii
2018-01-07 17:50                           ` Stefan Monnier
2018-01-07 17:58                             ` Eli Zaretskii
2018-01-07 19:04                               ` Stefan Monnier
2018-01-07 19:48                                 ` Alan Mackenzie
2018-01-07 19:58                                   ` Eli Zaretskii
2018-01-07 21:10                                     ` Alan Mackenzie
2018-01-08  3:41                                       ` Eli Zaretskii
2018-01-08 19:24                                         ` Alan Mackenzie
2018-01-08 21:15                                           ` Eli Zaretskii
2018-01-08 22:24                                             ` Stefan Monnier
2018-01-09  3:55                                               ` Eli Zaretskii
2018-01-09 13:30                                                 ` Stefan Monnier
2018-01-09 18:50                                                   ` Eli Zaretskii
2018-01-09 19:53                                             ` Alan Mackenzie
2018-01-09 20:05                                               ` Eli Zaretskii
2018-01-10 18:29                                                 ` Alan Mackenzie
2018-01-12 16:40                                                   ` Alan Mackenzie
2018-01-09 20:07                                               ` Stefan Monnier
2018-01-10 18:45                                                 ` Alan Mackenzie
2018-01-10 19:30                                                   ` Stefan Monnier
2018-01-10 19:48                                                     ` Alan Mackenzie
2018-01-10 20:33                                                       ` Stefan Monnier
2018-01-10 21:03                                                         ` Alan Mackenzie
2018-01-11 13:36                                                           ` Stefan Monnier
2018-01-11 17:39                                                             ` Alan Mackenzie
2018-01-11 19:35                                                               ` Stefan Monnier
2018-01-11 19:46                                                                 ` Alan Mackenzie
2018-01-11 20:15                                                                   ` Stefan Monnier
2018-01-11 21:20                                                                     ` Alan Mackenzie
2018-01-11 23:42                                                                       ` Stefan Monnier
2018-01-12 16:14                                                                         ` Alan Mackenzie
2018-01-10 22:06                                                       ` Clément Pit-Claudel
2018-01-10 22:20                                                         ` Alan Mackenzie
2018-01-08  4:29                                   ` Stefan Monnier
2018-01-07 17:54                           ` Alan Mackenzie
2018-01-07 18:05                             ` Eli Zaretskii
2018-01-05  6:55         ` Eli Zaretskii
2018-01-05 11:41           ` Alan Mackenzie
2018-01-05 13:00             ` Eli Zaretskii
2018-01-05 13:34               ` Alan Mackenzie
2018-01-05 14:08                 ` Eli Zaretskii
2018-01-05 15:54                   ` Alan Mackenzie
2018-01-05 16:50           ` Stefan Monnier
2018-01-05 17:38             ` Alan Mackenzie
2018-01-05 18:09               ` Stefan Monnier
2018-01-05 19:53             ` Eli Zaretskii
2018-01-05 22:28               ` Stefan Monnier
2018-01-06  9:05                 ` Eli Zaretskii
2018-01-06 15:26                   ` Stefan Monnier

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).