commit bc5da2c3fb882a2df9d358e5b82869ab48a04d9a (HEAD, refs/remotes/origin/master) Author: Stefan Kangas Date: Sat Aug 8 05:32:37 2020 +0200 Avoid some uses of obsolete function interactive-p * doc/lispref/help.texi (Accessing Documentation): * lisp/cedet/data-debug.el: * lisp/emacs-lisp/edebug.el (edebug-wrap-def-body): * lisp/simple.el (append-next-kill): * test/manual/cedet/cedet-utests.el (cedet-utest, pulse-test): * test/manual/cedet/semantic-tests.el (semantic-lex-spp-write-utest) (semantic-symref-test-count-hits-in-tag): Use 'called-interactively-p' instead of obsolete function 'interactive-p'. diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi index 9b3c4fcb23..d4505d5c3f 100644 --- a/doc/lispref/help.texi +++ b/doc/lispref/help.texi @@ -220,7 +220,8 @@ in the *Help* buffer." @group ;; @r{Display the data.} - (help-setup-xref (list 'describe-symbols pattern) (interactive-p)) + (help-setup-xref (list 'describe-symbols pattern) + (called-interactively-p 'interactive)) (with-help-window (help-buffer) (mapcar describe-func (sort sym-list 'string<))))) @end group diff --git a/lisp/cedet/data-debug.el b/lisp/cedet/data-debug.el index 604fc40926..44cce389cb 100644 --- a/lisp/cedet/data-debug.el +++ b/lisp/cedet/data-debug.el @@ -38,7 +38,7 @@ ;; "Calculate something complicated at point, and return it." ;; (interactive) ;; function not normally interactive ;; (let ((stuff (do-stuff))) -;; (when (interactive-p) +;; (when (called-interactively-p 'interactive) ;; (data-debug-show-stuff stuff "myStuff")) ;; stuff)) diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index d9bbf6129c..7ff6d68c3e 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -1229,7 +1229,7 @@ purpose by adding an entry to this alist, and setting "Wrap the FORMS of a definition body." (if edebug-def-interactive `(let ((,(edebug-interactive-p-name) - (interactive-p))) + (called-interactively-p 'interactive))) ,(edebug-make-enter-wrapper forms)) (edebug-make-enter-wrapper forms))) diff --git a/test/manual/cedet/cedet-utests.el b/test/manual/cedet/cedet-utests.el index 124b49907d..ee6be438dd 100644 --- a/test/manual/cedet/cedet-utests.el +++ b/test/manual/cedet/cedet-utests.el @@ -150,7 +150,7 @@ of just logging the error." ;; Cleanup stray input and events that are in the way. ;; Not doing this causes sit-for to not refresh the screen. ;; Doing this causes the user to need to press keys more frequently. - (when (and (interactive-p) (input-pending-p)) + (when (and (called-interactively-p 'interactive) (input-pending-p)) (if (fboundp 'read-event) (read-event) (read-char))) @@ -497,11 +497,11 @@ When optional NO-ERROR don't throw an error if we can't run tests." (error (concat "Pulse test only works on versions of Emacs" " that support pulsing"))) ;; Run the tests - (when (interactive-p) + (when (called-interactively-p 'interactive) (message " Pulse one line.") (read-char)) (pulse-momentary-highlight-one-line (point)) - (when (interactive-p) + (when (called-interactively-p 'interactive) (message " Pulse a region.") (read-char)) (pulse-momentary-highlight-region (point) @@ -510,11 +510,11 @@ When optional NO-ERROR don't throw an error if we can't run tests." (forward-char 30) (error nil)) (point))) - (when (interactive-p) + (when (called-interactively-p 'interactive) (message " Pulse line a specific color.") (read-char)) (pulse-momentary-highlight-one-line (point) 'mode-line) - (when (interactive-p) + (when (called-interactively-p 'interactive) (message " Pulse a pre-existing overlay.") (read-char)) (let* ((start (point-at-bol)) @@ -530,7 +530,7 @@ When optional NO-ERROR don't throw an error if we can't run tests." (delete-overlay o) (error "Non-temporary overlay was deleted!")) ) - (when (interactive-p) + (when (called-interactively-p 'interactive) (message "Done!")))) (provide 'cedet-utests) diff --git a/test/manual/cedet/semantic-tests.el b/test/manual/cedet/semantic-tests.el index 53552be06b..a0899cb932 100644 --- a/test/manual/cedet/semantic-tests.el +++ b/test/manual/cedet/semantic-tests.el @@ -235,7 +235,7 @@ Analyze the area between BEG and END." (set-buffer buff) (semantic-lex-spp-write-test) (kill-buffer buff) - (when (not (interactive-p)) + (when (not (called-interactively-p 'interactive)) (kill-buffer "*SPP Write Test*")) ))) @@ -276,7 +276,7 @@ tag that contains point, and return that." target (lambda (start end prefix) (setq Lcount (1+ Lcount))) (semantic-tag-start tag) (semantic-tag-end tag)) - (when (interactive-p) + (when (called-interactively-p 'interactive) (message "Found %d occurrences of %s in %.2f seconds" Lcount (semantic-tag-name target) (semantic-elapsed-time start nil))) commit 326fdb9ec05ab5e4aec0c7064272bb3d223e9875 Author: Stefan Kangas Date: Mon Aug 24 03:28:48 2020 +0200 Remove many items obsolete since Emacs 23.2 and 23.3 * lisp/allout.el (allout-init): * lisp/emacs-lisp/shadow.el (shadows-compare-text-p): * lisp/ffap.el (ffap-version): * lisp/filecache.el (file-cache-choose-completion): * lisp/help.el (print-help-return-message): * lisp/image-mode.el (image-mode-maybe): * lisp/imenu.el (imenu-example--name-and-position): * lisp/international/mule-cmds.el (princ-list): * lisp/mail/rmail.el (rmail-highlight-face): * lisp/minibuffer.el (read-file-name-predicate): * lisp/mouse.el (mouse-choose-completion): * lisp/progmodes/cc-cmds.el (c-forward-into-nomenclature): * lisp/progmodes/xscheme.el (advertised-xscheme-send-previous-expression): * lisp/simple.el (completion-base-size) (choose-completion-delete-max-match, exchange-dot-and-mark): * lisp/subr.el (eval-next-after-load): * lisp/term.el (term-dynamic-simple-complete): Remove items, obsolete since Emacs 23.2 and 23.3. * doc/misc/cc-mode.texi (Movement Commands): Doc fix. * doc/lispref/help.texi (Accessing Documentation): * lisp/emacs-lisp/edebug.el (edebug-wrap-def-body): * lisp/comint.el (comint-dynamic-list-completions): * lisp/progmodes/idlwave.el (idlwave-make-modified-completion-map-xemacs) (idlwave-make-modified-completion-map-emacs) (idlwave-choose-completion): * lisp/progmodes/vhdl-mode.el: * lisp/term.el (term-dynamic-list-completions): Remove references to 'mouse-choose-completion'. * lisp/image-mode.el (image-mode-to-text): Remove reference to 'image-mode-maybe'. * lisp/mail/rmail.el (rmail-highlight-headers): Use 'rmail-highlight' face instead of 'rmail-highlight-face'. * lisp/progmodes/antlr-mode.el (antlr-mode-map, antlr-mode-menu): Remove reference to 'c-forward-into-nomenclature'. * lisp/simple.el (choose-completion, choose-completion-string) (completion-list-mode, completion-setup-function): Don't use 'completion-base-size'. ; * etc/NEWS: List removed items. This was discussed in https://lists.gnu.org/archive/html/emacs-devel/2020-08/msg00400.html diff --git a/doc/misc/cc-mode.texi b/doc/misc/cc-mode.texi index 10bbf8ff09..adc233d99d 100644 --- a/doc/misc/cc-mode.texi +++ b/doc/misc/cc-mode.texi @@ -1024,9 +1024,7 @@ These key sequences are not bound in AWK Mode, which doesn't have preprocessor statements. @item @kbd{M-x c-backward-into-nomenclature} -@itemx @kbd{M-x c-forward-into-nomenclature} @findex c-backward-into-nomenclature -@findex c-forward-into-nomenclature @findex backward-into-nomenclature @r{(c-)} @findex forward-into-nomenclature @r{(c-)} A popular programming style, especially for object-oriented languages diff --git a/etc/NEWS b/etc/NEWS index cff435684e..a65852fcd0 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1066,33 +1066,40 @@ ledit.el, lmenu.el, lucid.el and old-whitespace.el. --- ** Some functions and variables obsolete since Emacs 23 have been removed: - -'GOLD-map', 'bookmark-jump-noselect', +'GOLD-map', 'advertised-xscheme-send-previous-expression', +'allout-init', 'bookmark-jump-noselect', 'bookmark-read-annotation-text-func', 'buffer-menu-mode-hook', -'char-coding-system-table', 'char-valid-p', 'charset-bytes', -'charset-id', 'charset-list' (function), 'complete-in-turn', -'completion-common-substring', 'crm-minibuffer-complete', -'crm-minibuffer-complete-and-exit', 'crm-minibuffer-completion-help', -'custom-mode', 'custom-mode-hook', 'detect-coding-with-priority', -'dirtrack-debug' (function), 'dirtrack-debug-toggle', -'dynamic-completion-table', +'c-forward-into-nomenclature', 'char-coding-system-table', +'char-valid-p', 'charset-bytes', 'charset-id', 'charset-list' +(function), 'choose-completion-delete-max-match', 'complete-in-turn', +'completion-base-size', 'completion-common-substring', +'crm-minibuffer-complete', 'crm-minibuffer-complete-and-exit', +'crm-minibuffer-completion-help', 'custom-mode', 'custom-mode-hook', +'detect-coding-with-priority', 'dirtrack-debug' (function), +'dirtrack-debug-toggle', 'dynamic-completion-table', 'easy-menu-precalculate-equivalent-keybindings', 'epa-display-verify-result', 'epg-passphrase-callback-function', -'eshell-report-bug', 'ffap-bug', 'ffap-submit-bug', 'forward-point', -'generic-char-p', 'global-highlight-changes', 'hi-lock-face-history', +'eshell-report-bug', 'eval-next-after-load', 'exchange-dot-and-mark', +'ffap-bug', 'ffap-submit-bug', 'ffap-version', +'file-cache-choose-completion', 'forward-point', 'generic-char-p', +'global-highlight-changes', 'hi-lock-face-history', 'hi-lock-regexp-history', 'highlight-changes-active-string', 'highlight-changes-initial-state', 'highlight-changes-passive-string', +'image-mode-maybe', 'imenu-example--name-and-position', 'ispell-aspell-supports-utf8', 'lisp-mode-auto-fill', 'locate-file-completion', 'make-coding-system', -'minibuffer-local-must-match-filename-map', 'mouse-major-mode-menu', -'mouse-popup-menubar', 'mouse-popup-menubar-stuff', -'newsticker-groups-filename', 'non-iso-charset-alist', -'nonascii-insert-offset', 'nonascii-translation-table', -'password-read-and-add', 'pre-abbrev-expand-hook', -'process-filter-multibyte-p', 'remember-buffer' (function), +'minibuffer-local-must-match-filename-map', 'mouse-choose-completion', +'mouse-major-mode-menu', 'mouse-popup-menubar', +'mouse-popup-menubar-stuff', 'newsticker-groups-filename', +'non-iso-charset-alist', 'nonascii-insert-offset', +'nonascii-translation-table', 'password-read-and-add', +'pre-abbrev-expand-hook', 'princ-list', 'print-help-return-message', +'process-filter-multibyte-p', 'read-file-name-predicate', +'remember-buffer' (function), 'rmail-highlight-face', 'rmail-message-filter', 'set-coding-priority', -'set-process-filter-multibyte', 'shell-dirtrack-toggle', -'t-mouse-mode', 'tooltip-hook', 'tpu-have-ispell', +'set-process-filter-multibyte', 'shadows-compare-text-p', +'shell-dirtrack-toggle', 't-mouse-mode', +'term-dynamic-simple-complete', 'tooltip-hook', 'tpu-have-ispell', 'url-generate-unique-filename', 'url-temporary-directory', 'vc-arch-command', 'vc-default-working-revision' (variable), 'vc-mtn-command', 'vc-revert-buffer', 'vc-workfile-version', diff --git a/lisp/allout.el b/lisp/allout.el index 05d9153a31..955b7000cb 100644 --- a/lisp/allout.el +++ b/lisp/allout.el @@ -62,8 +62,7 @@ ;; The outline menubar additions provide quick reference to many of the ;; features. See the docstring of the variables `allout-layout' and ;; `allout-auto-activation' for details on automatic activation of -;; `allout-mode' as a minor mode. (`allout-init' is deprecated in favor of -;; a purely customization-based method.) +;; `allout-mode' as a minor mode. ;; ;; Note -- the lines beginning with `;;;_' are outline topic headers. ;; Customize `allout-auto-activation' to enable, then revisit this @@ -1627,18 +1626,6 @@ non-nil in a lasting way.") "If t, `allout-mode's last deactivation was deliberate. So `allout-post-command-business' should not reactivate it...") (make-variable-buffer-local 'allout-explicitly-deactivated) -;;;_ > allout-init (mode) -(defun allout-init (mode) - "DEPRECATED - configure allout activation by customizing -`allout-auto-activation'. This function remains around, limited -from what it did before, for backwards compatibility. - -MODE is the activation mode - see `allout-auto-activation' for -valid values." - (declare (obsolete allout-auto-activation "23.3")) - (customize-set-variable 'allout-auto-activation (format "%s" mode)) - (format "%s" mode)) - ;;;_ > allout-setup-menubar () (defun allout-setup-menubar () "Populate the current buffer's menubar with `allout-mode' stuff." diff --git a/lisp/comint.el b/lisp/comint.el index 092902d865..be0e32b9e0 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -3450,7 +3450,7 @@ the completions." (eq (window-buffer (posn-window (event-start first))) (get-buffer "*Completions*")) (memq (key-binding key) - '(mouse-choose-completion choose-completion)))) + '(choose-completion)))) ;; If the user does choose-completion with the mouse, ;; execute the command, then delete the completion window. (progn diff --git a/lisp/emacs-lisp/shadow.el b/lisp/emacs-lisp/shadow.el index 4ff129e367..dd614dd792 100644 --- a/lisp/emacs-lisp/shadow.el +++ b/lisp/emacs-lisp/shadow.el @@ -55,9 +55,6 @@ :prefix "load-path-shadows-" :group 'lisp) -(define-obsolete-variable-alias 'shadows-compare-text-p - 'load-path-shadows-compare-text "23.3") - (defcustom load-path-shadows-compare-text nil "If non-nil, then shadowing files are reported only if their text differs. This is slower, but filters out some innocuous shadowing." diff --git a/lisp/ffap.el b/lisp/ffap.el index 28f566dd93..af7d84cd09 100644 --- a/lisp/ffap.el +++ b/lisp/ffap.el @@ -110,8 +110,6 @@ (require 'url-parse) (require 'thingatpt) -(define-obsolete-variable-alias 'ffap-version 'emacs-version "23.2") - (defgroup ffap nil "Find file or URL at point." :group 'matching diff --git a/lisp/filecache.el b/lisp/filecache.el index 3c07a49420..113d28cf75 100644 --- a/lisp/filecache.el +++ b/lisp/filecache.el @@ -614,9 +614,6 @@ the name is considered already unique; only the second substitution (select-window (active-minibuffer-window)) (file-cache-minibuffer-complete nil))) -(define-obsolete-function-alias 'file-cache-mouse-choose-completion - #'file-cache-choose-completion "23.2") - (defun file-cache-complete () "Complete the word at point, using the filecache." (interactive) diff --git a/lisp/help.el b/lisp/help.el index b7d867eb70..1b0149616f 100644 --- a/lisp/help.el +++ b/lisp/help.el @@ -131,7 +131,6 @@ This is a list (WINDOW . quit-window) do quit-window, then select WINDOW. (WINDOW BUF START POINT) display BUF at START, POINT, then select WINDOW.") -(define-obsolete-function-alias 'print-help-return-message 'help-print-return-message "23.2") (defun help-print-return-message (&optional function) "Display or return message saying how to restore windows after help command. This function assumes that `standard-output' is the help buffer. diff --git a/lisp/image-mode.el b/lisp/image-mode.el index 4c719f7cda..032ebf3873 100644 --- a/lisp/image-mode.el +++ b/lisp/image-mode.el @@ -718,7 +718,7 @@ A non-mage major mode found from `auto-mode-alist' or fundamental mode displays an image file as text." ;; image-mode-as-text = normal-mode + image-minor-mode (let ((previous-image-type image-type)) ; preserve `image-type' - (major-mode-restore '(image-mode image-mode-maybe image-mode-as-text)) + (major-mode-restore '(image-mode image-mode-as-text)) ;; Restore `image-type' after `kill-all-local-variables' in `normal-mode'. (setq image-type previous-image-type) ;; Enable image minor mode with `C-c C-c'. @@ -768,8 +768,6 @@ on these modes." (if (image-get-display-property) "text" "an image or hex") "."))) -(define-obsolete-function-alias 'image-mode-maybe 'image-mode "23.2") - (defun image-toggle-display-text () "Show the image file as text. Remove text properties that display the image." diff --git a/lisp/imenu.el b/lisp/imenu.el index 1949f2f48f..3a16dcb9ac 100644 --- a/lisp/imenu.el +++ b/lisp/imenu.el @@ -316,28 +316,6 @@ PREVPOS is the variable in which we store the last position displayed." ) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;; -;;;; Some examples of functions utilizing the framework of this -;;;; package. -;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; FIXME: This was the only imenu-example-* definition actually used, -;; by cperl-mode.el. Now cperl-mode has its own copy, so these can -;; all be removed. -(defun imenu-example--name-and-position () - "Return the current/previous sexp and its (beginning) location. -Don't move point." - (declare (obsolete "use your own function instead." "23.2")) - (save-excursion - (forward-sexp -1) - ;; [ydi] modified for imenu-use-markers - (let ((beg (if imenu-use-markers (point-marker) (point))) - (end (progn (forward-sexp) (point)))) - (cons (buffer-substring beg end) - beg)))) - ;;; ;;; Lisp ;;; diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el index 5fe931dd9b..02dacaf0a2 100644 --- a/lisp/international/mule-cmds.el +++ b/lisp/international/mule-cmds.el @@ -2070,12 +2070,6 @@ See `set-language-info-alist' for use in programs." "Do various unibyte-mode setups for language environment LANGUAGE-NAME." (set-display-table-and-terminal-coding-system language-name)) -(defun princ-list (&rest args) - "Print all arguments with `princ', then print \"\\n\"." - (declare (obsolete "use mapc and princ instead." "23.3")) - (mapc #'princ args) - (princ "\n")) - (put 'describe-specified-language-support 'apropos-inhibit t) ;; Print language-specific information such as input methods, diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el index 312baffb90..f14025a93a 100644 --- a/lisp/mail/rmail.el +++ b/lisp/mail/rmail.el @@ -417,20 +417,6 @@ The variable `rmail-highlighted-headers' specifies which headers." :group 'rmail-headers :version "22.1") -;; This was removed in Emacs 23.1 with no notification, an unnecessary -;; incompatible change. -(defcustom rmail-highlight-face 'rmail-highlight - "Face used by Rmail for highlighting headers." - ;; Note that nil doesn't actually mean use the default face, it - ;; means use either bold or highlight. It's not worth fixing this - ;; now that this is obsolete. - :type '(choice (const :tag "Default" nil) - face) - :group 'rmail-headers) -(make-obsolete-variable 'rmail-highlight-face - "customize the face `rmail-highlight' instead." - "23.2") - (defface rmail-header-name '((t (:inherit font-lock-function-name-face))) "Face to use for highlighting the header names. @@ -3012,7 +2998,7 @@ using the coding system CODING." (defun rmail-highlight-headers () "Highlight the headers specified by `rmail-highlighted-headers'. -Uses the face specified by `rmail-highlight-face'." +Uses the face `rmail-highlight'." (if rmail-highlighted-headers (save-excursion (search-forward "\n\n" nil 'move) @@ -3020,11 +3006,7 @@ Uses the face specified by `rmail-highlight-face'." (narrow-to-region (point-min) (point)) (let ((case-fold-search t) (inhibit-read-only t) - ;; When rmail-highlight-face is removed, just - ;; use 'rmail-highlight here. - (face (or rmail-highlight-face - (if (face-differs-from-default-p 'bold) - 'bold 'highlight))) + (face 'rmail-highlight) ;; List of overlays to reuse. (overlays rmail-overlay-list)) (goto-char (point-min)) diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 641a2e5315..1f2dcc4755 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -2539,11 +2539,6 @@ same as `substitute-in-file-name'." all)))))) (file-error nil))) ;PCM often calls with invalid directories. -(defvar read-file-name-predicate nil - "Current predicate used by `read-file-name-internal'.") -(make-obsolete-variable 'read-file-name-predicate - "use the regular PRED argument" "23.2") - (defun completion--sifn-requote (upos qstr) ;; We're looking for `qpos' such that: ;; (equal (substring (substitute-in-file-name qstr) 0 upos) diff --git a/lisp/mouse.el b/lisp/mouse.el index a06ca2a56c..06fdca12b9 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el @@ -2303,9 +2303,6 @@ and selects that window." ;; Few buffers--put them all in one pane. (list (cons title alist)))) -(define-obsolete-function-alias - 'mouse-choose-completion 'choose-completion "23.2") - ;; Font selection. (defun font-menu-add-default () diff --git a/lisp/progmodes/antlr-mode.el b/lisp/progmodes/antlr-mode.el index bf56a7ee49..24e1f8831a 100644 --- a/lisp/progmodes/antlr-mode.el +++ b/lisp/progmodes/antlr-mode.el @@ -695,7 +695,7 @@ imenu." (define-key map "\e\C-e" 'antlr-end-of-rule) (define-key map "\C-c\C-a" 'antlr-beginning-of-body) (define-key map "\C-c\C-e" 'antlr-end-of-body) - (define-key map "\C-c\C-f" 'c-forward-into-nomenclature) + (define-key map "\C-c\C-f" 'subword-forward) (define-key map "\C-c\C-b" 'c-backward-into-nomenclature) (define-key map "\C-c\C-c" 'comment-region) (define-key map "\C-c\C-v" 'antlr-hide-actions) @@ -745,7 +745,7 @@ imenu." ["Backward Statement" c-beginning-of-statement t] ["Forward Statement" c-end-of-statement t] ["Backward Into Nomencl." c-backward-into-nomenclature t] - ["Forward Into Nomencl." c-forward-into-nomenclature t]) + ["Forward Into Nomencl." subword-forward t]) ["Indent Region" indent-region :active (and (not buffer-read-only) (c-region-is-active-p))] ["Comment Out Region" comment-region diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el index 1b557c41a5..4425e275ac 100644 --- a/lisp/progmodes/cc-cmds.el +++ b/lisp/progmodes/cc-cmds.el @@ -1554,19 +1554,6 @@ left out." (declare-function c-backward-subword "ext:cc-subword" (&optional arg)) ;; "nomenclature" functions + c-scope-operator. -(defun c-forward-into-nomenclature (&optional arg) - "Compatibility alias for `c-forward-subword'." - (interactive "p") - (if (fboundp 'subword-mode) - (progn - (require 'subword) - (subword-forward arg)) - (require 'cc-subword) - (c-forward-subword arg))) -(make-obsolete 'c-forward-into-nomenclature - (if (fboundp 'subword-mode) 'subword-forward 'c-forward-subword) - "23.2") - (defun c-backward-into-nomenclature (&optional arg) "Compatibility alias for `c-backward-subword'." (interactive "p") diff --git a/lisp/progmodes/idlwave.el b/lisp/progmodes/idlwave.el index 153f2578bf..90e56943f2 100644 --- a/lisp/progmodes/idlwave.el +++ b/lisp/progmodes/idlwave.el @@ -7042,12 +7042,10 @@ If these don't exist, a letter in the string is automatically selected." #'idlwave-make-modified-completion-map "28.1") (defun idlwave-make-modified-completion-map (old-map) - "Replace `choose-completion' and `mouse-choose-completion' in OLD-MAP." + "Replace `choose-completion' in OLD-MAP." (let ((new-map (copy-keymap old-map))) (substitute-key-definition 'choose-completion 'idlwave-choose-completion new-map) - (substitute-key-definition - 'mouse-choose-completion 'idlwave-mouse-choose-completion new-map) (define-key new-map [mouse-3] 'idlwave-mouse-completion-help) new-map)) @@ -7056,10 +7054,8 @@ If these don't exist, a letter in the string is automatically selected." (interactive (list last-nonmenu-event)) (apply 'idlwave-choose 'choose-completion args)) -(defun idlwave-mouse-choose-completion (&rest args) - "Click on an alternative in the `*Completions*' buffer to choose it." - (interactive "e") - (apply 'idlwave-choose 'mouse-choose-completion args)) +(define-obsolete-function-alias 'idlwave-mouse-choose-completion + #'idlwave-choose-completion "28.1") ;;---------------------------------------------------------------------- ;;---------------------------------------------------------------------- diff --git a/lisp/progmodes/vhdl-mode.el b/lisp/progmodes/vhdl-mode.el index 9cd84cf713..3d66483b83 100644 --- a/lisp/progmodes/vhdl-mode.el +++ b/lisp/progmodes/vhdl-mode.el @@ -2304,10 +2304,6 @@ Ignore byte-compiler warnings you might see." (defvaralias 'vhdl-last-input-event 'last-input-char) (defvaralias 'vhdl-last-input-event 'last-input-event)) -;; `help-print-return-message' changed to `print-help-return-message' in Emacs -;;;(unless (fboundp 'help-print-return-message) -;;; (defalias 'help-print-return-message 'print-help-return-message)) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Compatibility with older VHDL Mode versions diff --git a/lisp/progmodes/xscheme.el b/lisp/progmodes/xscheme.el index 8dfb3a40dd..c6997862f7 100644 --- a/lisp/progmodes/xscheme.el +++ b/lisp/progmodes/xscheme.el @@ -446,8 +446,6 @@ Entry to this mode runs `scheme-mode-hook' and then (scheme-interaction-mode-initialize) (scheme-interaction-mode t))))) -(define-obsolete-function-alias 'advertised-xscheme-send-previous-expression - 'xscheme-send-previous-expression "23.2") ;;;; Debugger Mode diff --git a/lisp/simple.el b/lisp/simple.el index fa6e154004..eedbff2d08 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -6122,8 +6122,6 @@ Does not set point. Does nothing if mark ring is empty." (pop mark-ring)) (deactivate-mark)) -(define-obsolete-function-alias - 'exchange-dot-and-mark 'exchange-point-and-mark "23.3") (defun exchange-point-and-mark (&optional arg) "Put the mark where point is now, and point where the mark is now. This command works even when the mark is not active, @@ -8409,18 +8407,6 @@ Called with three arguments (BEG END TEXT), it should replace the text between BEG and END with TEXT. Expected to be set buffer-locally in the *Completions* buffer.") -(defvar completion-base-size nil - "Number of chars before point not involved in completion. -This is a local variable in the completion list buffer. -It refers to the chars in the minibuffer if completing in the -minibuffer, or in `completion-reference-buffer' otherwise. -Only characters in the field at point are included. - -If nil, Emacs determines which part of the tail end of the -buffer's text is involved in completion by comparing the text -directly.") -(make-obsolete-variable 'completion-base-size 'completion-base-position "23.2") - (defun delete-completion-window () "Delete the completion list window. Go to the window from which completion was requested." @@ -8474,7 +8460,6 @@ If EVENT, use EVENT's position to determine the starting position." (run-hooks 'mouse-leave-buffer-hook) (with-current-buffer (window-buffer (posn-window (event-start event))) (let ((buffer completion-reference-buffer) - (base-size completion-base-size) (base-position completion-base-position) (insert-function completion-list-insert-choice-function) (choice @@ -8501,10 +8486,6 @@ If EVENT, use EVENT's position to determine the starting position." (choose-completion-string choice buffer (or base-position - (when base-size - ;; Someone's using old completion code that doesn't know - ;; about base-position yet. - (list (+ base-size (field-beginning)))) ;; If all else fails, just guess. (list (choose-completion-guess-base-position choice))) insert-function))))) @@ -8532,10 +8513,6 @@ If EVENT, use EVENT's position to determine the starting position." (forward-char 1)) (point)))) -(defun choose-completion-delete-max-match (string) - (declare (obsolete choose-completion-guess-base-position "23.2")) - (delete-region (choose-completion-guess-base-position string) (point))) - (defvar choose-completion-string-functions nil "Functions that may override the normal insertion of a completion choice. These functions are called in order with three arguments: @@ -8564,13 +8541,6 @@ back on `completion-list-insert-choice-function' when nil." ;; unless it is reading a file name and CHOICE is a directory, ;; or completion-no-auto-exit is non-nil. - ;; Some older code may call us passing `base-size' instead of - ;; `base-position'. It's difficult to make any use of `base-size', - ;; so we just ignore it. - (unless (consp base-position) - (message "Obsolete `base-size' passed to choose-completion-string") - (setq base-position nil)) - (let* ((buffer (or buffer completion-reference-buffer)) (mini-p (minibufferp buffer))) ;; If BUFFER is a minibuffer, barf unless it's the currently @@ -8626,8 +8596,7 @@ Type \\\\[choose-completion] in the completion list\ to select the completion near point. Or click to select one with the mouse. -\\{completion-list-mode-map}" - (set (make-local-variable 'completion-base-size) nil)) +\\{completion-list-mode-map}") (defun completion-list-mode-finish () "Finish setup of the completions buffer. @@ -8664,14 +8633,11 @@ Called from `temp-buffer-show-hook'." (if minibuffer-completing-file-name (file-name-as-directory (expand-file-name - (buffer-substring (minibuffer-prompt-end) - (- (point) (or completion-base-size 0)))))))) + (buffer-substring (minibuffer-prompt-end) (point))))))) (with-current-buffer standard-output - (let ((base-size completion-base-size) ;Read before killing localvars. - (base-position completion-base-position) + (let ((base-position completion-base-position) (insert-fun completion-list-insert-choice-function)) (completion-list-mode) - (set (make-local-variable 'completion-base-size) base-size) (set (make-local-variable 'completion-base-position) base-position) (set (make-local-variable 'completion-list-insert-choice-function) insert-fun)) diff --git a/lisp/subr.el b/lisp/subr.el index 0bd09c6556..a58a873a33 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -4670,13 +4670,6 @@ This function is called directly from the C code." ;; Finally, run any other hook. (run-hook-with-args 'after-load-functions abs-file)) -(defun eval-next-after-load (file) - "Read the following input sexp, and run it whenever FILE is loaded. -This makes or adds to an entry on `after-load-alist'. -FILE should be the name of a library, with no directory name." - (declare (obsolete eval-after-load "23.2")) - (eval-after-load file (read))) - (defun display-delayed-warnings () "Display delayed warnings from `delayed-warnings-list'. diff --git a/lisp/term.el b/lisp/term.el index 99f1bf4f54..3c65b63911 100644 --- a/lisp/term.el +++ b/lisp/term.el @@ -4110,53 +4110,6 @@ see `expand-file-name' and `substitute-in-file-name'. For completion see (term-dynamic-complete-filename)) -(defun term-dynamic-simple-complete (stub candidates) - "Dynamically complete STUB from CANDIDATES list. -This function inserts completion characters at point by completing STUB from -the strings in CANDIDATES. A completions listing may be shown in a help buffer -if completion is ambiguous. - -Returns nil if no completion was inserted. -Returns `sole' if completed with the only completion match. -Returns `shortest' if completed with the shortest of the completion matches. -Returns `partial' if completed as far as possible with the completion matches. -Returns `listed' if a completion listing was shown. - -See also `term-dynamic-complete-filename'." - (declare (obsolete completion-in-region "23.2")) - (let* ((completion-ignore-case nil) - (completions (all-completions stub candidates))) - (cond ((null completions) - (message "No completions of %s" stub) - nil) - ((= 1 (length completions)) ; Gotcha! - (let ((completion (car completions))) - (if (string-equal completion stub) - (message "Sole completion") - (insert (substring completion (length stub))) - (message "Completed")) - (when term-completion-addsuffix (insert " ")) - 'sole)) - (t ; There's no unique completion. - (let ((completion (try-completion stub candidates))) - ;; Insert the longest substring. - (insert (substring completion (length stub))) - (cond ((and term-completion-recexact term-completion-addsuffix - (string-equal stub completion) - (member completion completions)) - ;; It's not unique, but user wants shortest match. - (insert " ") - (message "Completed shortest") - 'shortest) - ((or term-completion-autolist - (string-equal stub completion)) - ;; It's not unique, list possible completions. - (term-dynamic-list-completions completions) - 'listed) - (t - (message "Partially completed") - 'partial))))))) - (defun term-dynamic-list-filename-completions () "List in help buffer possible completions of the filename at point." (interactive) @@ -4186,7 +4139,7 @@ Typing SPC flushes the help buffer." (eq (window-buffer (posn-window (event-start first))) (get-buffer "*Completions*")) (memq (key-binding key) - '(mouse-choose-completion choose-completion)))) + '(choose-completion)))) ;; If the user does choose-completion with the mouse, ;; execute the command, then delete the completion window. (progn commit 631c73b28010dd80c7c909a291d356ab91ea2eae Author: Asher Gordon Date: Mon Aug 24 03:37:10 2020 +0200 Quote other suspicious characters in mml-insert-tag. * lisp/gnus/mml.el (mml-insert-tag): Ensure that the characters "[]<>=" are quoted correctly (bug#43009). Copyright-paperwork-exempt: yes diff --git a/lisp/gnus/mml.el b/lisp/gnus/mml.el index ef8aa6ac01..067396fc2a 100644 --- a/lisp/gnus/mml.el +++ b/lisp/gnus/mml.el @@ -1360,7 +1360,7 @@ If not set, `default-directory' will be used." (value (pop plist))) (when value ;; Quote VALUE if it contains suspicious characters. - (when (string-match "[\"'\\~/*;() \t\n[:multibyte:]]" value) + (when (string-match "[][\"'\\~/*;()<>= \t\n[:multibyte:]]" value) (setq value (with-output-to-string (let (print-escape-nonascii) (prin1 value))))) commit df589d36817a8804d67f133890b2f453aefdf3c1 Author: Paul Eggert Date: Sun Aug 23 14:59:15 2020 -0700 Simplify by using Gnulib sigdescr_np module Inspired by a straightforward patch by Bruno Haible. * admin/merge-gnulib (GNULIB_MODULES): Add sigdescr_np. * configure.ac: Do not check for sys_siglist or __sys_siglist. * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate. * lib/sigdescr_np.c, m4/sigdescr_np.m4: New files, copied from Gnulib. * src/sysdep.c (sys_siglist, sys_siglist_entries): Remove. (init_signals): Do not initialize sys_siglist. (safe_strsignal): Use sigdescr_np instead of sys_siglist. diff --git a/admin/CPP-DEFINES b/admin/CPP-DEFINES index ce9a44436d..a40b430272 100644 --- a/admin/CPP-DEFINES +++ b/admin/CPP-DEFINES @@ -124,9 +124,7 @@ HAVE_DECL_STRTOIMAX HAVE_DECL_STRTOLL HAVE_DECL_STRTOULL HAVE_DECL_STRTOUMAX -HAVE_DECL_SYS_SIGLIST HAVE_DECL_TZNAME -HAVE_DECL___SYS_SIGLIST HAVE_DIALOGS HAVE_DIFFTIME HAVE_DUP2 diff --git a/admin/merge-gnulib b/admin/merge-gnulib index 3f32536a62..164300e1db 100755 --- a/admin/merge-gnulib +++ b/admin/merge-gnulib @@ -40,7 +40,7 @@ GNULIB_MODULES=' manywarnings memmem-simple mempcpy memrchr minmax mkostemp mktime nstrftime pathmax pipe2 pselect pthread_sigmask qcopy-acl readlink readlinkat regex - sig2str socklen stat-time std-gnu11 stdalign stddef stdio + sig2str sigdescr_np socklen stat-time std-gnu11 stdalign stddef stdio stpcpy strnlen strtoimax symlink sys_stat sys_time tempname time time_r time_rz timegm timer-time timespec-add timespec-sub update-copyright unlocked-io utimensat diff --git a/configure.ac b/configure.ac index ace1085284..fb9aa19d6e 100644 --- a/configure.ac +++ b/configure.ac @@ -1772,13 +1772,6 @@ dnl On Solaris 8 there's a compilation warning for term.h because dnl it doesn't define 'bool'. AC_CHECK_HEADERS(term.h, , , -) AC_HEADER_TIME -AC_CHECK_DECLS([sys_siglist], [], [], [[#include - ]]) -if test $ac_cv_have_decl_sys_siglist != yes; then - # For Tru64, at least: - AC_CHECK_DECLS([__sys_siglist], [], [], [[#include - ]]) -fi AC_HEADER_SYS_WAIT AC_CHECK_HEADERS_ONCE(sys/socket.h) diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index 86eb14383c..f564d50122 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in @@ -136,6 +136,7 @@ # readlinkat \ # regex \ # sig2str \ +# sigdescr_np \ # socklen \ # stat-time \ # std-gnu11 \ @@ -2314,6 +2315,17 @@ EXTRA_libgnu_a_SOURCES += sig2str.c endif ## end gnulib module sig2str +## begin gnulib module sigdescr_np +ifeq (,$(OMIT_GNULIB_MODULE_sigdescr_np)) + + +EXTRA_DIST += sigdescr_np.c + +EXTRA_libgnu_a_SOURCES += sigdescr_np.c + +endif +## end gnulib module sigdescr_np + ## begin gnulib module signal-h ifeq (,$(OMIT_GNULIB_MODULE_signal-h)) diff --git a/lib/sigdescr_np.c b/lib/sigdescr_np.c new file mode 100644 index 0000000000..fc9cd3c236 --- /dev/null +++ b/lib/sigdescr_np.c @@ -0,0 +1,376 @@ +/* English descriptions of signals. + Copyright (C) 2020 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2020. */ + +#include + +/* Specification. */ +#include + +#include + +const char * +sigdescr_np (int sig) +{ + /* Note: Some platforms (glibc, FreeBSD, NetBSD, OpenBSD, AIX, IRIX, Haiku, + Android) have an array 'sys_siglist'. (On AIX, you need to declare it + yourself, and it has fewer than NSIG elements.) Its contents varies + depending on the OS. + On other OSes, you can invoke strsignal (sig) in the C locale. + In the code below, we show the differences. + You can see how cryptic some of these strings are. We try to pick more + understandable wordings. */ + + switch (sig) + { + /* Signals specified by ISO C. */ + case SIGABRT: + /* glibc: "Aborted". *BSD: "Abort trap". Solaris: "Abort". */ + return "Aborted"; + case SIGFPE: + /* glibc, *BSD: "Floating point exception". Solaris: "Arithmetic exception". + The latter is more correct, because of integer division by 0 or -1. */ + return "Arithmetic exception"; + case SIGILL: + return "Illegal instruction"; + case SIGINT: + return "Interrupt"; + case SIGSEGV: + return "Segmentation fault"; + case SIGTERM: + return "Terminated"; + + /* Signals specified by POSIX. + */ + #if defined SIGALRM + case SIGALRM: + return "Alarm clock"; + #endif + #if defined SIGBUS + case SIGBUS: + return "Bus error"; + #endif + #if defined SIGCHLD + case SIGCHLD: + /* glibc, *BSD: "Child exited". Solaris: "Child status changed". */ + return "Child stopped or exited"; + #endif + #if defined SIGCONT + case SIGCONT: + return "Continued"; + #endif + #if defined SIGHUP + case SIGHUP: + return "Hangup"; + #endif + #if defined SIGKILL + case SIGKILL: + return "Killed"; + #endif + #if defined SIGPIPE + case SIGPIPE: + return "Broken pipe"; + #endif + #if defined SIGQUIT + case SIGQUIT: + return "Quit"; + #endif + #if defined SIGSTOP + case SIGSTOP: + /* glibc, Solaris: "Stopped (signal)". *BSD: "Suspended (signal)". */ + return "Stopped (signal)"; + #endif + #if defined SIGTSTP + case SIGTSTP: + /* glibc: "Stopped". *BSD: "Suspended". Solaris: "Stopped (user)". */ + return "Stopped"; + #endif + #if defined SIGTTIN + case SIGTTIN: + return "Stopped (tty input)"; + #endif + #if defined SIGTTOU + case SIGTTOU: + return "Stopped (tty output)"; + #endif + #if defined SIGUSR1 + case SIGUSR1: + /* glibc, *BSD: "User defined signal 1". Solaris: "User signal 1". */ + return "User defined signal 1"; + #endif + #if defined SIGUSR2 + case SIGUSR2: + /* glibc, *BSD: "User defined signal 2". Solaris: "User signal 2". */ + return "User defined signal 2"; + #endif + #if defined SIGPOLL + case SIGPOLL: + /* glibc: "I/O possible". Solaris: "Pollable event". */ + return "I/O possible"; + #endif + #if defined SIGPROF + case SIGPROF: + return "Profiling timer expired"; + #endif + #if defined SIGSYS + case SIGSYS: + return "Bad system call"; + #endif + #if defined SIGTRAP + case SIGTRAP: + /* glibc, Solaris: "Trace/breakpoint trap". *BSD: "Trace/BPT trap". */ + return "Trace/breakpoint trap"; + #endif + #if defined SIGURG + case SIGURG: + /* glibc, *BSD: "Urgent I/O condition". Solaris: "Urgent socket condition". */ + return "Urgent I/O condition"; + #endif + #if defined SIGVTALRM + case SIGVTALRM: + return "Virtual timer expired"; + #endif + #if defined SIGXCPU + case SIGXCPU: + /* glibc, *BSD: "CPU time limit exceeded". Solaris: "Cpu limit exceeded". */ + return "CPU time limit exceeded"; + #endif + #if defined SIGXFSZ + case SIGXFSZ: + return "File size limit exceeded"; + #endif + + /* Other signals on other systems. */ + /* native Windows */ + #if defined SIGBREAK + case SIGBREAK: + return "Ctrl-Break"; + #endif + /* IRIX */ + #if defined SIGCKPT + case SIGCKPT: + return "Checkpoint"; /* See man 1 cpr, man 3C atcheckpoint */ + #endif + /* Linux, IRIX, Cygwin */ + #if defined SIGCLD && SIGCLD != SIGCHLD + case SIGCLD: + return "Child stopped or exited"; + #endif + /* AIX */ + #if defined SIGCPUFAIL + case SIGCPUFAIL: + /* AIX: "CPU failure predicted". */ + return "CPU going down"; /* See man bindprocessor */ + #endif + /* AIX */ + #if defined SIGDANGER + case SIGDANGER: + /* AIX: "Paging space low". */ + return "Swap space nearly exhausted"; + #endif + /* Mac OS X, FreeBSD, NetBSD, OpenBSD, Minix, AIX, IRIX, Cygwin, mingw */ + #if defined SIGEMT + case SIGEMT: + /* glibc/Hurd, *BSD: "EMT trap". Solaris: "Emulation trap". */ + return "Instruction emulation needed"; + #endif + /* Mac OS X, FreeBSD, NetBSD, OpenBSD, Minix */ + #if defined SIGINFO + case SIGINFO: + return "Information request"; + #endif + /* Linux, Mac OS X, FreeBSD, NetBSD, OpenBSD, Minix, AIX, IRIX, Cygwin */ + #if defined SIGIO && SIGIO != SIGPOLL + case SIGIO: + return "I/O possible"; + #endif + /* Linux, IRIX, Cygwin, mingw */ + #if defined SIGIOT && SIGIOT != SIGABRT + case SIGIOT: + return "IOT instruction"; /* a PDP-11 instruction */ + #endif + /* AIX */ + #if defined SIGKAP + case SIGKAP: + /* Process must issue a KSKAPACK ioctl, or will be killed in 30 seconds. */ + /* AIX: "Monitor mode granted". */ + return "Keep Alive Poll"; + #endif + /* Haiku */ + #if defined SIGKILLTHR + case SIGKILLTHR: + return "Kill thread"; + #endif + /* Minix */ + #if defined SIGKMEM + case SIGKMEM: + return "Kernel memory request"; + #endif + /* Minix */ + #if defined SIGKMESS + case SIGKMESS: + return "Kernel message"; + #endif + /* Minix */ + #if defined SIGKSIG + case SIGKSIG: + return "Kernel signal"; + #endif + /* Minix */ + #if defined SIGKSIGSM + case SIGKSIGSM: + return "Kernel signal for signal manager"; + #endif + /* FreeBSD */ + #if defined SIGLIBRT + case SIGLIBRT: + return "Real-time library interrupt"; + #endif + /* Cygwin */ + #if defined SIGLOST && SIGLOST != SIGABRT && SIGLOST != SIGPWR + case SIGLOST: + /* Solaris: "Resource lost". */ + return "File lock lost"; + #endif + /* AIX */ + #if defined SIGMIGRATE + case SIGMIGRATE: + return "Process migration"; + #endif + /* AIX */ + #if defined SIGMSG + case SIGMSG: + /* AIX: "Input device data". */ + return "Message in the ring"; + #endif + /* ACM */ + #if defined SIGPLAN + case SIGPLAN: + return "Programming language anomaly"; + #endif + /* AIX */ + #if defined SIGPRE + case SIGPRE: + return "Programmed exception"; + #endif + /* IRIX */ + #if defined SIGPTINTR + case SIGPTINTR: + return "Pthread interrupt"; + #endif + /* IRIX */ + #if defined SIGPTRESCHED + case SIGPTRESCHED: + return "Pthread rescheduling"; + #endif + /* Linux, NetBSD, Minix, AIX, IRIX, Cygwin */ + #if defined SIGPWR + case SIGPWR: + /* glibc: "Power failure". NetBSD: "Power fail/restart". */ + return "Power failure"; + #endif + /* AIX */ + #if defined SIGRECONFIG + case SIGRECONFIG: + return "Dynamic logical partitioning changed"; + #endif + /* AIX */ + #if defined SIGRECOVERY + case SIGRECOVERY: + return "Kernel recovery"; + #endif + /* IRIX */ + #if defined SIGRESTART + case SIGRESTART: + return "Checkpoint restart"; /* See man 1 cpr, man 3C atrestart */ + #endif + /* AIX */ + #if defined SIGRETRACT + case SIGRETRACT: + /* AIX: "Monitor mode retracted". */ + return "Retracting Keep Alive Poll"; + #endif + /* AIX */ + #if defined SIGSAK + case SIGSAK: + /* AIX: "Secure attention". */ + return "Secure Attention Key"; + #endif + /* ACM */ + #if defined SIGSAM + case SIGSAM: + return "Symbolic computation failed"; + #endif + /* Minix */ + #if defined SIGSNDELAY + case SIGSNDELAY: + return "Done sending message"; + #endif + /* AIX */ + #if defined SIGSOUND + case SIGSOUND: + /* AIX: "Sound completed". */ + return "Sound configuration changed"; + #endif + /* Linux */ + #if defined SIGSTKFLT + case SIGSTKFLT: + return "Stack fault"; + #endif + /* AIX */ + #if defined SIGSYSERROR + case SIGSYSERROR: + return "Kernel error"; + #endif + /* AIX */ + #if defined SIGTALRM + case SIGTALRM: + return "Thread alarm clock"; + #endif + /* FreeBSD, OpenBSD */ + #if defined SIGTHR + case SIGTHR: + /* OpenBSD: "Thread AST". */ + return "Thread library interrupt"; + #endif + /* IRIX */ + #if defined SIGUME + case SIGUME: + return "Uncorrectable memory error"; + #endif + /* AIX */ + #if defined SIGVIRT + case SIGVIRT: + return "Virtual time alarm clock"; + #endif + /* AIX */ + #if defined SIGWAITING + case SIGWAITING: + /* AIX: "No runnable lwp". */ + return "Thread waiting"; + #endif + /* Linux, Mac OS X, FreeBSD, NetBSD, OpenBSD, Minix, AIX, IRIX, Cygwin, Haiku */ + #if defined SIGWINCH + case SIGWINCH: + /* glibc: "Window changed". *BSD: "Window size changed" or "Window size changes". */ + return "Window size changed"; + #endif + + default: + return NULL; + } +} diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index 5bfa1473ed..f3e2cc9285 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -145,6 +145,7 @@ AC_DEFUN([gl_EARLY], # Code from module regex: # Code from module root-uid: # Code from module sig2str: + # Code from module sigdescr_np: # Code from module signal-h: # Code from module snippet/_Noreturn: # Code from module snippet/arg-nonnull: @@ -424,6 +425,11 @@ AC_DEFUN([gl_INIT], AC_LIBOBJ([sig2str]) gl_PREREQ_SIG2STR fi + gl_FUNC_SIGDESCR_NP + if test $HAVE_SIGDESCR_NP = 0; then + AC_LIBOBJ([sigdescr_np]) + fi + gl_STRING_MODULE_INDICATOR([sigdescr_np]) gl_SIGNAL_H gl_TYPE_SOCKLEN_T gt_TYPE_SSIZE_T @@ -1059,6 +1065,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/sha512.h lib/sig2str.c lib/sig2str.h + lib/sigdescr_np.c lib/signal.in.h lib/stat-time.c lib/stat-time.h @@ -1191,6 +1198,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/sha256.m4 m4/sha512.m4 m4/sig2str.m4 + m4/sigdescr_np.m4 m4/signal_h.m4 m4/socklen.m4 m4/ssize_t.m4 diff --git a/m4/sigdescr_np.m4 b/m4/sigdescr_np.m4 new file mode 100644 index 0000000000..f0f3f979e8 --- /dev/null +++ b/m4/sigdescr_np.m4 @@ -0,0 +1,17 @@ +# sigdescr_np.m4 serial 1 +dnl Copyright (C) 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, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_SIGDESCR_NP], +[ + dnl Persuade glibc to declare sigdescr_np(). + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + AC_CHECK_FUNCS([sigdescr_np]) + if test $ac_cv_func_sigdescr_np = no; then + HAVE_SIGDESCR_NP=0 + fi +]) diff --git a/src/sysdep.c b/src/sysdep.c index a1050c4309..e161172a79 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -1761,24 +1761,6 @@ deliver_thread_signal (int sig, signal_handler_t handler) errno = old_errno; } -#if !HAVE_DECL_SYS_SIGLIST -# undef sys_siglist -# ifdef _sys_siglist -# define sys_siglist _sys_siglist -# elif HAVE_DECL___SYS_SIGLIST -# define sys_siglist __sys_siglist -# else -# define sys_siglist my_sys_siglist -static char const *sys_siglist[NSIG]; -# endif -#endif - -#ifdef _sys_nsig -# define sys_siglist_entries _sys_nsig -#else -# define sys_siglist_entries NSIG -#endif - /* Handle bus errors, invalid instruction, etc. */ static void handle_fatal_signal (int sig) @@ -1970,143 +1952,6 @@ init_signals (void) main_thread_id = pthread_self (); #endif -#if !HAVE_DECL_SYS_SIGLIST && !defined _sys_siglist - if (! initialized) - { - sys_siglist[SIGABRT] = "Aborted"; -# ifdef SIGAIO - sys_siglist[SIGAIO] = "LAN I/O interrupt"; -# endif - sys_siglist[SIGALRM] = "Alarm clock"; -# ifdef SIGBUS - sys_siglist[SIGBUS] = "Bus error"; -# endif -# ifdef SIGCHLD - sys_siglist[SIGCHLD] = "Child status changed"; -# endif -# ifdef SIGCONT - sys_siglist[SIGCONT] = "Continued"; -# endif -# ifdef SIGDANGER - sys_siglist[SIGDANGER] = "Swap space dangerously low"; -# endif -# ifdef SIGDGNOTIFY - sys_siglist[SIGDGNOTIFY] = "Notification message in queue"; -# endif -# ifdef SIGEMT - sys_siglist[SIGEMT] = "Emulation trap"; -# endif - sys_siglist[SIGFPE] = "Arithmetic exception"; -# ifdef SIGFREEZE - sys_siglist[SIGFREEZE] = "SIGFREEZE"; -# endif -# ifdef SIGGRANT - sys_siglist[SIGGRANT] = "Monitor mode granted"; -# endif - sys_siglist[SIGHUP] = "Hangup"; - sys_siglist[SIGILL] = "Illegal instruction"; - sys_siglist[SIGINT] = "Interrupt"; -# ifdef SIGIO - sys_siglist[SIGIO] = "I/O possible"; -# endif -# ifdef SIGIOINT - sys_siglist[SIGIOINT] = "I/O intervention required"; -# endif -# ifdef SIGIOT - sys_siglist[SIGIOT] = "IOT trap"; -# endif - sys_siglist[SIGKILL] = "Killed"; -# ifdef SIGLOST - sys_siglist[SIGLOST] = "Resource lost"; -# endif -# ifdef SIGLWP - sys_siglist[SIGLWP] = "SIGLWP"; -# endif -# ifdef SIGMSG - sys_siglist[SIGMSG] = "Monitor mode data available"; -# endif -# ifdef SIGPHONE - sys_siglist[SIGWIND] = "SIGPHONE"; -# endif - sys_siglist[SIGPIPE] = "Broken pipe"; -# ifdef SIGPOLL - sys_siglist[SIGPOLL] = "Pollable event occurred"; -# endif -# ifdef SIGPROF - sys_siglist[SIGPROF] = "Profiling timer expired"; -# endif -# ifdef SIGPTY - sys_siglist[SIGPTY] = "PTY I/O interrupt"; -# endif -# ifdef SIGPWR - sys_siglist[SIGPWR] = "Power-fail restart"; -# endif - sys_siglist[SIGQUIT] = "Quit"; -# ifdef SIGRETRACT - sys_siglist[SIGRETRACT] = "Need to relinquish monitor mode"; -# endif -# ifdef SIGSAK - sys_siglist[SIGSAK] = "Secure attention"; -# endif - sys_siglist[SIGSEGV] = "Segmentation violation"; -# ifdef SIGSOUND - sys_siglist[SIGSOUND] = "Sound completed"; -# endif -# ifdef SIGSTOP - sys_siglist[SIGSTOP] = "Stopped (signal)"; -# endif -# ifdef SIGSTP - sys_siglist[SIGSTP] = "Stopped (user)"; -# endif -# ifdef SIGSYS - sys_siglist[SIGSYS] = "Bad argument to system call"; -# endif - sys_siglist[SIGTERM] = "Terminated"; -# ifdef SIGTHAW - sys_siglist[SIGTHAW] = "SIGTHAW"; -# endif -# ifdef SIGTRAP - sys_siglist[SIGTRAP] = "Trace/breakpoint trap"; -# endif -# ifdef SIGTSTP - sys_siglist[SIGTSTP] = "Stopped (user)"; -# endif -# ifdef SIGTTIN - sys_siglist[SIGTTIN] = "Stopped (tty input)"; -# endif -# ifdef SIGTTOU - sys_siglist[SIGTTOU] = "Stopped (tty output)"; -# endif -# ifdef SIGURG - sys_siglist[SIGURG] = "Urgent I/O condition"; -# endif -# ifdef SIGUSR1 - sys_siglist[SIGUSR1] = "User defined signal 1"; -# endif -# ifdef SIGUSR2 - sys_siglist[SIGUSR2] = "User defined signal 2"; -# endif -# ifdef SIGVTALRM - sys_siglist[SIGVTALRM] = "Virtual timer expired"; -# endif -# ifdef SIGWAITING - sys_siglist[SIGWAITING] = "Process's LWPs are blocked"; -# endif -# ifdef SIGWINCH - sys_siglist[SIGWINCH] = "Window size changed"; -# endif -# ifdef SIGWIND - sys_siglist[SIGWIND] = "SIGWIND"; -# endif -# ifdef SIGXCPU - sys_siglist[SIGXCPU] = "CPU time limit exceeded"; -# endif -# ifdef SIGXFSZ - sys_siglist[SIGXFSZ] = "File size limit exceeded"; -# endif - } -#endif /* !HAVE_DECL_SYS_SIGLIST && !_sys_siglist */ - /* Don't alter signal handlers if dumping. On some machines, changing signal handlers sets static data that would make signals fail to work right when the dumped Emacs is run. */ @@ -2762,15 +2607,13 @@ renameat_noreplace (int srcfd, char const *src, int dstfd, char const *dst) #endif } -/* Like strsignal, except async-signal-safe, and this function typically +/* Like strsignal, except async-signal-safe, and this function returns a string in the C locale rather than the current locale. */ char const * safe_strsignal (int code) { - char const *signame = 0; + char const *signame = sigdescr_np (code); - if (0 <= code && code < sys_siglist_entries) - signame = sys_siglist[code]; if (! signame) signame = "Unknown signal"; commit 42ec41251584c480ee3286ff369c18629f52a7d5 Author: Paul Eggert Date: Sun Aug 23 14:09:48 2020 -0700 Update from Gnulib This incorporates: 2020-08-23 intprops: be consistent about +X vs X+0 2020-08-23 intprops: fix INT_MULTIPLY_WRAPV bit-field bug 2020-08-23 verify: Make assume work on bit field expressions 2020-08-23 libc-config: Improve comments 2020-08-22 verify: Do use __builtin_assume on clang 2020-08-22 sig2str: Add more signals 2020-08-21 sigdescr_np: New module * lib/cdefs.h, lib/intprops.h, lib/sig2str.c, lib/string.in.h: * lib/verify.h, m4/string_h.m4: Copy from Gnulib. * lib/gnulib.mk.in: Regenerate. diff --git a/lib/cdefs.h b/lib/cdefs.h index b1870fd0a9..ff7c628a26 100644 --- a/lib/cdefs.h +++ b/lib/cdefs.h @@ -148,7 +148,11 @@ # define __warnattr(msg) __attribute__((__warning__ (msg))) # define __errordecl(name, msg) \ extern void name (void) __attribute__((__error__ (msg))) -#elif __glibc_clang_has_attribute (__diagnose_if__) && 0 /* fails on Fedora 31 with Clang 9. */ +#elif __glibc_clang_has_attribute (__diagnose_if__) && 0 +/* These definitions are not enabled, because they produce bogus warnings + in the glibc Fortify functions. These functions are written in a style + that works with GCC. In order to work with clang, these functions would + need to be modified. */ # define __warndecl(name, msg) \ extern void name (void) __attribute__((__diagnose_if__ (1, msg, "warning"))) # define __warnattr(msg) __attribute__((__diagnose_if__ (1, msg, "warning"))) diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index 78b4542d80..86eb14383c 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in @@ -426,6 +426,7 @@ GNULIB_SETENV = @GNULIB_SETENV@ GNULIB_SETHOSTNAME = @GNULIB_SETHOSTNAME@ GNULIB_SIGABBREV_NP = @GNULIB_SIGABBREV_NP@ GNULIB_SIGACTION = @GNULIB_SIGACTION@ +GNULIB_SIGDESCR_NP = @GNULIB_SIGDESCR_NP@ GNULIB_SIGNAL_H_SIGPIPE = @GNULIB_SIGNAL_H_SIGPIPE@ GNULIB_SIGPROCMASK = @GNULIB_SIGPROCMASK@ GNULIB_SLEEP = @GNULIB_SLEEP@ @@ -647,6 +648,7 @@ HAVE_SETHOSTNAME = @HAVE_SETHOSTNAME@ HAVE_SETSTATE = @HAVE_SETSTATE@ HAVE_SIGABBREV_NP = @HAVE_SIGABBREV_NP@ HAVE_SIGACTION = @HAVE_SIGACTION@ +HAVE_SIGDESCR_NP = @HAVE_SIGDESCR_NP@ HAVE_SIGHANDLER_T = @HAVE_SIGHANDLER_T@ HAVE_SIGINFO_T = @HAVE_SIGINFO_T@ HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@ @@ -2846,6 +2848,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's/@''GNULIB_STRERROR''@/$(GNULIB_STRERROR)/g' \ -e 's/@''GNULIB_STRERROR_R''@/$(GNULIB_STRERROR_R)/g' \ -e 's/@''GNULIB_SIGABBREV_NP''@/$(GNULIB_SIGABBREV_NP)/g' \ + -e 's/@''GNULIB_SIGDESCR_NP''@/$(GNULIB_SIGDESCR_NP)/g' \ -e 's/@''GNULIB_STRSIGNAL''@/$(GNULIB_STRSIGNAL)/g' \ -e 's/@''GNULIB_STRVERSCMP''@/$(GNULIB_STRVERSCMP)/g' \ < $(srcdir)/string.in.h | \ @@ -2869,6 +2872,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's|@''HAVE_DECL_STRTOK_R''@|$(HAVE_DECL_STRTOK_R)|g' \ -e 's|@''HAVE_DECL_STRERROR_R''@|$(HAVE_DECL_STRERROR_R)|g' \ -e 's|@''HAVE_SIGABBREV_NP''@|$(HAVE_SIGABBREV_NP)|g' \ + -e 's|@''HAVE_SIGDESCR_NP''@|$(HAVE_SIGDESCR_NP)|g' \ -e 's|@''HAVE_DECL_STRSIGNAL''@|$(HAVE_DECL_STRSIGNAL)|g' \ -e 's|@''HAVE_STRVERSCMP''@|$(HAVE_STRVERSCMP)|g' \ -e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \ diff --git a/lib/intprops.h b/lib/intprops.h index f2f70b3e73..b27f2eea05 100644 --- a/lib/intprops.h +++ b/lib/intprops.h @@ -48,7 +48,7 @@ /* Minimum and maximum values for integer types and expressions. */ /* The width in bits of the integer type or expression T. - Do not evaluate T. + Do not evaluate T. T must not be a bit-field expression. Padding bits are not supported; this is checked at compile-time below. */ #define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT) @@ -70,7 +70,7 @@ ? _GL_SIGNED_INT_MAXIMUM (e) \ : _GL_INT_NEGATE_CONVERT (e, 1)) #define _GL_SIGNED_INT_MAXIMUM(e) \ - (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH ((e) + 0) - 2)) - 1) * 2 + 1) + (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1) /* Work around OpenVMS incompatibility with C99. */ #if !defined LLONG_MAX && defined __INT64_MAX @@ -95,8 +95,9 @@ #endif /* Return 1 if the integer type or expression T might be signed. Return 0 - if it is definitely unsigned. This macro does not evaluate its argument, - and expands to an integer constant expression. */ + if it is definitely unsigned. T must not be a bit-field expression. + This macro does not evaluate its argument, and expands to an + integer constant expression. */ #if _GL_HAVE___TYPEOF__ # define _GL_SIGNED_TYPE_OR_EXPR(t) TYPE_SIGNED (__typeof__ (t)) #else @@ -109,6 +110,8 @@ #define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485) /* Bound on length of the string representing an integer type or expression T. + T must not be a bit-field expression. + Subtract 1 for the sign bit if T is signed, and then add 1 more for a minus sign if needed. @@ -120,7 +123,7 @@ + _GL_SIGNED_TYPE_OR_EXPR (t)) /* Bound on buffer size needed to represent an integer type or expression T, - including the terminating null. */ + including the terminating null. T must not be a bit-field expression. */ #define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1) @@ -566,7 +569,7 @@ ? (EXPR_SIGNED (_GL_INT_CONVERT (tmax, b)) \ ? (a) < (tmax) / (b) \ : ((INT_NEGATE_OVERFLOW (b) \ - ? _GL_INT_CONVERT (b, tmax) >> (TYPE_WIDTH (b) - 1) \ + ? _GL_INT_CONVERT (b, tmax) >> (TYPE_WIDTH (+ (b)) - 1) \ : (tmax) / -(b)) \ <= -1 - (a))) \ : INT_NEGATE_OVERFLOW (_GL_INT_CONVERT (b, tmin)) && (b) == -1 \ diff --git a/lib/sig2str.c b/lib/sig2str.c index 905daea2f2..cf7c3bb5c3 100644 --- a/lib/sig2str.c +++ b/lib/sig2str.c @@ -189,6 +189,11 @@ static struct numname { int num; char const name[8]; } numname_table[] = NUMNAME (STKFLT), #endif + /* AIX 7. */ +#ifdef SIGCPUFAIL + NUMNAME (CPUFAIL), +#endif + /* AIX 5L. */ #ifdef SIGDANGER NUMNAME (DANGER), @@ -229,7 +234,12 @@ static struct numname { int num; char const name[8]; } numname_table[] = NUMNAME (WINDOW), /* Older name for SIGWINCH. */ #endif - /* BeOS */ + /* OpenBSD. */ +#ifdef SIGTHR + NUMNAME (THR), +#endif + + /* BeOS, Haiku */ #ifdef SIGKILLTHR NUMNAME (KILLTHR), #endif @@ -239,6 +249,11 @@ static struct numname { int num; char const name[8]; } numname_table[] = NUMNAME (DIL), #endif + /* native Windows */ +#ifdef SIGBREAK + NUMNAME (BREAK), +#endif + /* Korn shell and Bash, of uncertain vintage. */ { 0, "EXIT" } }; diff --git a/lib/string.in.h b/lib/string.in.h index 5134e11289..776133c5eb 100644 --- a/lib/string.in.h +++ b/lib/string.in.h @@ -1060,6 +1060,21 @@ _GL_WARN_ON_USE (sigabbrev_np, "sigabbrev_np is unportable - " # endif #endif +/* Return an English description string for the signal number SIG. */ +#if @GNULIB_SIGDESCR_NP@ +# if ! @HAVE_SIGDESCR_NP@ +_GL_FUNCDECL_SYS (sigdescr_np, const char *, (int sig)); +# endif +_GL_CXXALIAS_SYS (sigdescr_np, const char *, (int sig)); +_GL_CXXALIASWARN (sigdescr_np); +#elif defined GNULIB_POSIXCHECK +# undef sigdescr_np +# if HAVE_RAW_DECL_SIGDESCR_NP +_GL_WARN_ON_USE (sigdescr_np, "sigdescr_np is unportable - " + "use gnulib module sigdescr_np for portability"); +# endif +#endif + #if @GNULIB_STRSIGNAL@ # if @REPLACE_STRSIGNAL@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) diff --git a/lib/verify.h b/lib/verify.h index d485a0283a..6d7b961db7 100644 --- a/lib/verify.h +++ b/lib/verify.h @@ -246,6 +246,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 @@ -305,14 +312,30 @@ template Although assuming R can help a compiler generate better code or diagnostics, performance can suffer if R uses hard-to-optimize - features such as function calls not inlined by the compiler. - - Avoid Clang’s __builtin_assume, as clang 9.0.1 -Wassume can - generate a bogus diagnostic "the argument to '__builtin_assume' has - side effects that will be discarded" even when the argument has no - side effects. */ - -#if _GL_HAS_BUILTIN_UNREACHABLE + features such as function calls not inlined by the compiler. */ + +/* Use __builtin_assume in preference to __builtin_unreachable, because + in clang versions 8.0.x and older, the definition based on + __builtin_assume has an effect on optimizations, whereas the definition + based on __builtin_unreachable does not. (GCC so far has only + __builtin_unreachable.) */ +#if _GL_HAS_BUILTIN_ASSUME +/* Use a temporary variable, to avoid a clang warning + "the argument to '__builtin_assume' has side effects that will be discarded" + if R contains invocations of functions not marked as 'const'. + The type of the temporary variable can't be __typeof__ (R), because that + does not work on bit field expressions. Use '_Bool' or 'bool' as type + instead. */ +# if defined __cplusplus +# define assume(R) \ + ((void) ({ bool _gl_verify_temp = (R); \ + __builtin_assume (_gl_verify_temp); })) +# else +# define assume(R) \ + ((void) ({ _Bool _gl_verify_temp = (R); \ + __builtin_assume (_gl_verify_temp); })) +# endif +#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/m4/string_h.m4 b/m4/string_h.m4 index d519beaa59..d7c12aaae8 100644 --- a/m4/string_h.m4 +++ b/m4/string_h.m4 @@ -5,7 +5,7 @@ # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 25 +# serial 26 # Written by Paul Eggert. @@ -28,7 +28,7 @@ AC_DEFUN([gl_HEADER_STRING_H_BODY], ]], [ffsl ffsll memmem mempcpy memrchr rawmemchr stpcpy stpncpy strchrnul strdup strncat strndup strnlen strpbrk strsep strcasestr strtok_r - strerror_r sigabbrev_np strsignal strverscmp]) + strerror_r sigabbrev_np sigdescr_np strsignal strverscmp]) AC_REQUIRE([AC_C_RESTRICT]) ]) @@ -81,6 +81,7 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS], GNULIB_STRERROR=0; AC_SUBST([GNULIB_STRERROR]) GNULIB_STRERROR_R=0; AC_SUBST([GNULIB_STRERROR_R]) GNULIB_SIGABBREV_NP=0;AC_SUBST([GNULIB_SIGABBREV_NP]) + GNULIB_SIGDESCR_NP=0; AC_SUBST([GNULIB_SIGDESCR_NP]) GNULIB_STRSIGNAL=0; AC_SUBST([GNULIB_STRSIGNAL]) GNULIB_STRVERSCMP=0; AC_SUBST([GNULIB_STRVERSCMP]) HAVE_MBSLEN=0; AC_SUBST([HAVE_MBSLEN]) @@ -104,6 +105,7 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS], HAVE_DECL_STRTOK_R=1; AC_SUBST([HAVE_DECL_STRTOK_R]) HAVE_DECL_STRERROR_R=1; AC_SUBST([HAVE_DECL_STRERROR_R]) HAVE_SIGABBREV_NP=1; AC_SUBST([HAVE_SIGABBREV_NP]) + HAVE_SIGDESCR_NP=1; AC_SUBST([HAVE_SIGDESCR_NP]) HAVE_DECL_STRSIGNAL=1; AC_SUBST([HAVE_DECL_STRSIGNAL]) HAVE_STRVERSCMP=1; AC_SUBST([HAVE_STRVERSCMP]) REPLACE_MEMCHR=0; AC_SUBST([REPLACE_MEMCHR]) commit 2c389455c72250b579f5225b99bc7de0cf435e4a Author: Eli Zaretskii Date: Sun Aug 23 22:09:39 2020 +0300 Fix more compilation warnings in xdisp.c * src/xdisp.c (display_mode_element, decode_mode_spec_coding): Avoid compilation warnings. diff --git a/src/xdisp.c b/src/xdisp.c index a6706b00c3..ed1d248990 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -25640,7 +25640,8 @@ display_mode_element (struct it *it, int depth, int field_width, int precision, /* Non-ASCII characters in SPEC should cause mode-line element be displayed as a multibyte string. */ ptrdiff_t nbytes = strlen (spec); - if (multibyte_chars_in_text (spec, nbytes) != nbytes) + if (multibyte_chars_in_text ((const unsigned char *)spec, + nbytes) != nbytes) multibyte = true; switch (mode_line_target) @@ -26261,7 +26262,8 @@ decode_mode_spec_coding (Lisp_Object coding_system, char *buf, bool eol_flag) eolvalue = AREF (val, 2); if (multibyte) - buf += CHAR_STRING (XFIXNAT (CODING_ATTR_MNEMONIC (attrs)), buf); + buf += CHAR_STRING (XFIXNAT (CODING_ATTR_MNEMONIC (attrs)), + (unsigned char *) buf); else *buf++ = ' '; commit f3e6dd1ce97bb279565465dc1ecce1516f42683e Author: Eli Zaretskii Date: Sun Aug 23 21:52:06 2020 +0300 Fix a compilation warning in xdisp.c * src/xdisp.c (gui_consider_frame_title): Fix compilation warning. Reported by Lars Ingebrigtsen . diff --git a/src/xdisp.c b/src/xdisp.c index 9d2bec379d..a6706b00c3 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -12568,8 +12568,8 @@ gui_consider_frame_title (Lisp_Object frame) /* Make sure that any raw bytes in the title are properly represented by their multibyte sequences. */ ptrdiff_t nchars = 0; - len = str_as_multibyte (title, mode_line_noprop_buf_end - title, - len, &nchars); + len = str_as_multibyte ((unsigned char *)title, + mode_line_noprop_buf_end - title, len, &nchars); unbind_to (count, Qnil); /* Set the title only if it's changed. This avoids consing in commit 3a99f966dc2dc9fb3922340caa0016b305789977 Author: Eli Zaretskii Date: Sun Aug 23 21:23:45 2020 +0300 Improve handling of coding-system mnemonic indicators This fixes assertion violations when the mnemonic is given as a string, and allows non-ASCII characters be used as mode-line mnemonic of a coding-system. * src/xdisp.c (decode_mode_spec_coding): Handle multibyte characters as coding-system's mnemonic. (display_mode_element): If decode_mode_spec returns a multibyte string, display it as multibyte. * src/coding.c (Fdefine_coding_system_internal) (Fcoding_system_put): If :mnemonic is a string, use its first character. This avoids assertion violations if someone uses a string as the mnemonic of a coding-system. diff --git a/src/coding.c b/src/coding.c index 51bd441de9..221a9cad89 100644 --- a/src/coding.c +++ b/src/coding.c @@ -10895,7 +10895,10 @@ usage: (define-coding-system-internal ...) */) ASET (attrs, coding_attr_base_name, name); Lisp_Object val = args[coding_arg_mnemonic]; - if (! STRINGP (val)) + /* decode_mode_spec_coding assumes the mnemonic is a single character. */ + if (STRINGP (val)) + val = make_fixnum (STRING_CHAR (SDATA (val))); + else CHECK_CHARACTER (val); ASET (attrs, coding_attr_mnemonic, val); @@ -11408,7 +11411,10 @@ DEFUN ("coding-system-put", Fcoding_system_put, Scoding_system_put, attrs = AREF (spec, 0); if (EQ (prop, QCmnemonic)) { - if (! STRINGP (val)) + /* decode_mode_spec_coding assumes the mnemonic is a single character. */ + if (STRINGP (val)) + val = make_fixnum (STRING_CHAR (SDATA (val))); + else CHECK_CHARACTER (val); ASET (attrs, coding_attr_mnemonic, val); } diff --git a/src/xdisp.c b/src/xdisp.c index e2ebbbdce7..9d2bec379d 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -25637,6 +25637,11 @@ display_mode_element (struct it *it, int depth, int field_width, int precision, spec = decode_mode_spec (it->w, c, field, &string); eassert (NILP (string) || STRINGP (string)); multibyte = !NILP (string) && STRING_MULTIBYTE (string); + /* Non-ASCII characters in SPEC should cause mode-line + element be displayed as a multibyte string. */ + ptrdiff_t nbytes = strlen (spec); + if (multibyte_chars_in_text (spec, nbytes) != nbytes) + multibyte = true; switch (mode_line_target) { @@ -26255,9 +26260,10 @@ decode_mode_spec_coding (Lisp_Object coding_system, char *buf, bool eol_flag) attrs = AREF (val, 0); eolvalue = AREF (val, 2); - *buf++ = multibyte - ? XFIXNAT (CODING_ATTR_MNEMONIC (attrs)) - : ' '; + if (multibyte) + buf += CHAR_STRING (XFIXNAT (CODING_ATTR_MNEMONIC (attrs)), buf); + else + *buf++ = ' '; if (eol_flag) { commit a5394884627db6f6091c4b85b635af81c20f0f31 Author: Mattias Engdegård Date: Fri Aug 21 16:09:04 2020 +0200 Always make a multibyte string for the frame title (bug#42904) * src/xdisp.c (gui_consider_frame_title): Multibyte-encode any raw bytes in the title, and then pass a multibyte string to the back-end for use as a frame title. This cuts down a little on the rubbish shown when raw bytes sneak in by mistake (as part of the buffer name, for instance). diff --git a/src/xdisp.c b/src/xdisp.c index 34644dff39..e2ebbbdce7 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -12565,6 +12565,11 @@ gui_consider_frame_title (Lisp_Object frame) display_mode_element (&it, 0, -1, -1, fmt, Qnil, false); len = MODE_LINE_NOPROP_LEN (title_start); title = mode_line_noprop_buf + title_start; + /* Make sure that any raw bytes in the title are properly + represented by their multibyte sequences. */ + ptrdiff_t nchars = 0; + len = str_as_multibyte (title, mode_line_noprop_buf_end - title, + len, &nchars); unbind_to (count, Qnil); /* Set the title only if it's changed. This avoids consing in @@ -12576,9 +12581,10 @@ gui_consider_frame_title (Lisp_Object frame) || SBYTES (f->name) != len || memcmp (title, SDATA (f->name), len) != 0) && FRAME_TERMINAL (f)->implicit_set_name_hook) - FRAME_TERMINAL (f)->implicit_set_name_hook (f, - make_string (title, len), - Qnil); + { + Lisp_Object title_string = make_multibyte_string (title, nchars, len); + FRAME_TERMINAL (f)->implicit_set_name_hook (f, title_string, Qnil); + } } } commit 6e2ee2a127952aaee63921a99a065693d3e8e07b Author: Eli Zaretskii Date: Sun Aug 23 19:25:58 2020 +0300 Fix image display on w32 as followup to recent changes The new code calls 'malloc' and 'free', so we can no longer * src/image.c (struct image_type): Rename 'load' to 'load_img' and 'free' to 'free_img'. All callers changed. (free_image) [WINDOWSNT]: Don't #undef 'free'. diff --git a/src/image.c b/src/image.c index 4933b619f6..35c5946c72 100644 --- a/src/image.c +++ b/src/image.c @@ -758,10 +758,10 @@ struct image_type /* Load IMG which is used on frame F from information contained in IMG->spec. Value is true if successful. */ - bool (*load) (struct frame *f, struct image *img); + bool (*load_img) (struct frame *f, struct image *img); /* Free resources of image IMG which is used on frame F. */ - void (*free) (struct frame *f, struct image *img); + void (*free_img) (struct frame *f, struct image *img); #ifdef WINDOWSNT /* Initialization function (used for dynamic loading of image @@ -1197,13 +1197,8 @@ free_image (struct frame *f, struct image *img) XRenderFreePicture (FRAME_X_DISPLAY (f), img->mask_picture); #endif - /* Windows NT redefines 'free', but in this file, we need to - avoid the redefinition. */ -#ifdef WINDOWSNT -#undef free -#endif /* Free resources, then free IMG. */ - img->type->free (f, img); + img->type->free_img (f, img); xfree (img); } } @@ -1249,7 +1244,7 @@ prepare_image_for_display (struct frame *f, struct image *img) /* If IMG doesn't have a pixmap yet, load it now, using the image type dependent loader function. */ if (img->pixmap == NO_PIXMAP && !img->load_failed_p) - img->load_failed_p = ! img->type->load (f, img); + img->load_failed_p = ! img->type->load_img (f, img); #ifdef USE_CAIRO if (!img->load_failed_p) @@ -1266,7 +1261,7 @@ prepare_image_for_display (struct frame *f, struct image *img) if (img->cr_data == NULL) { img->load_failed_p = 1; - img->type->free (f, img); + img->type->free_img (f, img); } } unblock_input (); @@ -2361,7 +2356,7 @@ lookup_image (struct frame *f, Lisp_Object spec, int face_id) cache_image (f, img); img->face_foreground = foreground; img->face_background = background; - img->load_failed_p = ! img->type->load (f, img); + img->load_failed_p = ! img->type->load_img (f, img); /* If we can't load the image, and we don't have a width and height, use some arbitrary width and height so that we can commit 8dc95e3598be0c20f1a192842bd2966ea342b255 Author: Alan Third Date: Sun Aug 23 17:06:02 2020 +0100 Silence compiler warning (bug#40845) * src/image.c (lookup_image): Don't allow face to be NULL. diff --git a/src/image.c b/src/image.c index e8e3388c6b..4933b619f6 100644 --- a/src/image.c +++ b/src/image.c @@ -2335,7 +2335,7 @@ lookup_image (struct frame *f, Lisp_Object spec, int face_id) EMACS_UINT hash; struct face *face = (face_id >= 0) ? FACE_FROM_ID (f, face_id) - : FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID); + : FACE_FROM_ID (f, DEFAULT_FACE_ID); unsigned long foreground = FACE_COLOR_TO_PIXEL (face->foreground, f); unsigned long background = FACE_COLOR_TO_PIXEL (face->background, f); commit 8f42b94fe43911c6b0c7e519ba439d61459dc744 Author: Alan Third Date: Sun Aug 23 16:28:17 2020 +0100 Set basic SVG attributes (bug#40845) * test/manual/image-transforms-tests.el: Replace hard-coded colors with defaults. * src/dispextern.h (struct image): * src/image.c (search_image_cache): (xbm_load_image): (xbm_load): (pbm_load): Rename from frame to face where relevant. (svg_load_image): Parse the image to find out the size, then wrap it in another SVG to set a new size and colors, etc. (lookup_image): Use the face colors instead of the frame colors. (search_image_cache): Add ability to ignore the face colors. (uncache_image): Uncache all copies of the image that share the spec, even if the face colors don't match. * etc/NEWS: Describe the changes. diff --git a/etc/NEWS b/etc/NEWS index d79cbe7611..cff435684e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -688,6 +688,22 @@ problematic in some contexts (like PDFs), so this list is now filtered based on 'auto-mode-alist'. Only file names that map to 'image-mode' are now supported. +--- +*** The background and foreground of images now default to face colors. +When an image doesn't specify a foreground or background color, Emacs +now uses colors from the face used to draw the surrounding text +instead of the frame's default colors. + +To load images with the default frame colors use the ':foreground' and +':background' image attributes, for example: + + (create-image "filename" nil nil + :foreground (face-attribute 'default :foreground) + :background (face-attribute 'default :background)) + +This change only affects image types that support foreground and +background colors or transparency, such as xbm, pbm, svg, png and gif. + ** EWW +++ diff --git a/lisp/net/shr.el b/lisp/net/shr.el index ddd8112721..24595301b7 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el @@ -1209,25 +1209,8 @@ Return a string with image data." ;; that are non-ASCII. (shr-dom-to-xml (libxml-parse-xml-region (point) (point-max)) 'utf-8))) - ;; SVG images often do not have a specified foreground/background - ;; color, so wrap them in styles. - (when (and (display-images-p) - (eq content-type 'image/svg+xml)) - (setq data (svg--wrap-svg data))) (list data content-type))) -(defun svg--wrap-svg (data) - "Add a default foreground colour to SVG images." - (let ((size (image-size (create-image data nil t :scaling 1) t))) - (with-temp-buffer - (insert - (format - " " - (face-foreground 'default) - (car size) (cdr size) - (base64-encode-string data t))) - (buffer-string)))) - (defun shr-image-displayer (content-function) "Return a function to display an image. CONTENT-FUNCTION is a function to retrieve an image for a cid url that diff --git a/src/dispextern.h b/src/dispextern.h index 311867a0c8..956ca96eb6 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -3056,9 +3056,9 @@ struct image if necessary. */ unsigned long background; - /* Foreground and background colors of the frame on which the image + /* Foreground and background colors of the face on which the image is created. */ - unsigned long frame_foreground, frame_background; + unsigned long face_foreground, face_background; /* True if this image has a `transparent' background -- that is, is uses an image mask. The accessor macro for this is @@ -3475,7 +3475,7 @@ void clear_image_caches (Lisp_Object); void mark_image_cache (struct image_cache *); bool valid_image_p (Lisp_Object); void prepare_image_for_display (struct frame *, struct image *); -ptrdiff_t lookup_image (struct frame *, Lisp_Object); +ptrdiff_t lookup_image (struct frame *, Lisp_Object, int); #if defined HAVE_X_WINDOWS || defined USE_CAIRO || defined HAVE_NS #define RGB_PIXEL_COLOR unsigned long diff --git a/src/gtkutil.c b/src/gtkutil.c index 1fe160acca..fafd94c0f7 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -5113,7 +5113,7 @@ update_frame_tool_bar (struct frame *f) else idx = -1; - img_id = lookup_image (f, image); + img_id = lookup_image (f, image, -1); img = IMAGE_FROM_ID (f, img_id); prepare_image_for_display (f, img); diff --git a/src/image.c b/src/image.c index 123de54ba2..e8e3388c6b 100644 --- a/src/image.c +++ b/src/image.c @@ -1081,7 +1081,7 @@ calling this function. */) if (valid_image_p (spec)) { struct frame *f = decode_window_system_frame (frame); - ptrdiff_t id = lookup_image (f, spec); + ptrdiff_t id = lookup_image (f, spec, -1); struct image *img = IMAGE_FROM_ID (f, id); int width = img->width + 2 * img->hmargin; int height = img->height + 2 * img->vmargin; @@ -1111,7 +1111,7 @@ or omitted means use the selected frame. */) if (valid_image_p (spec)) { struct frame *f = decode_window_system_frame (frame); - ptrdiff_t id = lookup_image (f, spec); + ptrdiff_t id = lookup_image (f, spec, -1); struct image *img = IMAGE_FROM_ID (f, id); if (img->mask) mask = Qt; @@ -1134,7 +1134,7 @@ or omitted means use the selected frame. */) if (valid_image_p (spec)) { struct frame *f = decode_window_system_frame (frame); - ptrdiff_t id = lookup_image (f, spec); + ptrdiff_t id = lookup_image (f, spec, -1); struct image *img = IMAGE_FROM_ID (f, id); ext = img->lisp_data; } @@ -1611,7 +1611,9 @@ equal_lists (Lisp_Object a, Lisp_Object b) /* Find an image matching SPEC in the cache, and return it. If no image is found, return NULL. */ static struct image * -search_image_cache (struct frame *f, Lisp_Object spec, EMACS_UINT hash) +search_image_cache (struct frame *f, Lisp_Object spec, EMACS_UINT hash, + unsigned long foreground, unsigned long background, + bool ignore_colors) { struct image *img; struct image_cache *c = FRAME_IMAGE_CACHE (f); @@ -1634,8 +1636,8 @@ search_image_cache (struct frame *f, Lisp_Object spec, EMACS_UINT hash) for (img = c->buckets[i]; img; img = img->next) if (img->hash == hash && equal_lists (img->spec, spec) - && img->frame_foreground == FRAME_FOREGROUND_PIXEL (f) - && img->frame_background == FRAME_BACKGROUND_PIXEL (f)) + && (ignore_colors || (img->face_foreground == foreground + && img->face_background == background))) break; return img; } @@ -1646,8 +1648,13 @@ search_image_cache (struct frame *f, Lisp_Object spec, EMACS_UINT hash) static void uncache_image (struct frame *f, Lisp_Object spec) { - struct image *img = search_image_cache (f, spec, sxhash (spec)); - if (img) + struct image *img; + + /* Because the background colors are based on the current face, we + can have multiple copies of an image with the same spec. We want + to remove them all to ensure the user doesn't see an old version + of the image when the face changes. */ + while ((img = search_image_cache (f, spec, sxhash (spec), 0, 0, true))) { free_image (f, img); /* As display glyphs may still be referring to the image ID, we @@ -2133,7 +2140,17 @@ image_set_transform (struct frame *f, struct image *img) /* Determine size. */ int width, height; - compute_image_size (img->width, img->height, img->spec, &width, &height); + +#ifdef HAVE_RSVG + /* SVGs are pre-scaled to the correct size. */ + if (EQ (image_spec_value (img->spec, QCtype, NULL), Qsvg)) + { + width = img->width; + height = img->height; + } + else +#endif + compute_image_size (img->width, img->height, img->spec, &width, &height); /* Determine rotation. */ double rotation = 0.0; @@ -2312,11 +2329,16 @@ image_set_transform (struct frame *f, struct image *img) SPEC must be a valid Lisp image specification (see valid_image_p). */ ptrdiff_t -lookup_image (struct frame *f, Lisp_Object spec) +lookup_image (struct frame *f, Lisp_Object spec, int face_id) { struct image *img; EMACS_UINT hash; + struct face *face = (face_id >= 0) ? FACE_FROM_ID (f, face_id) + : FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID); + unsigned long foreground = FACE_COLOR_TO_PIXEL (face->foreground, f); + unsigned long background = FACE_COLOR_TO_PIXEL (face->background, f); + /* F must be a window-system frame, and SPEC must be a valid image specification. */ eassert (FRAME_WINDOW_P (f)); @@ -2324,7 +2346,7 @@ lookup_image (struct frame *f, Lisp_Object spec) /* Look up SPEC in the hash table of the image cache. */ hash = sxhash (spec); - img = search_image_cache (f, spec, hash); + img = search_image_cache (f, spec, hash, foreground, background, true); if (img && img->load_failed_p) { free_image (f, img); @@ -2337,9 +2359,9 @@ lookup_image (struct frame *f, Lisp_Object spec) block_input (); img = make_image (spec, hash); cache_image (f, img); + img->face_foreground = foreground; + img->face_background = background; img->load_failed_p = ! img->type->load (f, img); - img->frame_foreground = FRAME_FOREGROUND_PIXEL (f); - img->frame_background = FRAME_BACKGROUND_PIXEL (f); /* If we can't load the image, and we don't have a width and height, use some arbitrary width and height so that we can @@ -2393,8 +2415,7 @@ lookup_image (struct frame *f, Lisp_Object spec) if (!NILP (bg)) { img->background - = image_alloc_image_color (f, img, bg, - FRAME_BACKGROUND_PIXEL (f)); + = image_alloc_image_color (f, img, bg, background); img->background_valid = 1; } } @@ -3667,8 +3688,8 @@ xbm_load_image (struct frame *f, struct image *img, char *contents, char *end) &data, 0); if (rc) { - unsigned long foreground = FRAME_FOREGROUND_PIXEL (f); - unsigned long background = FRAME_BACKGROUND_PIXEL (f); + unsigned long foreground = img->face_foreground; + unsigned long background = img->face_background; bool non_default_colors = 0; Lisp_Object value; @@ -3764,8 +3785,8 @@ xbm_load (struct frame *f, struct image *img) { struct image_keyword fmt[XBM_LAST]; Lisp_Object data; - unsigned long foreground = FRAME_FOREGROUND_PIXEL (f); - unsigned long background = FRAME_BACKGROUND_PIXEL (f); + unsigned long foreground = img->face_foreground; + unsigned long background = img->face_background; bool non_default_colors = 0; char *bits; bool parsed_p; @@ -6125,8 +6146,8 @@ pbm_load (struct frame *f, struct image *img) unsigned char c = 0; int g; struct image_keyword fmt[PBM_LAST]; - unsigned long fg = FRAME_FOREGROUND_PIXEL (f); - unsigned long bg = FRAME_BACKGROUND_PIXEL (f); + unsigned long fg = img->face_foreground; + unsigned long bg = img->face_background; /* Parse the image specification. */ memcpy (fmt, pbm_format, sizeof fmt); parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm); @@ -9433,6 +9454,7 @@ enum svg_keyword_index SVG_ALGORITHM, SVG_HEURISTIC_MASK, SVG_MASK, + SVG_FOREGROUND, SVG_BACKGROUND, SVG_LAST }; @@ -9451,6 +9473,7 @@ static const struct image_keyword svg_format[SVG_LAST] = {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, + {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0}, {":background", IMAGE_STRING_OR_NIL_VALUE, 0} }; @@ -9715,6 +9738,8 @@ svg_load_image (struct frame *f, struct image *img, char *contents, int height; const guint8 *pixels; int rowstride; + char *wrapped_contents = NULL; + ptrdiff_t wrapped_size; #if ! GLIB_CHECK_VERSION (2, 36, 0) /* g_type_init is a glib function that must be called prior to @@ -9722,6 +9747,8 @@ svg_load_image (struct frame *f, struct image *img, char *contents, g_type_init (); #endif + /* Parse the unmodified SVG data so we can get its initial size. */ + #if LIBRSVG_CHECK_VERSION (2, 32, 0) GInputStream *input_stream = g_memory_input_stream_new_from_data (contents, size, NULL); @@ -9750,6 +9777,105 @@ svg_load_image (struct frame *f, struct image *img, char *contents, rsvg_handle_write (rsvg_handle, (unsigned char *) contents, size, &err); if (err) goto rsvg_error; + /* The parsing is complete, rsvg_handle is ready to be used, close + it for further writes. */ + rsvg_handle_close (rsvg_handle, &err); + if (err) goto rsvg_error; +#endif + + /* Get the image dimensions. */ + rsvg_handle_get_dimensions (rsvg_handle, &dimension_data); + + /* We are now done with the unmodified data. */ + g_object_unref (rsvg_handle); + + /* Calculate the final image size. */ + compute_image_size (dimension_data.width, dimension_data.height, + img->spec, &width, &height); + + /* Wrap the SVG data in another SVG. This allows us to set the + width and height, as well as modify the foreground and background + colors. */ + { + Lisp_Object value; + unsigned long foreground = img->face_foreground; + unsigned long background = img->face_background; + + Lisp_Object encoded_contents + = Fbase64_encode_string (make_unibyte_string (contents, size), Qt); + + /* The wrapper sets the foreground color, width and height, and + viewBox must contain the dimensions of the original image. It + also draws a rectangle over the whole space, set to the + background color, before including the original image. This + acts to set the background color, instead of leaving it + transparent. */ + const char *wrapper = + "" + "" + "" + ""; + + /* FIXME: I've added 64 in the hope it will cover the size of the + width and height strings and things. */ + int buffer_size = SBYTES (encoded_contents) + strlen (wrapper) + 64; + + value = image_spec_value (img->spec, QCforeground, NULL); + if (!NILP (value)) + foreground = image_alloc_image_color (f, img, value, img->face_foreground); + value = image_spec_value (img->spec, QCbackground, NULL); + if (!NILP (value)) + { + background = image_alloc_image_color (f, img, value, img->face_background); + img->background = background; + img->background_valid = 1; + } + + wrapped_contents = malloc (buffer_size); + + if (!wrapped_contents + || buffer_size <= snprintf (wrapped_contents, buffer_size, wrapper, + foreground & 0xFFFFFF, width, height, + dimension_data.width, dimension_data.height, + background & 0xFFFFFF, SSDATA (encoded_contents))) + goto rsvg_error; + + wrapped_size = strlen (wrapped_contents); + } + + /* Now we parse the wrapped version. */ + +#if LIBRSVG_CHECK_VERSION (2, 32, 0) + input_stream = g_memory_input_stream_new_from_data (wrapped_contents, wrapped_size, NULL); + base_file = filename ? g_file_new_for_path (filename) : NULL; + rsvg_handle = rsvg_handle_new_from_stream_sync (input_stream, base_file, + RSVG_HANDLE_FLAGS_NONE, + NULL, &err); + if (base_file) + g_object_unref (base_file); + g_object_unref (input_stream); + + /* Check rsvg_handle too, to avoid librsvg 2.40.13 bug (Bug#36773#26). */ + if (!rsvg_handle || err) goto rsvg_error; +#else + /* Make a handle to a new rsvg object. */ + rsvg_handle = rsvg_handle_new (); + eassume (rsvg_handle); + + /* Set base_uri for properly handling referenced images (via 'href'). + See rsvg bug 596114 - "image refs are relative to curdir, not .svg file" + . */ + if (filename) + rsvg_handle_set_base_uri (rsvg_handle, filename); + + /* Parse the contents argument and fill in the rsvg_handle. */ + rsvg_handle_write (rsvg_handle, (unsigned char *) wrapped_contents, wrapped_size, &err); + if (err) goto rsvg_error; + /* The parsing is complete, rsvg_handle is ready to used, close it for further writes. */ rsvg_handle_close (rsvg_handle, &err); @@ -9768,6 +9894,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents, pixbuf = rsvg_handle_get_pixbuf (rsvg_handle); if (!pixbuf) goto rsvg_error; g_object_unref (rsvg_handle); + free (wrapped_contents); /* Extract some meta data from the svg handle. */ width = gdk_pixbuf_get_width (pixbuf); @@ -9792,25 +9919,6 @@ svg_load_image (struct frame *f, struct image *img, char *contents, init_color_table (); - /* Handle alpha channel by combining the image with a background - color. */ - Emacs_Color background; - Lisp_Object specified_bg = image_spec_value (img->spec, QCbackground, NULL); - if (!STRINGP (specified_bg) - || !FRAME_TERMINAL (f)->defined_color_hook (f, - SSDATA (specified_bg), - &background, - false, - false)) - FRAME_TERMINAL (f)->query_frame_background_color (f, &background); - - /* SVG pixmaps specify transparency in the last byte, so right - shift 8 bits to get rid of it, since emacs doesn't support - transparency. */ - background.red >>= 8; - background.green >>= 8; - background.blue >>= 8; - /* This loop handles opacity values, since Emacs assumes non-transparent images. Each pixel must be "flattened" by calculating the resulting color, given the transparency of the @@ -9822,16 +9930,11 @@ svg_load_image (struct frame *f, struct image *img, char *contents, int red = *pixels++; int green = *pixels++; int blue = *pixels++; - int opacity = *pixels++; - red = ((red * opacity) - + (background.red * ((1 << 8) - opacity))); - green = ((green * opacity) - + (background.green * ((1 << 8) - opacity))); - blue = ((blue * opacity) - + (background.blue * ((1 << 8) - opacity))); + /* Skip opacity. */ + pixels++; - PUT_PIXEL (ximg, x, y, lookup_rgb_color (f, red, green, blue)); + PUT_PIXEL (ximg, x, y, lookup_rgb_color (f, red << 8, green << 8, blue << 8)); } pixels += rowstride - 4 * width; @@ -9861,6 +9964,8 @@ svg_load_image (struct frame *f, struct image *img, char *contents, rsvg_error: if (rsvg_handle) g_object_unref (rsvg_handle); + if (wrapped_contents) + free (wrapped_contents); /* FIXME: Use error->message so the user knows what is the actual problem with the image. */ image_error ("Error parsing SVG image `%s'", img->spec); @@ -10159,7 +10264,7 @@ DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, ptrdiff_t id = -1; if (valid_image_p (spec)) - id = lookup_image (SELECTED_FRAME (), spec); + id = lookup_image (SELECTED_FRAME (), spec, -1); debug_print (spec); return make_fixnum (id); diff --git a/src/nsmenu.m b/src/nsmenu.m index b7e4cbd565..e313fc03f4 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -1092,7 +1092,7 @@ - (Lisp_Object)runMenuAt: (NSPoint)p forFrame: (struct frame *)f continue; } - img_id = lookup_image (f, image); + img_id = lookup_image (f, image, -1); img = IMAGE_FROM_ID (f, img_id); prepare_image_for_display (f, img); diff --git a/src/xdisp.c b/src/xdisp.c index a1f7706ead..34644dff39 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -5771,7 +5771,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, else { it->what = IT_IMAGE; - it->image_id = lookup_image (it->f, value); + it->image_id = lookup_image (it->f, value, it->face_id); it->position = start_pos; it->object = NILP (object) ? it->w->contents : object; it->method = GET_FROM_IMAGE; @@ -22517,7 +22517,7 @@ push_prefix_prop (struct it *it, Lisp_Object prop) else if (IMAGEP (prop)) { it->what = IT_IMAGE; - it->image_id = lookup_image (it->f, prop); + it->image_id = lookup_image (it->f, prop, it->face_id); it->method = GET_FROM_IMAGE; } #endif /* HAVE_WINDOW_SYSTEM */ @@ -27431,7 +27431,7 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop, if (FRAME_WINDOW_P (it->f) && valid_image_p (prop)) { - ptrdiff_t id = lookup_image (it->f, prop); + ptrdiff_t id = lookup_image (it->f, prop, it->face_id); struct image *img = IMAGE_FROM_ID (it->f, id); return OK_PIXELS (width_p ? img->width : img->height); diff --git a/test/manual/image-transforms-tests.el b/test/manual/image-transforms-tests.el index 0ebd5c7a19..02607e6367 100644 --- a/test/manual/image-transforms-tests.el +++ b/test/manual/image-transforms-tests.el @@ -48,24 +48,24 @@ (let ((image " - - + style='fill:none;stroke-width:1;stroke:currentColor'/> + + + style='fill:none;stroke-width:1;stroke:currentColor'/> ") (top-left " ") (middle " - - + style='fill:none;stroke-width:1;stroke:currentColor'/> + + ") (bottom-right " + style='fill:none;stroke-width:1;stroke:currentColor'/> ")) (insert-header "Test Crop: cropping an image (only works with ImageMagick)") (insert-test "all params" top-left image '(:crop (10 10 0 0))) @@ -77,23 +77,23 @@ (defun test-scaling () (let ((image " - - + style='fill:none;stroke-width:1;stroke:currentColor'/> + + ") (large " + style='fill:none;stroke-width:2;stroke:currentColor'/> + style='stroke-width:2;stroke:currentColor'/> + style='stroke-width:2;stroke:currentColor'/> ") (small " - - + style='fill:none;stroke-width:1;stroke:currentColor'/> + + ")) (insert-header "Test Scaling: resize an image (pixelization may occur)") (insert-test "1x" image image '(:scale 1)) @@ -107,27 +107,27 @@ (defun test-scaling-rotation () (let ((image " + style='fill:none;stroke-width:1;stroke:currentColor'/> + style='fill:currentColor'/> ") (x2-90 " + style='fill:none;stroke-width:1;stroke:currentColor'/> + style='fill:currentColor'/> ") (x2--90 " + style='fill:none;stroke-width:1;stroke:currentColor'/> + style='fill:currentColor'/> ") (x0.5-180 " + style='fill:none;stroke-width:1;stroke:currentColor'/> + style='fill:currentColor'/> ")) (insert-header "Test Scaling and Rotation: resize and rotate an image (pixelization may occur)") (insert-test "1x, 0 degrees" image image '(:scale 1 :rotation 0)) commit 4aff89ece6d9ceee882375879518b71ca6a89a70 Author: Michael Albinus Date: Sun Aug 23 13:30:43 2020 +0200 Rework direct async processes in Tramp * doc/misc/tramp.texi (Remote processes): Precise restrictions for direct async processes. * lisp/net/tramp.el (tramp-methods): Adapt docstring. (tramp-direct-async-process-p): Make it more precise. (tramp-handle-make-process): Rewrite, based on `make-process'. * test/lisp/net/tramp-tests.el (tramp-test-temporary-file-directory): Add `tramp-direct-async-args` for mock method. (tramp-test29-start-file-process, tramp-test30-make-process): Use weaker regexp checking "foo". (tramp-test30-make-process): Do not check stderr for direct async processes. (tramp--test--deftest-direct-async-process): New defmacro. (tramp-test29-start-file-process-direct-async) (tramp-test30-make-process-direct-async): New tests. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index c1a66d0251..bdf3b403d8 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -239,7 +239,7 @@ included in the file name portion, @value{tramp} sends the login name followed by a newline. @item -The remote host may then prompt for a password or pass phrase (for +The remote host may then prompt for a password or passphrase (for @command{rsh} or for @command{telnet}). @value{tramp} displays the password prompt in the minibuffer. @value{tramp} then sends whatever is entered to the remote host, followed by a newline. @@ -3563,9 +3563,8 @@ which must be set to a non-@code{nil} value. Example: Using direct asynchronous processes in @value{tramp} is not possible, if the remote host is connected via multiple hops -(@pxref{Multi-hops}), or the @code{make-process} / -@code{start-file-process} call uses a stderr stream. In this case, -@value{tramp} falls back to its classical implementation. +(@pxref{Multi-hops}). In this case, @value{tramp} falls back to its +classical implementation. Furthermore, this approach has the following limitations: @@ -3575,8 +3574,10 @@ It works only for connection methods defined in @file{tramp-sh.el} and @file{tramp-adb.el}. @item -It does not support interactive user authentication, like password -handling. +It does not support interactive user authentication. With +@option{ssh}-based methods, this can be avoided by using a password +agent like @command{ssh-agent}, using public key authentication, or +using @code{ControlMaster} options. @item It cannot be killed via @code{interrupt-process}. @@ -3584,6 +3585,9 @@ It cannot be killed via @code{interrupt-process}. @item It does not report the remote terminal name via @code{process-tty-name}. +@item +It does not set process property @code{remote-pid}. + @item It does not use @code{tramp-remote-path} and @code{tramp-remote-process-environment}. diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 83ade66ee1..28067faba3 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -248,6 +248,10 @@ pair of the form (KEY VALUE). The following KEYs are defined: parameters to suppress diagnostic messages, in order not to tamper the process output. + * `tramp-direct-async-args' + An additional argument when a direct asynchronous process is + started. Used so far only in the \"mock\" method of tramp-tests.el. + * `tramp-copy-program' This specifies the name of the program to use for remotely copying the file; this might be the absolute filename of scp or the name of @@ -3733,26 +3737,29 @@ User is always nil." (defun tramp-direct-async-process-p (&rest args) "Whether direct async `make-process' can be called." - (let ((v (tramp-dissect-file-name default-directory))) - (and (tramp-get-connection-property v "direct-async-process" nil) - (= (length (tramp-compute-multi-hops v)) 1) - (not (plist-get args :stderr))))) - -;; We use BUFFER also as connection buffer during setup. Because of -;; this, its original contents must be saved, and restored once -;; connection has been setup. + (let ((v (tramp-dissect-file-name default-directory)) + (buffer (plist-get args :buffer)) + (stderr (plist-get args :stderr))) + (and ;; It has been indicated. + (tramp-get-connection-property v "direct-async-process" nil) + ;; There's no multi-hop. + (or (not (tramp-multi-hop-p v)) + (= (length (tramp-compute-multi-hops v)) 1)) + ;; There's no remote stdout or stderr file. + (or (not (stringp buffer)) (not (tramp-tramp-file-p buffer))) + (or (not (stringp stderr)) (not (tramp-tramp-file-p stderr)))))) + (defun tramp-handle-make-process (&rest args) "An alternative `make-process' implementation for Tramp files. It does not support `:stderr'." (when args (with-parsed-tramp-file-name (expand-file-name default-directory) nil - (let ((name (plist-get args :name)) + (let ((default-directory (tramp-compat-temporary-file-directory)) + (name (plist-get args :name)) (buffer (plist-get args :buffer)) (command (plist-get args :command)) - ;; FIXME: `:coding' shall be used. (coding (plist-get args :coding)) (noquery (plist-get args :noquery)) - ;; FIXME: `:connection-type' shall be used. (connection-type (plist-get args :connection-type)) (filter (plist-get args :filter)) (sentinel (plist-get args :sentinel)) @@ -3775,122 +3782,77 @@ It does not support `:stderr'." (signal 'wrong-type-argument (list #'functionp filter))) (unless (or (null sentinel) (functionp sentinel)) (signal 'wrong-type-argument (list #'functionp sentinel))) - (when stderr - (signal - 'user-error - (list - "Stderr not supported for direct remote asynchronous processes" - stderr))) + (unless (or (null stderr) (bufferp stderr)) + (signal 'wrong-type-argument (list #'stringp stderr))) (let* ((buffer (if buffer (get-buffer-create buffer) ;; BUFFER can be nil. We use a temporary buffer. (generate-new-buffer tramp-temp-buffer-name))) - (command (append `("cd" ,localname "&&") - (mapcar #'tramp-shell-quote-argument command))) - (bmp (and (buffer-live-p buffer) (buffer-modified-p buffer))) - (name1 name) - (i 0) - ;; We do not want to raise an error when `make-process' - ;; has been started several times in `eshell' and - ;; friends. - tramp-current-connection - p) - - (while (get-process name1) - ;; NAME must be unique as process name. - (setq i (1+ i) - name1 (format "%s<%d>" name i))) - (setq name name1) - ;; Set the new process properties. - (tramp-set-connection-property v "process-name" name) - (tramp-set-connection-property v "process-buffer" buffer) + (command + (mapconcat + #'identity (append `("cd" ,localname "&&") command) " "))) ;; Check for `tramp-sh-file-name-handler', because something ;; is different between tramp-adb.el and tramp-sh.el. - (with-current-buffer (tramp-get-connection-buffer v) - (unwind-protect - (let* ((sh-file-name-handler-p (tramp-sh-file-name-handler-p v)) - (login-program - (tramp-get-method-parameter v 'tramp-login-program)) - (login-args - (tramp-get-method-parameter v 'tramp-login-args)) - (async-args - (tramp-get-method-parameter v 'tramp-async-args)) - ;; We don't create the temporary file. In - ;; fact, it is just a prefix for the - ;; ControlPath option of ssh; the real - ;; temporary file has another name, and it is - ;; created and protected by ssh. It is also - ;; removed by ssh when the connection is - ;; closed. The temporary file name is cached - ;; in the main connection process, therefore - ;; we cannot use `tramp-get-connection-process'. - (tmpfile - (when sh-file-name-handler-p - (with-tramp-connection-property - (tramp-get-process v) "temp-file" - (tramp-compat-make-temp-name)))) - (options - (when sh-file-name-handler-p - (tramp-compat-funcall - 'tramp-ssh-controlmaster-options v))) - spec) - - ;; Replace `login-args' place holders. - (setq - spec (format-spec-make ?t tmpfile) - options (format-spec (or options "") spec) - spec (format-spec-make - ?h (or host "") ?u (or user "") ?p (or port "") - ?c options ?l "") - ;; Add arguments for asynchronous processes. - login-args (append async-args login-args) - ;; Expand format spec. - login-args - (tramp-compat-flatten-tree - (mapcar - (lambda (x) - (setq x (mapcar (lambda (y) (format-spec y spec)) x)) - (unless (member "" x) x)) - login-args)) - ;; Split ControlMaster options. - login-args - (tramp-compat-flatten-tree - (mapcar (lambda (x) (split-string x " ")) login-args)) - p (apply - #'start-process - name buffer login-program (append login-args command))) - - (tramp-message v 6 "%s" (string-join (process-command p) " ")) - ;; Set sentinel and filter. - (when sentinel - (set-process-sentinel p sentinel)) - (when filter - (set-process-filter p filter)) - ;; Set query flag and process marker for this - ;; process. We ignore errors, because the - ;; process could have finished already. - (ignore-errors - (set-process-query-on-exit-flag p (null noquery)) - (set-marker (process-mark p) (point))) - ;; We must flush them here already; otherwise - ;; `rename-file', `delete-file' or - ;; `insert-file-contents' will fail. - (tramp-flush-connection-property v "process-name") - (tramp-flush-connection-property v "process-buffer") - ;; Return process. - p) - - ;; Save exit. - (if (string-match-p tramp-temp-buffer-name (buffer-name)) - (ignore-errors - (set-process-buffer p nil) - (kill-buffer (current-buffer))) - (set-buffer-modified-p bmp)) - (tramp-flush-connection-property v "process-name") - (tramp-flush-connection-property v "process-buffer")))))))) + (let* ((sh-file-name-handler-p (tramp-sh-file-name-handler-p v)) + (login-program + (tramp-get-method-parameter v 'tramp-login-program)) + (login-args + (tramp-get-method-parameter v 'tramp-login-args)) + (async-args + (tramp-get-method-parameter v 'tramp-async-args)) + (direct-async-args + (tramp-get-method-parameter v 'tramp-direct-async-args)) + ;; We don't create the temporary file. In fact, it + ;; is just a prefix for the ControlPath option of + ;; ssh; the real temporary file has another name, and + ;; it is created and protected by ssh. It is also + ;; removed by ssh when the connection is closed. The + ;; temporary file name is cached in the main + ;; connection process, therefore we cannot use + ;; `tramp-get-connection-process'. + (tmpfile + (when sh-file-name-handler-p + (with-tramp-connection-property + (tramp-get-process v) "temp-file" + (tramp-compat-make-temp-name)))) + (options + (when sh-file-name-handler-p + (tramp-compat-funcall + 'tramp-ssh-controlmaster-options v))) + spec p) + + ;; Replace `login-args' place holders. + (setq + spec (format-spec-make ?t tmpfile) + options (format-spec (or options "") spec) + spec (format-spec-make + ?h (or host "") ?u (or user "") ?p (or port "") + ?c options ?l "") + ;; Add arguments for asynchronous processes. + login-args (append async-args direct-async-args login-args) + ;; Expand format spec. + login-args + (tramp-compat-flatten-tree + (mapcar + (lambda (x) + (setq x (mapcar (lambda (y) (format-spec y spec)) x)) + (unless (member "" x) x)) + login-args)) + ;; Split ControlMaster options. + login-args + (tramp-compat-flatten-tree + (mapcar (lambda (x) (split-string x " ")) login-args)) + p (make-process + :name name :buffer buffer + :command (append `(,login-program) login-args `(,command)) + :coding coding :noquery noquery :connection-type connection-type + :filter filter :sentinel sentinel :stderr stderr)) + + (tramp-message v 6 "%s" (string-join (process-command p) " ")) + p)))))) (defun tramp-handle-make-symbolic-link (target linkname &optional ok-if-already-exists) diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 561dd268f8..6bfc7f93c4 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -98,6 +98,7 @@ '("mock" (tramp-login-program "sh") (tramp-login-args (("-i"))) + (tramp-direct-async-args (("-c"))) (tramp-remote-shell "/bin/sh") (tramp-remote-shell-args ("-c")) (tramp-connection-timeout 10))) @@ -4326,9 +4327,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." (with-timeout (10 (tramp--test-timeout-handler)) (while (< (- (point-max) (point-min)) (length "foo")) (while (accept-process-output proc 0 nil t)))) - ;; We cannot use `string-equal', because tramp-adb.el - ;; echoes also the sent string. - (should (string-match "\\`foo" (buffer-string)))) + (should (string-match "foo" (buffer-string)))) ;; Cleanup. (ignore-errors (delete-process proc))) @@ -4347,7 +4346,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." (with-timeout (10 (tramp--test-timeout-handler)) (while (< (- (point-max) (point-min)) (length "foo")) (while (accept-process-output proc 0 nil t)))) - (should (string-equal (buffer-string) "foo"))) + (should (string-match "foo" (buffer-string)))) ;; Cleanup. (ignore-errors @@ -4369,13 +4368,35 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." (with-timeout (10 (tramp--test-timeout-handler)) (while (< (- (point-max) (point-min)) (length "foo")) (while (accept-process-output proc 0 nil t)))) - ;; We cannot use `string-equal', because tramp-adb.el - ;; echoes also the sent string. - (should (string-match "\\`foo" (buffer-string)))) + (should (string-match "foo" (buffer-string)))) ;; Cleanup. (ignore-errors (delete-process proc)))))) +(defmacro tramp--test--deftest-direct-async-process + (test docstring &optional unstable) + "Define ert `TEST-direct-async' for direct async processes. +If UNSTABLE is non-nil, the test is tagged as `:unstable'." + (declare (indent 1)) + `(ert-deftest ,(intern (concat (symbol-name test) "-direct-async")) () + ,docstring + :tags (if ,unstable '(:expensive-test :unstable) '(:expensive-test)) + (skip-unless (tramp--test-enabled)) + (let ((default-directory tramp-test-temporary-file-directory) + (ert-test (ert-get-test ',test)) + (tramp-connection-properties + (cons '(nil "direct-async-process" t) tramp-connection-properties))) + (skip-unless (tramp-direct-async-process-p)) + ;; We do expect an established connection already, + ;; `file-truename' does it by side-effect. Suppress + ;; `tramp--test-enabled', in order to keep the connection. + (cl-letf (((symbol-function #'tramp--test-enabled) (lambda nil t))) + (file-truename tramp-test-temporary-file-directory) + (funcall (ert-test-body ert-test)))))) + +(tramp--test--deftest-direct-async-process tramp-test29-start-file-process + "Check direct async `start-file-process'.") + (ert-deftest tramp-test30-make-process () "Check `make-process'." :tags '(:expensive-test) @@ -4408,9 +4429,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." (with-timeout (10 (tramp--test-timeout-handler)) (while (< (- (point-max) (point-min)) (length "foo")) (while (accept-process-output proc 0 nil t)))) - ;; We cannot use `string-equal', because tramp-adb.el - ;; echoes also the sent string. - (should (string-match "\\`foo" (buffer-string)))) + (should (string-match "foo" (buffer-string)))) ;; Cleanup. (ignore-errors (delete-process proc))) @@ -4431,7 +4450,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." (with-timeout (10 (tramp--test-timeout-handler)) (while (< (- (point-max) (point-min)) (length "foo")) (while (accept-process-output proc 0 nil t)))) - (should (string-equal (buffer-string) "foo"))) + (should (string-match "foo" (buffer-string)))) ;; Cleanup. (ignore-errors @@ -4457,9 +4476,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." (with-timeout (10 (tramp--test-timeout-handler)) (while (not (string-match "foo" (buffer-string))) (while (accept-process-output proc 0 nil t)))) - ;; We cannot use `string-equal', because tramp-adb.el - ;; echoes also the sent string. - (should (string-match "\\`foo" (buffer-string)))) + (should (string-match "foo" (buffer-string)))) ;; Cleanup. (ignore-errors (delete-process proc))) @@ -4483,10 +4500,6 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." ;; Read output. (with-timeout (10 (tramp--test-timeout-handler)) (while (accept-process-output proc 0 nil t))) - ;; We cannot use `string-equal', because tramp-adb.el - ;; echoes also the sent string. And a remote macOS sends - ;; a slightly modified string. On MS Windows, - ;; `delete-process' sends an unknown signal. (should (string-match (if (eq system-type 'windows-nt) @@ -4497,55 +4510,60 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." (ignore-errors (delete-process proc))) ;; Process with stderr buffer. - (let ((stderr (generate-new-buffer "*stderr*"))) - (unwind-protect - (with-temp-buffer - (setq proc - (with-no-warnings - (make-process - :name "test5" :buffer (current-buffer) - :command '("cat" "/does-not-exist") - :stderr stderr - :file-handler t))) - (should (processp proc)) - ;; Read stderr. - (with-timeout (10 (tramp--test-timeout-handler)) - (while (accept-process-output proc 0 nil t))) - (delete-process proc) - (with-current-buffer stderr - (should - (string-match - "cat:.* No such file or directory" (buffer-string))))) + (unless (tramp-direct-async-process-p) + (let ((stderr (generate-new-buffer "*stderr*"))) + (unwind-protect + (with-temp-buffer + (setq proc + (with-no-warnings + (make-process + :name "test5" :buffer (current-buffer) + :command '("cat" "/does-not-exist") + :stderr stderr + :file-handler t))) + (should (processp proc)) + ;; Read stderr. + (with-timeout (10 (tramp--test-timeout-handler)) + (while (accept-process-output proc 0 nil t))) + (delete-process proc) + (with-current-buffer stderr + (should + (string-match + "cat:.* No such file or directory" (buffer-string))))) - ;; Cleanup. - (ignore-errors (delete-process proc)) - (ignore-errors (kill-buffer stderr)))) + ;; Cleanup. + (ignore-errors (delete-process proc)) + (ignore-errors (kill-buffer stderr))))) ;; Process with stderr file. - (dolist (tmpfile `(,tmp-name1 ,tmp-name2)) - (unwind-protect - (with-temp-buffer - (setq proc - (with-no-warnings - (make-process - :name "test6" :buffer (current-buffer) - :command '("cat" "/does-not-exist") - :stderr tmpfile - :file-handler t))) - (should (processp proc)) - ;; Read stderr. - (with-timeout (10 (tramp--test-timeout-handler)) - (while (accept-process-output proc nil nil t))) - (delete-process proc) + (unless (tramp-direct-async-process-p) + (dolist (tmpfile `(,tmp-name1 ,tmp-name2)) + (unwind-protect (with-temp-buffer - (insert-file-contents tmpfile) - (should - (string-match - "cat:.* No such file or directory" (buffer-string))))) + (setq proc + (with-no-warnings + (make-process + :name "test6" :buffer (current-buffer) + :command '("cat" "/does-not-exist") + :stderr tmpfile + :file-handler t))) + (should (processp proc)) + ;; Read stderr. + (with-timeout (10 (tramp--test-timeout-handler)) + (while (accept-process-output proc nil nil t))) + (delete-process proc) + (with-temp-buffer + (insert-file-contents tmpfile) + (should + (string-match + "cat:.* No such file or directory" (buffer-string))))) - ;; Cleanup. - (ignore-errors (delete-process proc)) - (ignore-errors (delete-file tmpfile))))))) + ;; Cleanup. + (ignore-errors (delete-process proc)) + (ignore-errors (delete-file tmpfile)))))))) + +(tramp--test--deftest-direct-async-process tramp-test30-make-process + "Check direct async `make-process'.") (ert-deftest tramp-test31-interrupt-process () "Check `interrupt-process'." commit 608b8113cbfb2f24fd806b63306333db7154eb61 Author: Michael Albinus Date: Sun Aug 23 13:19:02 2020 +0200 ; * test/lisp/net/tramp-tests.el (tramp-test28-process-file): Instrument test. diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 05196e7e4a..561dd268f8 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -4229,6 +4229,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." (skip-unless (or (tramp--test-adb-p) (tramp--test-sh-p))) (skip-unless (not (tramp--test-crypt-p))) + (tramp--test-instrument-test-case 10 (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil))) (let* ((tmp-name (tramp--test-make-temp-name nil quoted)) (fnnd (file-name-nondirectory tmp-name)) @@ -4289,7 +4290,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." (should-not (get-buffer-window (current-buffer) t)))) ;; Cleanup. - (ignore-errors (delete-file tmp-name)))))) + (ignore-errors (delete-file tmp-name))))))) ;; Must be a command, because used as `sigusr' handler. (defun tramp--test-timeout-handler (&rest _ignore)