commit 38d70f79a613af771f73daaa6307baed0a59e7d7 (HEAD, refs/remotes/origin/master) Author: Stefan Kangas Date: Mon Aug 10 00:22:51 2020 +0200 Remove comment on Burma / Myanmar (Bug#42788) * lisp/language/burmese.el: Remove comment on Burma / Myanmar. diff --git a/lisp/language/burmese.el b/lisp/language/burmese.el index 7f2a99a41a..1888c8f86a 100644 --- a/lisp/language/burmese.el +++ b/lisp/language/burmese.el @@ -23,7 +23,6 @@ ;;; Commentary: -;; Aung San Suu Kyi says to call her country "Burma". ;; The murderous generals say to call it "Myanmar". ;; We will call it "Burma". -- rms, Chief GNUisance. commit f75f7db952aa4e23cf38336bc73decff0d83275a Author: Stefan Kangas Date: Tue Aug 11 09:23:40 2020 +0200 Avoid ambiguity about what st refers to * lisp/term/st.el: Add link to website. diff --git a/lisp/term/st.el b/lisp/term/st.el index 3a15576ecc..617664bb26 100644 --- a/lisp/term/st.el +++ b/lisp/term/st.el @@ -1,6 +1,14 @@ ;;; st.el --- terminal initialization for st -*- lexical-binding:t -*- + ;; Copyright (C) 2020 Free Software Foundation, Inc. +;;; Commentary: + +;; Support for the st terminal emulator. +;; https://st.suckless.org/ + +;;; Code: + (require 'term/xterm) (defun terminal-init-st () commit 4491a55ac3c4e85a64e47519c8670ba23ae8d2f6 Author: Paul Eggert Date: Tue Aug 11 18:35:44 2020 -0700 Don’t warn about integer conversion in pdumper.c Problem reported by Juanma Barranquero in: https://lists.gnu.org/r/emacs-devel/2020-08/msg00279.html and a similar glitch was reported by Eli Zaretskii (Bug#36597#67). * src/pdumper.c: Remove -Wconversion pragma. (ALLOW_IMPLICIT_CONVERSION, DISALLOW_IMPLICIT_CONVERSION): Remove. All uses removed. Although -Wconversion may have been helpful when writing pdumper.c it is now causing more trouble than it’s worth here (just as in the rest of Emacs). (dump_read_all): Avoid no-longer-necessary use of ‘size_t’ rather than ‘int’. diff --git a/src/pdumper.c b/src/pdumper.c index 7708bc892f..bc41afc7c5 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -71,17 +71,7 @@ along with GNU Emacs. If not, see . */ #ifdef HAVE_PDUMPER #if GNUC_PREREQ (4, 7, 0) -# pragma GCC diagnostic error "-Wconversion" -# pragma GCC diagnostic ignored "-Wsign-conversion" # pragma GCC diagnostic error "-Wshadow" -# define ALLOW_IMPLICIT_CONVERSION \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wconversion\"") -# define DISALLOW_IMPLICIT_CONVERSION \ - _Pragma ("GCC diagnostic pop") -#else -# define ALLOW_IMPLICIT_CONVERSION ((void) 0) -# define DISALLOW_IMPLICIT_CONVERSION ((void) 0) #endif #define VM_POSIX 1 @@ -316,9 +306,7 @@ static void dump_reloc_set_offset (struct dump_reloc *reloc, dump_off offset) { eassert (offset >= 0); - ALLOW_IMPLICIT_CONVERSION; reloc->raw_offset = offset >> DUMP_RELOC_ALIGNMENT_BITS; - DISALLOW_IMPLICIT_CONVERSION; if (dump_reloc_get_offset (*reloc) != offset) error ("dump relocation out of range"); } @@ -744,10 +732,7 @@ dump_off_from_lisp (Lisp_Object value) { intmax_t n = intmax_t_from_lisp (value); eassert (DUMP_OFF_MIN <= n && n <= DUMP_OFF_MAX); - ALLOW_IMPLICIT_CONVERSION; - dump_off converted = n; - DISALLOW_IMPLICIT_CONVERSION; - return converted; + return n; } static Lisp_Object @@ -1994,11 +1979,7 @@ static dump_off finish_dump_pvec (struct dump_context *ctx, union vectorlike_header *out_hdr) { - ALLOW_IMPLICIT_CONVERSION; - dump_off result = dump_object_finish (ctx, out_hdr, - vectorlike_nbytes (out_hdr)); - DISALLOW_IMPLICIT_CONVERSION; - return result; + return dump_object_finish (ctx, out_hdr, vectorlike_nbytes (out_hdr)); } static void @@ -2664,9 +2645,7 @@ static void hash_table_thaw (Lisp_Object hash) { struct Lisp_Hash_Table *h = XHASH_TABLE (hash); - ALLOW_IMPLICIT_CONVERSION; h->hash = make_nil_vector (XFIXNUM (h->hash)); - DISALLOW_IMPLICIT_CONVERSION; h->next = Fmake_vector (h->next, make_fixnum (-1)); h->index = Fmake_vector (h->index, make_fixnum (-1)); @@ -3298,9 +3277,7 @@ static void dump_cold_charset (struct dump_context *ctx, Lisp_Object data) { /* Dump charset lookup tables. */ - ALLOW_IMPLICIT_CONVERSION; int cs_i = XFIXNUM (XCAR (data)); - DISALLOW_IMPLICIT_CONVERSION; dump_off cs_dump_offset = dump_off_from_lisp (XCDR (data)); dump_remember_fixup_ptr_raw (ctx, @@ -3608,9 +3585,7 @@ static struct emacs_reloc decode_emacs_reloc (struct dump_context *ctx, Lisp_Object lreloc) { struct emacs_reloc reloc = {0}; - ALLOW_IMPLICIT_CONVERSION; int type = XFIXNUM (dump_pop (&lreloc)); - DISALLOW_IMPLICIT_CONVERSION; reloc.emacs_offset = dump_off_from_lisp (dump_pop (&lreloc)); dump_check_emacs_off (reloc.emacs_offset); switch (type) @@ -3621,9 +3596,7 @@ decode_emacs_reloc (struct dump_context *ctx, Lisp_Object lreloc) reloc.u.dump_offset = dump_off_from_lisp (dump_pop (&lreloc)); dump_check_dump_off (ctx, reloc.u.dump_offset); dump_off length = dump_off_from_lisp (dump_pop (&lreloc)); - ALLOW_IMPLICIT_CONVERSION; reloc.length = length; - DISALLOW_IMPLICIT_CONVERSION; if (reloc.length != length) error ("relocation copy length too large"); } @@ -3634,9 +3607,7 @@ decode_emacs_reloc (struct dump_context *ctx, Lisp_Object lreloc) intmax_t value = intmax_t_from_lisp (dump_pop (&lreloc)); dump_off size = dump_off_from_lisp (dump_pop (&lreloc)); reloc.u.immediate = value; - ALLOW_IMPLICIT_CONVERSION; reloc.length = size; - DISALLOW_IMPLICIT_CONVERSION; eassert (reloc.length == size); } break; @@ -3661,9 +3632,7 @@ decode_emacs_reloc (struct dump_context *ctx, Lisp_Object lreloc) RELOC_EMACS_IMMEDIATE relocation instead. */ eassert (!dump_object_self_representing_p (target_value)); int tag_type = XTYPE (target_value); - ALLOW_IMPLICIT_CONVERSION; reloc.length = tag_type; - DISALLOW_IMPLICIT_CONVERSION; eassert (reloc.length == tag_type); if (type == RELOC_EMACS_EMACS_LV) @@ -3738,9 +3707,7 @@ dump_merge_emacs_relocs (Lisp_Object lreloc_a, Lisp_Object lreloc_b) return Qnil; dump_off new_length = reloc_a.length + reloc_b.length; - ALLOW_IMPLICIT_CONVERSION; reloc_a.length = new_length; - DISALLOW_IMPLICIT_CONVERSION; if (reloc_a.length != new_length) return Qnil; /* Overflow */ @@ -5074,7 +5041,7 @@ dump_read_all (int fd, void *buf, size_t bytes_to_read) /* Some platforms accept only int-sized values to read. Round this down to a page size (see MAX_RW_COUNT in sysdep.c). */ int max_rw_count = INT_MAX >> 18 << 18; - size_t chunk_to_read = min (bytes_to_read - bytes_read, max_rw_count); + int chunk_to_read = min (bytes_to_read - bytes_read, max_rw_count); ssize_t chunk = read (fd, (char *) buf + bytes_read, chunk_to_read); if (chunk < 0) return chunk; commit db3a7dfccceb9498227ab06e981706199e1e0f1b Author: Lars Ingebrigtsen Date: Tue Aug 11 21:21:13 2020 +0200 Remove compat code from autoload.el * lisp/emacs-lisp/autoload.el (autoload--make-defs-autoload): register-definition-prefixes is in subr.el, so it shouldn't be necessary to check whether it's defined. diff --git a/lisp/emacs-lisp/autoload.el b/lisp/emacs-lisp/autoload.el index c76de43be9..c263aa0907 100644 --- a/lisp/emacs-lisp/autoload.el +++ b/lisp/emacs-lisp/autoload.el @@ -604,9 +604,8 @@ Don't try to split prefixes that are already longer than that.") prefix file dropped) nil)))) prefixes))) - `(if (fboundp 'register-definition-prefixes) - (register-definition-prefixes ,file ',(sort (delq nil strings) - 'string<))))))) + `(register-definition-prefixes ,file ',(sort (delq nil strings) + 'string<)))))) (defun autoload--setup-output (otherbuf outbuf absfile load-name) (let ((outbuf commit 4d00db5538dc0ef47cf1cdf425b895d04145fe9e Author: Lars Ingebrigtsen Date: Tue Aug 11 20:57:56 2020 +0200 Remove compat code from comint.el * lisp/comint.el (make-comint-in-buffer): `start-file-process' is always defined, so remove test. diff --git a/lisp/comint.el b/lisp/comint.el index df947b93af..843cba1483 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -735,8 +735,6 @@ contents are sent to the process as its initial input. If PROGRAM is a string, any more args are arguments to PROGRAM. Return the (possibly newly created) process buffer." - (or (fboundp 'start-file-process) - (error "Multi-processing is not supported for this system")) (setq buffer (get-buffer-create (or buffer (concat "*" name "*")))) ;; If no process, or nuked process, crank up a new one and put buffer in ;; comint mode. Otherwise, leave buffer and existing process alone. commit 97c4d941daffba1635bd738fae9c4ff36e5ad0cf Author: Lars Ingebrigtsen Date: Tue Aug 11 20:57:10 2020 +0200 Remove compat code from esh-proc.el * lisp/eshell/esh-proc.el (eshell-gather-process-output): `start-file-process' is always defined, so remove the code that deals with Emacs versions that doesn't have it. diff --git a/lisp/eshell/esh-proc.el b/lisp/eshell/esh-proc.el index d2c17fe1f7..f612e875ff 100644 --- a/lisp/eshell/esh-proc.el +++ b/lisp/eshell/esh-proc.el @@ -294,91 +294,40 @@ See `eshell-needs-pipe'." delete-exited-processes)) (process-environment (eshell-environment-variables)) proc decoding encoding changed) - (cond - ((fboundp 'start-file-process) - (setq proc - (let ((process-connection-type - (unless (eshell-needs-pipe-p command) - process-connection-type)) - (command (file-local-name (expand-file-name command)))) - (apply #'start-file-process - (file-name-nondirectory command) nil command args))) - (eshell-record-process-object proc) - (set-process-buffer proc (current-buffer)) - (set-process-filter proc (if (eshell-interactive-output-p) - #'eshell-output-filter - #'eshell-insertion-filter)) - (set-process-sentinel proc #'eshell-sentinel) - (run-hook-with-args 'eshell-exec-hook proc) - (when (fboundp 'process-coding-system) - (let ((coding-systems (process-coding-system proc))) - (setq decoding (car coding-systems) - encoding (cdr coding-systems))) - ;; If start-process decided to use some coding system for - ;; decoding data sent from the process and the coding system - ;; doesn't specify EOL conversion, we had better convert CRLF - ;; to LF. - (if (vectorp (coding-system-eol-type decoding)) - (setq decoding (coding-system-change-eol-conversion decoding 'dos) - changed t)) - ;; Even if start-process left the coding system for encoding - ;; data sent from the process undecided, we had better use the - ;; same one as what we use for decoding. But, we should - ;; suppress EOL conversion. - (if (and decoding (not encoding)) - (setq encoding (coding-system-change-eol-conversion decoding 'unix) - changed t)) - (if changed - (set-process-coding-system proc decoding encoding)))) - (t - ;; No async subprocesses... - (let ((oldbuf (current-buffer)) - (interact-p (eshell-interactive-output-p)) - lbeg lend line proc-buf exit-status) - (and (not (markerp eshell-last-sync-output-start)) - (setq eshell-last-sync-output-start (point-marker))) - (setq proc-buf - (set-buffer (get-buffer-create eshell-scratch-buffer))) - (erase-buffer) - (set-buffer oldbuf) - (run-hook-with-args 'eshell-exec-hook command) - (setq exit-status - (apply #'call-process-region - (append (list eshell-last-sync-output-start (point) - command t - eshell-scratch-buffer nil) - args))) - ;; When in a pipeline, record the place where the output of - ;; this process will begin. - (and (bound-and-true-p eshell-in-pipeline-p) - (set-marker eshell-last-sync-output-start (point))) - ;; Simulate the effect of the process filter. - (when (numberp exit-status) - (set-buffer proc-buf) - (goto-char (point-min)) - (setq lbeg (point)) - (while (eq 0 (forward-line 1)) - (setq lend (point) - line (buffer-substring-no-properties lbeg lend)) - (set-buffer oldbuf) - (if interact-p - (eshell-output-filter nil line) - (eshell-output-object line)) - (setq lbeg lend) - (set-buffer proc-buf)) - (set-buffer oldbuf)) - (require 'esh-mode) - (declare-function eshell-update-markers "esh-mode" (pmark)) - (defvar eshell-last-output-end) ;Defined in esh-mode.el. - (eshell-update-markers eshell-last-output-end) - ;; Simulate the effect of eshell-sentinel. - (eshell-close-handles (if (numberp exit-status) exit-status -1)) - (eshell-kill-process-function command exit-status) - (or (bound-and-true-p eshell-in-pipeline-p) - (setq eshell-last-sync-output-start nil)) - (if (not (numberp exit-status)) - (error "%s: external command failed: %s" command exit-status)) - (setq proc t)))) + (setq proc + (let ((process-connection-type + (unless (eshell-needs-pipe-p command) + process-connection-type)) + (command (file-local-name (expand-file-name command)))) + (apply #'start-file-process + (file-name-nondirectory command) nil command args))) + (eshell-record-process-object proc) + (set-process-buffer proc (current-buffer)) + (set-process-filter proc (if (eshell-interactive-output-p) + #'eshell-output-filter + #'eshell-insertion-filter)) + (set-process-sentinel proc #'eshell-sentinel) + (run-hook-with-args 'eshell-exec-hook proc) + (when (fboundp 'process-coding-system) + (let ((coding-systems (process-coding-system proc))) + (setq decoding (car coding-systems) + encoding (cdr coding-systems))) + ;; If start-process decided to use some coding system for + ;; decoding data sent from the process and the coding system + ;; doesn't specify EOL conversion, we had better convert CRLF + ;; to LF. + (if (vectorp (coding-system-eol-type decoding)) + (setq decoding (coding-system-change-eol-conversion decoding 'dos) + changed t)) + ;; Even if start-process left the coding system for encoding + ;; data sent from the process undecided, we had better use the + ;; same one as what we use for decoding. But, we should + ;; suppress EOL conversion. + (if (and decoding (not encoding)) + (setq encoding (coding-system-change-eol-conversion decoding 'unix) + changed t)) + (if changed + (set-process-coding-system proc decoding encoding))) proc)) (defun eshell-insertion-filter (proc string) commit 958fa07879974721e86efe083840c2cb9f86d9d7 Author: Lars Ingebrigtsen Date: Tue Aug 11 20:53:46 2020 +0200 Remove compat code from allout.el * lisp/allout.el: (allout-process-exposed): Make allout-region-active-p an obsolete alias, and adjust callers. diff --git a/lisp/allout.el b/lisp/allout.el index 170d8687ed..fad9a172d0 100644 --- a/lisp/allout.el +++ b/lisp/allout.el @@ -5448,11 +5448,9 @@ header and body. The elements of that list are: (cdr format))))))) ;; Put the list with first at front, to last at back: (nreverse result)))) -;;;_ > allout-region-active-p () -(defmacro allout-region-active-p () - (cond ((fboundp 'use-region-p) '(use-region-p)) - ((fboundp 'region-active-p) '(region-active-p)) - (t 'mark-active))) + +(define-obsolete-function-alias 'allout-region-active-p 'region-active-p "28.1") + ;;_ > allout-process-exposed (&optional func from to frombuf ;;; tobuf format) (defun allout-process-exposed (&optional func from to frombuf tobuf @@ -5485,7 +5483,7 @@ Defaults: ; defaulting if necessary: (if (not func) (setq func 'allout-insert-listified)) (if (not (and from to)) - (if (allout-region-active-p) + (if (region-active-p) (setq from (region-beginning) to (region-end)) (setq from (point-min) to (point-max)))) (if frombuf commit 7bbfdcec6478c0b02166f49b1fb519a410b5961e Author: Lars Ingebrigtsen Date: Tue Aug 11 20:51:33 2020 +0200 Remove compat code in prolog.el * lisp/progmodes/prolog.el (use-region-p): Remove compat code. diff --git a/lisp/progmodes/prolog.el b/lisp/progmodes/prolog.el index 99b57354e2..bdb98a47fa 100644 --- a/lisp/progmodes/prolog.el +++ b/lisp/progmodes/prolog.el @@ -271,10 +271,6 @@ (require 'easymenu) (require 'align) -(eval-when-compile - (or (fboundp 'use-region-p) - (defsubst use-region-p () (region-exists-p)))) - (defgroup prolog nil "Editing and running Prolog and Mercury files." :group 'languages) commit 72c53fc3e1267bd740bb6a3785814eec8aa794c5 Author: Lars Ingebrigtsen Date: Tue Aug 11 20:50:16 2020 +0200 Slight allout.el clean-up * lisp/allout.el (allout-end-of-line, allout-mark-active-p): Make allout-mark-active-p obsolete, and adjust callers. diff --git a/lisp/allout.el b/lisp/allout.el index dedad45f82..170d8687ed 100644 --- a/lisp/allout.el +++ b/lisp/allout.el @@ -2484,20 +2484,16 @@ Outermost is first." (allout-back-to-current-heading) (allout-end-of-current-line)) (t - (if (not (allout-mark-active-p)) + (if (not mark-active) (push-mark)) (allout-end-of-entry)))))) + ;;;_ > allout-mark-active-p () (defun allout-mark-active-p () "True if the mark is currently or always active." - ;; `(cond (boundp...))' (or `(if ...)') invokes special byte-compiler - ;; provisions, at least in GNU Emacs to prevent warnings about lack of, - ;; eg, region-active-p. - (cond ((boundp 'mark-active) - mark-active) - ((fboundp 'region-active-p) - (region-active-p)) - (t))) + (declare (obsolete nil "28.1")) + mark-active) + ;;;_ > allout-next-heading () (defsubst allout-next-heading () "Move to the heading for the topic (possibly invisible) after this one. commit a19e9ab834d51832c0936cbad56f6b3746a5c4f2 Author: Lars Ingebrigtsen Date: Tue Aug 11 20:41:23 2020 +0200 Minor idlwave clean up * lisp/progmodes/idlw-shell.el (idlwave-shell-mouse-examine) (idlwave-shell-print): Adjust callers. * lisp/progmodes/idlwave.el (idlwave-region-active-p): Make into obsolete alias. diff --git a/lisp/progmodes/idlw-shell.el b/lisp/progmodes/idlw-shell.el index 6770fbe8ab..f875915ca8 100644 --- a/lisp/progmodes/idlw-shell.el +++ b/lisp/progmodes/idlw-shell.el @@ -2745,7 +2745,7 @@ Runs to the last statement and then steps 1 statement. Use the .out command." ;; event. mouse-drag-track does so. (if drag-track 'mouse-drag-track 'mouse-drag-region))) (funcall tracker event) - (idlwave-shell-print (if (idlwave-region-active-p) '(4) nil) + (idlwave-shell-print (if (region-active-p) '(4) nil) ,help ,ev)))) ;; Begin terrible hack section -- XEmacs tests for button2 explicitly @@ -2830,7 +2830,7 @@ from `idlwave-shell-examine-alist' via mini-buffer shortcut key." (cond ((equal arg '(16)) (setq expr (read-string "Expression: "))) - ((and (or arg (idlwave-region-active-p)) + ((and (or arg (region-active-p)) (< (- (region-end) (region-beginning)) 2000)) (setq beg (region-beginning) end (region-end))) diff --git a/lisp/progmodes/idlwave.el b/lisp/progmodes/idlwave.el index 3092d4c45b..f4eb2be8cc 100644 --- a/lisp/progmodes/idlwave.el +++ b/lisp/progmodes/idlwave.el @@ -2092,11 +2092,7 @@ Returns point if comment found and nil otherwise." (backward-char 1) (point))))) -(defun idlwave-region-active-p () - "Should we operate on an active region?" - (if (fboundp 'use-region-p) - (use-region-p) - (region-active-p))) +(define-obsolete-function-alias 'idlwave-region-active-p 'use-region-p "28.1") (defun idlwave-show-matching-quote () "Insert quote and show matching quote if this is end of a string." commit 86a326d2d8f526f2113e5c46da9c3dadf5260a3c Author: Lars Ingebrigtsen Date: Tue Aug 11 20:36:10 2020 +0200 Slight gnus-util clean-up * lisp/gnus/gnus-util.el (gnus-message-with-timestamp-1): messages-buffer is always defined. diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el index abe546b8cb..4876715ae6 100644 --- a/lisp/gnus/gnus-util.el +++ b/lisp/gnus/gnus-util.el @@ -455,9 +455,7 @@ displayed in the echo area." (> message-log-max 0) (/= (length str) 0)) (setq time (current-time)) - (with-current-buffer (if (fboundp 'messages-buffer) - (messages-buffer) - (get-buffer-create "*Messages*")) + (with-current-buffer (messages-buffer) (goto-char (point-max)) (let ((inhibit-read-only t)) (insert ,timestamp str "\n") commit 672bfdb9c91629f232435ca4a2157bb3e627df9d Author: Lars Ingebrigtsen Date: Tue Aug 11 18:46:34 2020 +0200 Slight cleanup in calc-yank * lisp/calc/calc-yank.el (calc-yank): Remove compat code. diff --git a/lisp/calc/calc-yank.el b/lisp/calc/calc-yank.el index b119f14980..690aaf2687 100644 --- a/lisp/calc/calc-yank.el +++ b/lisp/calc/calc-yank.el @@ -244,9 +244,7 @@ If RADIX is nil or if the yanked string already has a calc radix prefix, the yanked string will be passed on directly to the Calculator buffer without any alteration." (interactive "P") - (calc-yank-internal radix (if (fboundp 'current-kill) - (current-kill 0 t) - (car kill-ring-yank-pointer)))) + (calc-yank-internal radix (current-kill 0 t))) ;;; The Calc set- and get-register commands are modified versions of functions ;;; in register.el commit ccb5556b44f10124c7dd6c230a6d817fa83b9690 Author: Philipp Stephani Date: Tue Aug 11 20:20:44 2020 +0200 Unbreak build with --enable-checking=all Commit 16a16645f524c62f7906036b0e383e4247b58de7 has only changed a comment in ‘struct Lisp_Hash_Table’, so the portable dumper doesn’t need to be adapted. * src/pdumper.c (dump_hash_table): Update hash code for ‘struct Lisp_Hash_Table’. diff --git a/src/pdumper.c b/src/pdumper.c index aaa760d70d..7708bc892f 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -2678,7 +2678,7 @@ dump_hash_table (struct dump_context *ctx, Lisp_Object object, dump_off offset) { -#if CHECK_STRUCTS && !defined HASH_Lisp_Hash_Table_12AFBF47AF +#if CHECK_STRUCTS && !defined HASH_Lisp_Hash_Table_6D63EDB618 # error "Lisp_Hash_Table changed. See CHECK_STRUCTS comment in config.h." #endif const struct Lisp_Hash_Table *hash_in = XHASH_TABLE (object); commit 39c16c1170fd8bd7035e6e265048dd371cde4609 Author: Paul Eggert Date: Tue Aug 11 11:06:39 2020 -0700 Use Gnulib inttypes module Needed for platforms like MinGW that don’t support C99 PRIdPTR. * admin/merge-gnulib (GNULIB_MODULES): Add inttypes. * m4/gnulib-comp.m4: Regenerate. diff --git a/admin/merge-gnulib b/admin/merge-gnulib index 3f32536a62..98f7941bd8 100755 --- a/admin/merge-gnulib +++ b/admin/merge-gnulib @@ -36,7 +36,7 @@ GNULIB_MODULES=' fchmodat fcntl fcntl-h fdopendir filemode filename filevercmp flexmember fpieee fstatat fsusage fsync futimens getloadavg getopt-gnu getrandom gettime gettimeofday gitlog-to-changelog - ieee754-h ignore-value intprops largefile libgmp lstat + ieee754-h ignore-value intprops inttypes largefile libgmp lstat manywarnings memmem-simple mempcpy memrchr minmax mkostemp mktime nstrftime pathmax pipe2 pselect pthread_sigmask qcopy-acl readlink readlinkat regex diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index 92d0621c61..e7e9fbdc31 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in @@ -116,6 +116,7 @@ # ieee754-h \ # ignore-value \ # intprops \ +# inttypes \ # largefile \ # libgmp \ # lstat \ diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index 5bfa1473ed..1f8a87218e 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -113,6 +113,7 @@ AC_DEFUN([gl_EARLY], # Code from module ignore-value: # Code from module include_next: # Code from module intprops: + # Code from module inttypes: # Code from module inttypes-incomplete: # Code from module largefile: AC_REQUIRE([AC_SYS_LARGEFILE]) @@ -342,6 +343,7 @@ AC_DEFUN([gl_INIT], fi gl_SYS_TIME_MODULE_INDICATOR([gettimeofday]) gl_IEEE754_H + gl_INTTYPES_H gl_INTTYPES_INCOMPLETE AC_REQUIRE([gl_LARGEFILE]) gl___INLINE commit 124a7951f495b916cf38f0e1e1fe85e22bc08aba Author: Paul Eggert Date: Tue Aug 11 10:58:35 2020 -0700 Update from Gnulib This incorporates: 2020-08-11 Use expression statements also on clang 2020-08-10 Use many __attribute__s with clang 2020-08-09 Use attribute __aligned__ with clang 2020-08-09 Use __alignof__ with clang 2020-08-09 ignore-value: Simplify on clang 2020-08-09 Use __typeof__ with clang 2020-08-09 intprops: Fix typo in comment 2020-08-09 Silence warnings from clang 10 with -Wimplicit-fallthrough 2020-08-09 count-one-bits: Use __builtin_popcount{,l,ll} on clang 2020-08-09 string: Fix build error in C++ mode with clang 2020-08-09 Add ability to emit user-defined diagnostics with clang 2020-08-07 alloca: No need to compile alloca.c with clang 2020-08-06 Use __builtin_assume with clang * lib/alloca.in.h, lib/arg-nonnull.h, lib/c++defs.h, lib/cdefs.h: * lib/count-one-bits.h, lib/dirent.in.h, lib/ignore-value.h: * lib/intprops.h, lib/malloca.h, lib/regex_internal.h: * lib/stdalign.in.h, lib/stddef.in.h, lib/stdio.in.h: * lib/stdlib.in.h, lib/string.in.h, lib/verify.h, lib/warn-on-use.h: * m4/gnulib-common.m4, m4/stddef_h.m4, m4/stdint.m4: Copy from Gnulib. diff --git a/lib/alloca.in.h b/lib/alloca.in.h index 5686b082bb..c71e9bfed9 100644 --- a/lib/alloca.in.h +++ b/lib/alloca.in.h @@ -44,7 +44,7 @@ # endif #endif #ifndef alloca -# ifdef __GNUC__ +# if defined __GNUC__ || (__clang_major__ >= 4) # define alloca __builtin_alloca # elif defined _AIX # define alloca __alloca diff --git a/lib/arg-nonnull.h b/lib/arg-nonnull.h index ac26ca8cfe..db9d9ae116 100644 --- a/lib/arg-nonnull.h +++ b/lib/arg-nonnull.h @@ -18,7 +18,7 @@ that the values passed as arguments n, ..., m must be non-NULL pointers. n = 1 stands for the first argument, n = 2 for the second argument etc. */ #ifndef _GL_ARG_NONNULL -# if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ > 3 +# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || defined __clang__ # define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params)) # else # define _GL_ARG_NONNULL(params) diff --git a/lib/c++defs.h b/lib/c++defs.h index 182c2b3a88..90e6fd62e6 100644 --- a/lib/c++defs.h +++ b/lib/c++defs.h @@ -298,7 +298,7 @@ we enable the warning only when not optimizing. */ # if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__) # define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ - _GL_WARN_ON_USE_CXX (func, rettype, parameters_and_attributes, \ + _GL_WARN_ON_USE_CXX (func, rettype, rettype, parameters_and_attributes, \ "The symbol ::" #func " refers to the system function. " \ "Use " #namespace "::" #func " instead.") # else diff --git a/lib/cdefs.h b/lib/cdefs.h index f6c447ad37..beedd891fb 100644 --- a/lib/cdefs.h +++ b/lib/cdefs.h @@ -34,7 +34,34 @@ #undef __P #undef __PMT -#ifdef __GNUC__ +/* Compilers that are not clang may object to + #if defined __clang__ && __has_attribute(...) + even though they do not need to evaluate the right-hand side of the &&. */ +#if defined __clang__ && defined __has_attribute +# define __glibc_clang_has_attribute(name) __has_attribute (name) +#else +# define __glibc_clang_has_attribute(name) 0 +#endif + +/* Compilers that are not clang may object to + #if defined __clang__ && __has_builtin(...) + even though they do not need to evaluate the right-hand side of the &&. */ +#if defined __clang__ && defined __has_builtin +# define __glibc_clang_has_builtin(name) __has_builtin (name) +#else +# define __glibc_clang_has_builtin(name) 0 +#endif + +/* Compilers that are not clang may object to + #if defined __clang__ && __has_extension(...) + even though they do not need to evaluate the right-hand side of the &&. */ +#if defined __clang__ && defined __has_extension +# define __glibc_clang_has_extension(ext) __has_extension (ext) +#else +# define __glibc_clang_has_extension(ext) 0 +#endif + +#if defined __GNUC__ || defined __clang__ /* All functions, except those with callbacks or those that synchronize memory, are leaf functions. */ @@ -51,7 +78,8 @@ gcc 2.8.x and egcs. For gcc 3.2 and up we even mark C functions as non-throwing using a function attribute since programs can use the -fexceptions options for C code as well. */ -# if !defined __cplusplus && __GNUC_PREREQ (3, 3) +# if !defined __cplusplus \ + && (__GNUC_PREREQ (3, 3) || __glibc_clang_has_attribute (__nothrow__)) # define __THROW __attribute__ ((__nothrow__ __LEAF)) # define __THROWNL __attribute__ ((__nothrow__)) # define __NTH(fct) __attribute__ ((__nothrow__ __LEAF)) fct @@ -70,7 +98,7 @@ # endif # endif -#else /* Not GCC. */ +#else /* Not GCC or clang. */ # if (defined __cplusplus \ || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) @@ -83,16 +111,7 @@ # define __THROWNL # define __NTH(fct) fct -#endif /* GCC. */ - -/* Compilers that are not clang may object to - #if defined __clang__ && __has_extension(...) - even though they do not need to evaluate the right-hand side of the &&. */ -#if defined __clang__ && defined __has_extension -# define __glibc_clang_has_extension(ext) __has_extension (ext) -#else -# define __glibc_clang_has_extension(ext) 0 -#endif +#endif /* GCC || clang. */ /* These two macros are not used in glibc anymore. They are kept here only because some other projects expect the macros to be defined. */ @@ -129,6 +148,12 @@ # define __warnattr(msg) __attribute__((__warning__ (msg))) # define __errordecl(name, msg) \ extern void name (void) __attribute__((__error__ (msg))) +#elif __glibc_clang_has_attribute (__diagnose_if__) +# define __warndecl(name, msg) \ + extern void name (void) __attribute__((__diagnose_if__ (1, msg, "warning"))) +# define __warnattr(msg) __attribute__((__diagnose_if__ (1, msg, "warning"))) +# define __errordecl(name, msg) \ + extern void name (void) __attribute__((__diagnose_if__ (1, msg, "error"))) #else # define __warndecl(name, msg) extern void name (void) # define __warnattr(msg) @@ -194,17 +219,17 @@ */ #endif -/* GCC has various useful declarations that can be made with the - `__attribute__' syntax. All of the ways we use this do fine if - they are omitted for compilers that don't understand it. */ -#if !defined __GNUC__ || __GNUC__ < 2 +/* GCC and clang have various useful declarations that can be made with + the '__attribute__' syntax. All of the ways we use this do fine if + they are omitted for compilers that don't understand it. */ +#if !(defined __GNUC__ || defined __clang__) # define __attribute__(xyz) /* Ignore */ #endif /* At some point during the gcc 2.96 development the `malloc' attribute for functions was introduced. We don't want to use it unconditionally (although this would be possible) since it generates warnings. */ -#if __GNUC_PREREQ (2,96) +#if __GNUC_PREREQ (2,96) || __glibc_clang_has_attribute (__malloc__) # define __attribute_malloc__ __attribute__ ((__malloc__)) #else # define __attribute_malloc__ /* Ignore */ @@ -222,14 +247,14 @@ /* At some point during the gcc 2.96 development the `pure' attribute for functions was introduced. We don't want to use it unconditionally (although this would be possible) since it generates warnings. */ -#if __GNUC_PREREQ (2,96) +#if __GNUC_PREREQ (2,96) || __glibc_clang_has_attribute (__pure__) # define __attribute_pure__ __attribute__ ((__pure__)) #else # define __attribute_pure__ /* Ignore */ #endif /* This declaration tells the compiler that the value is constant. */ -#if __GNUC_PREREQ (2,5) +#if __GNUC_PREREQ (2,5) || __glibc_clang_has_attribute (__const__) # define __attribute_const__ __attribute__ ((__const__)) #else # define __attribute_const__ /* Ignore */ @@ -238,7 +263,7 @@ /* At some point during the gcc 3.1 development the `used' attribute for functions was introduced. We don't want to use it unconditionally (although this would be possible) since it generates warnings. */ -#if __GNUC_PREREQ (3,1) +#if __GNUC_PREREQ (3,1) || __glibc_clang_has_attribute (__used__) # define __attribute_used__ __attribute__ ((__used__)) # define __attribute_noinline__ __attribute__ ((__noinline__)) #else @@ -247,7 +272,7 @@ #endif /* Since version 3.2, gcc allows marking deprecated functions. */ -#if __GNUC_PREREQ (3,2) +#if __GNUC_PREREQ (3,2) || __glibc_clang_has_attribute (__deprecated__) # define __attribute_deprecated__ __attribute__ ((__deprecated__)) #else # define __attribute_deprecated__ /* Ignore */ @@ -270,7 +295,7 @@ If several `format_arg' attributes are given for the same function, in gcc-3.0 and older, all but the last one are ignored. In newer gccs, all designated arguments are considered. */ -#if __GNUC_PREREQ (2,8) +#if __GNUC_PREREQ (2,8) || __glibc_clang_has_attribute (__format_arg__) # define __attribute_format_arg__(x) __attribute__ ((__format_arg__ (x))) #else # define __attribute_format_arg__(x) /* Ignore */ @@ -280,7 +305,7 @@ attribute for functions was introduced. We don't want to use it unconditionally (although this would be possible) since it generates warnings. */ -#if __GNUC_PREREQ (2,97) +#if __GNUC_PREREQ (2,97) || __glibc_clang_has_attribute (__format__) # define __attribute_format_strfmon__(a,b) \ __attribute__ ((__format__ (__strfmon__, a, b))) #else @@ -291,7 +316,7 @@ must not be NULL. Do not define __nonnull if it is already defined, for portability when this file is used in Gnulib. */ #ifndef __nonnull -# if __GNUC_PREREQ (3,3) +# if __GNUC_PREREQ (3,3) || __glibc_clang_has_attribute (__nonnull__) # define __nonnull(params) __attribute__ ((__nonnull__ params)) # else # define __nonnull(params) @@ -300,7 +325,7 @@ /* If fortification mode, we warn about unused results of certain function calls which can lead to problems. */ -#if __GNUC_PREREQ (3,4) +#if __GNUC_PREREQ (3,4) || __glibc_clang_has_attribute (__warn_unused_result__) # define __attribute_warn_unused_result__ \ __attribute__ ((__warn_unused_result__)) # if defined __USE_FORTIFY_LEVEL && __USE_FORTIFY_LEVEL > 0 @@ -314,7 +339,7 @@ #endif /* Forces a function to be always inlined. */ -#if __GNUC_PREREQ (3,2) +#if __GNUC_PREREQ (3,2) || __glibc_clang_has_attribute (__always_inline__) /* The Linux kernel defines __always_inline in stddef.h (283d7573), and it conflicts with this definition. Therefore undefine it first to allow either header to be included first. */ @@ -327,7 +352,7 @@ /* Associate error messages with the source location of the call site rather than with the source location inside the function. */ -#if __GNUC_PREREQ (4,3) +#if __GNUC_PREREQ (4,3) || __glibc_clang_has_attribute (__artificial__) # define __attribute_artificial__ __attribute__ ((__artificial__)) #else # define __attribute_artificial__ /* Ignore */ @@ -370,7 +395,7 @@ run in pedantic mode if the uses are carefully marked using the `__extension__' keyword. But this is not generally available before version 2.8. */ -#if !__GNUC_PREREQ (2,8) +#if !(__GNUC_PREREQ (2,8) || defined __clang__) # define __extension__ /* Ignore */ #endif @@ -401,7 +426,7 @@ # endif #endif -#if (__GNUC__ >= 3) || (__clang_major__ >= 4) +#if (__GNUC__ >= 3) || __glibc_clang_has_builtin (__builtin_expect) # define __glibc_unlikely(cond) __builtin_expect ((cond), 0) # define __glibc_likely(cond) __builtin_expect ((cond), 1) #else @@ -417,7 +442,8 @@ #if (!defined _Noreturn \ && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \ - && !__GNUC_PREREQ (4,7)) + && !(__GNUC_PREREQ (4,7) \ + || (3 < __clang_major__ + (5 <= __clang_minor__)))) # if __GNUC_PREREQ (2,8) # define _Noreturn __attribute__ ((__noreturn__)) # else diff --git a/lib/count-one-bits.h b/lib/count-one-bits.h index 6c5b75708c..a9e166aed8 100644 --- a/lib/count-one-bits.h +++ b/lib/count-one-bits.h @@ -38,7 +38,8 @@ extern "C" { expand to code that computes the number of 1-bits of the local variable 'x' of type TYPE (an unsigned integer type) and return it from the current function. */ -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) \ + || (__clang_major__ >= 4) # define COUNT_ONE_BITS(GCC_BUILTIN, MSC_BUILTIN, TYPE) \ return GCC_BUILTIN (x) #else diff --git a/lib/dirent.in.h b/lib/dirent.in.h index 6fa44f0d28..23c4e05577 100644 --- a/lib/dirent.in.h +++ b/lib/dirent.in.h @@ -58,7 +58,7 @@ typedef struct gl_directory DIR; /* The __attribute__ feature is available in gcc versions 2.5 and later. The attribute __pure__ was added in gcc 2.96. */ #ifndef _GL_ATTRIBUTE_PURE -# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) +# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__ # define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) # else # define _GL_ATTRIBUTE_PURE /* empty */ diff --git a/lib/ignore-value.h b/lib/ignore-value.h index 7a92226843..ec3288f0df 100644 --- a/lib/ignore-value.h +++ b/lib/ignore-value.h @@ -39,8 +39,9 @@ versions 3.4 and newer have __attribute__ ((__warn_unused_result__)) which may cause unwanted diagnostics in that case. Use __typeof__ and __extension__ to work around the problem, if the workaround is - known to be needed. */ -#if 3 < __GNUC__ + (4 <= __GNUC_MINOR__) + known to be needed. + The workaround is not needed with clang. */ +#if (3 < __GNUC__ + (4 <= __GNUC_MINOR__)) && !defined __clang__ # define ignore_value(x) \ (__extension__ ({ __typeof__ (x) __x = (x); (void) __x; })) #else diff --git a/lib/intprops.h b/lib/intprops.h index dfbcaae73e..220f532e49 100644 --- a/lib/intprops.h +++ b/lib/intprops.h @@ -86,6 +86,7 @@ /* Does the __typeof__ keyword work? This could be done by 'configure', but for now it's easier to do it by hand. */ #if (2 <= __GNUC__ \ + || (4 <= __clang_major__) \ || (1210 <= __IBMC__ && defined __IBM__TYPEOF__) \ || (0x5110 <= __SUNPRO_C && !__STDC__)) # define _GL_HAVE___TYPEOF__ 1 @@ -239,7 +240,7 @@ #endif /* True if __builtin_add_overflow_p (A, B, C) works, and similarly for - __builtin_mul_overflow_p and __builtin_mul_overflow_p. */ + __builtin_sub_overflow_p and __builtin_mul_overflow_p. */ #define _GL_HAS_BUILTIN_OVERFLOW_P (7 <= __GNUC__) /* The _GL*_OVERFLOW macros have the same restrictions as the diff --git a/lib/malloca.h b/lib/malloca.h index cfcd4de4ad..ccc485a6a4 100644 --- a/lib/malloca.h +++ b/lib/malloca.h @@ -89,7 +89,7 @@ extern void freea (void *p); /* ------------------- Auxiliary, non-public definitions ------------------- */ /* Determine the alignment of a type at compile time. */ -#if defined __GNUC__ || defined __IBM__ALIGNOF__ +#if defined __GNUC__ || defined __clang__ || defined __IBM__ALIGNOF__ # define sa_alignof __alignof__ #elif defined __cplusplus template struct sa_alignof_helper { char __slot1; type __slot2; }; diff --git a/lib/regex_internal.h b/lib/regex_internal.h index f6ebfb003e..9a0c2ed97c 100644 --- a/lib/regex_internal.h +++ b/lib/regex_internal.h @@ -841,10 +841,10 @@ re_string_elem_size_at (const re_string_t *pstr, Idx idx) #endif /* RE_ENABLE_I18N */ #ifndef FALLTHROUGH -# if __GNUC__ < 7 -# define FALLTHROUGH ((void) 0) -# else +# if (__GNUC__ >= 7) || (__clang_major__ >= 10) # define FALLTHROUGH __attribute__ ((__fallthrough__)) +# else +# define FALLTHROUGH ((void) 0) # endif #endif diff --git a/lib/stdalign.in.h b/lib/stdalign.in.h index cd786bed2c..e4809b401f 100644 --- a/lib/stdalign.in.h +++ b/lib/stdalign.in.h @@ -34,11 +34,12 @@ requirement of a structure member (i.e., slot or field) that is of type TYPE, as an integer constant expression. - This differs from GCC's __alignof__ operator, which can yield a - better-performing alignment for an object of that type. For - example, on x86 with GCC, __alignof__ (double) and __alignof__ - (long long) are 8, whereas alignof (double) and alignof (long long) - are 4 unless the option '-malign-double' is used. + This differs from GCC's and clang's __alignof__ operator, which can + yield a better-performing alignment for an object of that type. For + example, on x86 with GCC and on Linux/x86 with clang, + __alignof__ (double) and __alignof__ (long long) are 8, whereas + alignof (double) and alignof (long long) are 4 unless the option + '-malign-double' is used. The result cannot be used as a value for an 'enum' constant, if you want to be portable to HP-UX 10.20 cc and AIX 3.2.5 xlc. @@ -55,7 +56,8 @@ /* GCC releases before GCC 4.9 had a bug in _Alignof. See GCC bug 52023 . */ #if (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 \ - || (defined __GNUC__ && __GNUC__ < 4 + (__GNUC_MINOR__ < 9))) + || (defined __GNUC__ && __GNUC__ < 4 + (__GNUC_MINOR__ < 9) \ + && !defined __clang__)) # ifdef __cplusplus # if 201103 <= __cplusplus # define _Alignof(type) alignof (type) @@ -102,8 +104,9 @@ # define _Alignas(a) alignas (a) # elif ((defined __APPLE__ && defined __MACH__ \ ? 4 < __GNUC__ + (1 <= __GNUC_MINOR__) \ - : __GNUC__ && !defined __ibmxl__) \ - || (__ia64 && (61200 <= __HP_cc || 61200 <= __HP_aCC)) \ + : __GNUC__ && !defined __ibmxl__) \ + || (4 <= __clang_major__) \ + || (__ia64 && (61200 <= __HP_cc || 61200 <= __HP_aCC)) \ || __ICC || 0x590 <= __SUNPRO_C || 0x0600 <= __xlC__) # define _Alignas(a) __attribute__ ((__aligned__ (a))) # elif 1300 <= _MSC_VER diff --git a/lib/stddef.in.h b/lib/stddef.in.h index 2e50a1f01e..87b46d5320 100644 --- a/lib/stddef.in.h +++ b/lib/stddef.in.h @@ -97,7 +97,7 @@ and the C11 standard allows this. Work around this problem by using __alignof__ (which returns 8 for double) rather than _Alignof (which returns 4), and align each union member accordingly. */ -# ifdef __GNUC__ +# if defined __GNUC__ || (__clang_major__ >= 4) # define _GL_STDDEF_ALIGNAS(type) \ __attribute__ ((__aligned__ (__alignof__ (type)))) # else diff --git a/lib/stdio.in.h b/lib/stdio.in.h index 6c338dd6c0..cbebc8462f 100644 --- a/lib/stdio.in.h +++ b/lib/stdio.in.h @@ -63,7 +63,7 @@ gnulib and libintl do '#define printf __printf__' when they override the 'printf' function. */ #ifndef _GL_ATTRIBUTE_FORMAT -# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) +# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) || defined __clang__ # define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) # else # define _GL_ATTRIBUTE_FORMAT(spec) /* empty */ diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index 59f9e6c71d..5c598a275d 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -102,7 +102,7 @@ struct random_data /* The __attribute__ feature is available in gcc versions 2.5 and later. The attribute __pure__ was added in gcc 2.96. */ #ifndef _GL_ATTRIBUTE_PURE -# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) +# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__ # define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) # else # define _GL_ATTRIBUTE_PURE /* empty */ diff --git a/lib/string.in.h b/lib/string.in.h index aa9802791e..c0c1a54f39 100644 --- a/lib/string.in.h +++ b/lib/string.in.h @@ -55,7 +55,7 @@ /* The __attribute__ feature is available in gcc versions 2.5 and later. The attribute __pure__ was added in gcc 2.96. */ #ifndef _GL_ATTRIBUTE_PURE -# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) +# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || defined __clang__ # define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) # else # define _GL_ATTRIBUTE_PURE /* empty */ @@ -329,7 +329,8 @@ _GL_WARN_ON_USE (stpncpy, "stpncpy is unportable - " GB18030 and the character to be searched is a digit. */ # undef strchr /* Assume strchr is always declared. */ -_GL_WARN_ON_USE_CXX (strchr, const char *, (const char *, int), +_GL_WARN_ON_USE_CXX (strchr, + const char *, char *, (const char *, int), "strchr cannot work correctly on character strings " "in some multibyte locales - " "use mbschr if you care about internationalization"); @@ -524,7 +525,8 @@ _GL_CXXALIASWARN (strpbrk); locale encoding is GB18030 and one of the characters to be searched is a digit. */ # undef strpbrk -_GL_WARN_ON_USE_CXX (strpbrk, const char *, (const char *, const char *), +_GL_WARN_ON_USE_CXX (strpbrk, + const char *, char *, (const char *, const char *), "strpbrk cannot work correctly on character strings " "in multibyte locales - " "use mbspbrk if you care about internationalization"); @@ -532,7 +534,8 @@ _GL_WARN_ON_USE_CXX (strpbrk, const char *, (const char *, const char *), #elif defined GNULIB_POSIXCHECK # undef strpbrk # if HAVE_RAW_DECL_STRPBRK -_GL_WARN_ON_USE_CXX (strpbrk, const char *, (const char *, const char *), +_GL_WARN_ON_USE_CXX (strpbrk, + const char *, char *, (const char *, const char *), "strpbrk is unportable - " "use gnulib module strpbrk for portability"); # endif @@ -553,7 +556,8 @@ _GL_WARN_ON_USE (strspn, "strspn cannot work correctly on character strings " GB18030 and the character to be searched is a digit. */ # undef strrchr /* Assume strrchr is always declared. */ -_GL_WARN_ON_USE_CXX (strrchr, const char *, (const char *, int), +_GL_WARN_ON_USE_CXX (strrchr, + const char *, char *, (const char *, int), "strrchr cannot work correctly on character strings " "in some multibyte locales - " "use mbsrchr if you care about internationalization"); diff --git a/lib/verify.h b/lib/verify.h index f109761270..58172f3cb7 100644 --- a/lib/verify.h +++ b/lib/verify.h @@ -233,6 +233,13 @@ template /* @assert.h omit start@ */ +#if defined __has_builtin +/* */ +# define _GL_HAS_BUILTIN_ASSUME __has_builtin (__builtin_assume) +#else +# define _GL_HAS_BUILTIN_ASSUME 0 +#endif + #if 3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__)) # define _GL_HAS_BUILTIN_TRAP 1 #elif defined __has_builtin @@ -294,7 +301,9 @@ template diagnostics, performance can suffer if R uses hard-to-optimize features such as function calls not inlined by the compiler. */ -#if _GL_HAS_BUILTIN_UNREACHABLE +#if _GL_HAS_BUILTIN_ASSUME +# define assume(R) __builtin_assume (R) +#elif _GL_HAS_BUILTIN_UNREACHABLE # define assume(R) ((R) ? (void) 0 : __builtin_unreachable ()) #elif 1200 <= _MSC_VER # define assume(R) __assume (R) diff --git a/lib/warn-on-use.h b/lib/warn-on-use.h index 23c10fdd12..3f728d1a9d 100644 --- a/lib/warn-on-use.h +++ b/lib/warn-on-use.h @@ -87,6 +87,13 @@ extern __typeof__ (function) function __attribute__ ((__warning__ (message))) # define _GL_WARN_ON_USE_ATTRIBUTE(message) \ __attribute__ ((__warning__ (message))) +# elif __clang_major__ >= 4 +/* Another compiler attribute is available in clang. */ +# define _GL_WARN_ON_USE(function, message) \ +extern __typeof__ (function) function \ + __attribute__ ((__diagnose_if__ (1, message, "warning"))) +# define _GL_WARN_ON_USE_ATTRIBUTE(message) \ + __attribute__ ((__diagnose_if__ (1, message, "warning"))) # elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING /* Verify the existence of the function. */ # define _GL_WARN_ON_USE(function, message) \ @@ -99,27 +106,33 @@ _GL_WARN_EXTERN_C int _gl_warn_on_use # endif #endif -/* _GL_WARN_ON_USE_CXX (function, rettype, parameters_and_attributes, "string") - is like _GL_WARN_ON_USE (function, "string"), except that in C++ mode the +/* _GL_WARN_ON_USE_CXX (function, rettype_gcc, rettype_clang, parameters_and_attributes, "message") + is like _GL_WARN_ON_USE (function, "message"), except that in C++ mode the function is declared with the given prototype, consisting of return type, parameters, and attributes. This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does not work in this case. */ #ifndef _GL_WARN_ON_USE_CXX # if !defined __cplusplus -# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ +# define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ _GL_WARN_ON_USE (function, msg) # else # if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) -# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ -extern rettype function parameters_and_attributes \ - __attribute__ ((__warning__ (msg))) +/* A compiler attribute is available in gcc versions 4.3.0 and later. */ +# define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ +extern rettype_gcc function parameters_and_attributes \ + __attribute__ ((__warning__ (msg))) +# elif __clang_major__ >= 4 +/* Another compiler attribute is available in clang. */ +# define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ +extern rettype_clang function parameters_and_attributes \ + __attribute__ ((__diagnose_if__ (1, msg, "warning"))) # elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING /* Verify the existence of the function. */ -# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ -extern rettype function parameters_and_attributes +# define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ +extern rettype_gcc function parameters_and_attributes # else /* Unsupported. */ -# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ +# define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \ _GL_WARN_EXTERN_C int _gl_warn_on_use # endif # endif diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4 index 50acc0a474..03da2287d4 100644 --- a/m4/gnulib-common.m4 +++ b/m4/gnulib-common.m4 @@ -1,4 +1,4 @@ -# gnulib-common.m4 serial 53 +# gnulib-common.m4 serial 55 dnl Copyright (C) 2007-2020 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -45,7 +45,7 @@ AC_DEFUN([gl_COMMON_BODY], [ ? 6000000 <= __apple_build_version__ \ : 3 < __clang_major__ + (5 <= __clang_minor__)))) /* _Noreturn works as-is. */ -# elif _GL_GNUC_PREREQ (2, 8) || 0x5110 <= __SUNPRO_C +# elif _GL_GNUC_PREREQ (2, 8) || defined __clang__ || 0x5110 <= __SUNPRO_C # define _Noreturn __attribute__ ((__noreturn__)) # elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0) # define _Noreturn __declspec (noreturn) @@ -76,6 +76,7 @@ AC_DEFUN([gl_COMMON_BODY], [ # define _GL_ATTR_cold _GL_GNUC_PREREQ (4, 3) # define _GL_ATTR_const _GL_GNUC_PREREQ (2, 95) # define _GL_ATTR_deprecated _GL_GNUC_PREREQ (3, 1) +# define _GL_ATTR_diagnose_if 0 # define _GL_ATTR_error _GL_GNUC_PREREQ (4, 3) # define _GL_ATTR_externally_visible _GL_GNUC_PREREQ (4, 1) # define _GL_ATTR_fallthrough _GL_GNUC_PREREQ (7, 0) @@ -149,6 +150,9 @@ AC_DEFUN([gl_COMMON_BODY], [ #if _GL_HAS_ATTRIBUTE (error) # define _GL_ATTRIBUTE_ERROR(msg) __attribute__ ((__error__ (msg))) # define _GL_ATTRIBUTE_WARNING(msg) __attribute__ ((__warning__ (msg))) +#elif _GL_HAS_ATTRIBUTE (diagnose_if) +# define _GL_ATTRIBUTE_ERROR(msg) __attribute__ ((__diagnose_if__ (1, msg, "error"))) +# define _GL_ATTRIBUTE_WARNING(msg) __attribute__ ((__diagnose_if__ (1, msg, "warning"))) #else # define _GL_ATTRIBUTE_ERROR(msg) # define _GL_ATTRIBUTE_WARNING(msg) diff --git a/m4/stddef_h.m4 b/m4/stddef_h.m4 index 6bcfadb74e..d8bc8ff64e 100644 --- a/m4/stddef_h.m4 +++ b/m4/stddef_h.m4 @@ -1,5 +1,5 @@ dnl A placeholder for , for platforms that have issues. -# stddef_h.m4 serial 6 +# stddef_h.m4 serial 7 dnl Copyright (C) 2009-2020 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -19,7 +19,7 @@ AC_DEFUN([gl_STDDEF_H], [AC_LANG_PROGRAM( [[#include unsigned int s = sizeof (max_align_t); - #if defined __GNUC__ || defined __IBM__ALIGNOF__ + #if defined __GNUC__ || defined __clang__ || defined __IBM__ALIGNOF__ int check1[2 * (__alignof__ (double) <= __alignof__ (max_align_t)) - 1]; int check2[2 * (__alignof__ (long double) <= __alignof__ (max_align_t)) - 1]; #endif diff --git a/m4/stdint.m4 b/m4/stdint.m4 index 29ad826d8e..e0fa8a51fb 100644 --- a/m4/stdint.m4 +++ b/m4/stdint.m4 @@ -1,4 +1,4 @@ -# stdint.m4 serial 54 +# stdint.m4 serial 55 dnl Copyright (C) 2001-2020 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -152,7 +152,7 @@ uintmax_t j = UINTMAX_MAX; /* Check that SIZE_MAX has the correct type, if possible. */ #if 201112 <= __STDC_VERSION__ int k = _Generic (SIZE_MAX, size_t: 0); -#elif (2 <= __GNUC__ || defined __IBM__TYPEOF__ \ +#elif (2 <= __GNUC__ || 4 <= __clang_major__ || defined __IBM__TYPEOF__ \ || (0x5110 <= __SUNPRO_C && !__STDC__)) extern size_t k; extern __typeof__ (SIZE_MAX) k; commit 669aeafbd14b0ebb824bacba0a6b3daad30847a9 Author: Paul Eggert Date: Tue Aug 11 10:29:02 2020 -0700 Prefer make_nil_vector to make-vector with nil * src/pdumper.c (hash_table_thaw): Pacify -Wconversion so we can use make_nil_vector again. * src/timefns.c (syms_of_timefns): Prefer make_nil_vector to make_vector with Qnil. diff --git a/src/lisp.h b/src/lisp.h index d88038d91b..2962babb4f 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3947,7 +3947,8 @@ make_uninit_sub_char_table (int depth, int min_char) return v; } -/* Make a vector of SIZE nils. */ +/* Make a vector of SIZE nils - faster than make_vector (size, Qnil) + if the OS already cleared the new memory. */ INLINE Lisp_Object make_nil_vector (ptrdiff_t size) diff --git a/src/pdumper.c b/src/pdumper.c index 6c581bcd0b..aaa760d70d 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -2664,7 +2664,9 @@ static void hash_table_thaw (Lisp_Object hash) { struct Lisp_Hash_Table *h = XHASH_TABLE (hash); - h->hash = Fmake_vector (h->hash, Qnil); + ALLOW_IMPLICIT_CONVERSION; + h->hash = make_nil_vector (XFIXNUM (h->hash)); + DISALLOW_IMPLICIT_CONVERSION; h->next = Fmake_vector (h->next, make_fixnum (-1)); h->index = Fmake_vector (h->index, make_fixnum (-1)); diff --git a/src/timefns.c b/src/timefns.c index 7bcc37d7c1..94cfddf0da 100644 --- a/src/timefns.c +++ b/src/timefns.c @@ -2048,7 +2048,7 @@ syms_of_timefns (void) defsubr (&Scurrent_time_zone); defsubr (&Sset_time_zone_rule); - flt_radix_power = make_vector (flt_radix_power_size, Qnil); + flt_radix_power = make_nil_vector (flt_radix_power_size); staticpro (&flt_radix_power); #ifdef NEED_ZTRILLION_INIT commit b5b7f6eb88d6588f6150c34e1405457f062538bb Author: Eli Zaretskii Date: Tue Aug 11 19:59:17 2020 +0300 Fix MinGW build broken by recent pdumper changes. * src/pdumper.c (hash_table_thaw): Use Fmake_vector. Suggested by Pip Cet . (dump_trace): Declare ATTRIBUTE_FORMAT_PRINTF, not ATTRIBUTE_FORMAT((__printf__), so that we pick the right attribute for MinGW. diff --git a/src/pdumper.c b/src/pdumper.c index 94921dc9ea..6c581bcd0b 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -145,7 +145,7 @@ typedef int_least32_t dump_off; enum { EMACS_INT_XDIGITS = (EMACS_INT_WIDTH + 3) / 4 }; -static void ATTRIBUTE_FORMAT ((printf, 1, 2)) +static void ATTRIBUTE_FORMAT_PRINTF (1, 2) dump_trace (const char *fmt, ...) { if (0) @@ -2664,7 +2664,7 @@ static void hash_table_thaw (Lisp_Object hash) { struct Lisp_Hash_Table *h = XHASH_TABLE (hash); - h->hash = make_nil_vector (XFIXNUM (h->hash)); + h->hash = Fmake_vector (h->hash, Qnil); h->next = Fmake_vector (h->next, make_fixnum (-1)); h->index = Fmake_vector (h->index, make_fixnum (-1)); commit e0fa8fef6f45177fa4fa1d9983182471ef765ce7 Author: Bastian Beischer Date: Tue Aug 11 18:45:01 2020 +0200 Make mouse-2 respect select-enable-primary etc * lisp/calc/calc-yank.el (calc-yank-internal): Factor out into its own function (bug#23629). (calc-yank): Factored out from here. (calc-yank-mouse-primary): New command to Copyright-paperwork-exempt: yes diff --git a/lisp/calc/calc-yank.el b/lisp/calc/calc-yank.el index f5150ca552..b119f14980 100644 --- a/lisp/calc/calc-yank.el +++ b/lisp/calc/calc-yank.el @@ -150,34 +150,16 @@ ;; otherwise it just parses the yanked string. ;; Modified to use Emacs 19 extended concept of kill-ring. -- daveg 12/15/96 ;;;###autoload -(defun calc-yank (radix) - "Yank a value into the Calculator buffer. - -Valid numeric prefixes for RADIX: 0, 2, 6, 8 -No radix notation is prepended for any other numeric prefix. - -If RADIX is 2, prepend \"2#\" - Binary. -If RADIX is 8, prepend \"8#\" - Octal. -If RADIX is 0, prepend \"10#\" - Decimal. -If RADIX is 6, prepend \"16#\" - Hexadecimal. +(defun calc-yank-internal (radix thing-raw) + "Internal common implementation for yank functions. -If RADIX is a non-nil list (created using \\[universal-argument]), the user -will be prompted to enter the radix in the minibuffer. - -If RADIX is nil or if the yanked string already has a calc radix prefix, the -yanked string will be passed on directly to the Calculator buffer without any -alteration." - (interactive "P") +This function is used by both `calc-yank' and `calc-yank-mouse-primary'." (calc-wrapper (calc-pop-push-record-list 0 "yank" (let* (radix-num radix-notation valid-num-regexp - (thing-raw - (if (fboundp 'current-kill) - (current-kill 0 t) - (car kill-ring-yank-pointer))) (thing (if (or (null radix) ;; Match examples: -2#10, 10\n(10#10,01) @@ -232,6 +214,40 @@ alteration." val)) val)))))))) +;;;###autoload +(defun calc-yank-mouse-primary (radix) + "Yank the current primary selection into the Calculator buffer. +See `calc-yank' for details about RADIX." + (interactive "P") + (if (or select-enable-primary + select-enable-clipboard) + (calc-yank-internal radix (gui-get-primary-selection)) + ;; Yank from the kill ring. + (calc-yank radix))) + +;;;###autoload +(defun calc-yank (radix) + "Yank a value into the Calculator buffer. + +Valid numeric prefixes for RADIX: 0, 2, 6, 8 +No radix notation is prepended for any other numeric prefix. + +If RADIX is 2, prepend \"2#\" - Binary. +If RADIX is 8, prepend \"8#\" - Octal. +If RADIX is 0, prepend \"10#\" - Decimal. +If RADIX is 6, prepend \"16#\" - Hexadecimal. + +If RADIX is a non-nil list (created using \\[universal-argument]), the user +will be prompted to enter the radix in the minibuffer. + +If RADIX is nil or if the yanked string already has a calc radix prefix, the +yanked string will be passed on directly to the Calculator buffer without any +alteration." + (interactive "P") + (calc-yank-internal radix (if (fboundp 'current-kill) + (current-kill 0 t) + (car kill-ring-yank-pointer)))) + ;;; The Calc set- and get-register commands are modified versions of functions ;;; in register.el commit 4d4d3e42caca5d823dd66b62f25a1bdd833ba484 Author: Robert Weiner Date: Tue Aug 11 16:52:01 2020 +0200 Allow count-lines to ignore invisible lines * doc/lispref/positions.texi (Text Lines): Document it (bug#23675). * lisp/simple.el (count-lines): Add an optional parameter to ignore invisible lines (bug#23675). diff --git a/doc/lispref/positions.texi b/doc/lispref/positions.texi index d7856ce73e..91419702ca 100644 --- a/doc/lispref/positions.texi +++ b/doc/lispref/positions.texi @@ -411,7 +411,7 @@ function counts that line as one line successfully moved. In an interactive call, @var{count} is the numeric prefix argument. @end deffn -@defun count-lines start end +@defun count-lines start end &optional ignore-invisible-lines @cindex lines in region @anchor{Definition of count-lines} This function returns the number of lines between the positions @@ -420,6 +420,9 @@ This function returns the number of lines between the positions 1, even if @var{start} and @var{end} are on the same line. This is because the text between them, considered in isolation, must contain at least one line unless it is empty. + +If the optional @var{ignore-invisible-lines} is non-@code{nil}, +invisible lines will not be included in the count. @end defun @deffn Command count-words start end diff --git a/etc/NEWS b/etc/NEWS index f914e1be20..5c44c970dd 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -868,6 +868,10 @@ have now been removed. * Lisp Changes in Emacs 28.1 ++++ +** The 'count-lines' function now takes an optional parameter to +ignore invisible lines. + --- ** New function 'custom-add-choice'. This function can be used by modes to add elements to the diff --git a/lisp/simple.el b/lisp/simple.el index 4d59108a34..6f72c3b81b 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1366,28 +1366,47 @@ END, without printing any message." (message "line %d (narrowed line %d)" (+ n (line-number-at-pos start) -1) n)))))) -(defun count-lines (start end) +(defun count-lines (start end &optional ignore-invisible-lines) "Return number of lines between START and END. -This is usually the number of newlines between them, -but can be one more if START is not equal to END -and the greater of them is not at the start of a line." +This is usually the number of newlines between them, but can be +one more if START is not equal to END and the greater of them is +not at the start of a line. + +When IGNORE-INVISIBLE-LINES is non-nil, invisible lines are not +included in the count." (save-excursion (save-restriction (narrow-to-region start end) (goto-char (point-min)) - (if (eq selective-display t) - (save-match-data - (let ((done 0)) - (while (re-search-forward "[\n\C-m]" nil t 40) - (setq done (+ 40 done))) - (while (re-search-forward "[\n\C-m]" nil t 1) - (setq done (+ 1 done))) - (goto-char (point-max)) - (if (and (/= start end) - (not (bolp))) - (1+ done) - done))) - (- (buffer-size) (forward-line (buffer-size))))))) + (cond ((and (not ignore-invisible-lines) + (eq selective-display t)) + (save-match-data + (let ((done 0)) + (while (re-search-forward "\n\\|\r[^\n]" nil t 40) + (setq done (+ 40 done))) + (while (re-search-forward "\n\\|\r[^\n]" nil t 1) + (setq done (+ 1 done))) + (goto-char (point-max)) + (if (and (/= start end) + (not (bolp))) + (1+ done) + done)))) + (ignore-invisible-lines + (save-match-data + (- (buffer-size) + (forward-line (buffer-size)) + (let ((invisible-count 0) + prop) + (goto-char (point-min)) + (while (re-search-forward "\n\\|\r[^\n]" nil t) + (setq prop (get-char-property (1- (point)) 'invisible)) + (if (if (eq buffer-invisibility-spec t) + prop + (or (memq prop buffer-invisibility-spec) + (assq prop buffer-invisibility-spec))) + (setq invisible-count (1+ invisible-count)))) + invisible-count)))) + (t (- (buffer-size) (forward-line (buffer-size)))))))) (defun line-number-at-pos (&optional pos absolute) "Return buffer line number at position POS. commit 119a9ecfe1183f3b6f99a885689d10739687dcc8 Author: Michael Albinus Date: Tue Aug 11 16:46:41 2020 +0200 * lisp/net/tramp.el: Make last change backward compatible. diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index fdf26f6b78..d8113a9af9 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -3814,9 +3814,12 @@ support symbolic links." (setq current-buffer-p t) (current-buffer)) (t (get-buffer-create + ;; These variables have been introduced with Emacs 28.1. (if asynchronous - shell-command-buffer-name-async - shell-command-buffer-name))))) + (or (bound-and-true-p shell-command-buffer-name-async) + "*Async Shell Command*") + (or (bound-and-true-p shell-command-buffer-name) + "*Shell Command Output*")))))) (error-buffer (cond ((bufferp error-buffer) error-buffer) commit 39c90f8dfabe158ad7ac9243aa9b9dedb9409e19 Author: Eli Zaretskii Date: Tue Aug 11 17:39:35 2020 +0300 Fix face merging at EOL when inherited face specifies :extend * src/xfaces.c (merge_face_ref): Handle correctly faces that inherit from another, and in addition specify :extend. (Bug#42552) diff --git a/src/xfaces.c b/src/xfaces.c index 585cfa1cf4..2c6e593f63 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -2517,6 +2517,7 @@ merge_face_ref (struct window *w, { bool ok = true; /* Succeed without an error? */ Lisp_Object filtered_face_ref; + bool attr_filter_passed = false; filtered_face_ref = face_ref; do @@ -2613,6 +2614,7 @@ merge_face_ref (struct window *w, || UNSPECIFIEDP (scratch_attrs[attr_filter])) return true; } + attr_filter_passed = true; } while (CONSP (face_ref) && CONSP (XCDR (face_ref))) { @@ -2776,9 +2778,21 @@ merge_face_ref (struct window *w, { /* This is not really very useful; it's just like a normal face reference. */ - if (! merge_face_ref (w, f, value, to, - err_msgs, named_merge_points, - attr_filter)) + if (attr_filter_passed) + { + /* We already know that this face was tested + against attr_filter and was found applicable, + so don't pass attr_filter to merge_face_ref. + This is for when a face is specified like + (:inherit FACE :extend t), but the parent + FACE itself doesn't specify :extend. */ + if (! merge_face_ref (w, f, value, to, + err_msgs, named_merge_points, 0)) + err = true; + } + else if (! merge_face_ref (w, f, value, to, + err_msgs, named_merge_points, + attr_filter)) err = true; } else if (EQ (keyword, QCextend)) commit 05bffa1f0e3e04a501801d8e7417b623ac78a584 Author: Robert Weiner Date: Tue Aug 11 16:37:01 2020 +0200 Add new commands for environment movement in .texi files * lisp/textmodes/texinfo.el (texinfo-mode-map): New keystrokes for environment movement commands (bug#23985). diff --git a/etc/NEWS b/etc/NEWS index 271a190490..f914e1be20 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -522,6 +522,14 @@ with a newline. *** New user option 'texinfo-texi2dvi-options'. This is used when invoking 'texi2dvi' from 'texinfo-tex-buffer'. +--- +*** New commands for moving in and between environments. +An "environment" is something that ends with @end. The commands are +'C-c C-c C-f' (next end), 'C-c C-c C-b' (previous end), +'C-c C-c C-n' (next start) and 'C-c C-c C-p' (previous start), as well +as 'C-c .', which will alternate between the start end the end of the +current environment. + ** Rmail --- diff --git a/lisp/textmodes/texinfo.el b/lisp/textmodes/texinfo.el index 66378cb346..b3bc634de9 100644 --- a/lisp/textmodes/texinfo.el +++ b/lisp/textmodes/texinfo.el @@ -482,6 +482,13 @@ Subexpression 1 is what goes into the corresponding `@end' statement.") (define-key map "\C-c\C-ce" 'texinfo-insert-@end) (define-key map "\C-c\C-cd" 'texinfo-insert-@dfn) (define-key map "\C-c\C-cc" 'texinfo-insert-@code) + + ;; bindings for environment movement + (define-key map "\C-c." 'texinfo-to-environment-bounds) + (define-key map "\C-c\C-c\C-f" 'texinfo-next-environment-end) + (define-key map "\C-c\C-c\C-b" 'texinfo-previous-environment-end) + (define-key map "\C-c\C-c\C-n" 'texinfo-next-environment-start) + (define-key map "\C-c\C-c\C-p" 'texinfo-previous-environment-start) map)) (easy-menu-define texinfo-mode-menu @@ -1072,6 +1079,70 @@ You are prompted for the job number (use a number shown by a previous ;; job-number"\n")) (tex-recenter-output-buffer nil)) +(defun texinfo-to-environment-bounds () + "Move point alternately to the start and end of a Texinfo environment. +Do nothing when outside of an environment. This command does not +handle nested environments." + (interactive) + (cond ((save-excursion + (forward-line 0) + (looking-at texinfo-environment-regexp)) + (if (save-excursion + (forward-line 0) + (looking-at "^@end")) + (texinfo-previous-environment-start) + (texinfo-next-environment-end))) + ((save-excursion + (and (re-search-backward texinfo-environment-regexp nil t) + (not (looking-at "^@end")))) + (texinfo-previous-environment-start)) + ;; Otherwise, point is outside of an environment, so do nothing. + )) + +(defun texinfo-next-environment-start () + "Move forward to the beginning of a Texinfo environment." + (interactive) + (if (looking-at texinfo-environment-regexp) + (forward-line 1)) + (while (and (re-search-forward texinfo-environment-regexp nil t) + (save-excursion + (goto-char (match-beginning 0)) + (looking-at "@end")))) + (if (save-excursion + (forward-line 0) + (looking-at texinfo-environment-regexp)) + (forward-line 0))) + +(defun texinfo-previous-environment-start () + "Move back to the beginning of the previous Texinfo environment." + (interactive) + (while (and (re-search-backward texinfo-environment-regexp nil t) + (save-excursion + (goto-char (match-beginning 0)) + (looking-at "@end"))))) + +(defun texinfo-next-environment-end () + "Move forward to the beginning of the next @end line of an environment." + (interactive) + (if (looking-at "^@end") + (forward-line 1)) + (while (and (re-search-forward texinfo-environment-regexp nil t) + (save-excursion + (goto-char (match-beginning 0)) + (not (looking-at "^@end"))))) + (if (save-excursion + (forward-line 0) + (looking-at "^@end")) + (forward-line 0))) + +(defun texinfo-previous-environment-end () + "Move backward to the beginning of the next @end line of an environment." + (interactive) + (while (and (re-search-backward texinfo-environment-regexp nil t) + (save-excursion + (goto-char (match-beginning 0)) + (not (looking-at "@end")))))) + (provide 'texinfo) ;;; texinfo.el ends here commit be0fecf81911622ad166be00c59900033fcfde71 Author: Puneeth Chaganti Date: Tue Aug 11 16:23:10 2020 +0200 Allow specifying the callback in new xwidget sessions * lisp/xwidget.el (xwidget-webkit-new-session): Optional callback arg (bug#24019). (xwidget-event-handler): Respect the 'callback parameter. diff --git a/lisp/xwidget.el b/lisp/xwidget.el index aed6c09122..a4c15a1e26 100644 --- a/lisp/xwidget.el +++ b/lisp/xwidget.el @@ -207,12 +207,8 @@ Interactively, URL defaults to the string looking like a url around point." (let* ((xwidget-event-type (nth 1 last-input-event)) (xwidget (nth 2 last-input-event)) - ;;(xwidget-callback (xwidget-get xwidget 'callback)) - ;;TODO stopped working for some reason - ) - ;;(funcall xwidget-callback xwidget xwidget-event-type) - (message "xw callback %s" xwidget) - (funcall 'xwidget-webkit-callback xwidget xwidget-event-type))) + (xwidget-callback (xwidget-get xwidget 'callback))) + (funcall xwidget-callback xwidget xwidget-event-type))) (defun xwidget-webkit-callback (xwidget xwidget-event-type) "Callback for xwidgets. @@ -481,10 +477,11 @@ For example, use this to display an anchor." (add-to-list 'window-size-change-functions 'xwidget-webkit-adjust-size-in-frame)) -(defun xwidget-webkit-new-session (url) +(defun xwidget-webkit-new-session (url &optional callback) "Create a new webkit session buffer with URL." (let* ((bufname (generate-new-buffer-name "*xwidget-webkit*")) + (callback (or callback #'xwidget-webkit-callback)) xw) (setq xwidget-webkit-last-session-buffer (switch-to-buffer (get-buffer-create bufname))) @@ -494,7 +491,7 @@ For example, use this to display an anchor." (setq xw (xwidget-insert 1 'webkit bufname (window-pixel-width) (window-pixel-height))) - (xwidget-put xw 'callback 'xwidget-webkit-callback) + (xwidget-put xw 'callback callback) (xwidget-webkit-mode) (xwidget-webkit-goto-uri (xwidget-webkit-last-session) url))) commit 9b9473ad755da13cb74bf33c99c081f39eec6e08 Author: Noam Postavsky Date: Tue Aug 11 16:02:11 2020 +0200 Fix (end-of-defun N) for N >= 2 * lisp/emacs-lisp/lisp.el (end-of-defun): Only skip to next line when after end of defun when ARG is 1 or less. * test/lisp/emacs-lisp/lisp-tests.el (end-of-defun-twice): New test (bug#24427). diff --git a/lisp/emacs-lisp/lisp.el b/lisp/emacs-lisp/lisp.el index 043cf01d2e..8c18557c79 100644 --- a/lisp/emacs-lisp/lisp.el +++ b/lisp/emacs-lisp/lisp.el @@ -482,7 +482,8 @@ is called as a function to find the defun's end." (if (looking-at "\\s<\\|\n") (forward-line 1)))))) (funcall end-of-defun-function) - (funcall skip) + (when (<= arg 1) + (funcall skip)) (cond ((> arg 0) ;; Moving forward. diff --git a/test/lisp/emacs-lisp/lisp-tests.el b/test/lisp/emacs-lisp/lisp-tests.el index 8736ac7020..a2b8304c96 100644 --- a/test/lisp/emacs-lisp/lisp-tests.el +++ b/test/lisp/emacs-lisp/lisp-tests.el @@ -367,6 +367,61 @@ start." " "Test buffer for `mark-defun'.")) +;;; end-of-defun + +(ert-deftest end-of-defun-twice () + "Test behavior of prefix arg for `end-of-defun' (Bug#24427). +Calling `end-of-defun' twice should be the same as a prefix arg +of two." + (setq last-command nil) + (cl-flet ((eod2 (lambda () + (goto-char (point-min)) + (end-of-defun) + (end-of-defun) + (let ((pt-eod2 (point))) + (goto-char (point-min)) + (end-of-defun 2) + (should (= (point) pt-eod2)))))) + (with-temp-buffer + (insert "\ +\(defun a ()) + +\(defun b ()) + +\(defun c ())") + (eod2)) + (with-temp-buffer + (insert "\ +\(defun a ()) +\(defun b ()) +\(defun c ())") + (eod2))) + (elisp-tests-with-temp-buffer ";; Comment header + +\(defun func-1 (arg) + \"docstring\" + body) +=!p1= +;; Comment before a defun +\(defun func-2 (arg) + \"docstring\" + body) + +\(defun func-3 (arg) + \"docstring\" + body) +=!p2=(defun func-4 (arg) + \"docstring\" + body) + +;; end +" + (goto-char p1) + (end-of-defun 2) + (should (= (point) p2)))) + +;;; mark-defun + (ert-deftest mark-defun-no-arg-region-inactive () "Test `mark-defun' with no prefix argument and inactive region." commit 2a47ef86e95fad1dcc14a02e7471ba5d9cad4b9b Author: Tino Calancha Date: Tue Aug 11 15:40:48 2020 +0200 Change the Calc text input method to insert at point * lisp/calc/calc.el (calcDigit-delchar): New command to delete chars forward in the calc minibuffer. (calc-digit-map): Bind calcDigit-delchar to '\C-d'. (calcDigit-key): Do not go to (point-max) in calc minibuffer before insert a digit (Bug#24612). diff --git a/etc/NEWS b/etc/NEWS index 49c0b8688c..271a190490 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -757,6 +757,15 @@ name. ** Recentf The recentf files are no longer backed up. +** Calc + +--- +*** The behaviour when doing forward-delete has been changed. +Previously, using the 'C-d' command would delete the final number in +the input field, no matter where point was. This has been changed to +work more traditionally, with 'C-d' deleting the next character. +Likewise, point isn't moved to the end of the string before inserting +digits. ** Miscellaneous diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el index 09b4962107..fb1287baaa 100644 --- a/lisp/calc/calc.el +++ b/lisp/calc/calc.el @@ -1087,8 +1087,26 @@ Used by `calc-user-invocation'.") (append (where-is-internal 'delete-backward-char global-map) (where-is-internal 'backward-delete-char global-map) (where-is-internal 'backward-delete-char-untabify global-map) - '("\C-d")) - '("\177" "\C-d"))) + '("\177")) + '("\177"))) + +(mapc (lambda (x) + (ignore-errors + (define-key calc-digit-map x 'calcDigit-delchar) + (define-key calc-mode-map x 'calc-pop) + (define-key calc-mode-map + (if (and (vectorp x) (featurep 'xemacs)) + (if (= (length x) 1) + (vector (if (consp (aref x 0)) + (cons 'meta (aref x 0)) + (list 'meta (aref x 0)))) + "\e\C-d") + (vconcat "\e" x)) + 'calc-pop-above))) + (if calc-scan-for-dels + (append (where-is-internal 'delete-forward-char global-map) + '("\C-d")) + '("\C-d"))) (defvar calc-dispatch-map (let ((map (make-keymap))) @@ -2343,7 +2361,6 @@ the United States." (defun calcDigit-key () (interactive) - (goto-char (point-max)) (if (or (and (memq last-command-event '(?+ ?-)) (> (buffer-size) 0) (/= (preceding-char) ?e)) @@ -2386,8 +2403,7 @@ the United States." (delete-char 1)) (if (looking-at "-") (delete-char 1) - (insert "-"))) - (goto-char (point-max))) + (insert "-")))) ((eq last-command-event ?p) (if (or (calc-minibuffer-contains ".*\\+/-.*") (calc-minibuffer-contains ".*mod.*") @@ -2440,17 +2456,9 @@ the United States." (setq calc-prev-prev-char calc-prev-char calc-prev-char last-command-event)) - (defun calcDigit-backspace () (interactive) - (goto-char (point-max)) - (cond ((calc-minibuffer-contains ".* \\+/- \\'") - (backward-delete-char 5)) - ((calc-minibuffer-contains ".* mod \\'") - (backward-delete-char 5)) - ((calc-minibuffer-contains ".* \\'") - (backward-delete-char 2)) - ((eq last-command 'calcDigit-start) + (cond ((eq last-command 'calcDigit-start) (erase-buffer)) (t (backward-delete-char 1))) (if (= (calc-minibuffer-size) 0) @@ -2925,6 +2933,20 @@ the United States." (- (- (nth 2 a) (nth 2 b)) ldiff)))) +(defun calcDigit-delchar () + (interactive) + (cond ((looking-at-p " \\+/- \\'") + (delete-char 5)) + ((looking-at-p " mod \\'") + (delete-char 5)) + ((looking-at-p " \\'") + (delete-char 2)) + ((eq last-command 'calcDigit-start) + (erase-buffer)) + (t (unless (eobp) (delete-char 1)))) + (when (= (calc-minibuffer-size) 0) + (setq last-command-event 13) + (calcDigit-nondigit))) (defvar math-comp-selected) commit e7819074013ac3c2b84abbc05a6f4f6c413d981e Author: Alexander Gramiak Date: Tue Aug 11 15:26:24 2020 +0200 Only search for a variable when instructed * lisp/help-fns.el (find-lisp-object-file-name): Check for 'defvar argument before searching for an internal variable (Bug#24697). * test/lisp/help-fns-tests.el: New tests. diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 5a99103f6a..a137c50488 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -364,6 +364,7 @@ suitable file is found, return nil." (help-C-file-name type 'subr) 'C-source)) ((and (not file-name) (symbolp object) + (eq type 'defvar) (integerp (get object 'variable-documentation))) ;; A variable defined in C. The form is from `describe-variable'. (if (get-buffer " *DOC*") diff --git a/test/lisp/help-fns-tests.el b/test/lisp/help-fns-tests.el index d2dc3d24ae..da2b49e6b8 100644 --- a/test/lisp/help-fns-tests.el +++ b/test/lisp/help-fns-tests.el @@ -160,4 +160,15 @@ Return first line of the output of (describe-function-1 FUNC)." (with-current-buffer "*Help*" (should (looking-at "^help-fns-test--describe-keymap-foo is")))) +;;; Tests for find-lisp-object-file-name +(ert-deftest help-fns-test-bug24697-function-search () + (should-not (find-lisp-object-file-name 'tab-width 1))) + +(ert-deftest help-fns-test-bug24697-non-internal-variable () + (let ((help-fns--test-var (make-symbol "help-fns--test-var"))) + ;; simulate an internal variable + (put help-fns--test-var 'variable-documentation 1) + (should-not (find-lisp-object-file-name help-fns--test-var 'defface)) + (should-not (find-lisp-object-file-name help-fns--test-var 1)))) + ;;; help-fns-tests.el ends here commit 9b01badf7cf7bb6cd64bc8d39564b46ae74b889f Author: Kaushal Modi Date: Tue Aug 11 15:16:11 2020 +0200 Allow Dired to dereference symbolic links when copying * doc/emacs/dired.texi (Operating on Files): Mention the new defcustom (bug#25075). * lisp/dired-aux.el (dired-do-copy): Invert the value of `dired-copy-dereference' in lexical scope when prefix argument is '(4). Update function documentation for the new defcustom. * lisp/dired-aux.el (dired-copy-file): Use `dired-copy-dereference' as the `dereference' argument to `dired-copy-file-recursive'. * lisp/dired-aux.el (dired-copy-file-recursive): Add new optional argument `dereference'. * lisp/dired.el (dired-copy-dereference): New defcustom, defaults to nil. diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi index 4ff1dc1bd9..de449e31c3 100644 --- a/doc/emacs/dired.texi +++ b/doc/emacs/dired.texi @@ -694,6 +694,14 @@ The variable @code{dired-recursive-copies} controls whether to copy directories recursively (like @samp{cp -r}). The default is @code{top}, which means to ask before recursively copying a directory. +@vindex dired-copy-dereference +@cindex follow symbolic links +@cindex dereference symbolic links +The variable @code{dired-copy-dereference} controls whether to copy +symbolic links as links or after dereferencing (like @samp{cp -L}). +The default is @code{nil}, which means that the symbolic links are +copied by creating new ones. + @item D @findex dired-do-delete @kindex D @r{(Dired)} diff --git a/etc/NEWS b/etc/NEWS index ddb42fbb4b..49c0b8688c 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -222,6 +222,12 @@ like "+0100" instead of "CET". ** Dired ++++ +*** New used option 'dired-copy-dereference'. +If set, Dired will dereferences symbolic links when copying. This can +be switched off on a per-usage basis by providing 'dired-do-copy' with +a 'C-u' prefix. + *** New user option 'dired-mark-region' affects all Dired commands that mark files. When non-nil and the region is active in Transient Mark mode, then Dired commands operate only on files in the active diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 69b175339a..c197ed04fe 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -1604,7 +1604,7 @@ Special value `always' suppresses confirmation." (defun dired-copy-file (from to ok-flag) (dired-handle-overwrite to) (dired-copy-file-recursive from to ok-flag dired-copy-preserve-time t - dired-recursive-copies)) + dired-recursive-copies dired-copy-dereference)) (declare-function make-symbolic-link "fileio.c") @@ -1627,7 +1627,8 @@ If `ask', ask for user confirmation." (dired-create-directory dir)))) (defun dired-copy-file-recursive (from to ok-flag &optional - preserve-time top recursive) + preserve-time top recursive + dereference) (when (and (eq t (file-attribute-type (file-attributes from))) (file-in-directory-p to from)) (error "Cannot copy `%s' into its subdirectory `%s'" from to)) @@ -1639,7 +1640,8 @@ If `ask', ask for user confirmation." (copy-directory from to preserve-time) (or top (dired-handle-overwrite to)) (condition-case err - (if (stringp (file-attribute-type attrs)) + (if (and (not dereference) + (stringp (file-attribute-type attrs))) ;; It is a symlink (make-symbolic-link (file-attribute-type attrs) to ok-flag) (dired-maybe-create-dirs (file-name-directory to)) @@ -2165,6 +2167,9 @@ See HOW-TO argument for `dired-do-create-files'.") ;;;###autoload (defun dired-do-copy (&optional arg) "Copy all marked (or next ARG) files, or copy the current file. +ARG has to be numeric for above functionality. See +`dired-get-marked-files' for more details. + When operating on just the current file, prompt for the new name. When operating on multiple or marked files, prompt for a target @@ -2178,10 +2183,18 @@ If `dired-copy-preserve-time' is non-nil, this command preserves the modification time of each old file in the copy, similar to the \"-p\" option for the \"cp\" shell command. -This command copies symbolic links by creating new ones, similar -to the \"-d\" option for the \"cp\" shell command." +This command copies symbolic links by creating new ones, +similar to the \"-d\" option for the \"cp\" shell command. +But if `dired-copy-dereference' is non-nil, the symbolic +links are dereferenced and then copied, similar to the \"-L\" +option for the \"cp\" shell command. If ARG is a cons with +element 4 (`\\[universal-argument]'), the inverted value of +`dired-copy-dereference' will be used." (interactive "P") - (let ((dired-recursive-copies dired-recursive-copies)) + (let ((dired-recursive-copies dired-recursive-copies) + (dired-copy-dereference (if (equal arg '(4)) + (not dired-copy-dereference) + dired-copy-dereference))) (dired-do-create-files 'copy #'dired-copy-file "Copy" arg dired-keep-marker-copy diff --git a/lisp/dired.el b/lisp/dired.el index d19d6d1581..77bb6cfa9c 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -216,6 +216,12 @@ The target is used in the prompt for file copy, rename etc." :type 'boolean :group 'dired) +(defcustom dired-copy-dereference nil + "If non-nil, Dired dereferences symlinks when copying them. +This is similar to the \"-L\" option for the \"cp\" shell command." + :type 'boolean + :group 'dired) + ; ; These variables were deleted and the replacements are on files.el. ; We leave aliases behind for back-compatibility. (define-obsolete-variable-alias 'dired-free-space-program commit dcfd16cc687d622d66a72bc30bbeb5ae973dde03 Author: Lars Ingebrigtsen Date: Tue Aug 11 13:44:33 2020 +0200 Mark further mml-sec-tests as unstable * test/lisp/gnus/mml-sec-tests.el (mml-secure-en-decrypt-sign-3): (mml-secure-en-decrypt-sign-1-3-double): These tests are unstable on Ubuntu (bug#42803). diff --git a/test/lisp/gnus/mml-sec-tests.el b/test/lisp/gnus/mml-sec-tests.el index 8f78a66f61..272918688d 100644 --- a/test/lisp/gnus/mml-sec-tests.el +++ b/test/lisp/gnus/mml-sec-tests.el @@ -663,6 +663,7 @@ In this test, just multiple encryption and signing keys may be available." (ert-deftest mml-secure-en-decrypt-sign-1-3-double () "Sign and encrypt message; then decrypt and test for expected result. In this test, just multiple encryption and signing keys may be available." + :tags '(:unstable) (skip-unless (test-conf)) (mml-secure-test-key-fixture (lambda () @@ -714,6 +715,7 @@ In this test, lists of encryption and signing keys are customized." (ert-deftest mml-secure-en-decrypt-sign-3 () "Sign and encrypt message; then decrypt and test for expected result. Use sign-with-sender and encrypt-to-self." + :tags '(:unstable) (skip-unless (test-conf)) (mml-secure-test-key-fixture (lambda () commit 1687cda47b5d273688ace5e785d3868b6263bfaf Author: Lars Ingebrigtsen Date: Tue Aug 11 13:16:07 2020 +0200 Further tweaks to the user manual about shell-command-buffer-name * doc/emacs/misc.texi (Single Shell): Reintroduce the actual buffer names in the user manual (bug#39138), but keep the references to the variables. It's easier for people reading the user manual to deal with actual names. diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index 39aae87efa..f3c9d76981 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi @@ -729,10 +729,9 @@ See the Eshell Info manual, which is distributed with Emacs. minibuffer and executes it as a shell command, in a subshell made just for that command. Standard input for the command comes from the null device. If the shell command produces any output, the output appears -either in the echo area (if it is short), or in an Emacs buffer, -displayed in another window (if the output is long). The name of -this buffer is taken from the constant @code{shell-command-buffer-name}. -The variables @code{resize-mini-windows} and +either in the echo area (if it is short), or in the @samp{"*Shell +Command Output*"} (@code{shell-command-buffer-name}) buffer (if the +output is long). The variables @code{resize-mini-windows} and @code{max-mini-window-height} (@pxref{Minibuffer Edit}) control when Emacs should consider the output to be too long for the echo area. @@ -766,10 +765,11 @@ which is impossible to ignore. You can also type @kbd{M-&} (@code{async-shell-command}) to execute a shell command asynchronously; this is exactly like calling @kbd{M-!} with a trailing @samp{&}, except that you do not need the @samp{&}. -The constant @code{shell-command-buffer-name-async} stores the name -of the default output buffer for asynchronous shell commands. -Emacs inserts the output into this buffer as it comes in, -whether or not the buffer is visible in a window. +The output from asynchronous shell commands, by default, goes into the +@samp{"*Async Shell Command*"} buffer +(@code{shell-command-buffer-name-async}). Emacs inserts the output +into this buffer as it comes in, whether or not the buffer is visible +in a window. @vindex async-shell-command-buffer If you want to run more than one asynchronous shell command at the commit 25b416888847db26fa6de2e64d628851a275e10c Author: Paul Eggert Date: Tue Aug 11 02:16:54 2020 -0700 pdumper avoid listing hash table contents * src/pdumper.c (hash_table_contents): Create a vector directly, instead of creating a list and then converting that to a vector. diff --git a/src/pdumper.c b/src/pdumper.c index bc9d197ca2..94921dc9ea 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -2617,25 +2617,28 @@ hash_table_contents (struct Lisp_Hash_Table *h) { if (h->test.hashfn == hashfn_user_defined) error ("cannot dump hash tables with user-defined tests"); /* Bug#36769 */ - Lisp_Object contents = Qnil; + + ptrdiff_t size = HASH_TABLE_SIZE (h); + Lisp_Object key_and_value = make_uninit_vector (2 * size); + ptrdiff_t n = 0; /* Make sure key_and_value ends up in the same order; charset.c relies on it by expecting hash table indices to stay constant across the dump. */ - for (ptrdiff_t i = 0; i < HASH_TABLE_SIZE (h) - h->count; i++) - { - dump_push (&contents, Qnil); - dump_push (&contents, Qunbound); - } - - for (ptrdiff_t i = HASH_TABLE_SIZE (h) - 1; i >= 0; --i) + for (ptrdiff_t i = 0; i < size; i++) if (!NILP (HASH_HASH (h, i))) { - dump_push (&contents, HASH_VALUE (h, i)); - dump_push (&contents, HASH_KEY (h, i)); + ASET (key_and_value, n++, HASH_KEY (h, i)); + ASET (key_and_value, n++, HASH_VALUE (h, i)); } - return CALLN (Fapply, Qvector, contents); + while (n < 2 * size) + { + ASET (key_and_value, n++, Qunbound); + ASET (key_and_value, n++, Qnil); + } + + return key_and_value; } static dump_off commit 53132c1639beb2fc8687d88a6e17fffa4216b440 Author: Paul Eggert Date: Tue Aug 11 02:16:54 2020 -0700 pdumper speed tweeks for hash tables * src/pdumper.c (dump_queue_empty_p): Avoid unnecessary call to Fhash_table_count on a known hash table. (dump_hash_table_list): !NILP, not CONSP. (hash_table_freeze, hash_table_thaw): ASIZE, not Flength, on vectors. Initialize in same order as struct. (hash_table_thaw): make_nil_vector, not Fmake_vector with nil. diff --git a/src/pdumper.c b/src/pdumper.c index fcad5242df..bc9d197ca2 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -964,11 +964,9 @@ dump_queue_init (struct dump_queue *dump_queue) static bool dump_queue_empty_p (struct dump_queue *dump_queue) { - bool is_empty = - EQ (Fhash_table_count (dump_queue->sequence_numbers), - make_fixnum (0)); - eassert (EQ (Fhash_table_count (dump_queue->sequence_numbers), - Fhash_table_count (dump_queue->link_weights))); + ptrdiff_t count = XHASH_TABLE (dump_queue->sequence_numbers)->count; + bool is_empty = count == 0; + eassert (count == XFIXNAT (Fhash_table_count (dump_queue->link_weights))); if (!is_empty) { eassert (!dump_tailq_empty_p (&dump_queue->zero_weight_objects) @@ -2643,7 +2641,7 @@ hash_table_contents (struct Lisp_Hash_Table *h) static dump_off dump_hash_table_list (struct dump_context *ctx) { - if (CONSP (ctx->hash_tables)) + if (!NILP (ctx->hash_tables)) return dump_object (ctx, CALLN (Fapply, Qvector, ctx->hash_tables)); else return 0; @@ -2652,20 +2650,20 @@ dump_hash_table_list (struct dump_context *ctx) static void hash_table_freeze (struct Lisp_Hash_Table *h) { - ptrdiff_t nkeys = XFIXNAT (Flength (h->key_and_value)) / 2; + ptrdiff_t npairs = ASIZE (h->key_and_value) / 2; h->key_and_value = hash_table_contents (h); - h->next_free = (nkeys == h->count ? -1 : h->count); - h->index = Flength (h->index); - h->next = h->hash = make_fixnum (nkeys); + h->next = h->hash = make_fixnum (npairs); + h->index = make_fixnum (ASIZE (h->index)); + h->next_free = (npairs == h->count ? -1 : h->count); } static void hash_table_thaw (Lisp_Object hash) { struct Lisp_Hash_Table *h = XHASH_TABLE (hash); - h->index = Fmake_vector (h->index, make_fixnum (-1)); - h->hash = Fmake_vector (h->hash, Qnil); + h->hash = make_nil_vector (XFIXNUM (h->hash)); h->next = Fmake_vector (h->next, make_fixnum (-1)); + h->index = Fmake_vector (h->index, make_fixnum (-1)); hash_table_rehash (hash); } commit 9e4e4775364490d31406f247237934dd7f203808 Author: Paul Eggert Date: Tue Aug 11 02:16:54 2020 -0700 In pdumper, simplify INT_MAX computation * src/pdumper.c (dump_read_all): Avoid unnecessary cast. Also, round down to page size, as sysdep.c does. Also, don’t assume INT_MAX <= UINT_MAX (!). diff --git a/src/pdumper.c b/src/pdumper.c index 6d303af77d..fcad5242df 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -5065,14 +5065,13 @@ dump_read_all (int fd, void *buf, size_t bytes_to_read) { /* We don't want to use emacs_read, since that relies on the lisp world, and we're not in the lisp world yet. */ - eassert (bytes_to_read <= SSIZE_MAX); size_t bytes_read = 0; while (bytes_read < bytes_to_read) { - /* Some platforms accept only int-sized values to read. */ - unsigned chunk_to_read = INT_MAX; - if (bytes_to_read - bytes_read < chunk_to_read) - chunk_to_read = (unsigned) (bytes_to_read - bytes_read); + /* Some platforms accept only int-sized values to read. + Round this down to a page size (see MAX_RW_COUNT in sysdep.c). */ + int max_rw_count = INT_MAX >> 18 << 18; + size_t chunk_to_read = min (bytes_to_read - bytes_read, max_rw_count); ssize_t chunk = read (fd, (char *) buf + bytes_read, chunk_to_read); if (chunk < 0) return chunk; commit eeaef1aec6d881f206a37c6e476fd94a5c289fc3 Author: Paul Eggert Date: Tue Aug 11 02:16:54 2020 -0700 Don’t needlessly convert to ‘unsigned’ in pdumper * src/pdumper.c (PRIdDUMP_OFF): New macro. (EMACS_INT_XDIGITS): New constant. (struct dump_context): Use dump_off for relocation counts. All uses changed. (dump_queue_enqueue, dump_queue_dequeue, Fdump_emacs_portable): Don’t assume counts fit in ‘unsigned’ or ‘unsigned long’. Use EMACS_INT_XDIGITS instead of assuming it’s 16. diff --git a/src/pdumper.c b/src/pdumper.c index c38cb2d34f..6d303af77d 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -141,6 +141,9 @@ static int nr_remembered_data = 0; typedef int_least32_t dump_off; #define DUMP_OFF_MIN INT_LEAST32_MIN #define DUMP_OFF_MAX INT_LEAST32_MAX +#define PRIdDUMP_OFF PRIdLEAST32 + +enum { EMACS_INT_XDIGITS = (EMACS_INT_WIDTH + 3) / 4 }; static void ATTRIBUTE_FORMAT ((printf, 1, 2)) dump_trace (const char *fmt, ...) @@ -553,8 +556,8 @@ struct dump_context /* List of hash tables that have been dumped. */ Lisp_Object hash_tables; - unsigned number_hot_relocations; - unsigned number_discardable_relocations; + dump_off number_hot_relocations; + dump_off number_discardable_relocations; }; /* These special values for use as offsets in dump_remember_object and @@ -1007,9 +1010,9 @@ dump_queue_enqueue (struct dump_queue *dump_queue, if (NILP (weights)) { /* Object is new. */ - dump_trace ("new object %016x weight=%u\n", - (unsigned) XLI (object), - (unsigned) weight.value); + EMACS_UINT uobj = XLI (object); + dump_trace ("new object %0*"pI"x weight=%d\n", EMACS_INT_XDIGITS, uobj, + weight.value); if (weight.value == WEIGHT_NONE.value) { @@ -1224,17 +1227,15 @@ dump_queue_dequeue (struct dump_queue *dump_queue, dump_off basis) + dump_tailq_length (&dump_queue->one_weight_normal_objects) + dump_tailq_length (&dump_queue->one_weight_strong_objects))); - bool dump_object_counts = true; - if (dump_object_counts) - dump_trace - ("dump_queue_dequeue basis=%d fancy=%u zero=%u " - "normal=%u strong=%u hash=%u\n", - basis, - (unsigned) dump_tailq_length (&dump_queue->fancy_weight_objects), - (unsigned) dump_tailq_length (&dump_queue->zero_weight_objects), - (unsigned) dump_tailq_length (&dump_queue->one_weight_normal_objects), - (unsigned) dump_tailq_length (&dump_queue->one_weight_strong_objects), - (unsigned) XFIXNUM (Fhash_table_count (dump_queue->link_weights))); + dump_trace + (("dump_queue_dequeue basis=%"PRIdDUMP_OFF" fancy=%"PRIdPTR + " zero=%"PRIdPTR" normal=%"PRIdPTR" strong=%"PRIdPTR" hash=%td\n"), + basis, + dump_tailq_length (&dump_queue->fancy_weight_objects), + dump_tailq_length (&dump_queue->zero_weight_objects), + dump_tailq_length (&dump_queue->one_weight_normal_objects), + dump_tailq_length (&dump_queue->one_weight_strong_objects), + XHASH_TABLE (dump_queue->link_weights)->count); static const int nr_candidates = 3; struct candidate @@ -1307,10 +1308,10 @@ dump_queue_dequeue (struct dump_queue *dump_queue, dump_off basis) else emacs_abort (); - dump_trace (" result score=%f src=%s object=%016x\n", + EMACS_UINT uresult = XLI (result); + dump_trace (" result score=%f src=%s object=%0*"pI"x\n", best < 0 ? -1.0 : (double) candidates[best].score, - src, - (unsigned) XLI (result)); + src, EMACS_INT_XDIGITS, uresult); { Lisp_Object weights = Fgethash (result, dump_queue->link_weights, Qnil); @@ -4162,9 +4163,9 @@ types. */) of the dump. */ drain_reloc_list (ctx, dump_emit_dump_reloc, emacs_reloc_merger, &ctx->dump_relocs, &ctx->header.dump_relocs); - unsigned number_hot_relocations = ctx->number_hot_relocations; + dump_off number_hot_relocations = ctx->number_hot_relocations; ctx->number_hot_relocations = 0; - unsigned number_discardable_relocations = ctx->number_discardable_relocations; + dump_off number_discardable_relocations = ctx->number_discardable_relocations; ctx->number_discardable_relocations = 0; drain_reloc_list (ctx, dump_emit_dump_reloc, emacs_reloc_merger, &ctx->object_starts, &ctx->header.object_starts); @@ -4188,14 +4189,17 @@ types. */) dump_seek (ctx, 0); dump_write (ctx, &ctx->header, sizeof (ctx->header)); + dump_off + header_bytes = header_end - header_start, + hot_bytes = hot_end - hot_start, + discardable_bytes = discardable_end - ctx->header.discardable_start, + cold_bytes = cold_end - ctx->header.cold_start; fprintf (stderr, ("Dump complete\n" - "Byte counts: header=%lu hot=%lu discardable=%lu cold=%lu\n" - "Reloc counts: hot=%u discardable=%u\n"), - (unsigned long) (header_end - header_start), - (unsigned long) (hot_end - hot_start), - (unsigned long) (discardable_end - ctx->header.discardable_start), - (unsigned long) (cold_end - ctx->header.cold_start), + "Byte counts: header=%"PRIdDUMP_OFF" hot=%"PRIdDUMP_OFF + " discardable=%"PRIdDUMP_OFF" cold=%"PRIdDUMP_OFF"\n" + "Reloc counts: hot=%"PRIdDUMP_OFF" discardable=%"PRIdDUMP_OFF"\n"), + header_bytes, hot_bytes, discardable_bytes, cold_bytes, number_hot_relocations, number_discardable_relocations); commit 5bd7b3c7f7af97f62bbc4f4ba9040e533e20e841 Author: Paul Eggert Date: Tue Aug 11 02:16:54 2020 -0700 * src/pdumper.c (pdumper_load): XSETVECTOR -> make_lisp_ptr. diff --git a/src/pdumper.c b/src/pdumper.c index 10dfa8737f..c38cb2d34f 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -391,6 +391,7 @@ struct dump_header boundary. */ dump_off cold_start; + /* Offset of a vector of the dumped hash tables. */ dump_off hash_list; }; @@ -549,6 +550,7 @@ struct dump_context heap objects. */ Lisp_Object bignum_data; + /* List of hash tables that have been dumped. */ Lisp_Object hash_tables; unsigned number_hot_relocations; @@ -2610,7 +2612,7 @@ dump_vectorlike_generic (struct dump_context *ctx, } /* Return a vector of KEY, VALUE pairs in the given hash table H. The - first H->count pairs are valid, the rest is left as nil. */ + first H->count pairs are valid, and the rest are unbound. */ static Lisp_Object hash_table_contents (struct Lisp_Hash_Table *h) { @@ -5405,8 +5407,8 @@ pdumper_load (const char *dump_filename) if (header->hash_list) { struct Lisp_Vector *hash_tables = - ((struct Lisp_Vector *)(dump_base + header->hash_list)); - XSETVECTOR (hashes, hash_tables); + (struct Lisp_Vector *) (dump_base + header->hash_list); + hashes = make_lisp_ptr (hash_tables, Lisp_Vectorlike); } pdumper_hashes = &hashes; commit 23c1d5dff99f1c5d502096be4584c786c55e9262 Author: Paul Eggert Date: Tue Aug 11 02:16:54 2020 -0700 * src/fns.c (hash_table_rehash): Help the compiler a bit. diff --git a/src/fns.c b/src/fns.c index 41e26104f3..9199178212 100644 --- a/src/fns.c +++ b/src/fns.c @@ -4250,14 +4250,16 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h) Normally there's never a need to recompute hashes. This is done only on first access to a hash-table loaded from the "pdump", because the objects' addresses may have changed, thus - affecting their hash. */ + affecting their hashes. */ void hash_table_rehash (Lisp_Object hash) { struct Lisp_Hash_Table *h = XHASH_TABLE (hash); + ptrdiff_t i, count = h->count; + /* Recompute the actual hash codes for each entry in the table. Order is still invalid. */ - for (ptrdiff_t i = 0; i < h->count; ++i) + for (i = 0; i < count; i++) { Lisp_Object key = HASH_KEY (h, i); Lisp_Object hash_code = h->test.hashfn (key, h); @@ -4268,7 +4270,8 @@ hash_table_rehash (Lisp_Object hash) eassert (HASH_NEXT (h, i) != i); /* Stop loops. */ } - for (ptrdiff_t i = h->count; i < ASIZE (h->next) - 1; i++) + ptrdiff_t size = ASIZE (h->next); + for (; i + 1 < size; i++) set_hash_next_slot (h, i, i + 1); } @@ -4892,7 +4895,6 @@ DEFUN ("hash-table-count", Fhash_table_count, Shash_table_count, 1, 1, 0, (Lisp_Object table) { struct Lisp_Hash_Table *h = check_hash_table (table); - return make_fixnum (h->count); } commit 16a16645f524c62f7906036b0e383e4247b58de7 Author: Pip Cet Date: Tue Aug 11 02:16:53 2020 -0700 Rehash hash tables eagerly after loading a dump This simplifies code, and helps performance in some cases (Bug#36597). * src/lisp.h (hash_rehash_needed_p): Remove. All uses removed. (hash_rehash_if_needed): Remove. All uses removed. (struct Lisp_Hash_Table): Remove comment about rehashing hash tables. * src/pdumper.c (thaw_hash_tables): New function. (hash_table_thaw): New function. (hash_table_freeze): New function. (dump_hash_table): Simplify. (dump_hash_table_list): New function. (hash_table_contents): New function. (Fdump_emacs_portable): Handle hash tables by eager rehashing. (pdumper_load): Restore hash tables. (init_pdumper_once): New function. diff --git a/src/bytecode.c b/src/bytecode.c index 1913a4812a..1c3b6eac0d 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -1401,7 +1401,6 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, Lisp_Object v1 = POP; ptrdiff_t i; struct Lisp_Hash_Table *h = XHASH_TABLE (jmp_table); - hash_rehash_if_needed (h); /* h->count is a faster approximation for HASH_TABLE_SIZE (h) here. */ diff --git a/src/composite.c b/src/composite.c index f96f0b7772..ec2b8328f7 100644 --- a/src/composite.c +++ b/src/composite.c @@ -652,7 +652,6 @@ Lisp_Object composition_gstring_put_cache (Lisp_Object gstring, ptrdiff_t len) { struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table); - hash_rehash_if_needed (h); Lisp_Object header = LGSTRING_HEADER (gstring); Lisp_Object hash = h->test.hashfn (header, h); if (len < 0) diff --git a/src/emacs.c b/src/emacs.c index 8e5eaf5e43..d31fa2cb28 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -1536,6 +1536,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem if (!initialized) { init_alloc_once (); + init_pdumper_once (); init_obarray_once (); init_eval_once (); init_charset_once (); diff --git a/src/fns.c b/src/fns.c index 811d6e8200..41e26104f3 100644 --- a/src/fns.c +++ b/src/fns.c @@ -4248,50 +4248,28 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h) /* Recompute the hashes (and hence also the "next" pointers). Normally there's never a need to recompute hashes. - This is done only on first-access to a hash-table loaded from - the "pdump", because the object's addresses may have changed, thus + This is done only on first access to a hash-table loaded from + the "pdump", because the objects' addresses may have changed, thus affecting their hash. */ void -hash_table_rehash (struct Lisp_Hash_Table *h) +hash_table_rehash (Lisp_Object hash) { - ptrdiff_t size = HASH_TABLE_SIZE (h); - - /* These structures may have been purecopied and shared - (bug#36447). */ - Lisp_Object hash = make_nil_vector (size); - h->next = Fcopy_sequence (h->next); - h->index = Fcopy_sequence (h->index); - + struct Lisp_Hash_Table *h = XHASH_TABLE (hash); /* Recompute the actual hash codes for each entry in the table. Order is still invalid. */ - for (ptrdiff_t i = 0; i < size; ++i) + for (ptrdiff_t i = 0; i < h->count; ++i) { Lisp_Object key = HASH_KEY (h, i); - if (!EQ (key, Qunbound)) - ASET (hash, i, h->test.hashfn (key, h)); + Lisp_Object hash_code = h->test.hashfn (key, h); + ptrdiff_t start_of_bucket = XUFIXNUM (hash_code) % ASIZE (h->index); + set_hash_hash_slot (h, i, hash_code); + set_hash_next_slot (h, i, HASH_INDEX (h, start_of_bucket)); + set_hash_index_slot (h, start_of_bucket, i); + eassert (HASH_NEXT (h, i) != i); /* Stop loops. */ } - /* Reset the index so that any slot we don't fill below is marked - invalid. */ - Ffillarray (h->index, make_fixnum (-1)); - - /* Rebuild the collision chains. */ - for (ptrdiff_t i = 0; i < size; ++i) - if (!NILP (AREF (hash, i))) - { - EMACS_UINT hash_code = XUFIXNUM (AREF (hash, i)); - ptrdiff_t start_of_bucket = hash_code % ASIZE (h->index); - set_hash_next_slot (h, i, HASH_INDEX (h, start_of_bucket)); - set_hash_index_slot (h, start_of_bucket, i); - eassert (HASH_NEXT (h, i) != i); /* Stop loops. */ - } - - /* Finally, mark the hash table as having a valid hash order. - Do this last so that if we're interrupted, we retry on next - access. */ - eassert (hash_rehash_needed_p (h)); - h->hash = hash; - eassert (!hash_rehash_needed_p (h)); + for (ptrdiff_t i = h->count; i < ASIZE (h->next) - 1; i++) + set_hash_next_slot (h, i, i + 1); } /* Lookup KEY in hash table H. If HASH is non-null, return in *HASH @@ -4303,8 +4281,6 @@ hash_lookup (struct Lisp_Hash_Table *h, Lisp_Object key, Lisp_Object *hash) { ptrdiff_t start_of_bucket, i; - hash_rehash_if_needed (h); - Lisp_Object hash_code = h->test.hashfn (key, h); if (hash) *hash = hash_code; @@ -4339,8 +4315,6 @@ hash_put (struct Lisp_Hash_Table *h, Lisp_Object key, Lisp_Object value, { ptrdiff_t start_of_bucket, i; - hash_rehash_if_needed (h); - /* Increment count after resizing because resizing may fail. */ maybe_resize_hash_table (h); h->count++; @@ -4373,8 +4347,6 @@ hash_remove_from_table (struct Lisp_Hash_Table *h, Lisp_Object key) ptrdiff_t start_of_bucket = XUFIXNUM (hash_code) % ASIZE (h->index); ptrdiff_t prev = -1; - hash_rehash_if_needed (h); - for (ptrdiff_t i = HASH_INDEX (h, start_of_bucket); 0 <= i; i = HASH_NEXT (h, i)) @@ -4415,8 +4387,7 @@ hash_clear (struct Lisp_Hash_Table *h) if (h->count > 0) { ptrdiff_t size = HASH_TABLE_SIZE (h); - if (!hash_rehash_needed_p (h)) - memclear (xvector_contents (h->hash), size * word_size); + memclear (xvector_contents (h->hash), size * word_size); for (ptrdiff_t i = 0; i < size; i++) { set_hash_next_slot (h, i, i < size - 1 ? i + 1 : -1); @@ -4452,9 +4423,7 @@ sweep_weak_table (struct Lisp_Hash_Table *h, bool remove_entries_p) for (ptrdiff_t bucket = 0; bucket < n; ++bucket) { /* Follow collision chain, removing entries that don't survive - this garbage collection. It's okay if hash_rehash_needed_p - (h) is true, since we're operating entirely on the cached - hash values. */ + this garbage collection. */ ptrdiff_t prev = -1; ptrdiff_t next; for (ptrdiff_t i = HASH_INDEX (h, bucket); 0 <= i; i = next) @@ -4499,7 +4468,7 @@ sweep_weak_table (struct Lisp_Hash_Table *h, bool remove_entries_p) set_hash_hash_slot (h, i, Qnil); eassert (h->count != 0); - h->count += h->count > 0 ? -1 : 1; + h->count--; } else { @@ -4923,7 +4892,7 @@ DEFUN ("hash-table-count", Fhash_table_count, Shash_table_count, 1, 1, 0, (Lisp_Object table) { struct Lisp_Hash_Table *h = check_hash_table (table); - eassert (h->count >= 0); + return make_fixnum (h->count); } diff --git a/src/lisp.h b/src/lisp.h index 17b92a0414..d88038d91b 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2275,11 +2275,7 @@ struct hash_table_test struct Lisp_Hash_Table { - /* Change pdumper.c if you change the fields here. - - IMPORTANT!!!!!!! - - Call hash_rehash_if_needed() before accessing. */ + /* Change pdumper.c if you change the fields here. */ /* This is for Lisp; the hash table code does not refer to it. */ union vectorlike_header header; @@ -2398,20 +2394,7 @@ HASH_TABLE_SIZE (const struct Lisp_Hash_Table *h) return size; } -void hash_table_rehash (struct Lisp_Hash_Table *h); - -INLINE bool -hash_rehash_needed_p (const struct Lisp_Hash_Table *h) -{ - return NILP (h->hash); -} - -INLINE void -hash_rehash_if_needed (struct Lisp_Hash_Table *h) -{ - if (hash_rehash_needed_p (h)) - hash_table_rehash (h); -} +void hash_table_rehash (Lisp_Object); /* Default size for hash tables if not specified. */ diff --git a/src/minibuf.c b/src/minibuf.c index 9d870ce364..cb302c5a60 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -1212,9 +1212,6 @@ is used to further constrain the set of candidates. */) bucket = AREF (collection, idx); } - if (HASH_TABLE_P (collection)) - hash_rehash_if_needed (XHASH_TABLE (collection)); - while (1) { /* Get the next element of the alist, obarray, or hash-table. */ diff --git a/src/pdumper.c b/src/pdumper.c index 63ee0fcb7f..10dfa8737f 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -105,17 +105,6 @@ along with GNU Emacs. If not, see . */ # define VM_SUPPORTED 0 #endif -/* PDUMPER_CHECK_REHASHING being true causes the portable dumper to - check, for each hash table it dumps, that the hash table means the - same thing after rehashing. */ -#ifndef PDUMPER_CHECK_REHASHING -# if ENABLE_CHECKING -# define PDUMPER_CHECK_REHASHING 1 -# else -# define PDUMPER_CHECK_REHASHING 0 -# endif -#endif - /* Require an architecture in which pointers, ptrdiff_t and intptr_t are the same size and have the same layout, and where bytes have eight bits --- that is, a general-purpose computer made after 1990. @@ -401,6 +390,8 @@ struct dump_header The start of the cold region is always aligned on a page boundary. */ dump_off cold_start; + + dump_off hash_list; }; /* Double-ended singly linked list. */ @@ -558,6 +549,8 @@ struct dump_context heap objects. */ Lisp_Object bignum_data; + Lisp_Object hash_tables; + unsigned number_hot_relocations; unsigned number_discardable_relocations; }; @@ -2616,78 +2609,62 @@ dump_vectorlike_generic (struct dump_context *ctx, return offset; } -/* Determine whether the hash table's hash order is stable - across dump and load. If it is, we don't have to trigger - a rehash on access. */ -static bool -dump_hash_table_stable_p (const struct Lisp_Hash_Table *hash) +/* Return a vector of KEY, VALUE pairs in the given hash table H. The + first H->count pairs are valid, the rest is left as nil. */ +static Lisp_Object +hash_table_contents (struct Lisp_Hash_Table *h) { - if (hash->test.hashfn == hashfn_user_defined) + if (h->test.hashfn == hashfn_user_defined) error ("cannot dump hash tables with user-defined tests"); /* Bug#36769 */ - bool is_eql = hash->test.hashfn == hashfn_eql; - bool is_equal = hash->test.hashfn == hashfn_equal; - ptrdiff_t size = HASH_TABLE_SIZE (hash); - for (ptrdiff_t i = 0; i < size; ++i) + Lisp_Object contents = Qnil; + + /* Make sure key_and_value ends up in the same order; charset.c + relies on it by expecting hash table indices to stay constant + across the dump. */ + for (ptrdiff_t i = 0; i < HASH_TABLE_SIZE (h) - h->count; i++) { - Lisp_Object key = HASH_KEY (hash, i); - if (!EQ (key, Qunbound)) - { - bool key_stable = (dump_builtin_symbol_p (key) - || FIXNUMP (key) - || (is_equal - && (STRINGP (key) || BOOL_VECTOR_P (key))) - || ((is_equal || is_eql) - && (FLOATP (key) || BIGNUMP (key)))); - if (!key_stable) - return false; - } + dump_push (&contents, Qnil); + dump_push (&contents, Qunbound); } - return true; + for (ptrdiff_t i = HASH_TABLE_SIZE (h) - 1; i >= 0; --i) + if (!NILP (HASH_HASH (h, i))) + { + dump_push (&contents, HASH_VALUE (h, i)); + dump_push (&contents, HASH_KEY (h, i)); + } + + return CALLN (Fapply, Qvector, contents); } -/* Return a list of (KEY . VALUE) pairs in the given hash table. */ -static Lisp_Object -hash_table_contents (Lisp_Object table) +static dump_off +dump_hash_table_list (struct dump_context *ctx) { - Lisp_Object contents = Qnil; - struct Lisp_Hash_Table *h = XHASH_TABLE (table); - for (ptrdiff_t i = 0; i < HASH_TABLE_SIZE (h); ++i) - { - Lisp_Object key = HASH_KEY (h, i); - if (!EQ (key, Qunbound)) - dump_push (&contents, Fcons (key, HASH_VALUE (h, i))); - } - return Fnreverse (contents); + if (CONSP (ctx->hash_tables)) + return dump_object (ctx, CALLN (Fapply, Qvector, ctx->hash_tables)); + else + return 0; } -/* Copy the given hash table, rehash it, and make sure that we can - look up all the values in the original. */ static void -check_hash_table_rehash (Lisp_Object table_orig) -{ - ptrdiff_t count = XHASH_TABLE (table_orig)->count; - hash_rehash_if_needed (XHASH_TABLE (table_orig)); - Lisp_Object table_rehashed = Fcopy_hash_table (table_orig); - eassert (!hash_rehash_needed_p (XHASH_TABLE (table_rehashed))); - XHASH_TABLE (table_rehashed)->hash = Qnil; - eassert (count == 0 || hash_rehash_needed_p (XHASH_TABLE (table_rehashed))); - hash_rehash_if_needed (XHASH_TABLE (table_rehashed)); - eassert (!hash_rehash_needed_p (XHASH_TABLE (table_rehashed))); - Lisp_Object expected_contents = hash_table_contents (table_orig); - while (!NILP (expected_contents)) - { - Lisp_Object key_value_pair = dump_pop (&expected_contents); - Lisp_Object key = XCAR (key_value_pair); - Lisp_Object expected_value = XCDR (key_value_pair); - Lisp_Object arbitrary = Qdump_emacs_portable__sort_predicate_copied; - Lisp_Object found_value = Fgethash (key, table_rehashed, arbitrary); - eassert (EQ (expected_value, found_value)); - Fremhash (key, table_rehashed); - } +hash_table_freeze (struct Lisp_Hash_Table *h) +{ + ptrdiff_t nkeys = XFIXNAT (Flength (h->key_and_value)) / 2; + h->key_and_value = hash_table_contents (h); + h->next_free = (nkeys == h->count ? -1 : h->count); + h->index = Flength (h->index); + h->next = h->hash = make_fixnum (nkeys); +} - eassert (EQ (Fhash_table_count (table_rehashed), - make_fixnum (0))); +static void +hash_table_thaw (Lisp_Object hash) +{ + struct Lisp_Hash_Table *h = XHASH_TABLE (hash); + h->index = Fmake_vector (h->index, make_fixnum (-1)); + h->hash = Fmake_vector (h->hash, Qnil); + h->next = Fmake_vector (h->next, make_fixnum (-1)); + + hash_table_rehash (hash); } static dump_off @@ -2699,51 +2676,11 @@ dump_hash_table (struct dump_context *ctx, # error "Lisp_Hash_Table changed. See CHECK_STRUCTS comment in config.h." #endif const struct Lisp_Hash_Table *hash_in = XHASH_TABLE (object); - bool is_stable = dump_hash_table_stable_p (hash_in); - /* If the hash table is likely to be modified in memory (either - because we need to rehash, and thus toggle hash->count, or - because we need to assemble a list of weak tables) punt the hash - table to the end of the dump, where we can lump all such hash - tables together. */ - if (!(is_stable || !NILP (hash_in->weak)) - && ctx->flags.defer_hash_tables) - { - if (offset != DUMP_OBJECT_ON_HASH_TABLE_QUEUE) - { - eassert (offset == DUMP_OBJECT_ON_NORMAL_QUEUE - || offset == DUMP_OBJECT_NOT_SEEN); - /* We still want to dump the actual keys and values now. */ - dump_enqueue_object (ctx, hash_in->key_and_value, WEIGHT_NONE); - /* We'll get to the rest later. */ - offset = DUMP_OBJECT_ON_HASH_TABLE_QUEUE; - dump_remember_object (ctx, object, offset); - dump_push (&ctx->deferred_hash_tables, object); - } - return offset; - } - - if (PDUMPER_CHECK_REHASHING) - check_hash_table_rehash (make_lisp_ptr ((void *) hash_in, Lisp_Vectorlike)); - struct Lisp_Hash_Table hash_munged = *hash_in; struct Lisp_Hash_Table *hash = &hash_munged; - /* Remember to rehash this hash table on first access. After a - dump reload, the hash table values will have changed, so we'll - need to rebuild the index. - - TODO: for EQ and EQL hash tables, it should be possible to rehash - here using the preferred load address of the dump, eliminating - the need to rehash-on-access if we can load the dump where we - want. */ - if (hash->count > 0 && !is_stable) - /* Hash codes will have to be recomputed anyway, so let's not dump them. - Also set `hash` to nil for hash_rehash_needed_p. - We could also refrain from dumping the `next' and `index' vectors, - except that `next' is currently used for HASH_TABLE_SIZE and - we'd have to rebuild the next_free list as well as adjust - sweep_weak_hash_table for the case where there's no `index'. */ - hash->hash = Qnil; + hash_table_freeze (hash); + dump_push (&ctx->hash_tables, object); START_DUMP_PVEC (ctx, &hash->header, struct Lisp_Hash_Table, out); dump_pseudovector_lisp_fields (ctx, &out->header, &hash->header); @@ -4151,6 +4088,19 @@ types. */) || !NILP (ctx->deferred_hash_tables) || !NILP (ctx->deferred_symbols)); + ctx->header.hash_list = ctx->offset; + dump_hash_table_list (ctx); + + do + { + dump_drain_deferred_hash_tables (ctx); + dump_drain_deferred_symbols (ctx); + dump_drain_normal_queue (ctx); + } + while (!dump_queue_empty_p (&ctx->dump_queue) + || !NILP (ctx->deferred_hash_tables) + || !NILP (ctx->deferred_symbols)); + dump_sort_copied_objects (ctx); /* While we copy built-in symbols into the Emacs image, these @@ -5302,6 +5252,9 @@ enum dump_section NUMBER_DUMP_SECTIONS, }; +/* Pointer to a stack variable to avoid having to staticpro it. */ +static Lisp_Object *pdumper_hashes = &zero_vector; + /* Load a dump from DUMP_FILENAME. Return an error code. N.B. We run very early in initialization, so we can't use lisp, @@ -5448,6 +5401,15 @@ pdumper_load (const char *dump_filename) for (int i = 0; i < ARRAYELTS (sections); ++i) dump_mmap_reset (§ions[i]); + Lisp_Object hashes = zero_vector; + if (header->hash_list) + { + struct Lisp_Vector *hash_tables = + ((struct Lisp_Vector *)(dump_base + header->hash_list)); + XSETVECTOR (hashes, hash_tables); + } + + pdumper_hashes = &hashes; /* Run the functions Emacs registered for doing post-dump-load initialization. */ for (int i = 0; i < nr_dump_hooks; ++i) @@ -5518,6 +5480,19 @@ Value is nil if this session was not started using a dump file.*/) #endif /* HAVE_PDUMPER */ +static void +thaw_hash_tables (void) +{ + Lisp_Object hash_tables = *pdumper_hashes; + for (ptrdiff_t i = 0; i < ASIZE (hash_tables); i++) + hash_table_thaw (AREF (hash_tables, i)); +} + +void +init_pdumper_once (void) +{ + pdumper_do_now_and_after_load (thaw_hash_tables); +} void syms_of_pdumper (void) diff --git a/src/pdumper.h b/src/pdumper.h index 6a99b511f2..c793fb4058 100644 --- a/src/pdumper.h +++ b/src/pdumper.h @@ -256,6 +256,7 @@ pdumper_clear_marks (void) file was loaded. */ extern void pdumper_record_wd (const char *); +void init_pdumper_once (void); void syms_of_pdumper (void); INLINE_HEADER_END