commit ff0f4c731231b03d73cc35de9e042d1fc1b75f4e (HEAD, refs/remotes/origin/master) Author: Amin Bandali Date: Sat Aug 17 14:09:11 2019 -0400 Fix erc-lurker-update-status (bug#36843) Broken since 2013-08-22 "* lisp/erc/erc.el: Use lexical-binding". * lisp/erc/erc.el (erc-message-parsed): New variable. (erc-display-message): Dynamically bind it. (erc-lurker-update-status): Check it instead of using `parsed' directly. This results in `erc-lurker-state' being properly updated to keep track of non-lurkers, and thus `erc-lurker-p' returning correct results rather than return t for everyone. diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index f5c9decc3a..fd1bd5545d 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -2594,6 +2594,8 @@ every `erc-lurker-cleanup-interval' updates to consumption of lurker state during long Emacs sessions and/or ERC sessions with large numbers of incoming PRIVMSGs.") +(defvar erc-message-parsed) + (defun erc-lurker-update-status (_message) "Update `erc-lurker-state' if necessary. @@ -2603,18 +2605,20 @@ reflect the fact that its sender has issued a PRIVMSG at the current time. Otherwise, take no action. This function depends on the fact that `erc-display-message' -dynamically binds `parsed', which is used to check if the current -message is a PRIVMSG and to determine its sender. See also -`erc-lurker-trim-nicks' and `erc-lurker-ignore-chars'. +dynamically binds `erc-message-parsed', which is used to check if +the current message is a PRIVMSG and to determine its sender. +See also `erc-lurker-trim-nicks' and `erc-lurker-ignore-chars'. In order to limit memory consumption, this function also calls `erc-lurker-cleanup' once every `erc-lurker-cleanup-interval' updates of `erc-lurker-state'." - (when (and (boundp 'parsed) (erc-response-p parsed)) - (let* ((command (erc-response.command parsed)) + (when (and (boundp 'erc-message-parsed) + (erc-response-p erc-message-parsed)) + (let* ((command (erc-response.command erc-message-parsed)) (sender (erc-lurker-maybe-trim - (car (erc-parse-user (erc-response.sender parsed))))) + (car (erc-parse-user + (erc-response.sender erc-message-parsed))))) (server (erc-canonicalize-server-name erc-server-announced-name))) (when (equal command "PRIVMSG") @@ -2704,7 +2708,8 @@ ARGS, PARSED, and TYPE are used to format MSG sensibly. See also `erc-format-message' and `erc-display-line'." (let ((string (if (symbolp msg) (apply #'erc-format-message msg args) - msg))) + msg)) + (erc-message-parsed parsed)) (setq string (cond ((null type) commit 16ab25f136c4eef27743dfa50953692d115f162c Author: Paul Eggert Date: Thu Sep 5 13:25:43 2019 -0700 Fix bugs when recalculating consing_until_gc Problem reported by Joseph Mingrone (Bug#37006#72). * src/alloc.c (watch_gc_cons_threshold) (watch_gc_cons_percentage): Don’t try to store an intmax_t into an int. Redo to make the code clearer. (watch_gc_cons_percentage): Use gc_cons_threshold, not consing_until_gc. diff --git a/src/alloc.c b/src/alloc.c index 089f61f833..5fc515f33b 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -5783,18 +5783,18 @@ mark_and_sweep_weak_table_contents (void) /* Return the number of bytes to cons between GCs, assuming gc-cons-threshold is THRESHOLD and gc-cons-percentage is - GC_CONS_PERCENTAGE. */ + PERCENTAGE. */ static intmax_t -consing_threshold (intmax_t threshold, Lisp_Object gc_cons_percentage) +consing_threshold (intmax_t threshold, Lisp_Object percentage) { if (!NILP (Vmemory_full)) return memory_full_cons_threshold; else { threshold = max (threshold, GC_DEFAULT_THRESHOLD / 10); - if (FLOATP (gc_cons_percentage)) + if (FLOATP (percentage)) { - double tot = (XFLOAT_DATA (gc_cons_percentage) + double tot = (XFLOAT_DATA (percentage) * total_bytes_of_live_objects ()); if (threshold < tot) { @@ -5825,11 +5825,12 @@ static Lisp_Object watch_gc_cons_threshold (Lisp_Object symbol, Lisp_Object newval, Lisp_Object operation, Lisp_Object where) { - intmax_t new_threshold; - int diff = (INTEGERP (newval) && integer_to_intmax (newval, &new_threshold) - ? (consing_threshold (new_threshold, Vgc_cons_percentage) - - consing_threshold (gc_cons_threshold, Vgc_cons_percentage)) - : 0); + Lisp_Object percentage = Vgc_cons_percentage; + intmax_t threshold; + intmax_t diff = (INTEGERP (newval) && integer_to_intmax (newval, &threshold) + ? (consing_threshold (threshold, percentage) + - consing_threshold (gc_cons_threshold, percentage)) + : 0); return bump_consing_until_gc (diff); } @@ -5838,8 +5839,9 @@ static Lisp_Object watch_gc_cons_percentage (Lisp_Object symbol, Lisp_Object newval, Lisp_Object operation, Lisp_Object where) { - int diff = (consing_threshold (consing_until_gc, newval) - - consing_threshold (consing_until_gc, Vgc_cons_percentage)); + intmax_t threshold = gc_cons_threshold; + intmax_t diff = (consing_threshold (threshold, newval) + - consing_threshold (threshold, Vgc_cons_percentage)); return bump_consing_until_gc (diff); } commit b9e37f551add188f82f2583d3eb13cb81e707387 Author: Paul Eggert Date: Thu Sep 5 11:42:56 2019 -0700 Port :safe-renegotiation test to GnuTLS < 3.6.3 Problem reported by Robert Pluim in https://lists.gnu.org/r/emacs-devel/2019-09/msg00127.html * src/gnutls.c (Fgnutls_peer_status): Simplify test for whether the :safe-renegotiation result is needed, so that it works all the way back to GnuTLS 2.12.2. diff --git a/src/gnutls.c b/src/gnutls.c index c74936c840..d43534b5ae 100644 --- a/src/gnutls.c +++ b/src/gnutls.c @@ -1520,12 +1520,7 @@ returned as the :certificate entry. */) #endif /* Renegotiation Indication */ -#ifdef GNUTLS_TLS1_3 - bool older_proto = proto < GNUTLS_TLS1_3; -#else - bool older_proto = true; -#endif - if (older_proto) + if (proto <= GNUTLS_TLS1_2) result = nconc2 (result, list2 (intern (":safe-renegotiation"), gnutls_safe_renegotiation_status (state) ? Qt : Qnil)); commit 2180852c72a3edb5b03074fb293fb995a9b9485d Author: Lars Ingebrigtsen Date: Thu Sep 5 13:26:08 2019 +0200 Further fix for network-security-protocol-checks * lisp/net/nsm.el (network-security-protocol-checks): Fix the defcustom type some more (bug#37306). diff --git a/lisp/net/nsm.el b/lisp/net/nsm.el index 1a5febeda0..11535a5a5a 100644 --- a/lisp/net/nsm.el +++ b/lisp/net/nsm.el @@ -171,7 +171,7 @@ otherwise. See also: `nsm-check-tls-connection', `nsm-save-host-names', `nsm-settings-file'" :version "27.1" - :type '(repeat (cons (symbol :tag "Check function") + :type '(repeat (list (symbol :tag "Check function") (choice :tag "Level" :value medium (const :tag "Low" low) commit 71964ccc10029c5810f78a04353d657ff9a9d321 Author: Lars Ingebrigtsen Date: Thu Sep 5 13:23:07 2019 +0200 Fix defcustom type of network-security-protocol-checks * lisp/net/nsm.el (network-security-protocol-checks): Fix the defcustom type (bug#37306). diff --git a/lisp/net/nsm.el b/lisp/net/nsm.el index 2121fdeb51..1a5febeda0 100644 --- a/lisp/net/nsm.el +++ b/lisp/net/nsm.el @@ -55,7 +55,6 @@ compatibility concerns. See the Emacs manual for a description of all things that are checked and warned against." :version "25.1" - :group 'nsm :type '(choice (const :tag "Low" low) (const :tag "Medium" medium) (const :tag "High" high) @@ -76,7 +75,6 @@ connecting to hosts on a local network. Make sure you know what you are doing before enabling this option." :version "27.1" - :group 'nsm :type '(choice (const :tag "On" t) (const :tag "Off" nil) (function :tag "Custom function"))) @@ -85,7 +83,6 @@ option." user-emacs-directory) "The file the security manager settings will be stored in." :version "25.1" - :group 'nsm :type 'file) (defcustom nsm-save-host-names nil @@ -93,7 +90,6 @@ option." By default, only hosts that have exceptions have their names stored in plain text." :version "25.1" - :group 'nsm :type 'boolean) (defvar nsm-noninteractive nil @@ -175,8 +171,7 @@ otherwise. See also: `nsm-check-tls-connection', `nsm-save-host-names', `nsm-settings-file'" :version "27.1" - :group 'nsm - :type '(repeat (cons (function :tag "Check function") + :type '(repeat (cons (symbol :tag "Check function") (choice :tag "Level" :value medium (const :tag "Low" low) commit 365dad197bac5deec9244fd9c189d23c46c99b31 Author: Paul Eggert Date: Wed Sep 4 23:13:54 2019 -0700 Use plain ‘static’ for Emacs C inline functions This improved performance of ‘make compile-always’ by 8.2% on my platform (AMD Phenom II X4 910e, Fedora 30 x86-64). * src/conf_post.h (INLINE, EXTERN_INLINE, INLINE_HEADER_BEGIN) (INLINE_HEADER_END) [!EMACS_EXTERN_INLINE]: Use plain ‘static’. diff --git a/src/conf_post.h b/src/conf_post.h index 4af1ba9331..43f98620a4 100644 --- a/src/conf_post.h +++ b/src/conf_post.h @@ -373,8 +373,13 @@ extern int emacs_setenv_TZ (char const *); #undef noinline #endif -/* Use Gnulib's extern-inline module for extern inline functions. - An include file foo.h should prepend FOO_INLINE to function +/* INLINE marks functions defined in Emacs-internal C headers. + INLINE is implemented via C99-style 'extern inline' if Emacs is built + with -DEMACS_EXTERN_INLINE; otherwise it is implemented via 'static'. + EMACS_EXTERN_INLINE is no longer the default, as 'static' seems to + have better performance with GCC. + + An include file foo.h should prepend INLINE to function definitions, with the following overall pattern: [#include any other .h files first.] @@ -399,20 +404,40 @@ extern int emacs_setenv_TZ (char const *); For Emacs, this is done by having emacs.c first '#define INLINE EXTERN_INLINE' and then include every .h file that uses INLINE. - The INLINE_HEADER_BEGIN and INLINE_HEADER_END suppress bogus - warnings in some GCC versions; see ../m4/extern-inline.m4. + The INLINE_HEADER_BEGIN and INLINE_HEADER_END macros suppress bogus + warnings in some GCC versions; see ../m4/extern-inline.m4. */ + +#ifdef EMACS_EXTERN_INLINE + +/* Use Gnulib's extern-inline module for extern inline functions. C99 compilers compile functions like 'incr' as C99-style extern inline functions. Buggy GCC implementations do something similar with GNU-specific keywords. Buggy non-GCC compilers use static functions, which bloats the code but is good enough. */ -#ifndef INLINE -# define INLINE _GL_INLINE +# ifndef INLINE +# define INLINE _GL_INLINE +# endif +# define EXTERN_INLINE _GL_EXTERN_INLINE +# define INLINE_HEADER_BEGIN _GL_INLINE_HEADER_BEGIN +# define INLINE_HEADER_END _GL_INLINE_HEADER_END + +#else + +/* Use 'static' instead of 'extern inline' because 'static' typically + has better performance for Emacs. Do not use the 'inline' keyword, + as modern compilers inline automatically. ATTRIBUTE_UNUSED + pacifies gcc -Wunused-function. */ + +# ifndef INLINE +# define INLINE EXTERN_INLINE +# endif +# define EXTERN_INLINE static ATTRIBUTE_UNUSED +# define INLINE_HEADER_BEGIN +# define INLINE_HEADER_END + #endif -#define EXTERN_INLINE _GL_EXTERN_INLINE -#define INLINE_HEADER_BEGIN _GL_INLINE_HEADER_BEGIN -#define INLINE_HEADER_END _GL_INLINE_HEADER_END /* 'int x UNINIT;' is equivalent to 'int x;', except it cajoles GCC into not warning incorrectly about use of an uninitialized variable. */ commit 507d5548349540dbde67d3e535a4607fd2207c49 Author: Paul Eggert Date: Wed Sep 4 17:43:16 2019 -0700 Tweak xd_append_arg to pacify -Wnull-dereference * src/dbusbind.c (xd_append_arg): Redo to pacify gcc -Wnull-dereference. Also, check that the Lisp string won’t overrun the C signature buffer. diff --git a/src/dbusbind.c b/src/dbusbind.c index 90ba461c6b..7f4c8717f4 100644 --- a/src/dbusbind.c +++ b/src/dbusbind.c @@ -728,22 +728,27 @@ xd_append_arg (int dtype, Lisp_Object object, DBusMessageIter *iter) strcpy (signature, DBUS_TYPE_STRING_AS_STRING); else - /* If the element type is DBUS_TYPE_SIGNATURE, and this is - the only element, the value of this element is used as - the array's element signature. */ - if ((XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object)) - == DBUS_TYPE_SIGNATURE) - && STRINGP (CAR_SAFE (XD_NEXT_VALUE (object))) - && NILP (CDR_SAFE (XD_NEXT_VALUE (object)))) - { - lispstpcpy (signature, CAR_SAFE (XD_NEXT_VALUE (object))); - object = CDR_SAFE (XD_NEXT_VALUE (object)); - } - - else - xd_signature (signature, - XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object)), - dtype, CAR_SAFE (XD_NEXT_VALUE (object))); + { + /* If the element type is DBUS_TYPE_SIGNATURE, and this is + the only element, the value of this element is used as + the array's element signature. */ + if (CONSP (object) && (XD_OBJECT_TO_DBUS_TYPE (XCAR (object)) + == DBUS_TYPE_SIGNATURE)) + { + Lisp_Object val = XD_NEXT_VALUE (object); + if (CONSP (val) && STRINGP (XCAR (val)) && NILP (XCDR (val)) + && SBYTES (XCAR (val)) < DBUS_MAXIMUM_SIGNATURE_LENGTH) + { + lispstpcpy (signature, XCAR (val)); + object = Qnil; + } + } + + if (!NILP (object)) + xd_signature (signature, + XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (object)), + dtype, CAR_SAFE (XD_NEXT_VALUE (object))); + } XD_DEBUG_MESSAGE ("%c %s %s", dtype, signature, XD_OBJECT_TO_STRING (object)); commit 95becaaf3b65d6227a41f4cb3f0f114bcfbe5562 Author: Robert Pluim Date: Mon Sep 2 14:55:00 2019 +0200 Don't check for :safe-renegotiation with TLS1.3 * lisp/net/nsm.el (nsm-protocol-check--renegotiation-info-ext): Don't check when using TLS1.3, renegotiation has been removed from TLS. Reported in diff --git a/lisp/net/nsm.el b/lisp/net/nsm.el index 8750c19267..2121fdeb51 100644 --- a/lisp/net/nsm.el +++ b/lisp/net/nsm.el @@ -665,17 +665,19 @@ the MD5 Message-Digest and the HMAC-MD5 Algorithms\", If this TLS extension is not used, the connection established is vulnerable to an attack in which an impersonator can extract sensitive information such as HTTP session ID cookies or login -passwords. +passwords. Renegotiation was removed in TLS1.3, so this is only +checked for earlier protocol versions. Reference: E. Rescorla, M. Ray, S. Dispensa, N. Oskov (Feb 2010). \"Transport Layer Security (TLS) Renegotiation Indication Extension\", `https://tools.ietf.org/html/rfc5746'" - (let ((unsafe-renegotiation (not (plist-get status :safe-renegotiation)))) - (and unsafe-renegotiation - (format-message - "safe renegotiation is not supported, connection not protected from impersonators")))) + (when (plist-member status :safe-renegotiation) + (let ((unsafe-renegotiation (not (plist-get status :safe-renegotiation)))) + (and unsafe-renegotiation + (format-message + "safe renegotiation is not supported, connection not protected from impersonators"))))) ;; Compression checks commit a8432661130ac73ecf7606b1132e9b0d388ab60f Author: Paul Eggert Date: Tue Sep 3 12:16:21 2019 -0700 Don’t mention :safe-renegotiation in TLS 1.3 * src/gnutls.c (Fgnutls_peer_status): Don’t put the safe-renegotiation indication into the status in TLS 1.3, which removed support for renegotiation. diff --git a/src/gnutls.c b/src/gnutls.c index 042f43e291..c74936c840 100644 --- a/src/gnutls.c +++ b/src/gnutls.c @@ -1487,10 +1487,10 @@ returned as the :certificate entry. */) (gnutls_kx_get (state))))); /* Protocol name. */ + gnutls_protocol_t proto = gnutls_protocol_get_version (state); result = nconc2 (result, list2 (intern (":protocol"), - build_string (gnutls_protocol_get_name - (gnutls_protocol_get_version (state))))); + build_string (gnutls_protocol_get_name (proto)))); /* Cipher name. */ result = nconc2 @@ -1520,9 +1520,15 @@ returned as the :certificate entry. */) #endif /* Renegotiation Indication */ - result = nconc2 - (result, list2 (intern (":safe-renegotiation"), - gnutls_safe_renegotiation_status (state) ? Qt : Qnil)); +#ifdef GNUTLS_TLS1_3 + bool older_proto = proto < GNUTLS_TLS1_3; +#else + bool older_proto = true; +#endif + if (older_proto) + result = nconc2 + (result, list2 (intern (":safe-renegotiation"), + gnutls_safe_renegotiation_status (state) ? Qt : Qnil)); return result; } commit fc9ed61a4357f766292d157ad89e0c1ffb1fa1e2 Author: Robert Pluim Date: Wed Sep 4 23:43:56 2019 +0200 Fix nsm for unencrypted connections When connecting using a cleartext connection, nsm was erroring out and tearing down the connection because it was trying to display nonexistent certificate information. * lisp/net/nsm.el (nsm-query-user): Only format certificate status when it is valid. (Bug#37221) diff --git a/lisp/net/nsm.el b/lisp/net/nsm.el index 5e8381075b..8750c19267 100644 --- a/lisp/net/nsm.el +++ b/lisp/net/nsm.el @@ -823,7 +823,7 @@ protocol." ;; First format the certificate and warnings. (with-current-buffer-window buffer nil nil - (insert (nsm-format-certificate status)) + (when status (insert (nsm-format-certificate status))) (insert message) (goto-char (point-min)) ;; Fill the first line of the message, which usually commit d607067dd7d54f65f3f0453f4319de17788b60c1 Author: Paul Eggert Date: Wed Sep 4 11:08:34 2019 -0700 Port pdumper mmap to AIX * src/pdumper.c (needs_mmap_retry_p) [_AIX]: Return true. Problem observed on AIX 7.1 and 7.2 in GCC compile farm. diff --git a/src/pdumper.c b/src/pdumper.c index 306a70396e..98090238b1 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -4734,7 +4734,7 @@ dump_mmap_release_vm (struct dump_memory_map *map) static bool needs_mmap_retry_p (void) { -#if defined (CYGWIN) || VM_SUPPORTED == VM_MS_WINDOWS +#if defined CYGWIN || VM_SUPPORTED == VM_MS_WINDOWS || defined _AIX return true; #else return false; commit d5d6772dfb29a73a8da4c21576b4d23da5da2565 Author: Paul Eggert Date: Wed Sep 4 11:07:14 2019 -0700 Port to platforms with Xrender lib but not header * configure.ac (HAVE_XRENDER): Also require ‘#include ’ to work. Problem found on gcc119 in GCC compile farm. diff --git a/configure.ac b/configure.ac index e39a438052..e822b0b7b0 100644 --- a/configure.ac +++ b/configure.ac @@ -3288,7 +3288,8 @@ fi # Check for XRender HAVE_XRENDER=no if test "${HAVE_X11}" = "yes"; then - AC_CHECK_LIB(Xrender, XRenderQueryExtension, HAVE_XRENDER=yes) + AC_CHECK_HEADER([X11/extensions/Xrender.h], + [AC_CHECK_LIB([Xrender], [XRenderQueryExtension], [HAVE_XRENDER=yes])]) if test $HAVE_XRENDER = yes; then XRENDER_LIBS="-lXrender" AC_SUBST(XRENDER_LIBS) commit 2aee20fbf88322eff653405ea4932823fbb70fd5 Author: Mattias Engdegård Date: Wed Sep 4 16:27:02 2019 +0200 Correct arguments to `skip-syntax-forward' * lisp/wid-edit.el (widget-sexp-validate): Fix bad calls to `skip-syntax-forward', whose argument is not a regexp. diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el index 1ddc461f4e..fdc16299c8 100644 --- a/lisp/wid-edit.el +++ b/lisp/wid-edit.el @@ -3333,13 +3333,13 @@ It reads a directory name from an editable text field." (condition-case data ;Note: We get a spurious byte-compile warning here. (progn ;; Avoid a confusing end-of-file error. - (skip-syntax-forward "\\s-") + (skip-syntax-forward "-") (if (eobp) (setq err "Empty sexp -- use nil?") (unless (widget-apply widget :match (read (current-buffer))) (setq err (widget-get widget :type-error)))) ;; Allow whitespace after expression. - (skip-syntax-forward "\\s-") + (skip-syntax-forward "-") (if (and (not (eobp)) (not err)) (setq err (format "Junk at end of expression: %s" commit 4c3a40a9b7b8b953d7882942d44373ccd8f7a3cd Author: Lars Ingebrigtsen Date: Wed Sep 4 15:19:40 2019 +0200 Make the NSM not pop up an X dialogue on non-mouse actions * lisp/emacs-lisp/rmc.el (read-multiple-choice): Don't pop up X dialogues on (url-retrieve "https://expired.badssl.com/" #'ignore) and the like. diff --git a/lisp/emacs-lisp/rmc.el b/lisp/emacs-lisp/rmc.el index 47f3b8dc9c..13cd1c0f42 100644 --- a/lisp/emacs-lisp/rmc.el +++ b/lisp/emacs-lisp/rmc.el @@ -106,7 +106,7 @@ Usage example: (setq tchar (if (and (display-popup-menus-p) last-input-event ; not during startup - (listp last-nonmenu-event) + (consp last-nonmenu-event) use-dialog-box) (x-popup-dialog t commit 9df72ecb6339110a0380c6faf75e7e93025bb26a Author: Lars Ingebrigtsen Date: Fri Aug 30 12:20:30 2019 +0200 Preserve more markers when reverting .gpg files * lisp/epa-file.el (epa-file--replace-text): Gingerly replace the text in the buffer to preserve as many markers as possible (bug#34720). This emulates the behaviour of Finsert_file_contents more accurately. (epa-file-decode-and-insert): Remove compat code. (epa-file-insert-file-contents): Use the new function. * lisp/emacs-lisp/cl-lib.el (cl-incf): Add autoload cookie. diff --git a/lisp/emacs-lisp/cl-lib.el b/lisp/emacs-lisp/cl-lib.el index c09fcf51eb..ff09691817 100644 --- a/lisp/emacs-lisp/cl-lib.el +++ b/lisp/emacs-lisp/cl-lib.el @@ -110,6 +110,7 @@ a future Emacs interpreter will be able to use it.") ;; These macros are defined here so that they ;; can safely be used in init files. +;;;###autoload (defmacro cl-incf (place &optional x) "Increment PLACE by X (1 by default). PLACE may be a symbol, or any generalized variable allowed by `setf'. diff --git a/lisp/epa-file.el b/lisp/epa-file.el index d9886d3d67..c43641aacf 100644 --- a/lisp/epa-file.el +++ b/lisp/epa-file.el @@ -102,16 +102,15 @@ encryption is used." (apply operation args))) (defun epa-file-decode-and-insert (string file visit beg end replace) - (if (fboundp 'decode-coding-inserted-region) - (save-restriction - (narrow-to-region (point) (point)) - (insert string) - (decode-coding-inserted-region - (point-min) (point-max) - (substring file 0 (string-match epa-file-name-regexp file)) - visit beg end replace)) - (insert (epa-file--decode-coding-string string (or coding-system-for-read - 'undecided))))) + (save-restriction + (narrow-to-region (point) (point)) + (insert string) + (decode-coding-inserted-region + (point-min) (point-max) + (substring file 0 (string-match epa-file-name-regexp file)) + visit beg end replace) + (goto-char (point-max)) + (- (point-max) (point-min)))) (defvar epa-file-error nil) (defun epa-file--find-file-not-found-function () @@ -147,8 +146,6 @@ encryption is used." (format "Decrypting %s" file))) (unwind-protect (progn - (if replace - (goto-char (point-min))) (condition-case error (setq string (epg-decrypt-file context local-file nil)) (error @@ -187,12 +184,11 @@ encryption is used." ;; really edit the buffer. (let ((buffer-file-name (if visit nil buffer-file-name))) - (save-restriction - (narrow-to-region (point) (point)) - (epa-file-decode-and-insert string file visit beg end replace) - (setq length (- (point-max) (point-min)))) - (if replace - (delete-region (point) (point-max)))) + (setq length + (if replace + (epa-file--replace-text string file visit beg end) + (epa-file-decode-and-insert + string file visit beg end replace)))) (if visit (set-visited-file-modtime)))) (if (and local-copy @@ -201,6 +197,38 @@ encryption is used." (list file length))) (put 'insert-file-contents 'epa-file 'epa-file-insert-file-contents) +(defun epa-file--replace-text (string file visit beg end) + ;; The idea here is that we want to replace the text in the buffer + ;; (for instance, for a `revert-buffer'), but we want to touch as + ;; little of the text as possible. So we compare the new and the + ;; old text and only starts replacing when the text changes. + (let ((orig-point (point)) + new-start length) + (goto-char (point-max)) + (setq new-start (point)) + (setq length + (epa-file-decode-and-insert + string file visit beg end t)) + (if (equal (buffer-substring (point-min) new-start) + (buffer-substring new-start (point-max))) + ;; The new text is equal to the old, so just keep the old. + (delete-region new-start (point-max)) + ;; Compute the region the hard way. + (let ((p1 (point-min)) + (p2 new-start)) + (while (and (< p1 new-start) + (< p2 (point-max)) + (eql (char-after p1) (char-after p2))) + (cl-incf p1) + (cl-incf p2)) + (delete-region new-start p2) + (delete-region p1 new-start))) + ;; Restore point, if possible. + (if (< orig-point (point-max)) + (goto-char orig-point) + (goto-char (point-max))) + length)) + (defun epa-file-write-region (start end file &optional append visit lockname mustbenew) (if append commit 3f30d98af9401562c68f3a0388cf16593eb572e5 Author: Mattias Engdegård Date: Wed Sep 4 14:35:18 2019 +0200 Repair change to compilation-context-lines (bug#36832) * lisp/progmodes/compile.el (compilation-set-window): Restore proper behaviour when compilation-context-lines is nil, which is the default. diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el index b7bd2243d9..c1f23b16aa 100644 --- a/lisp/progmodes/compile.el +++ b/lisp/progmodes/compile.el @@ -2600,7 +2600,8 @@ column zero points to the current message." (goto-char mk) (beginning-of-line 1) (point))) - (set-window-point w mk)))) + (set-window-point w mk)) + (t (set-window-point w mk)))) (defvar-local compilation-arrow-overlay nil "Overlay with the before-string property of `overlay-arrow-string'. commit ed80d6d88cd8c14fd585390a1fa622ba4f7a67d0 Author: Michael Albinus Date: Wed Sep 4 14:13:13 2019 +0200 Further work on Bug#37202 * test/lisp/shadowfile-tests.el (shadow-debug): Set to t. (shadow--tests-cleanup): Simplify. (shadow-test*): Call `shadow-initialize'. (shadow-test08-shadow-todo, shadow-test09-shadow-copy-files): In cleanup, kill buffers used for test. (top): Do not initialize. diff --git a/test/lisp/shadowfile-tests.el b/test/lisp/shadowfile-tests.el index 5ab663c69b..a523a340a4 100644 --- a/test/lisp/shadowfile-tests.el +++ b/test/lisp/shadowfile-tests.el @@ -64,7 +64,7 @@ "Temporary directory for Tramp tests.") (setq password-cache-expiry nil - shadow-debug nil + shadow-debug t tramp-verbose 0 tramp-message-show-message nil) @@ -92,11 +92,11 @@ (set-buffer-modified-p nil) (kill-buffer)) ;; Delete buffers. - (when (buffer-live-p shadow-info-buffer) + (ignore-errors (with-current-buffer shadow-info-buffer (set-buffer-modified-p nil) (kill-buffer))) - (when (buffer-live-p shadow-todo-buffer) + (ignore-errors (with-current-buffer shadow-todo-buffer (set-buffer-modified-p nil) (kill-buffer))) @@ -131,8 +131,9 @@ guaranteed by the originator of a cluster definition." ((symbol-function 'read-string) (lambda (&rest args) (pop mocked-input)))) - ;; Cleanup. + ;; Cleanup & initialize. (shadow--tests-cleanup) + (shadow-initialize) ;; Define a cluster. (setq cluster "cluster" @@ -247,8 +248,9 @@ guaranteed by the originator of a cluster definition." ((symbol-function 'read-string) (lambda (&rest args) (pop mocked-input)))) - ;; Cleanup. + ;; Cleanup & initialize. (shadow--tests-cleanup) + (shadow-initialize) ;; Define a cluster. (setq cluster1 "cluster1" @@ -342,8 +344,10 @@ guaranteed by the originator of a cluster definition." cluster primary regexp file hup) (unwind-protect (progn - ;; Cleanup. + + ;; Cleanup & initialize. (shadow--tests-cleanup) + (shadow-initialize) ;; Define a cluster. (setq cluster "cluster" @@ -412,8 +416,10 @@ guaranteed by the originator of a cluster definition." cluster primary regexp file1 file2) (unwind-protect (progn - ;; Cleanup. + + ;; Cleanup & initialize. (shadow--tests-cleanup) + (shadow-initialize) ;; Define a cluster. (setq cluster "cluster" @@ -477,8 +483,10 @@ guaranteed by the originator of a cluster definition." cluster primary regexp file) (unwind-protect (progn - ;; Cleanup. + + ;; Cleanup & initialize. (shadow--tests-cleanup) + (shadow-initialize) ;; Define a cluster. (setq cluster "cluster" @@ -532,8 +540,10 @@ guaranteed by the originator of a cluster definition." cluster primary regexp file) (unwind-protect (progn - ;; Cleanup. + + ;; Cleanup & initialize. (shadow--tests-cleanup) + (shadow-initialize) ;; Define a cluster. (setq cluster "cluster" @@ -591,8 +601,9 @@ guaranteed by the originator of a cluster definition." ((symbol-function 'read-string) (lambda (&rest args) (pop mocked-input)))) - ;; Cleanup. + ;; Cleanup & initialize. (shadow--tests-cleanup) + (shadow-initialize) ;; Define clusters. (setq cluster1 "cluster1" @@ -651,8 +662,9 @@ guaranteed by the originator of a cluster definition." ((symbol-function 'read-string) (lambda (&rest args) (pop mocked-input)))) - ;; Cleanup. + ;; Cleanup & initialize. (shadow--tests-cleanup) + (shadow-initialize) ;; Define clusters. (setq cluster1 "cluster1" @@ -710,8 +722,10 @@ guaranteed by the originator of a cluster definition." cluster1 cluster2 primary regexp file) (unwind-protect (progn - ;; Cleanup. + + ;; Cleanup & initialize. (shadow--tests-cleanup) + (shadow-initialize) ;; Define clusters. (setq cluster1 "cluster1" @@ -817,8 +831,12 @@ guaranteed by the originator of a cluster definition." shadow-files-to-copy))) ;; Cleanup. - (ignore-errors (delete-file file)) - (ignore-errors (delete-file (concat (shadow-site-primary cluster2) file))) + (dolist (elt `(,file ,(concat (shadow-site-primary cluster2) file))) + (ignore-errors + (with-current-buffer (get-file-buffer elt) + (set-buffer-modified-p nil) + (kill-buffer))) + (ignore-errors (delete-file elt))) (shadow--tests-cleanup)))) (ert-deftest shadow-test09-shadow-copy-files () @@ -836,8 +854,10 @@ guaranteed by the originator of a cluster definition." cluster1 cluster2 primary regexp file mocked-input) (unwind-protect (progn - ;; Cleanup. + + ;; Cleanup & initialize. (shadow--tests-cleanup) + (shadow-initialize) ;; Define clusters. (setq cluster1 "cluster1" @@ -894,8 +914,12 @@ guaranteed by the originator of a cluster definition." ;; Cleanup. (remove-function (symbol-function 'write-region) "write-region-mock") - (ignore-errors (delete-file file)) - (ignore-errors (delete-file (concat (shadow-site-primary cluster2) file))) + (dolist (elt `(,file ,(concat (shadow-site-primary cluster2) file))) + (ignore-errors + (with-current-buffer (get-file-buffer elt) + (set-buffer-modified-p nil) + (kill-buffer))) + (ignore-errors (delete-file elt))) (shadow--tests-cleanup)))) (defun shadowfile-test-all (&optional interactive) @@ -905,10 +929,5 @@ guaranteed by the originator of a cluster definition." (ert-run-tests-interactively "^shadowfile-") (ert-run-tests-batch "^shadowfile-"))) -(let ((shadow-info-file shadow-test-info-file) - (shadow-todo-file shadow-test-todo-file)) - (shadow--tests-cleanup) - (shadow-initialize)) - (provide 'shadowfile-tests) ;;; shadowfile-tests.el ends here commit 6c2e107a54fe39bbd6ce31d9f29464da33bbf4af Author: Michael Albinus Date: Wed Sep 4 09:37:37 2019 +0200 * lisp/net/tramp.el (tramp-process-sentinel): Use `process-buffer'. diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index fdad43ef6f..ed0f1def18 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -4210,11 +4210,11 @@ the remote host use line-endings as defined in the variable (when vec (tramp-message vec 5 "Sentinel called: `%S' `%s'" proc event) (tramp-flush-connection-properties proc) - (tramp-flush-directory-properties vec "") - (with-current-buffer (tramp-get-buffer vec) - (goto-char (point-max)) - (when (and prompt (re-search-backward (regexp-quote prompt) nil t)) - (delete-region (point) (point-max)))))))) + (tramp-flush-directory-properties vec "")) + (with-current-buffer (process-buffer proc) + (goto-char (point-max)) + (when (and prompt (re-search-backward (regexp-quote prompt) nil t)) + (delete-region (point) (point-max))))))) (defun tramp-get-inode (vec) "Returns the virtual inode number. commit 22213f00527d96355e1e3d8a4c9bc37b1fffb0f0 Author: Paul Eggert Date: Tue Sep 3 23:40:32 2019 -0700 * src/systime.h (hz): #undef to work around AIX build issue. diff --git a/src/systime.h b/src/systime.h index 125b2f1385..2f783efcfc 100644 --- a/src/systime.h +++ b/src/systime.h @@ -41,6 +41,8 @@ typedef unsigned long Time; #endif #include /* for 'struct timeval' */ + +#undef hz /* AIX #defines this. */ /* Emacs uses struct timespec to represent nonnegative temporal intervals. commit d84b4f83a55e3b1a12e399ad199cc36cd013dcb3 Author: Paul Eggert Date: Tue Sep 3 21:54:58 2019 -0700 Prefer functions to macros in buffer.h In buffer.h, prefer inline functions to function-like macros when either will do. This helps avoid confusion about how many times an arg is evaluated. On my platform, this patch improves performance of ‘make compile-always’ by 5.7%. Also, prefer enum constants to object-like macros when either will do. * src/buffer.h (BEG, BEG_BYTE, GAP_BYTES_DFL, GAP_BYTES_MIN) (MAX_PER_BUFFER_VARS, NONEXISTENT_MODTIME_NSECS) (UNKNOWN_MODTIME_NSECS, BUFFER_LISP_SIZE, BUFFER_REST_SIZE): Now enum constants, instead of macros. (BUFFER_CEILING_OF, BUFFER_FLOOR_OF, BUF_BEG, BUF_BEG_BYTE) (BUF_BEGV, BUF_BEGV_BYTE, BUF_PT, BUF_PT_BYTE, BUF_ZV) (BUF_ZV_BYTE, BUF_GPT_ADDR, BUF_Z_ADDR, BUF_GAP_END_ADDR) (BUF_COMPUTE_UNCHANGED, SET_PT, TEMP_SET_PT, SET_PT_BOTH) (TEMP_SET_PT_BOTH, BUF_TEMP_SET_PT, SET_BUF_BEGV, SET_BUF_ZV) (SET_BUF_BEGV_BOTH, SET_BUF_ZV_BOTH, SET_BUF_PT_BOTH) (BYTE_POS_ADDR, CHAR_POS_ADDR, CHAR_TO_BYTE, BYTE_TO_CHAR) (PTR_BYTE_POS, FETCH_CHAR, FETCH_CHAR_AS_MULTIBYTE) (BUF_BYTE_ADDRESS, BUF_CHAR_ADDRESS, BUF_PTR_BYTE_POS) (BUF_FETCH_CHAR, BUF_FETCH_CHAR_AS_MULTIBYTE, BUF_FETCH_BYTE) (BUFFER_PVEC_INIT, BUFFER_LIVE_P, BUFFER_HIDDEN_P) (BUFFER_CHECK_INDIRECTION, OVERLAY_POSITION, PER_BUFFER_VALUE_P) (SET_PER_BUFFER_VALUE_P, PER_BUFFER_IDX): Now inline functions instead of macros. diff --git a/src/buffer.h b/src/buffer.h index 14de70c648..82d9350bfc 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -31,12 +31,11 @@ INLINE_HEADER_BEGIN /* Accessing the parameters of the current buffer. */ -/* These macros come in pairs, one for the char position +/* These constants and macros come in pairs, one for the char position and one for the byte position. */ /* Position of beginning of buffer. */ -#define BEG (1) -#define BEG_BYTE (BEG) +enum { BEG = 1, BEG_BYTE = BEG }; /* Position of beginning of accessible range of buffer. */ #define BEGV (current_buffer->begv) @@ -96,59 +95,7 @@ INLINE_HEADER_BEGIN /* Modification count as of last visit or save. */ #define SAVE_MODIFF (current_buffer->text->save_modiff) - -/* BUFFER_CEILING_OF (resp. BUFFER_FLOOR_OF), when applied to n, return - the max (resp. min) p such that - - BYTE_POS_ADDR (p) - BYTE_POS_ADDR (n) == p - n */ - -#define BUFFER_CEILING_OF(BYTEPOS) \ - (((BYTEPOS) < GPT_BYTE && GPT < ZV ? GPT_BYTE : ZV_BYTE) - 1) -#define BUFFER_FLOOR_OF(BYTEPOS) \ - (BEGV <= GPT && GPT_BYTE <= (BYTEPOS) ? GPT_BYTE : BEGV_BYTE) -/* Similar macros to operate on a specified buffer. - Note that many of these evaluate the buffer argument more than once. */ - -/* Position of beginning of buffer. */ -#define BUF_BEG(buf) (BEG) -#define BUF_BEG_BYTE(buf) (BEG_BYTE) - -/* The BUF_BEGV[_BYTE], BUF_ZV[_BYTE], and BUF_PT[_BYTE] macros cannot - be used for assignment; use SET_BUF_* macros below for that. */ - -/* Position of beginning of accessible range of buffer. */ -#define BUF_BEGV(buf) \ - (buf == current_buffer ? BEGV \ - : NILP (BVAR (buf, begv_marker)) ? buf->begv \ - : marker_position (BVAR (buf, begv_marker))) - -#define BUF_BEGV_BYTE(buf) \ - (buf == current_buffer ? BEGV_BYTE \ - : NILP (BVAR (buf, begv_marker)) ? buf->begv_byte \ - : marker_byte_position (BVAR (buf, begv_marker))) - -/* Position of point in buffer. */ -#define BUF_PT(buf) \ - (buf == current_buffer ? PT \ - : NILP (BVAR (buf, pt_marker)) ? buf->pt \ - : marker_position (BVAR (buf, pt_marker))) - -#define BUF_PT_BYTE(buf) \ - (buf == current_buffer ? PT_BYTE \ - : NILP (BVAR (buf, pt_marker)) ? buf->pt_byte \ - : marker_byte_position (BVAR (buf, pt_marker))) - -/* Position of end of accessible range of buffer. */ -#define BUF_ZV(buf) \ - (buf == current_buffer ? ZV \ - : NILP (BVAR (buf, zv_marker)) ? buf->zv \ - : marker_position (BVAR (buf, zv_marker))) - -#define BUF_ZV_BYTE(buf) \ - (buf == current_buffer ? ZV_BYTE \ - : NILP (BVAR (buf, zv_marker)) ? buf->zv_byte \ - : marker_byte_position (BVAR (buf, zv_marker))) /* Position of gap in buffer. */ #define BUF_GPT(buf) ((buf)->text->gpt) @@ -161,15 +108,6 @@ INLINE_HEADER_BEGIN /* Address of beginning of buffer. */ #define BUF_BEG_ADDR(buf) ((buf)->text->beg) -/* Address of beginning of gap of buffer. */ -#define BUF_GPT_ADDR(buf) ((buf)->text->beg + (buf)->text->gpt_byte - BEG_BYTE) - -/* Address of end of buffer. */ -#define BUF_Z_ADDR(buf) ((buf)->text->beg + (buf)->text->gap_size + (buf)->text->z_byte - BEG_BYTE) - -/* Address of end of gap in buffer. */ -#define BUF_GAP_END_ADDR(buf) ((buf)->text->beg + (buf)->text->gpt_byte + (buf)->text->gap_size - BEG_BYTE) - /* Size of gap. */ #define BUF_GAP_SIZE(buf) ((buf)->text->gap_size) @@ -209,43 +147,8 @@ INLINE_HEADER_BEGIN BUF_OVERLAY_UNCHANGED_MODIFIED (current_buffer) #define BEG_UNCHANGED BUF_BEG_UNCHANGED (current_buffer) #define END_UNCHANGED BUF_END_UNCHANGED (current_buffer) - -/* Compute how many characters at the top and bottom of BUF are - unchanged when the range START..END is modified. This computation - must be done each time BUF is modified. */ - -#define BUF_COMPUTE_UNCHANGED(buf, start, end) \ - do \ - { \ - if (BUF_UNCHANGED_MODIFIED (buf) == BUF_MODIFF (buf) \ - && (BUF_OVERLAY_UNCHANGED_MODIFIED (buf) \ - == BUF_OVERLAY_MODIFF (buf))) \ - { \ - BUF_BEG_UNCHANGED (buf) = (start) - BUF_BEG (buf); \ - BUF_END_UNCHANGED (buf) = BUF_Z (buf) - (end); \ - } \ - else \ - { \ - if (BUF_Z (buf) - (end) < BUF_END_UNCHANGED (buf)) \ - BUF_END_UNCHANGED (buf) = BUF_Z (buf) - (end); \ - if ((start) - BUF_BEG (buf) < BUF_BEG_UNCHANGED (buf)) \ - BUF_BEG_UNCHANGED (buf) = (start) - BUF_BEG (buf); \ - } \ - } \ - while (false) - -/* Macros to set PT in the current buffer, or another buffer. */ - -#define SET_PT(position) (set_point (position)) -#define TEMP_SET_PT(position) (temp_set_point (current_buffer, (position))) - -#define SET_PT_BOTH(position, byte) (set_point_both (position, byte)) -#define TEMP_SET_PT_BOTH(position, byte) \ - (temp_set_point_both (current_buffer, (position), (byte))) - -#define BUF_TEMP_SET_PT(buffer, position) \ - (temp_set_point ((buffer), (position))) +/* Functions to set PT in the current buffer, or another buffer. */ extern void set_point (ptrdiff_t); extern void temp_set_point (struct buffer *, ptrdiff_t); @@ -255,39 +158,32 @@ extern void temp_set_point_both (struct buffer *, extern void set_point_from_marker (Lisp_Object); extern void enlarge_buffer_text (struct buffer *, ptrdiff_t); +INLINE void +SET_PT (ptrdiff_t position) +{ + set_point (position); +} +INLINE void +TEMP_SET_PT (ptrdiff_t position) +{ + temp_set_point (current_buffer, position); +} +INLINE void +SET_PT_BOTH (ptrdiff_t position, ptrdiff_t byte) +{ + set_point_both (position, byte); +} +INLINE void +TEMP_SET_PT_BOTH (ptrdiff_t position, ptrdiff_t byte) +{ + temp_set_point_both (current_buffer, position, byte); +} +INLINE void +BUF_TEMP_SET_PT (struct buffer *buffer, ptrdiff_t position) +{ + temp_set_point (buffer, position); +} -/* Macros for setting the BEGV, ZV or PT of a given buffer. - - The ..._BOTH macros take both a charpos and a bytepos, - which must correspond to each other. - - The macros without ..._BOTH take just a charpos, - and compute the bytepos from it. */ - -#define SET_BUF_BEGV(buf, charpos) \ - ((buf)->begv_byte = buf_charpos_to_bytepos ((buf), (charpos)), \ - (buf)->begv = (charpos)) - -#define SET_BUF_ZV(buf, charpos) \ - ((buf)->zv_byte = buf_charpos_to_bytepos ((buf), (charpos)), \ - (buf)->zv = (charpos)) - -#define SET_BUF_BEGV_BOTH(buf, charpos, byte) \ - ((buf)->begv = (charpos), \ - (buf)->begv_byte = (byte)) - -#define SET_BUF_ZV_BOTH(buf, charpos, byte) \ - ((buf)->zv = (charpos), \ - (buf)->zv_byte = (byte)) - -#define SET_BUF_PT_BOTH(buf, charpos, byte) \ - ((buf)->pt = (charpos), \ - (buf)->pt_byte = (byte)) - -/* Macros to access a character or byte in the current buffer, - or convert between a byte position and an address. - These macros do not check that the position is in range. */ - /* Maximum number of bytes in a buffer. A buffer cannot contain more bytes than a 1-origin fixnum can represent, nor can it be so large that C pointer arithmetic stops working. @@ -298,115 +194,21 @@ extern void enlarge_buffer_text (struct buffer *, ptrdiff_t); /* Maximum gap size after compact_buffer, in bytes. Also used in make_gap_larger to get some extra reserved space. */ -#define GAP_BYTES_DFL 2000 +enum { GAP_BYTES_DFL = 2000 }; /* Minimum gap size after compact_buffer, in bytes. Also used in make_gap_smaller to avoid too small gap size. */ -#define GAP_BYTES_MIN 20 - -/* Return the address of byte position N in current buffer. */ - -#define BYTE_POS_ADDR(n) \ - (((n) >= GPT_BYTE ? GAP_SIZE : 0) + (n) + BEG_ADDR - BEG_BYTE) - -/* Return the address of char position N. */ - -#define CHAR_POS_ADDR(n) \ - (((n) >= GPT ? GAP_SIZE : 0) \ - + buf_charpos_to_bytepos (current_buffer, n) \ - + BEG_ADDR - BEG_BYTE) - -/* Convert a character position to a byte position. */ - -#define CHAR_TO_BYTE(charpos) \ - (buf_charpos_to_bytepos (current_buffer, charpos)) - -/* Convert a byte position to a character position. */ - -#define BYTE_TO_CHAR(bytepos) \ - (buf_bytepos_to_charpos (current_buffer, bytepos)) +enum { GAP_BYTES_MIN = 20 }; /* For those very rare cases where you may have a "random" pointer into the middle of a multibyte char, this moves to the next boundary. */ extern ptrdiff_t advance_to_char_boundary (ptrdiff_t byte_pos); -/* Convert PTR, the address of a byte in the buffer, into a byte position. */ - -#define PTR_BYTE_POS(ptr) \ - ((ptr) - (current_buffer)->text->beg \ - - (ptr - (current_buffer)->text->beg <= GPT_BYTE - BEG_BYTE ? 0 : GAP_SIZE) \ - + BEG_BYTE) - -/* Return character at byte position POS. See the caveat WARNING for - FETCH_MULTIBYTE_CHAR below. */ - -#define FETCH_CHAR(pos) \ - (!NILP (BVAR (current_buffer, enable_multibyte_characters)) \ - ? FETCH_MULTIBYTE_CHAR ((pos)) \ - : FETCH_BYTE ((pos))) - -/* Return the byte at byte position N. */ +/* Return the byte at byte position N. + Do not check that the position is in range. */ #define FETCH_BYTE(n) *(BYTE_POS_ADDR ((n))) - -/* Return character at byte position POS. If the current buffer is unibyte - and the character is not ASCII, make the returning character - multibyte. */ - -#define FETCH_CHAR_AS_MULTIBYTE(pos) \ - (!NILP (BVAR (current_buffer, enable_multibyte_characters)) \ - ? FETCH_MULTIBYTE_CHAR ((pos)) \ - : UNIBYTE_TO_CHAR (FETCH_BYTE ((pos)))) - - -/* Macros for accessing a character or byte, - or converting between byte positions and addresses, - in a specified buffer. */ - -/* Return the address of character at byte position POS in buffer BUF. - Note that both arguments can be computed more than once. */ - -#define BUF_BYTE_ADDRESS(buf, pos) \ - ((buf)->text->beg + (pos) - BEG_BYTE \ - + ((pos) >= (buf)->text->gpt_byte ? (buf)->text->gap_size : 0)) - -/* Return the address of character at char position POS in buffer BUF. - Note that both arguments can be computed more than once. */ - -#define BUF_CHAR_ADDRESS(buf, pos) \ - ((buf)->text->beg + buf_charpos_to_bytepos ((buf), (pos)) - BEG_BYTE \ - + ((pos) >= (buf)->text->gpt ? (buf)->text->gap_size : 0)) - -/* Convert PTR, the address of a char in buffer BUF, - into a character position. */ - -#define BUF_PTR_BYTE_POS(buf, ptr) \ - ((ptr) - (buf)->text->beg \ - - (ptr - (buf)->text->beg <= BUF_GPT_BYTE (buf) - BEG_BYTE \ - ? 0 : BUF_GAP_SIZE ((buf))) \ - + BEG_BYTE) - -/* Return the character at byte position POS in buffer BUF. */ - -#define BUF_FETCH_CHAR(buf, pos) \ - (!NILP (buf->enable_multibyte_characters) \ - ? BUF_FETCH_MULTIBYTE_CHAR ((buf), (pos)) \ - : BUF_FETCH_BYTE ((buf), (pos))) - -/* Return character at byte position POS in buffer BUF. If BUF is - unibyte and the character is not ASCII, make the returning - character multibyte. */ - -#define BUF_FETCH_CHAR_AS_MULTIBYTE(buf, pos) \ - (! NILP (BVAR ((buf), enable_multibyte_characters)) \ - ? BUF_FETCH_MULTIBYTE_CHAR ((buf), (pos)) \ - : UNIBYTE_TO_CHAR (BUF_FETCH_BYTE ((buf), (pos)))) - -/* Return the byte at byte position N in buffer BUF. */ - -#define BUF_FETCH_BYTE(buf, n) \ - *(BUF_BYTE_ADDRESS ((buf), (n))) /* Define the actual buffer data structures. */ @@ -482,6 +284,13 @@ struct buffer_text #define BVAR(buf, field) ((buf)->field ## _) +/* Max number of builtin per-buffer variables. */ +enum { MAX_PER_BUFFER_VARS = 50 }; + +/* Special values for struct buffer.modtime. */ +enum { NONEXISTENT_MODTIME_NSECS = -1 }; +enum { UNKNOWN_MODTIME_NSECS = -2 }; + /* This is the structure that the buffer Lisp object points to. */ struct buffer @@ -796,7 +605,6 @@ struct buffer for a buffer-local variable is stored in that variable's slot in buffer_local_flags as a Lisp integer. If the index is -1, this means the variable is always local in all buffers. */ -#define MAX_PER_BUFFER_VARS 50 char local_flags[MAX_PER_BUFFER_VARS]; /* Set to the modtime of the visited file when read or written. @@ -804,8 +612,6 @@ struct buffer visited file was nonexistent. modtime.tv_nsec == UNKNOWN_MODTIME_NSECS means visited file modtime unknown; in no case complain about any mismatch on next save attempt. */ -#define NONEXISTENT_MODTIME_NSECS (-1) -#define UNKNOWN_MODTIME_NSECS (-2) struct timespec modtime; /* Size of the file when modtime was set. This is used to detect the @@ -1018,49 +824,281 @@ bset_width_table (struct buffer *b, Lisp_Object val) b->width_table_ = val; } +/* BUFFER_CEILING_OF (resp. BUFFER_FLOOR_OF), when applied to n, return + the max (resp. min) p such that + + BYTE_POS_ADDR (p) - BYTE_POS_ADDR (n) == p - n */ + +INLINE ptrdiff_t +BUFFER_CEILING_OF (ptrdiff_t bytepos) +{ + return (bytepos < GPT_BYTE && GPT < ZV ? GPT_BYTE : ZV_BYTE) - 1; +} + +INLINE ptrdiff_t +BUFFER_FLOOR_OF (ptrdiff_t bytepos) +{ + return BEGV <= GPT && GPT_BYTE <= bytepos ? GPT_BYTE : BEGV_BYTE; +} + +/* The BUF_BEGV[_BYTE], BUF_ZV[_BYTE], and BUF_PT[_BYTE] functions cannot + be used for assignment; use SET_BUF_* functions below for that. */ + +/* Position of beginning of accessible range of buffer. */ +INLINE ptrdiff_t +BUF_BEGV (struct buffer *buf) +{ + return (buf == current_buffer ? BEGV + : NILP (BVAR (buf, begv_marker)) ? buf->begv + : marker_position (BVAR (buf, begv_marker))); +} + +INLINE ptrdiff_t +BUF_BEGV_BYTE (struct buffer *buf) +{ + return (buf == current_buffer ? BEGV_BYTE + : NILP (BVAR (buf, begv_marker)) ? buf->begv_byte + : marker_byte_position (BVAR (buf, begv_marker))); +} + +/* Position of point in buffer. */ +INLINE ptrdiff_t +BUF_PT (struct buffer *buf) +{ + return (buf == current_buffer ? PT + : NILP (BVAR (buf, pt_marker)) ? buf->pt + : marker_position (BVAR (buf, pt_marker))); +} + +INLINE ptrdiff_t +BUF_PT_BYTE (struct buffer *buf) +{ + return (buf == current_buffer ? PT_BYTE + : NILP (BVAR (buf, pt_marker)) ? buf->pt_byte + : marker_byte_position (BVAR (buf, pt_marker))); +} + +/* Position of end of accessible range of buffer. */ +INLINE ptrdiff_t +BUF_ZV (struct buffer *buf) +{ + return (buf == current_buffer ? ZV + : NILP (BVAR (buf, zv_marker)) ? buf->zv + : marker_position (BVAR (buf, zv_marker))); +} + +INLINE ptrdiff_t +BUF_ZV_BYTE (struct buffer *buf) +{ + return (buf == current_buffer ? ZV_BYTE + : NILP (BVAR (buf, zv_marker)) ? buf->zv_byte + : marker_byte_position (BVAR (buf, zv_marker))); +} + +/* Similar functions to operate on a specified buffer. */ + +/* Position of beginning of buffer. */ +INLINE ptrdiff_t +BUF_BEG (struct buffer *buf) +{ + return BEG; +} + +INLINE ptrdiff_t +BUF_BEG_BYTE (struct buffer *buf) +{ + return BEG_BYTE; +} + +/* Address of beginning of gap of buffer. */ +INLINE unsigned char * +BUF_GPT_ADDR (struct buffer *buf) +{ + return buf->text->beg + buf->text->gpt_byte - BEG_BYTE; +} + +/* Address of end of buffer. */ +INLINE unsigned char * +BUF_Z_ADDR (struct buffer *buf) +{ + return buf->text->beg + buf->text->gap_size + buf->text->z_byte - BEG_BYTE; +} + +/* Address of end of gap in buffer. */ +INLINE unsigned char * +BUF_GAP_END_ADDR (struct buffer *buf) +{ + return buf->text->beg + buf->text->gpt_byte + buf->text->gap_size - BEG_BYTE; +} + +/* Compute how many characters at the top and bottom of BUF are + unchanged when the range START..END is modified. This computation + must be done each time BUF is modified. */ + +INLINE void +BUF_COMPUTE_UNCHANGED (struct buffer *buf, ptrdiff_t start, ptrdiff_t end) +{ + if (BUF_UNCHANGED_MODIFIED (buf) == BUF_MODIFF (buf) + && (BUF_OVERLAY_UNCHANGED_MODIFIED (buf) + == BUF_OVERLAY_MODIFF (buf))) + { + buf->text->beg_unchanged = start - BUF_BEG (buf); + buf->text->end_unchanged = BUF_Z (buf) - (end); + } + else + { + if (BUF_Z (buf) - end < BUF_END_UNCHANGED (buf)) + buf->text->end_unchanged = BUF_Z (buf) - end; + if (start - BUF_BEG (buf) < BUF_BEG_UNCHANGED (buf)) + buf->text->beg_unchanged = start - BUF_BEG (buf); + } +} + +/* Functions for setting the BEGV, ZV or PT of a given buffer. + + The ..._BOTH functions take both a charpos and a bytepos, + which must correspond to each other. + + The functions without ..._BOTH take just a charpos, + and compute the bytepos from it. */ + +INLINE void +SET_BUF_BEGV (struct buffer *buf, ptrdiff_t charpos) +{ + buf->begv_byte = buf_charpos_to_bytepos (buf, charpos); + buf->begv = charpos; +} + +INLINE void +SET_BUF_ZV (struct buffer *buf, ptrdiff_t charpos) +{ + buf->zv_byte = buf_charpos_to_bytepos (buf, charpos); + buf->zv = charpos; +} + +INLINE void +SET_BUF_BEGV_BOTH (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t byte) +{ + buf->begv = charpos; + buf->begv_byte = byte; +} + +INLINE void +SET_BUF_ZV_BOTH (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t byte) +{ + buf->zv = charpos; + buf->zv_byte = byte; +} + +INLINE void +SET_BUF_PT_BOTH (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t byte) +{ + buf->pt = charpos; + buf->pt_byte = byte; +} + +/* Functions to access a character or byte in the current buffer, + or convert between a byte position and an address. + These functions do not check that the position is in range. */ + +/* Return the address of byte position N in current buffer. */ + +INLINE unsigned char * +BYTE_POS_ADDR (ptrdiff_t n) +{ + return (n < GPT_BYTE ? 0 : GAP_SIZE) + n + BEG_ADDR - BEG_BYTE; +} + +/* Return the address of char position N. */ + +INLINE unsigned char * +CHAR_POS_ADDR (ptrdiff_t n) +{ + return ((n < GPT ? 0 : GAP_SIZE) + + buf_charpos_to_bytepos (current_buffer, n) + + BEG_ADDR - BEG_BYTE); +} + +/* Convert a character position to a byte position. */ + +INLINE ptrdiff_t +CHAR_TO_BYTE (ptrdiff_t charpos) +{ + return buf_charpos_to_bytepos (current_buffer, charpos); +} + +/* Convert a byte position to a character position. */ + +INLINE ptrdiff_t +BYTE_TO_CHAR (ptrdiff_t bytepos) +{ + return buf_bytepos_to_charpos (current_buffer, bytepos); +} + +/* Convert PTR, the address of a byte in the buffer, into a byte position. */ + +INLINE ptrdiff_t +PTR_BYTE_POS (unsigned char const *ptr) +{ + ptrdiff_t byte = ptr - current_buffer->text->beg; + return byte - (byte <= GPT_BYTE - BEG_BYTE ? 0 : GAP_SIZE) + BEG_BYTE; +} + /* Number of Lisp_Objects at the beginning of struct buffer. If you add, remove, or reorder Lisp_Objects within buffer structure, make sure that this is still correct. */ -#define BUFFER_LISP_SIZE \ - PSEUDOVECSIZE (struct buffer, cursor_in_non_selected_windows_) +enum { BUFFER_LISP_SIZE = PSEUDOVECSIZE (struct buffer, + cursor_in_non_selected_windows_) }; /* Allocated size of the struct buffer part beyond leading Lisp_Objects, in word_size units. */ -#define BUFFER_REST_SIZE (VECSIZE (struct buffer) - BUFFER_LISP_SIZE) +enum { BUFFER_REST_SIZE = VECSIZE (struct buffer) - BUFFER_LISP_SIZE }; /* Initialize the pseudovector header of buffer object. BUFFER_LISP_SIZE is required for GC, but BUFFER_REST_SIZE is set up just to be consistent with other pseudovectors. */ -#define BUFFER_PVEC_INIT(b) \ - XSETPVECTYPESIZE (b, PVEC_BUFFER, BUFFER_LISP_SIZE, BUFFER_REST_SIZE) +INLINE void +BUFFER_PVEC_INIT (struct buffer *b) +{ + XSETPVECTYPESIZE (b, PVEC_BUFFER, BUFFER_LISP_SIZE, BUFFER_REST_SIZE); +} /* Convenient check whether buffer B is live. */ -#define BUFFER_LIVE_P(b) (!NILP (BVAR (b, name))) +INLINE bool +BUFFER_LIVE_P (struct buffer *b) +{ + return !NILP (BVAR (b, name)); +} /* Convenient check whether buffer B is hidden (i.e. its name starts with a space). Caller must ensure that B is live. */ -#define BUFFER_HIDDEN_P(b) (SREF (BVAR (b, name), 0) == ' ') +INLINE bool +BUFFER_HIDDEN_P (struct buffer *b) +{ + return SREF (BVAR (b, name), 0) == ' '; +} /* Verify indirection counters. */ -#define BUFFER_CHECK_INDIRECTION(b) \ - do { \ - if (BUFFER_LIVE_P (b)) \ - { \ - if (b->base_buffer) \ - { \ - eassert (b->indirections == -1); \ - eassert (b->base_buffer->indirections > 0); \ - } \ - else \ - eassert (b->indirections >= 0); \ - } \ - } while (false) +INLINE void +BUFFER_CHECK_INDIRECTION (struct buffer *b) +{ + if (BUFFER_LIVE_P (b)) + { + if (b->base_buffer) + { + eassert (b->indirections == -1); + eassert (b->base_buffer->indirections > 0); + } + else + eassert (b->indirections >= 0); + } +} /* Chain of all buffers, including killed ones. */ @@ -1157,7 +1195,9 @@ record_unwind_current_buffer (void) /* Get overlays at POSN into array OVERLAYS with NOVERLAYS elements. If NEXTP is non-NULL, return next overlay there. - See overlay_at arg CHANGE_REQ for meaning of CHRQ arg. */ + See overlay_at arg CHANGE_REQ for meaning of CHRQ arg. + This macro might evaluate its args multiple times, + and it treat some args as lvalues. */ #define GET_OVERLAYS_AT(posn, overlays, noverlays, nextp, chrq) \ do { \ @@ -1207,6 +1247,10 @@ buffer_has_overlays (void) { return current_buffer->overlays_before || current_buffer->overlays_after; } + +/* Functions for accessing a character or byte, + or converting between byte positions and addresses, + in a specified buffer. */ /* Return character code of multi-byte form at byte position POS. If POS doesn't point the head of valid multi-byte form, only the byte at @@ -1232,6 +1276,80 @@ BUF_FETCH_MULTIBYTE_CHAR (struct buffer *buf, ptrdiff_t pos) return STRING_CHAR (p); } +/* Return character at byte position POS. + If the current buffer is unibyte and the character is not ASCII, + make the returning character multibyte. */ + +INLINE int +FETCH_CHAR_AS_MULTIBYTE (ptrdiff_t pos) +{ + return (!NILP (BVAR (current_buffer, enable_multibyte_characters)) + ? FETCH_MULTIBYTE_CHAR (pos) + : UNIBYTE_TO_CHAR (FETCH_BYTE (pos))); +} + +/* Return character at byte position POS. + See the caveat WARNING for FETCH_MULTIBYTE_CHAR above. */ + +INLINE int +FETCH_CHAR (ptrdiff_t pos) +{ + return (!NILP (BVAR (current_buffer, enable_multibyte_characters)) + ? FETCH_MULTIBYTE_CHAR (pos) + : FETCH_BYTE (pos)); +} + +/* Return the address of character at byte position POS in buffer BUF. + Note that both arguments can be computed more than once. */ + +INLINE unsigned char * +BUF_BYTE_ADDRESS (struct buffer *buf, ptrdiff_t pos) +{ + return (buf->text->beg + pos - BEG_BYTE + + (pos < buf->text->gpt_byte ? 0 : buf->text->gap_size)); +} + +/* Return the address of character at char position POS in buffer BUF. + Note that both arguments can be computed more than once. */ + +INLINE unsigned char * +BUF_CHAR_ADDRESS (struct buffer *buf, ptrdiff_t pos) +{ + return (buf->text->beg + buf_charpos_to_bytepos (buf, pos) - BEG_BYTE + + (pos < buf->text->gpt ? 0 : buf->text->gap_size)); +} + +/* Convert PTR, the address of a char in buffer BUF, + into a character position. */ + +INLINE ptrdiff_t +BUF_PTR_BYTE_POS (struct buffer *buf, unsigned char *ptr) +{ + ptrdiff_t byte = ptr - buf->text->beg; + return (byte - (byte <= BUF_GPT_BYTE (buf) - BEG_BYTE ? 0 : BUF_GAP_SIZE (buf)) + + BEG_BYTE); +} + +/* Return the byte at byte position N in buffer BUF. */ + +INLINE unsigned char +BUF_FETCH_BYTE (struct buffer *buf, ptrdiff_t n) +{ + return *BUF_BYTE_ADDRESS (buf, n); +} + +/* Return character at byte position POS in buffer BUF. If BUF is + unibyte and the character is not ASCII, make the returning + character multibyte. */ + +INLINE int +BUF_FETCH_CHAR_AS_MULTIBYTE (struct buffer *buf, ptrdiff_t pos) +{ + return (! NILP (BVAR (buf, enable_multibyte_characters)) + ? BUF_FETCH_MULTIBYTE_CHAR (buf, pos) + : UNIBYTE_TO_CHAR (BUF_FETCH_BYTE (buf, pos))); +} + /* Return number of windows showing B. */ INLINE int @@ -1260,8 +1378,11 @@ buffer_window_count (struct buffer *b) /* Return the actual buffer position for the marker P. We assume you know which buffer it's pointing into. */ -#define OVERLAY_POSITION(P) \ - (MARKERP (P) ? marker_position (P) : (emacs_abort (), 0)) +INLINE ptrdiff_t +OVERLAY_POSITION (Lisp_Object p) +{ + return marker_position (p); +} /*********************************************************************** @@ -1297,16 +1418,22 @@ extern bool valid_per_buffer_idx (int); /* Value is true if the variable with index IDX has a local value in buffer B. */ -#define PER_BUFFER_VALUE_P(B, IDX) \ - (eassert (valid_per_buffer_idx (IDX)), \ - (B)->local_flags[IDX]) +INLINE bool +PER_BUFFER_VALUE_P (struct buffer *b, int idx) +{ + eassert (valid_per_buffer_idx (idx)); + return b->local_flags[idx]; +} /* Set whether per-buffer variable with index IDX has a buffer-local value in buffer B. VAL zero means it hasn't. */ -#define SET_PER_BUFFER_VALUE_P(B, IDX, VAL) \ - (eassert (valid_per_buffer_idx (IDX)), \ - (B)->local_flags[IDX] = (VAL)) +INLINE void +SET_PER_BUFFER_VALUE_P (struct buffer *b, int idx, bool val) +{ + eassert (valid_per_buffer_idx (idx)); + b->local_flags[idx] = val; +} /* Return the index value of the per-buffer variable at offset OFFSET in the buffer structure. @@ -1326,11 +1453,13 @@ extern bool valid_per_buffer_idx (int); new buffer. If a slot in this structure corresponding to a DEFVAR_PER_BUFFER is - zero, that is a bug */ + zero, that is a bug. */ - -#define PER_BUFFER_IDX(OFFSET) \ - XFIXNUM (*(Lisp_Object *)((OFFSET) + (char *) &buffer_local_flags)) +INLINE int +PER_BUFFER_IDX (ptrdiff_t offset) +{ + return XFIXNUM (*(Lisp_Object *) (offset + (char *) &buffer_local_flags)); +} /* Functions to get and set default value of the per-buffer variable at offset OFFSET in the buffer structure. */ commit bbe45091de5418a85fb3b429b40747d66485bb6e Author: Paul Eggert Date: Tue Sep 3 21:54:58 2019 -0700 * src/xdisp.c (hscroll_window_tree): Fix type typo. diff --git a/src/xdisp.c b/src/xdisp.c index 75bc536cb9..94f969f37c 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -13509,7 +13509,8 @@ hscroll_window_tree (Lisp_Object window) get glyph rows whose start and end have zero buffer positions, which we cannot handle below. Just skip such windows. */ - && CHARPOS (cursor_row->start.pos) >= BUF_BEG (w->contents) + && (CHARPOS (cursor_row->start.pos) + >= BUF_BEG (XBUFFER (w->contents))) /* For left-to-right rows, hscroll when cursor is either (i) inside the right hscroll margin, or (ii) if it is inside the left margin and the window is already commit 97cfda2638afc7fed6ac7e465c6fe927f428a932 Author: Paul Eggert Date: Tue Sep 3 21:54:58 2019 -0700 Take last_per_buffer_idx private This will simplify future changes. Turn the runtime check into an eassert, since it’s not needed in production. * src/buffer.c (last_per_buffer_idx): Now static. (valid_per_buffer_idx): New function. * src/buffer.h (PER_BUFFER_VALUE_P, SET_PER_BUFFER_VALUE_P): Use it. diff --git a/src/buffer.c b/src/buffer.c index 62a3d66c8b..77e8b6bb77 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -105,7 +105,7 @@ static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS]; /* Number of per-buffer variables used. */ -int last_per_buffer_idx; +static int last_per_buffer_idx; static void call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay, bool after, Lisp_Object arg1, @@ -655,6 +655,12 @@ set_buffer_overlays_after (struct buffer *b, struct Lisp_Overlay *o) b->overlays_after = o; } +bool +valid_per_buffer_idx (int idx) +{ + return 0 <= idx && idx < last_per_buffer_idx; +} + /* Clone per-buffer values of buffer FROM. Buffer TO gets the same per-buffer values as FROM, with the diff --git a/src/buffer.h b/src/buffer.h index 2080a6f40b..14de70c648 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -1268,10 +1268,6 @@ buffer_window_count (struct buffer *b) Buffer-local Variables ***********************************************************************/ -/* Number of per-buffer variables used. */ - -extern int last_per_buffer_idx; - /* Return the offset in bytes of member VAR of struct buffer from the start of a buffer structure. */ @@ -1296,23 +1292,21 @@ extern int last_per_buffer_idx; #define PER_BUFFER_VAR_IDX(VAR) \ PER_BUFFER_IDX (PER_BUFFER_VAR_OFFSET (VAR)) +extern bool valid_per_buffer_idx (int); + /* Value is true if the variable with index IDX has a local value in buffer B. */ #define PER_BUFFER_VALUE_P(B, IDX) \ - (((IDX) < 0 || IDX >= last_per_buffer_idx) \ - ? (emacs_abort (), false) \ - : ((B)->local_flags[IDX] != 0)) + (eassert (valid_per_buffer_idx (IDX)), \ + (B)->local_flags[IDX]) /* Set whether per-buffer variable with index IDX has a buffer-local value in buffer B. VAL zero means it hasn't. */ #define SET_PER_BUFFER_VALUE_P(B, IDX, VAL) \ - do { \ - if ((IDX) < 0 || (IDX) >= last_per_buffer_idx) \ - emacs_abort (); \ - (B)->local_flags[IDX] = (VAL); \ - } while (false) + (eassert (valid_per_buffer_idx (IDX)), \ + (B)->local_flags[IDX] = (VAL)) /* Return the index value of the per-buffer variable at offset OFFSET in the buffer structure. commit 9117a667908064a0b4ae6ec6c8f3674d95ad6225 Author: Paul Eggert Date: Tue Sep 3 21:53:36 2019 -0700 Avoid macros in pdumper.c when it’s easy Problem with DUMP_SET_REFERRER mentioned by Pip Cet at end of: https://lists.gnu.org/archive/html/emacs-devel/2019-07/msg00548.html * src/pdumper.c (DANGEROUS, EMACS_RELOC_TYPE_BITS) (EMACS_RELOC_LENGTH_BITS, DUMP_RELOC_TYPE_BITS) (DUMP_RELOC_ALIGNMENT_BITS, DUMP_RELOC_OFFSET_BITS) (DUMP_RELOCATION_ALIGNMENT, DUMP_ALIGNMENT) (WEIGHT_NONE, WEIGHT_NORMAL, WEIGHT_STRONG) (PDUMPER_MAX_OBJECT_SIZE): Now a constant, not a macro. (divide_round_up): Now a function, not a macro DIVIDE_ROUND_UP. All uses changed. (enum link_weight_enum, WEIGHT_NONE_VALUE) (WEIGHT_NORMAL_VALUE, WEIGHT_STRONG_VALUE): Remove. (struct link_weight): Just use an int. (dump_set_referrer): New function, replacing DUMP_SET_REFERRER macro with a different API. All uses changed. (dump_clear_referrer): Rename from DUMP_CLEAR_REFERRER. All uses changed. (DEFINE_FROMLISP_FUNC, DEFINE_TOLISP_FUNC): Remove. (intmax_t_from_lisp, intmax_t_to_lisp, dump_off_from_lisp) (dump_off_to_lisp): Define without using macros, (dump_off_from_lisp): Add an eassert range check. (DUMP_FIELD_COPY): Simplify. diff --git a/src/pdumper.c b/src/pdumper.c index f9c31d125a..306a70396e 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -105,8 +105,6 @@ along with GNU Emacs. If not, see . */ # define VM_SUPPORTED 0 #endif -#define DANGEROUS 0 - /* PDUMPER_CHECK_REHASHING being true causes the portable dumper to check, for each hash table it dumps, that the hash table means the same thing after rehashing. */ @@ -129,7 +127,11 @@ verify (sizeof (ptrdiff_t) <= sizeof (Lisp_Object)); verify (sizeof (ptrdiff_t) <= sizeof (EMACS_INT)); verify (CHAR_BIT == 8); -#define DIVIDE_ROUND_UP(x, y) (((x) + (y) - 1) / (y)) +static size_t +divide_round_up (size_t x, size_t y) +{ + return (x + y - 1) / y; +} static const char dump_magic[16] = { 'D', 'U', 'M', 'P', 'E', 'D', @@ -235,9 +237,12 @@ enum emacs_reloc_type RELOC_EMACS_EMACS_LV, }; -#define EMACS_RELOC_TYPE_BITS 3 -#define EMACS_RELOC_LENGTH_BITS \ - (sizeof (dump_off) * CHAR_BIT - EMACS_RELOC_TYPE_BITS) +enum + { + EMACS_RELOC_TYPE_BITS = 3, + EMACS_RELOC_LENGTH_BITS = (sizeof (dump_off) * CHAR_BIT + - EMACS_RELOC_TYPE_BITS) + }; struct emacs_reloc { @@ -274,19 +279,22 @@ struct dump_table_locator dump_off nr_entries; }; -#define DUMP_RELOC_TYPE_BITS 5 -verify (RELOC_DUMP_TO_EMACS_LV + 8 < (1 << DUMP_RELOC_TYPE_BITS)); +enum + { + DUMP_RELOC_TYPE_BITS = 5, + DUMP_RELOC_ALIGNMENT_BITS = 2, + + /* Minimum alignment required by dump file format. */ + DUMP_RELOCATION_ALIGNMENT = 1 << DUMP_RELOC_ALIGNMENT_BITS, -#define DUMP_RELOC_ALIGNMENT_BITS 2 -#define DUMP_RELOC_OFFSET_BITS \ - (sizeof (dump_off) * CHAR_BIT - DUMP_RELOC_TYPE_BITS) + /* The alignment granularity (in bytes) for objects we store in the + dump. Always suitable for heap objects; may be more aligned. */ + DUMP_ALIGNMENT = max (GCALIGNMENT, DUMP_RELOCATION_ALIGNMENT), -/* Minimum alignment required by dump file format. */ -#define DUMP_RELOCATION_ALIGNMENT (1<= GCALIGNMENT); struct dump_reloc @@ -572,23 +580,17 @@ enum dump_object_special_offset }; /* Weights for score scores for object non-locality. */ -enum link_weight_enum - { - WEIGHT_NONE_VALUE = 0, - WEIGHT_NORMAL_VALUE = 1000, - WEIGHT_STRONG_VALUE = 1200, - }; struct link_weight { /* Wrapped in a struct to break unwanted implicit conversion. */ - enum link_weight_enum value; + int value; }; -#define LINK_WEIGHT_LITERAL(x) ((struct link_weight){.value=(x)}) -#define WEIGHT_NONE LINK_WEIGHT_LITERAL (WEIGHT_NONE_VALUE) -#define WEIGHT_NORMAL LINK_WEIGHT_LITERAL (WEIGHT_NORMAL_VALUE) -#define WEIGHT_STRONG LINK_WEIGHT_LITERAL (WEIGHT_STRONG_VALUE) +static struct link_weight const + WEIGHT_NONE = { .value = 0 }, + WEIGHT_NORMAL = { .value = 1000 }, + WEIGHT_STRONG = { .value = 1200 }; /* Dump file creation */ @@ -628,35 +630,27 @@ dump_set_have_current_referrer (struct dump_context *ctx, bool have) #endif } -/* Remember the reason objects are enqueued. +/* Return true if if objects should be enqueued in CTX to refer to an + object that the caller should store into CTX->current_referrer. - Until DUMP_CLEAR_REFERRER is called, any objects enqueued are being - enqueued because OBJECT refers to them. It is not legal to enqueue - objects without a referer set. We check this constraint + Until dump_clear_referrer is called, any objects enqueued are being + enqueued because the object refers to them. It is not valid to + enqueue objects without a referrer set. We check this constraint at runtime. - It is illegal to call DUMP_SET_REFERRER twice without an - intervening call to DUMP_CLEAR_REFERRER. - - Define as a macro so we can avoid evaluating OBJECT - if we dont want referrer tracking. */ -#define DUMP_SET_REFERRER(ctx, object) \ - do \ - { \ - struct dump_context *_ctx = (ctx); \ - eassert (!_ctx->have_current_referrer); \ - dump_set_have_current_referrer (_ctx, true); \ - if (dump_tracking_referrers_p (_ctx)) \ - ctx->current_referrer = (object); \ - } \ - while (0) - -/* Unset the referer that DUMP_SET_REFERRER set. - - Named with upper-case letters for symmetry with - DUMP_SET_REFERRER. */ + It is invalid to call dump_set_referrer twice without an + intervening call to dump_clear_referrer. */ +static bool +dump_set_referrer (struct dump_context *ctx) +{ + eassert (!ctx->have_current_referrer); + dump_set_have_current_referrer (ctx, true); + return dump_tracking_referrers_p (ctx); +} + +/* Unset the referrer that dump_set_referrer prepared for. */ static void -DUMP_CLEAR_REFERRER (struct dump_context *ctx) +dump_clear_referrer (struct dump_context *ctx) { eassert (ctx->have_current_referrer); dump_set_have_current_referrer (ctx, false); @@ -732,34 +726,36 @@ dump_object_self_representing_p (Lisp_Object object) return FIXNUMP (object) || dump_builtin_symbol_p (object); } -#define DEFINE_FROMLISP_FUNC(fn, type) \ - static type \ - fn (Lisp_Object value) \ - { \ - ALLOW_IMPLICIT_CONVERSION; \ - if (FIXNUMP (value)) \ - return XFIXNUM (value); \ - eassert (BIGNUMP (value)); \ - type result; \ - if (TYPE_SIGNED (type)) \ - result = bignum_to_intmax (value); \ - else \ - result = bignum_to_uintmax (value); \ - DISALLOW_IMPLICIT_CONVERSION; \ - return result; \ - } +static intmax_t +intmax_t_from_lisp (Lisp_Object value) +{ + intmax_t n; + bool ok = integer_to_intmax (value, &n); + eassert (ok); + return n; +} -#define DEFINE_TOLISP_FUNC(fn, type) \ - static Lisp_Object \ - fn (type value) \ - { \ - return INT_TO_INTEGER (value); \ - } +static Lisp_Object +intmax_t_to_lisp (intmax_t value) +{ + return INT_TO_INTEGER (value); +} + +static dump_off +dump_off_from_lisp (Lisp_Object value) +{ + intmax_t n = intmax_t_from_lisp (value); + eassert (DUMP_OFF_MIN <= n && n <= DUMP_OFF_MAX); + ALLOW_IMPLICIT_CONVERSION; + return n; + DISALLOW_IMPLICIT_CONVERSION; +} -DEFINE_FROMLISP_FUNC (intmax_t_from_lisp, intmax_t) -DEFINE_TOLISP_FUNC (intmax_t_to_lisp, intmax_t) -DEFINE_FROMLISP_FUNC (dump_off_from_lisp, dump_off) -DEFINE_TOLISP_FUNC (dump_off_to_lisp, dump_off) +static Lisp_Object +dump_off_to_lisp (dump_off value) +{ + return INT_TO_INTEGER (value); +} static void dump_write (struct dump_context *ctx, const void *buf, dump_off nbyte) @@ -1731,9 +1727,10 @@ dump_root_visitor (Lisp_Object const *root_ptr, enum gc_root_type type, eassert (dump_builtin_symbol_p (value)); /* Remember to dump the object itself later along with all the rest of the copied-to-Emacs objects. */ - DUMP_SET_REFERRER (ctx, build_string ("built-in symbol list")); + if (dump_set_referrer (ctx)) + ctx->current_referrer = build_string ("built-in symbol list"); dump_enqueue_object (ctx, value, WEIGHT_NONE); - DUMP_CLEAR_REFERRER (ctx); + dump_clear_referrer (ctx); } else { @@ -1743,9 +1740,11 @@ dump_root_visitor (Lisp_Object const *root_ptr, enum gc_root_type type, ctx->staticpro_table); if (root_ptr != &Vinternal_interpreter_environment) { - DUMP_SET_REFERRER (ctx, dump_ptr_referrer ("emacs root", root_ptr)); + if (dump_set_referrer (ctx)) + ctx->current_referrer + = dump_ptr_referrer ("emacs root", root_ptr); dump_emacs_reloc_to_lv (ctx, root_ptr, *root_ptr); - DUMP_CLEAR_REFERRER (ctx); + dump_clear_referrer (ctx); } } } @@ -1759,7 +1758,7 @@ dump_roots (struct dump_context *ctx) visit_static_gc_roots (visitor); } -#define PDUMPER_MAX_OBJECT_SIZE 2048 +enum { PDUMPER_MAX_OBJECT_SIZE = 2048 }; static dump_off field_relpos (const void *in_start, const void *in_field) @@ -1788,11 +1787,7 @@ cpyptr (void *out, const void *in) /* Convenience macro for regular assignment. */ #define DUMP_FIELD_COPY(out, in, name) \ - do \ - { \ - (out)->name = (in)->name; \ - } \ - while (0) + ((out)->name = (in)->name) static void dump_field_lv_or_rawptr (struct dump_context *ctx, @@ -1848,6 +1843,7 @@ dump_field_lv_or_rawptr (struct dump_context *ctx, intptr_t out_value; dump_off out_field_offset = ctx->obj_offset + relpos; dump_off target_offset = dump_recall_object (ctx, value); + enum { DANGEROUS = false }; if (DANGEROUS && target_offset > 0 && dump_object_emacs_ptr (value) == NULL) { @@ -2408,7 +2404,8 @@ dump_pre_dump_symbol (struct dump_context *ctx, struct Lisp_Symbol *symbol) { Lisp_Object symbol_lv = make_lisp_symbol (symbol); eassert (!dump_recall_symbol_aux (ctx, symbol_lv)); - DUMP_SET_REFERRER (ctx, symbol_lv); + if (dump_set_referrer (ctx)) + ctx->current_referrer = symbol_lv; switch (symbol->u.s.redirect) { case SYMBOL_LOCALIZED: @@ -2422,7 +2419,7 @@ dump_pre_dump_symbol (struct dump_context *ctx, struct Lisp_Symbol *symbol) default: break; } - DUMP_CLEAR_REFERRER (ctx); + dump_clear_referrer (ctx); } static dump_off @@ -2443,13 +2440,14 @@ dump_symbol (struct dump_context *ctx, { eassert (offset == DUMP_OBJECT_ON_NORMAL_QUEUE || offset == DUMP_OBJECT_NOT_SEEN); - DUMP_CLEAR_REFERRER (ctx); + dump_clear_referrer (ctx); struct dump_flags old_flags = ctx->flags; ctx->flags.dump_object_contents = false; ctx->flags.defer_symbols = false; dump_object (ctx, object); ctx->flags = old_flags; - DUMP_SET_REFERRER (ctx, object); + if (dump_set_referrer (ctx)) + ctx->current_referrer = object; offset = DUMP_OBJECT_ON_SYMBOL_QUEUE; dump_remember_object (ctx, object, offset); @@ -3118,7 +3116,8 @@ dump_object (struct dump_context *ctx, Lisp_Object object) } /* Object needs to be dumped. */ - DUMP_SET_REFERRER (ctx, object); + if (dump_set_referrer (ctx)) + ctx->current_referrer = object; switch (XTYPE (object)) { case Lisp_String: @@ -3142,7 +3141,7 @@ dump_object (struct dump_context *ctx, Lisp_Object object) default: emacs_abort (); } - DUMP_CLEAR_REFERRER (ctx); + dump_clear_referrer (ctx); /* offset can be < 0 if we've deferred an object. */ if (ctx->flags.dump_object_contents && offset > DUMP_OBJECT_NOT_SEEN) @@ -3507,9 +3506,10 @@ dump_drain_user_remembered_data_hot (struct dump_context *ctx) read_ptr_raw_and_lv (mem, type, &value, &lv); if (value != NULL) { - DUMP_SET_REFERRER (ctx, dump_ptr_referrer ("user data", mem)); + if (dump_set_referrer (ctx)) + ctx->current_referrer = dump_ptr_referrer ("user data", mem); dump_enqueue_object (ctx, lv, WEIGHT_NONE); - DUMP_CLEAR_REFERRER (ctx); + dump_clear_referrer (ctx); } } } @@ -4877,7 +4877,7 @@ dump_bitset_init (struct dump_bitset *bitset, size_t number_bits) { int xword_size = sizeof (bitset->bits[0]); int bits_per_word = xword_size * CHAR_BIT; - ptrdiff_t words_needed = DIVIDE_ROUND_UP (number_bits, bits_per_word); + ptrdiff_t words_needed = divide_round_up (number_bits, bits_per_word); bitset->number_words = words_needed; bitset->bits = calloc (words_needed, xword_size); return bitset->bits != NULL; @@ -5420,7 +5420,7 @@ pdumper_load (const char *dump_filename) err = PDUMPER_LOAD_ERROR; mark_bits_needed = - DIVIDE_ROUND_UP (header->discardable_start, DUMP_ALIGNMENT); + divide_round_up (header->discardable_start, DUMP_ALIGNMENT); if (!dump_bitset_init (&mark_bits, mark_bits_needed)) goto out; commit d20655669bd6f94cdd9fb2472668e92a069c0cf2 Author: Paul Eggert Date: Tue Sep 3 17:34:08 2019 -0700 Avoid casting -1 to possibly-unsigned enum * src/alloc.c (mark_maybe_pointer): * src/pdumper.h (pdumper_object_p_precise): Use pdumper_valid_object_type_p. * src/pdumper.c (pdumper_find_object_type_impl): * src/pdumper.h (pdumper_find_object_type): Return int, not enum Lisp_Type. All callers changed. * src/pdumper.h (PDUMPER_NO_OBJECT): Do not cast -1 to enum Lisp_Type; in theory, C18 says this could yield 7, which would mean PDUMPER_NO_OBJECT == Lisp_Float (!). (pdumper_valid_object_type_p): New function. diff --git a/src/alloc.c b/src/alloc.c index 5f8ef0a5dd..089f61f833 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -4617,11 +4617,11 @@ mark_maybe_pointer (void *p) if (pdumper_object_p (p)) { - enum Lisp_Type type = pdumper_find_object_type (p); - if (type != PDUMPER_NO_OBJECT) - mark_object ((type == Lisp_Symbol) - ? make_lisp_symbol(p) - : make_lisp_ptr(p, type)); + int type = pdumper_find_object_type (p); + if (pdumper_valid_object_type_p (type)) + mark_object (type == Lisp_Symbol + ? make_lisp_symbol (p) + : make_lisp_ptr (p, type)); /* See mark_maybe_object for why we can confidently return. */ return; } diff --git a/src/pdumper.c b/src/pdumper.c index 5e70e20431..f9c31d125a 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -5057,7 +5057,7 @@ pdumper_cold_object_p_impl (const void *obj) return offset >= dump_private.header.cold_start; } -enum Lisp_Type +int pdumper_find_object_type_impl (const void *obj) { eassert (pdumper_object_p (obj)); @@ -5067,7 +5067,7 @@ pdumper_find_object_type_impl (const void *obj) const struct dump_reloc *reloc = dump_find_relocation (&dump_private.header.object_starts, offset); return (reloc != NULL && dump_reloc_get_offset (*reloc) == offset) - ? (enum Lisp_Type) reloc->type + ? reloc->type : PDUMPER_NO_OBJECT; } diff --git a/src/pdumper.h b/src/pdumper.h index 5d1e9c3aea..83c094f3ca 100644 --- a/src/pdumper.h +++ b/src/pdumper.h @@ -24,7 +24,7 @@ along with GNU Emacs. If not, see . */ INLINE_HEADER_BEGIN -#define PDUMPER_NO_OBJECT ((enum Lisp_Type) -1) +enum { PDUMPER_NO_OBJECT = -1 }; /* Indicate in source code that we're deliberately relying on pdumper not preserving the given value. Compiles to nothing --- for humans @@ -170,12 +170,12 @@ pdumper_cold_object_p (const void *obj) } -extern enum Lisp_Type pdumper_find_object_type_impl (const void *obj); +extern int pdumper_find_object_type_impl (const void *obj); /* Return the type of the dumped object that starts at OBJ. It is a programming error to call this routine for an OBJ for which pdumper_object_p would return false. */ -INLINE _GL_ATTRIBUTE_CONST enum Lisp_Type +INLINE _GL_ATTRIBUTE_CONST int pdumper_find_object_type (const void *obj) { #ifdef HAVE_PDUMPER @@ -186,6 +186,14 @@ pdumper_find_object_type (const void *obj) #endif } +/* Return true if TYPE is that of a Lisp object. + PDUMPER_NO_OBJECT is invalid. */ +INLINE bool +pdumper_valid_object_type_p (int type) +{ + return 0 <= type; +} + /* Return whether OBJ points exactly to the start of some object in the loaded dump image. It is a programming error to call this routine for an OBJ for which pdumper_object_p would return @@ -194,7 +202,7 @@ INLINE _GL_ATTRIBUTE_CONST bool pdumper_object_p_precise (const void *obj) { #ifdef HAVE_PDUMPER - return pdumper_find_object_type (obj) != PDUMPER_NO_OBJECT; + return pdumper_valid_object_type_p (pdumper_find_object_type (obj)); #else (void) obj; emacs_abort (); commit 5f089ac93f18fbd6e8131b81e1c6b403894b5759 Author: Daniel Colascione Date: Tue Sep 3 13:16:21 2019 -0700 Run tramp cleanup in correct buffer Fixes bug #37297. * lisp/net/tramp.el (tramp-process-sentinel): Do process-end cleanup in the tramp buffer, not a random file buffer. diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index d419f9d87d..fdad43ef6f 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -4210,10 +4210,11 @@ the remote host use line-endings as defined in the variable (when vec (tramp-message vec 5 "Sentinel called: `%S' `%s'" proc event) (tramp-flush-connection-properties proc) - (tramp-flush-directory-properties vec "")) - (goto-char (point-max)) - (when (and prompt (re-search-backward (regexp-quote prompt) nil t)) - (delete-region (point) (point-max)))))) + (tramp-flush-directory-properties vec "") + (with-current-buffer (tramp-get-buffer vec) + (goto-char (point-max)) + (when (and prompt (re-search-backward (regexp-quote prompt) nil t)) + (delete-region (point) (point-max)))))))) (defun tramp-get-inode (vec) "Returns the virtual inode number. commit 97ffa339b6d67cebcbefbdfaa2880214adab639c Author: Paul Eggert Date: Tue Sep 3 13:03:34 2019 -0700 Sync consing_until_gc with gc-cons-threshold Add watchers for gc-cons-threshold and gc-cons-percentage that update consing_until_gc accordingly. Suggested by Eli Zaretskii (Bug#37006#52). * src/alloc.c (consing_threshold, bump_consing_until_gc) (watch_gc_cons_threshold, watch_gc_cons_percentage): New functions. (garbage_collect_1): Use consing_threshold. (syms_of_alloc): Arrange to watch gc-cons-threshold and gc-cons-percentage. diff --git a/src/alloc.c b/src/alloc.c index 39964c4b29..5f8ef0a5dd 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -5781,6 +5781,68 @@ mark_and_sweep_weak_table_contents (void) } } +/* Return the number of bytes to cons between GCs, assuming + gc-cons-threshold is THRESHOLD and gc-cons-percentage is + GC_CONS_PERCENTAGE. */ +static intmax_t +consing_threshold (intmax_t threshold, Lisp_Object gc_cons_percentage) +{ + if (!NILP (Vmemory_full)) + return memory_full_cons_threshold; + else + { + threshold = max (threshold, GC_DEFAULT_THRESHOLD / 10); + if (FLOATP (gc_cons_percentage)) + { + double tot = (XFLOAT_DATA (gc_cons_percentage) + * total_bytes_of_live_objects ()); + if (threshold < tot) + { + if (tot < INTMAX_MAX) + threshold = tot; + else + threshold = INTMAX_MAX; + } + } + return threshold; + } +} + +/* Increment consing_until_gc by DIFF, avoiding overflow. */ +static Lisp_Object +bump_consing_until_gc (intmax_t diff) +{ + /* If consing_until_gc is negative leave it alone, since this prevents + negative integer overflow and a GC would have been done soon anyway. */ + if (0 <= consing_until_gc + && INT_ADD_WRAPV (consing_until_gc, diff, &consing_until_gc)) + consing_until_gc = INTMAX_MAX; + return Qnil; +} + +/* Watch changes to gc-cons-threshold. */ +static Lisp_Object +watch_gc_cons_threshold (Lisp_Object symbol, Lisp_Object newval, + Lisp_Object operation, Lisp_Object where) +{ + intmax_t new_threshold; + int diff = (INTEGERP (newval) && integer_to_intmax (newval, &new_threshold) + ? (consing_threshold (new_threshold, Vgc_cons_percentage) + - consing_threshold (gc_cons_threshold, Vgc_cons_percentage)) + : 0); + return bump_consing_until_gc (diff); +} + +/* Watch changes to gc-cons-percentage. */ +static Lisp_Object +watch_gc_cons_percentage (Lisp_Object symbol, Lisp_Object newval, + Lisp_Object operation, Lisp_Object where) +{ + int diff = (consing_threshold (consing_until_gc, newval) + - consing_threshold (consing_until_gc, Vgc_cons_percentage)); + return bump_consing_until_gc (diff); +} + /* Subroutine of Fgarbage_collect that does most of the work. */ static bool garbage_collect_1 (struct gcstat *gcst) @@ -5923,25 +5985,8 @@ garbage_collect_1 (struct gcstat *gcst) unblock_input (); - if (!NILP (Vmemory_full)) - consing_until_gc = memory_full_cons_threshold; - else - { - intmax_t threshold = max (gc_cons_threshold, GC_DEFAULT_THRESHOLD / 10); - if (FLOATP (Vgc_cons_percentage)) - { - double tot = (XFLOAT_DATA (Vgc_cons_percentage) - * total_bytes_of_live_objects ()); - if (threshold < tot) - { - if (tot < INTMAX_MAX) - threshold = tot; - else - threshold = INTMAX_MAX; - } - } - consing_until_gc = threshold; - } + consing_until_gc = consing_threshold (gc_cons_threshold, + Vgc_cons_percentage); if (garbage_collection_messages && NILP (Vmemory_full)) { @@ -7362,6 +7407,7 @@ do hash-consing of the objects allocated to pure space. */); DEFSYM (Qheap, "heap"); DEFSYM (QAutomatic_GC, "Automatic GC"); + DEFSYM (Qgc_cons_percentage, "gc-cons-percentage"); DEFSYM (Qgc_cons_threshold, "gc-cons-threshold"); DEFSYM (Qchar_table_extra_slots, "char-table-extra-slots"); @@ -7395,6 +7441,22 @@ N should be nonnegative. */); defsubr (&Smemory_info); defsubr (&Smemory_use_counts); defsubr (&Ssuspicious_object); + + Lisp_Object watcher; + + static union Aligned_Lisp_Subr Swatch_gc_cons_threshold = + {{{ PSEUDOVECTOR_FLAG | (PVEC_SUBR << PSEUDOVECTOR_AREA_BITS) }, + { .a4 = watch_gc_cons_threshold }, + 4, 4, "watch_gc_cons_threshold", 0, 0}}; + XSETSUBR (watcher, &Swatch_gc_cons_threshold.s); + Fadd_variable_watcher (Qgc_cons_threshold, watcher); + + static union Aligned_Lisp_Subr Swatch_gc_cons_percentage = + {{{ PSEUDOVECTOR_FLAG | (PVEC_SUBR << PSEUDOVECTOR_AREA_BITS) }, + { .a4 = watch_gc_cons_percentage }, + 4, 4, "watch_gc_cons_percentage", 0, 0}}; + XSETSUBR (watcher, &Swatch_gc_cons_percentage.s); + Fadd_variable_watcher (Qgc_cons_percentage, watcher); } #ifdef HAVE_X_WINDOWS commit c34dbd80e72204cd0ac65254ff3145dbd916f5c5 Author: Alan Mackenzie Date: Tue Sep 3 17:33:26 2019 +0000 Use left margin to hold "=>" to indicate current error in fringeless windows This applies to compilation-mode. It amends the fix for bug #36832. * lisp/progmodes/compile.el (compilation-arrow-overlay): renamed from overlay-arrow-overlay. (compilation-margin-string, compilation--dummy-string): New variables. (compilation-set-up-arrow-spec-in-margin) (compilation-tear-down-arrow-spec-in-margin): New functions. (compilation-set-overlay-arrow): Rewritten to use the new variables/functions. diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el index 09188dc14b..b7bd2243d9 100644 --- a/lisp/progmodes/compile.el +++ b/lisp/progmodes/compile.el @@ -2602,45 +2602,68 @@ column zero points to the current message." (point))) (set-window-point w mk)))) -(defvar-local overlay-arrow-overlay nil +(defvar-local compilation-arrow-overlay nil "Overlay with the before-string property of `overlay-arrow-string'. When non-nil, this overlay causes redisplay to display `overlay-arrow-string' at the overlay's start position.") +(defvar compilation-margin-string "=>" + "The string which will appear in the margin in compilation mode. +This must be two characters long; there should be no need to +change the default.") +(put-text-property 0 2 'face 'default compilation-margin-string) + +(defconst compilation--dummy-string + (propertize ">" 'display + `((margin left-margin) ,compilation-margin-string)) + "A string which is only a placeholder for compilation-margin-string. +Actual value is never used, only the text property.") + +(defun compilation-set-up-arrow-spec-in-margin () + "Set up compilation-arrow-overlay to display as an arrow in a margin." + (setq overlay-arrow-string "") + (setq compilation-arrow-overlay + (make-overlay overlay-arrow-position overlay-arrow-position)) + (overlay-put compilation-arrow-overlay + 'before-string compilation--dummy-string) + (set-window-margins (selected-window) (+ (or (car (window-margins)) 0) 2))) + +(defun compilation-tear-down-arrow-spec-in-margin () + "Restore compilation-arrow-overlay to not using the margin, which is removed." + (overlay-put compilation-arrow-overlay 'before-string nil) + (delete-overlay compilation-arrow-overlay) + (setq compilation-arrow-overlay nil) + (set-window-margins (selected-window) (- (car (window-margins)) 2))) + (defun compilation-set-overlay-arrow (w) "Set up, or switch off, the overlay-arrow for window W." - (with-current-buffer (window-buffer w) + (with-selected-window w ; So the later `goto-char' will work. (if (and (eq compilation-context-lines t) (equal (car (window-fringes w)) 0)) ; No left fringe - ;; Insert a "=>" before-string overlay at the beginning of the - ;; line pointed to by `overlay-arrow-position'. - (cond - ((overlayp overlay-arrow-overlay) - (when (not (eq (overlay-start overlay-arrow-overlay) - overlay-arrow-position)) - (if overlay-arrow-position - (progn - (move-overlay overlay-arrow-overlay + ;; Insert a before-string overlay at the beginning of the line + ;; pointed to by `overlay-arrow-position', such that it will + ;; display in a 2-character margin. + (progn + (cond + ((overlayp compilation-arrow-overlay) + (when (not (eq (overlay-start compilation-arrow-overlay) + overlay-arrow-position)) + (if overlay-arrow-position + (move-overlay compilation-arrow-overlay overlay-arrow-position overlay-arrow-position) - (setq overlay-arrow-string "=>") - (overlay-put overlay-arrow-overlay - 'before-string overlay-arrow-string)) - (delete-overlay overlay-arrow-overlay) - (setq overlay-arrow-overlay nil)))) - - (overlay-arrow-position - (setq overlay-arrow-overlay - (make-overlay overlay-arrow-position overlay-arrow-position)) - (setq overlay-arrow-string "=>") - (overlay-put overlay-arrow-overlay 'before-string overlay-arrow-string))) + (compilation-tear-down-arrow-spec-in-margin)))) + + (overlay-arrow-position + (compilation-set-up-arrow-spec-in-margin))) + ;; Ensure that the "=>" remains in the window by causing + ;; the window to be scrolled, if needed. + (goto-char (overlay-start compilation-arrow-overlay))) ;; `compilation-context-lines' isn't t, or we've got a left ;; fringe, so remove any overlay arrow. - (when (overlayp overlay-arrow-overlay) - (setq overlay-arrow-string "") - (delete-overlay overlay-arrow-overlay) - (setq overlay-arrow-overlay nil))))) + (when (overlayp compilation-arrow-overlay) + (compilation-tear-down-arrow-spec-in-margin))))) (defvar next-error-highlight-timer) commit ea5d591f29ba2e9e5d31da7ad450b958a4c9ca03 Author: Michael Albinus Date: Tue Sep 3 13:55:42 2019 +0200 Fix Bug#37202 * lisp/shadowfile.el (shadow-debug): New defvar. (shadow-read-files): Suppress error if there's no TODO file. * test/lisp/shadowfile-tests.el (shadow-debug): Set to nil. (shadow--tests-cleanup): New defun. Apply to all tests. (Bug#37202) (shadow-test06-literal-groups): Cleanup temp buffer. (shadow-test08-shadow-todo): Add debug messages. (top): Cleanup initially. diff --git a/lisp/shadowfile.el b/lisp/shadowfile.el index 07e7850665..4566ea19f8 100644 --- a/lisp/shadowfile.el +++ b/lisp/shadowfile.el @@ -165,6 +165,9 @@ created by `shadow-define-regexp-group'.") (defvar shadow-info-buffer nil) ; buf visiting shadow-info-file (defvar shadow-todo-buffer nil) ; buf visiting shadow-todo-file +(defvar shadow-debug nil + "Use for debug messages.") + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Syntactic sugar; General list and string manipulation ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -673,7 +676,7 @@ Return t unless files were locked; then return nil." (eval-buffer)) (when shadow-todo-file (set-buffer (setq shadow-todo-buffer - (find-file-noselect shadow-todo-file))) + (find-file-noselect shadow-todo-file 'nowarn))) (when (and (not (buffer-modified-p)) (file-newer-than-file-p (make-auto-save-file-name) shadow-todo-file)) diff --git a/test/lisp/shadowfile-tests.el b/test/lisp/shadowfile-tests.el index 2a777af472..5ab663c69b 100644 --- a/test/lisp/shadowfile-tests.el +++ b/test/lisp/shadowfile-tests.el @@ -64,6 +64,7 @@ "Temporary directory for Tramp tests.") (setq password-cache-expiry nil + shadow-debug nil tramp-verbose 0 tramp-message-show-message nil) @@ -79,6 +80,35 @@ (expand-file-name "shadow_todo_test" temporary-file-directory) "File to store the list of uncopied shadows in during tests.") +(defun shadow--tests-cleanup () + "Reset all `shadowfile' internals." + ;; Delete auto-saved files. + (with-current-buffer (find-file-noselect shadow-info-file 'nowarn) + (ignore-errors (delete-file (make-auto-save-file-name))) + (set-buffer-modified-p nil) + (kill-buffer)) + (with-current-buffer (find-file-noselect shadow-todo-file 'nowarn) + (ignore-errors (delete-file (make-auto-save-file-name))) + (set-buffer-modified-p nil) + (kill-buffer)) + ;; Delete buffers. + (when (buffer-live-p shadow-info-buffer) + (with-current-buffer shadow-info-buffer + (set-buffer-modified-p nil) + (kill-buffer))) + (when (buffer-live-p shadow-todo-buffer) + (with-current-buffer shadow-todo-buffer + (set-buffer-modified-p nil) + (kill-buffer))) + ;; Delete files. + (ignore-errors (delete-file shadow-info-file)) + (ignore-errors (delete-file shadow-todo-file)) + ;; Reset variables. + (setq shadow-info-buffer nil + shadow-hashtable nil + shadow-todo-buffer nil + shadow-files-to-copy nil)) + (ert-deftest shadow-test00-clusters () "Check cluster definitions. Per definition, all files are identical on the different hosts of @@ -101,11 +131,8 @@ guaranteed by the originator of a cluster definition." ((symbol-function 'read-string) (lambda (&rest args) (pop mocked-input)))) - ;; Cleanup. - (when (file-exists-p shadow-info-file) - (delete-file shadow-info-file)) - (when (file-exists-p shadow-todo-file) - (delete-file shadow-todo-file)) + ;; Cleanup. + (shadow--tests-cleanup) ;; Define a cluster. (setq cluster "cluster" @@ -198,10 +225,7 @@ guaranteed by the originator of a cluster definition." ;; Cleanup. (with-current-buffer (messages-buffer) (widen)) - (when (file-exists-p shadow-info-file) - (delete-file shadow-info-file)) - (when (file-exists-p shadow-todo-file) - (delete-file shadow-todo-file))))) + (shadow--tests-cleanup)))) (ert-deftest shadow-test01-sites () "Check site definitions. @@ -224,10 +248,7 @@ guaranteed by the originator of a cluster definition." (lambda (&rest args) (pop mocked-input)))) ;; Cleanup. - (when (file-exists-p shadow-info-file) - (delete-file shadow-info-file)) - (when (file-exists-p shadow-todo-file) - (delete-file shadow-todo-file)) + (shadow--tests-cleanup) ;; Define a cluster. (setq cluster1 "cluster1" @@ -308,10 +329,7 @@ guaranteed by the originator of a cluster definition." (shadow-site-match (shadow-site-primary cluster1) cluster2))) ;; Cleanup. - (when (file-exists-p shadow-info-file) - (delete-file shadow-info-file)) - (when (file-exists-p shadow-todo-file) - (delete-file shadow-todo-file))))) + (shadow--tests-cleanup)))) (ert-deftest shadow-test02-files () "Check file manipulation functions." @@ -325,10 +343,7 @@ guaranteed by the originator of a cluster definition." (unwind-protect (progn ;; Cleanup. - (when (file-exists-p shadow-info-file) - (delete-file shadow-info-file)) - (when (file-exists-p shadow-todo-file) - (delete-file shadow-todo-file)) + (shadow--tests-cleanup) ;; Define a cluster. (setq cluster "cluster" @@ -384,10 +399,7 @@ guaranteed by the originator of a cluster definition." (should-not (shadow-local-file nil))) ;; Cleanup. - (when (file-exists-p shadow-info-file) - (delete-file shadow-info-file)) - (when (file-exists-p shadow-todo-file) - (delete-file shadow-todo-file))))) + (shadow--tests-cleanup)))) (ert-deftest shadow-test03-expand-cluster-in-file-name () "Check canonical file name of a cluster or site." @@ -401,10 +413,7 @@ guaranteed by the originator of a cluster definition." (unwind-protect (progn ;; Cleanup. - (when (file-exists-p shadow-info-file) - (delete-file shadow-info-file)) - (when (file-exists-p shadow-todo-file) - (delete-file shadow-todo-file)) + (shadow--tests-cleanup) ;; Define a cluster. (setq cluster "cluster" @@ -455,10 +464,7 @@ guaranteed by the originator of a cluster definition." (concat primary file1)))) ;; Cleanup. - (when (file-exists-p shadow-info-file) - (delete-file shadow-info-file)) - (when (file-exists-p shadow-todo-file) - (delete-file shadow-todo-file))))) + (shadow--tests-cleanup)))) (ert-deftest shadow-test04-contract-file-name () "Check canonical file name of a cluster or site." @@ -472,10 +478,7 @@ guaranteed by the originator of a cluster definition." (unwind-protect (progn ;; Cleanup. - (when (file-exists-p shadow-info-file) - (delete-file shadow-info-file)) - (when (file-exists-p shadow-todo-file) - (delete-file shadow-todo-file)) + (shadow--tests-cleanup) ;; Define a cluster. (setq cluster "cluster" @@ -516,10 +519,7 @@ guaranteed by the originator of a cluster definition." (concat "/cluster:" file)))) ;; Cleanup. - (when (file-exists-p shadow-info-file) - (delete-file shadow-info-file)) - (when (file-exists-p shadow-todo-file) - (delete-file shadow-todo-file))))) + (shadow--tests-cleanup)))) (ert-deftest shadow-test05-file-match () "Check `shadow-same-site' and `shadow-file-match'." @@ -533,10 +533,7 @@ guaranteed by the originator of a cluster definition." (unwind-protect (progn ;; Cleanup. - (when (file-exists-p shadow-info-file) - (delete-file shadow-info-file)) - (when (file-exists-p shadow-todo-file) - (delete-file shadow-todo-file)) + (shadow--tests-cleanup) ;; Define a cluster. (setq cluster "cluster" @@ -575,10 +572,7 @@ guaranteed by the originator of a cluster definition." file))) ;; Cleanup. - (when (file-exists-p shadow-info-file) - (delete-file shadow-info-file)) - (when (file-exists-p shadow-todo-file) - (delete-file shadow-todo-file))))) + (shadow--tests-cleanup)))) (ert-deftest shadow-test06-literal-groups () "Check literal group definitions." @@ -598,10 +592,7 @@ guaranteed by the originator of a cluster definition." (lambda (&rest args) (pop mocked-input)))) ;; Cleanup. - (when (file-exists-p shadow-info-file) - (delete-file shadow-info-file)) - (when (file-exists-p shadow-todo-file) - (delete-file shadow-todo-file)) + (shadow--tests-cleanup) ;; Define clusters. (setq cluster1 "cluster1" @@ -627,7 +618,8 @@ guaranteed by the originator of a cluster definition." mocked-input `(,cluster1 ,file1 ,cluster2 ,file2 ,(kbd "RET"))) (with-temp-buffer (set-visited-file-name file1) - (call-interactively 'shadow-define-literal-group)) + (call-interactively 'shadow-define-literal-group) + (set-buffer-modified-p nil)) ;; `shadow-literal-groups' is a list of lists. (should (consp shadow-literal-groups)) @@ -640,10 +632,7 @@ guaranteed by the originator of a cluster definition." (car shadow-literal-groups)))) ;; Cleanup. - (when (file-exists-p shadow-info-file) - (delete-file shadow-info-file)) - (when (file-exists-p shadow-todo-file) - (delete-file shadow-todo-file))))) + (shadow--tests-cleanup)))) (ert-deftest shadow-test07-regexp-groups () "Check regexp group definitions." @@ -663,10 +652,7 @@ guaranteed by the originator of a cluster definition." (lambda (&rest args) (pop mocked-input)))) ;; Cleanup. - (when (file-exists-p shadow-info-file) - (delete-file shadow-info-file)) - (when (file-exists-p shadow-todo-file) - (delete-file shadow-todo-file)) + (shadow--tests-cleanup) ;; Define clusters. (setq cluster1 "cluster1" @@ -707,10 +693,7 @@ guaranteed by the originator of a cluster definition." (car shadow-regexp-groups)))) ;; Cleanup. - (when (file-exists-p shadow-info-file) - (delete-file shadow-info-file)) - (when (file-exists-p shadow-todo-file) - (delete-file shadow-todo-file))))) + (shadow--tests-cleanup)))) (ert-deftest shadow-test08-shadow-todo () "Check that needed shadows are added to todo." @@ -728,22 +711,23 @@ guaranteed by the originator of a cluster definition." (unwind-protect (progn ;; Cleanup. - (when (file-exists-p shadow-info-file) - (delete-file shadow-info-file)) - (when (file-exists-p shadow-todo-file) - (delete-file shadow-todo-file)) + (shadow--tests-cleanup) ;; Define clusters. (setq cluster1 "cluster1" primary shadow-system-name regexp (shadow-regexp-superquote primary)) (shadow-set-cluster cluster1 primary regexp) + (when shadow-debug + (message "%s %s %s %s" cluster1 primary regexp shadow-clusters)) (setq cluster2 "cluster2" primary (file-remote-p shadow-test-remote-temporary-file-directory) regexp (shadow-regexp-superquote primary)) (shadow-set-cluster cluster2 primary regexp) + (when shadow-debug + (message "%s %s %s %s" cluster2 primary regexp shadow-clusters)) ;; Define a literal group. (setq file @@ -751,12 +735,19 @@ guaranteed by the originator of a cluster definition." (expand-file-name "shadowfile-tests" temporary-file-directory)) shadow-literal-groups `((,(concat "/cluster1:" file) ,(concat "/cluster2:" file)))) + (when shadow-debug + (message "%s %s" file shadow-literal-groups)) ;; Save file from "cluster1" definition. (with-temp-buffer (set-visited-file-name file) (insert "foo") (save-buffer)) + (when shadow-debug + (message + "%s %s" + (cons file (shadow-contract-file-name (concat "/cluster2:" file))) + shadow-files-to-copy)) (should (member (cons file (shadow-contract-file-name (concat "/cluster2:" file))) @@ -767,6 +758,13 @@ guaranteed by the originator of a cluster definition." (set-visited-file-name (concat (shadow-site-primary cluster2) file)) (insert "foo") (save-buffer)) + (when shadow-debug + (message + "%s %s" + (cons + (concat (shadow-site-primary cluster2) file) + (shadow-contract-file-name (concat "/cluster1:" file))) + shadow-files-to-copy)) (should (member (cons @@ -781,12 +779,19 @@ guaranteed by the originator of a cluster definition." (shadow-regexp-superquote file)) ,(concat (shadow-site-primary cluster2) (shadow-regexp-superquote file))))) + (when shadow-debug + (message "%s %s" file shadow-regexp-groups)) ;; Save file from "cluster1" definition. (with-temp-buffer (set-visited-file-name file) (insert "foo") (save-buffer)) + (when shadow-debug + (message + "%s %s" + (cons file (shadow-contract-file-name (concat "/cluster2:" file))) + shadow-files-to-copy)) (should (member (cons file (shadow-contract-file-name (concat "/cluster2:" file))) @@ -797,6 +802,13 @@ guaranteed by the originator of a cluster definition." (set-visited-file-name (concat (shadow-site-primary cluster2) file)) (insert "foo") (save-buffer)) + (when shadow-debug + (message + "%s %s" + (cons + (concat (shadow-site-primary cluster2) file) + (shadow-contract-file-name (concat "/cluster1:" file))) + shadow-files-to-copy)) (should (member (cons @@ -805,16 +817,9 @@ guaranteed by the originator of a cluster definition." shadow-files-to-copy))) ;; Cleanup. - (when (file-exists-p shadow-info-file) - (delete-file shadow-info-file)) - (when (file-exists-p shadow-todo-file) - (delete-file shadow-todo-file)) - (ignore-errors - (when (file-exists-p file) - (delete-file file))) - (ignore-errors - (when (file-exists-p (concat (shadow-site-primary cluster2) file)) - (delete-file (concat (shadow-site-primary cluster2) file))))))) + (ignore-errors (delete-file file)) + (ignore-errors (delete-file (concat (shadow-site-primary cluster2) file))) + (shadow--tests-cleanup)))) (ert-deftest shadow-test09-shadow-copy-files () "Check that needed shadow files are copied." @@ -832,12 +837,7 @@ guaranteed by the originator of a cluster definition." (unwind-protect (progn ;; Cleanup. - (when (file-exists-p shadow-info-file) - (delete-file shadow-info-file)) - (when (file-exists-p shadow-todo-file) - (delete-file shadow-todo-file)) - (when (buffer-live-p shadow-todo-buffer) - (with-current-buffer shadow-todo-buffer (erase-buffer))) + (shadow--tests-cleanup) ;; Define clusters. (setq cluster1 "cluster1" @@ -894,16 +894,9 @@ guaranteed by the originator of a cluster definition." ;; Cleanup. (remove-function (symbol-function 'write-region) "write-region-mock") - (when (file-exists-p shadow-info-file) - (delete-file shadow-info-file)) - (when (file-exists-p shadow-todo-file) - (delete-file shadow-todo-file)) - (ignore-errors - (when (file-exists-p file) - (delete-file file))) - (ignore-errors - (when (file-exists-p (concat (shadow-site-primary cluster2) file)) - (delete-file (concat (shadow-site-primary cluster2) file))))))) + (ignore-errors (delete-file file)) + (ignore-errors (delete-file (concat (shadow-site-primary cluster2) file))) + (shadow--tests-cleanup)))) (defun shadowfile-test-all (&optional interactive) "Run all tests for \\[shadowfile]." @@ -914,6 +907,7 @@ guaranteed by the originator of a cluster definition." (let ((shadow-info-file shadow-test-info-file) (shadow-todo-file shadow-test-todo-file)) + (shadow--tests-cleanup) (shadow-initialize)) (provide 'shadowfile-tests) commit fda015e7b82a1ec3d1cb075799a67772744ce6c1 Author: Paul Eggert Date: Mon Sep 2 12:37:52 2019 -0700 Update from Gnulib This incorporates: 2019-08-25 intprops.h, verify.h: port better to clang 2019-08-21 New strip-trailing-space option for srclist-update * .gitattributes: Remove doc/misc/texinfo.tex special case, which is no longer needed now that Gnulib trims blank-at-eol. * build-aux/install-sh, doc/misc/texinfo.tex, lib/intprops.h: * lib/regex_internal.c, lib/verify.h: Copy from Gnulib. diff --git a/.gitattributes b/.gitattributes index 65a943f695..e1fd4b12a8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -31,9 +31,6 @@ test/manual/etags/html-src/algrthms.html whitespace=cr-at-eol # The todo-mode file format includes trailing whitespace. *.tod[aorty] -whitespace=blank-at-eol -# The upstream maintainer does not want to remove trailing whitespace. -doc/misc/texinfo.tex -whitespace=blank-at-eol - # Some files should not be treated as text when diffing or merging. *.cur binary *.gpg binary diff --git a/build-aux/install-sh b/build-aux/install-sh index 8175c640fe..20d8b2eaea 100755 --- a/build-aux/install-sh +++ b/build-aux/install-sh @@ -451,7 +451,18 @@ do trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + (umask $cp_umask && + { test -z "$stripcmd" || { + # Create $dsttmp read-write so that cp doesn't create it read-only, + # which would cause strip to fail. + if test -z "$doit"; then + : >"$dsttmp" # No need to fork-exec 'touch'. + else + $doit touch "$dsttmp" + fi + } + } && + $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # diff --git a/doc/misc/texinfo.tex b/doc/misc/texinfo.tex index ed3f0ee98f..d2e895f362 100644 --- a/doc/misc/texinfo.tex +++ b/doc/misc/texinfo.tex @@ -1,9 +1,9 @@ % texinfo.tex -- TeX macros to handle Texinfo files. -% +% % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % -\def\texinfoversion{2019-06-01.23} +\def\texinfoversion{2019-08-18.20} % % Copyright 1985, 1986, 1988, 1990-2019 Free Software Foundation, Inc. % @@ -218,7 +218,7 @@ % @errormsg{MSG}. Do the index-like expansions on MSG, but if things % aren't perfect, it's not the end of the world, being an error message, % after all. -% +% \def\errormsg{\begingroup \indexnofonts \doerrormsg} \def\doerrormsg#1{\errmessage{#1}} @@ -323,9 +323,9 @@ % the output routine. The saved contents are valid until we actually % \shipout a page. % -% (We used to run a short output routine to actually set \topmark and -% \firstmark to the right values, but if this was called with an empty page -% containing whatsits for writing index entries, the whatsits would be thrown +% (We used to run a short output routine to actually set \topmark and +% \firstmark to the right values, but if this was called with an empty page +% containing whatsits for writing index entries, the whatsits would be thrown % away and the index auxiliary file would remain empty.) % \newtoks\savedtopmark @@ -365,7 +365,7 @@ \let\thischapterheading\thischapter \else % \thischapterheading is the same as \thischapter except it is blank - % for the first page of a chapter. This is to prevent the chapter name + % for the first page of a chapter. This is to prevent the chapter name % being shown twice. \def\thischapterheading{}% \fi @@ -448,7 +448,7 @@ }% } -% First remove any @comment, then any @c comment. Pass the result on to +% First remove any @comment, then any @c comment. Pass the result on to % \argcheckspaces. \def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm} \def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm} @@ -1137,7 +1137,7 @@ % for display in the outlines, and in other places. Thus, we have to % double any backslashes. Otherwise, a name like "\node" will be % interpreted as a newline (\n), followed by o, d, e. Not good. -% +% % See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and % related messages. The final outcome is that it is up to the TeX user % to double the backslashes and otherwise make the string valid, so @@ -1442,7 +1442,7 @@ % their "best" equivalent, based on the @documentencoding. Too % much work for too little return. Just use the ASCII equivalents % we use for the index sort strings. - % + % \indexnofonts \setupdatafile % We can have normal brace characters in the PDF outlines, unlike @@ -2726,7 +2726,7 @@ } % Commands to set the quote options. -% +% \parseargdef\codequoteundirected{% \def\temp{#1}% \ifx\temp\onword @@ -2767,7 +2767,7 @@ % If we are in a monospaced environment, however, 1) always use \ttsl, % and 2) do not add an italic correction. \def\dosmartslant#1#2{% - \ifusingtt + \ifusingtt {{\ttsl #2}\let\next=\relax}% {\def\next{{#1#2}\futurelet\next\smartitaliccorrection}}% \next @@ -2914,14 +2914,14 @@ \gdef\codedash{\futurelet\next\codedashfinish} \gdef\codedashfinish{% \normaldash % always output the dash character itself. - % + % % Now, output a discretionary to allow a line break, unless % (a) the next character is a -, or % (b) the preceding character is a -. % E.g., given --posix, we do not want to allow a break after either -. % Given --foo-bar, we do want to allow a break between the - and the b. \ifx\next\codedash \else - \ifx\codedashprev\codedash + \ifx\codedashprev\codedash \else \discretionary{}{}{}\fi \fi % we need the space after the = for the case when \next itself is a @@ -3003,7 +3003,7 @@ % For pdfTeX and LuaTeX \ifurefurlonlylink % PDF plus option to not display url, show just arg - \unhbox0 + \unhbox0 \else % PDF, normally display both arg and url for consistency, % visibility, if the pdf is eventually used to print, etc. @@ -3016,7 +3016,7 @@ % For XeTeX \ifurefurlonlylink % PDF plus option to not display url, show just arg - \unhbox0 + \unhbox0 \else % PDF, normally display both arg and url for consistency, % visibility, if the pdf is eventually used to print, etc. @@ -3074,10 +3074,10 @@ } } -% By default we'll break after the special characters, but some people like to -% break before the special chars, so allow that. Also allow no breaking at +% By default we'll break after the special characters, but some people like to +% break before the special chars, so allow that. Also allow no breaking at % all, for manual control. -% +% \parseargdef\urefbreakstyle{% \def\txiarg{#1}% \ifx\txiarg\wordnone @@ -3095,7 +3095,7 @@ \def\wordbefore{before} \def\wordnone{none} -% Allow a ragged right output to aid breaking long URL's. Putting stretch in +% Allow a ragged right output to aid breaking long URL's. Putting stretch in % between characters of the URL doesn't look good. \def\urefallowbreak{% \hskip 0pt plus 4 em\relax @@ -3299,7 +3299,7 @@ % @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}. % Ignore unless FMTNAME == tex; then it is like @iftex and @tex, % except specified as a normal braced arg, so no newlines to worry about. -% +% \def\outfmtnametex{tex} % \long\def\inlinefmt#1{\doinlinefmt #1,\finish} @@ -3307,7 +3307,7 @@ \def\inlinefmtname{#1}% \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\fi } -% +% % @inlinefmtifelse{FMTNAME,THEN-TEXT,ELSE-TEXT} expands THEN-TEXT if % FMTNAME is tex, else ELSE-TEXT. \long\def\inlinefmtifelse#1{\doinlinefmtifelse #1,,,\finish} @@ -3323,7 +3323,7 @@ % *right* brace they would have to use a command anyway, so they may as % well use a command to get a left brace too. We could re-use the % delimiter character idea from \verb, but it seems like overkill. -% +% \long\def\inlineraw{\tex \doinlineraw} \long\def\doinlineraw#1{\doinlinerawtwo #1,\finish} \def\doinlinerawtwo#1,#2,\finish{% @@ -3600,7 +3600,7 @@ % for non-CM glyphs. That is ec* for regular text and tc* for the text % companion symbols (LaTeX TS1 encoding). Both are part of the ec % package and follow the same conventions. -% +% \def\ecfont{\etcfont{e}} \def\tcfont{\etcfont{t}} % @@ -3672,7 +3672,7 @@ after the title page.}}% \def\setshortcontentsaftertitlepage{% \errmessage{@setshortcontentsaftertitlepage has been removed as a Texinfo - command; move your @shortcontents and @contents commands if you + command; move your @shortcontents and @contents commands if you want the contents after the title page.}}% \parseargdef\shorttitlepage{% @@ -3727,7 +3727,7 @@ % don't worry much about spacing, ragged right. This should be used % inside a \vbox, and fonts need to be set appropriately first. \par should % be specified before the end of the \vbox, since a vbox is a group. -% +% \def\raggedtitlesettings{% \rm \hyphenpenalty=10000 @@ -4350,7 +4350,7 @@ } % multitable-only commands. -% +% % @headitem starts a heading row, which we typeset in bold. Assignments % have to be global since we are inside the implicit group of an % alignment entry. \everycr below resets \everytab so we don't have to @@ -4669,13 +4669,13 @@ % Like \expandablevalue, but completely expandable (the \message in the % definition above operates at the execution level of TeX). Used when % writing to auxiliary files, due to the expansion that \write does. -% If flag is undefined, pass through an unexpanded @value command: maybe it +% If flag is undefined, pass through an unexpanded @value command: maybe it % will be set by the time it is read back in. % % NB flag names containing - or _ may not work here. \def\dummyvalue#1{% \expandafter\ifx\csname SET#1\endcsname\relax - \noexpand\value{#1}% + \string\value{#1}% \else \csname SET#1\endcsname \fi @@ -4693,7 +4693,7 @@ % @ifset VAR ... @end ifset reads the `...' iff VAR has been defined % with @set. -% +% % To get the special treatment we need for `@end ifset,' we call % \makecond and then redefine. % @@ -4726,7 +4726,7 @@ % without the @) is in fact defined. We can only feasibly check at the % TeX level, so something like `mathcode' is going to considered % defined even though it is not a Texinfo command. -% +% \makecond{ifcommanddefined} \def\ifcommanddefined{\parsearg{\doifcmddefined{\let\next=\ifcmddefinedfail}}} % @@ -4834,8 +4834,8 @@ \def\docodeindex#1{\edef\indexname{#1}\parsearg\docodeindexxxx} \def\docodeindexxxx #1{\doind{\indexname}{\code{#1}}} - -% Used for the aux, toc and index files to prevent expansion of Texinfo + +% Used for the aux, toc and index files to prevent expansion of Texinfo % commands. % \def\atdummies{% @@ -5180,7 +5180,7 @@ } \def\defglyph#1#2{\def#1##1{#2}} % see above - + % #1 is the index name, #2 is the entry text. @@ -5207,7 +5207,7 @@ \ifx\suffix\indexisfl\def\suffix{f1}\fi % Open the file \immediate\openout\csname#1indfile\endcsname \jobname.\suffix - % Using \immediate above here prevents an object entering into the current + % Using \immediate above here prevents an object entering into the current % box, which could confound checks such as those in \safewhatsit for % preceding skips. \typeout{Writing index file \jobname.\suffix}% @@ -5259,7 +5259,7 @@ \ifx\segment\isfinish \else % - % Fully expand the segment, throwing away any @sortas directives, and + % Fully expand the segment, throwing away any @sortas directives, and % trim spaces. \edef\trimmed{\segment}% \edef\trimmed{\expandafter\eatspaces\expandafter{\trimmed}}% @@ -5317,12 +5317,12 @@ % the current value of \escapechar. \def\escapeisbackslash{\escapechar=`\\} -% Use \ in index files by default. texi2dvi didn't support @ as the escape -% character (as it checked for "\entry" in the files, and not "@entry"). When -% the new version of texi2dvi has had a chance to become more prevalent, then -% the escape character can change back to @ again. This should be an easy -% change to make now because both @ and \ are only used as escape characters in -% index files, never standing for themselves. +% Use \ in index files by default. texi2dvi didn't support @ as the escape +% character (as it checked for "\entry" in the files, and not "@entry"). When +% the new version of texi2dvi has had a chance to become more prevalent, then +% the escape character can change back to @ again. This should be an easy +% change to make now because both @ and \ are only used as escape characters in +% index files, never standing for themselves. % \set txiindexescapeisbackslash @@ -5342,7 +5342,7 @@ \def\}{\rbracechar{}}% \uccode`\~=`\\ \uppercase{\def~{\backslashchar{}}}% % - % Split the entry into primary entry and any subentries, and get the index + % Split the entry into primary entry and any subentries, and get the index % sort key. \splitindexentry\indextext % @@ -5523,18 +5523,18 @@ \uccode`\~=`\\ \uppercase{\if\noexpand~}\noexpand#1 \expandafter\ifx\csname SETtxiskipindexfileswithbackslash\endcsname\relax \errmessage{% -ERROR: A sorted index file in an obsolete format was skipped. +ERROR: A sorted index file in an obsolete format was skipped. To fix this problem, please upgrade your version of 'texi2dvi' or 'texi2pdf' to that at . -If you are using an old version of 'texindex' (part of the Texinfo +If you are using an old version of 'texindex' (part of the Texinfo distribution), you may also need to upgrade to a newer version (at least 6.0). You may be able to typeset the index if you run 'texindex \jobname.\indexname' yourself. -You could also try setting the 'txiindexescapeisbackslash' flag by +You could also try setting the 'txiindexescapeisbackslash' flag by running a command like -'texi2dvi -t "@set txiindexescapeisbackslash" \jobname.texi'. If you do +'texi2dvi -t "@set txiindexescapeisbackslash" \jobname.texi'. If you do this, Texinfo will try to use index files in the old format. -If you continue to have problems, deleting the index files and starting again +If you continue to have problems, deleting the index files and starting again might help (with 'rm \jobname.?? \jobname.??s')% }% \else @@ -5603,7 +5603,7 @@ % bottom of a column to reduce an increase in inter-line spacing. \nobreak \vskip 0pt plus 5\baselineskip - \penalty -300 + \penalty -300 \vskip 0pt plus -5\baselineskip % % Typeset the initial. Making this add up to a whole number of @@ -5719,7 +5719,7 @@ \advance\dimen@ii by 1\dimen@i \ifdim\wd\boxA > \dimen@ii % If the entry doesn't fit in one line \ifdim\dimen@ > 0.8\dimen@ii % due to long index text - % Try to split the text roughly evenly. \dimen@ will be the length of + % Try to split the text roughly evenly. \dimen@ will be the length of % the first line. \dimen@ = 0.7\dimen@ \dimen@ii = \hsize @@ -5927,7 +5927,7 @@ \newbox\balancedcolumns \setbox\balancedcolumns=\vbox{shouldnt see this}% % -% Only called for the last of the double column material. \doublecolumnout +% Only called for the last of the double column material. \doublecolumnout % does the others. \def\balancecolumns{% \setbox0 = \vbox{\unvbox\PAGE}% like \box255 but more efficient, see p.120. @@ -5955,7 +5955,7 @@ }% % Now the left column is in box 1, and the right column in box 3. % - % Check whether the left column has come out higher than the page itself. + % Check whether the left column has come out higher than the page itself. % (Note that we have doubled \vsize for the double columns, so % the actual height of the page is 0.5\vsize). \ifdim2\ht1>\vsize @@ -6252,7 +6252,7 @@ \let\top\unnumbered % Sections. -% +% \outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz \def\seczzz#1{% \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 @@ -6275,7 +6275,7 @@ } % Subsections. -% +% % normally calls numberedsubseczzz: \outer\parseargdef\numberedsubsec{\numhead2{#1}} \def\numberedsubseczzz#1{% @@ -6300,7 +6300,7 @@ } % Subsubsections. -% +% % normally numberedsubsubseczzz: \outer\parseargdef\numberedsubsubsec{\numhead3{#1}} \def\numberedsubsubseczzz#1{% @@ -7358,7 +7358,7 @@ % @indentedblock is like @quotation, but indents only on the left and % has no optional argument. -% +% \makedispenvdef{indentedblock}{\indentedblockstart} % \def\indentedblockstart{% @@ -7658,7 +7658,7 @@ % @deftypefnnewline on|off says whether the return type of typed functions % are printed on their own line. This affects @deftypefn, @deftypefun, % @deftypeop, and @deftypemethod. -% +% \parseargdef\deftypefnnewline{% \def\temp{#1}% \ifx\temp\onword @@ -7677,8 +7677,8 @@ % \dosubind {index}{topic}{subtopic} % % If SUBTOPIC is present, precede it with a space, and call \doind. -% (At some time during the 20th century, this made a two-level entry in an -% index such as the operation index. Nobody seemed to notice the change in +% (At some time during the 20th century, this made a two-level entry in an +% index such as the operation index. Nobody seemed to notice the change in % behaviour though.) \def\dosubind#1#2#3{% \def\thirdarg{#3}% @@ -7853,7 +7853,7 @@ \tclose{\temp}% typeset the return type \ifrettypeownline % put return type on its own line; prohibit line break following: - \hfil\vadjust{\nobreak}\break + \hfil\vadjust{\nobreak}\break \else \space % type on same line, so just followed by a space \fi @@ -8000,7 +8000,7 @@ \scantokens{#1@comment}% % % The \comment is to remove the \newlinechar added by \scantokens, and - % can be noticed by \parsearg. Note \c isn't used because this means cedilla + % can be noticed by \parsearg. Note \c isn't used because this means cedilla % in math mode. } @@ -8201,7 +8201,7 @@ % list to some hook where the argument is to be expanded. If there are % less than 10 arguments that hook is to be replaced by ##N where N % is the position in that list, that is to say the macro arguments are to be -% defined `a la TeX in the macro body. +% defined `a la TeX in the macro body. % % That gets used by \mbodybackslash (above). % @@ -8232,8 +8232,8 @@ % % Read recursive and nonrecursive macro bodies. (They're different since % rec and nonrec macros end differently.) -% -% We are in \macrobodyctxt, and the \xdef causes backslashshes in the macro +% +% We are in \macrobodyctxt, and the \xdef causes backslashshes in the macro % body to be transformed. % Set \macrobody to the body of the macro, and call \defmacro. % @@ -8267,7 +8267,7 @@ % twice the \macarg.BLAH macros does not cost too much processing power. \def\parsemmanyargdef@@#1,{% \if#1;\let\next=\relax - \else + \else \let\next=\parsemmanyargdef@@ \edef\tempb{\eatspaces{#1}}% \expandafter\def\expandafter\tempa @@ -8352,7 +8352,7 @@ % Replace arguments by their values in the macro body, and place the result % in macro \@tempa. -% +% \def\macvalstoargs@{% % To do this we use the property that token registers that are \the'ed % within an \edef expand only once. So we are going to place all argument @@ -8376,9 +8376,9 @@ \expandafter\def\expandafter\@tempa\expandafter{\@tempc}% } -% Define the named-macro outside of this group and then close this group. -% -\def\macargexpandinbody@{% +% Define the named-macro outside of this group and then close this group. +% +\def\macargexpandinbody@{% \expandafter \endgroup \macargdeflist@ @@ -8416,7 +8416,7 @@ } % Trailing missing arguments are set to empty. -% +% \def\setemptyargvalues@{% \ifx\paramlist\nilm@ \let\next\macargexpandinbody@ @@ -8493,7 +8493,7 @@ \else % at most 9 \ifnum\paramno<10\relax % @MACNAME sets the context for reading the macro argument - % @MACNAME@@ gets the argument, processes backslashes and appends a + % @MACNAME@@ gets the argument, processes backslashes and appends a % comma. % @MACNAME@@@ removes braces surrounding the argument list. % @MACNAME@@@@ scans the macro body with arguments substituted. @@ -8537,11 +8537,11 @@ % Call #1 with a list of tokens #2, with any doubled backslashes in #2 % compressed to one. % -% This implementation works by expansion, and not execution (so we cannot use -% \def or similar). This reduces the risk of this failing in contexts where -% complete expansion is done with no execution (for example, in writing out to +% This implementation works by expansion, and not execution (so we cannot use +% \def or similar). This reduces the risk of this failing in contexts where +% complete expansion is done with no execution (for example, in writing out to % an auxiliary file for an index entry). -% +% % State is kept in the input stream: the argument passed to % @look_ahead, @gobble_and_check_finish and @add_segment is % @@ -8563,11 +8563,11 @@ % #3 - NEXT_TOKEN % #4 used to look ahead % -% If the next token is not a backslash, process the rest of the argument; +% If the next token is not a backslash, process the rest of the argument; % otherwise, remove the next token. @gdef@look_ahead#1!#2#3#4{% @ifx#4\% - @expandafter@gobble_and_check_finish + @expandafter@gobble_and_check_finish @else @expandafter@add_segment @fi#1!{#2}#4#4% @@ -8591,9 +8591,9 @@ % #3 - NEXT_TOKEN % #4 is input stream until next backslash % -% Input stream is either at the start of the argument, or just after a -% backslash sequence, either a lone backslash, or a doubled backslash. -% NEXT_TOKEN contains the first token in the input stream: if it is \finish, +% Input stream is either at the start of the argument, or just after a +% backslash sequence, either a lone backslash, or a doubled backslash. +% NEXT_TOKEN contains the first token in the input stream: if it is \finish, % finish; otherwise, append to ARG_RESULT the segment of the argument up until % the next backslash. PENDING_BACKSLASH contains a backslash to represent % a backslash just before the start of the input stream that has not been @@ -8605,13 +8605,13 @@ % append the pending backslash to the result, followed by the next segment @expandafter@is_fi@look_ahead#1#2#4!{\}@fi % this @fi is discarded by @look_ahead. - % we can't get rid of it with \expandafter because we don't know how + % we can't get rid of it with \expandafter because we don't know how % long #4 is. } % #1 - THE_MACRO % #2 - ARG_RESULT -% #3 discards the res of the conditional in @add_segment, and @is_fi ends the +% #3 discards the res of the conditional in @add_segment, and @is_fi ends the % conditional. @gdef@call_the_macro#1#2!#3@fi{@is_fi #1{#2}} @@ -8623,7 +8623,7 @@ % for reading the argument (slightly different in the two cases). Then, % to read the argument, in the whole-line case, it then calls the regular % \parsearg MAC; in the lbrace case, it calls \passargtomacro MAC. -% +% \def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx} \def\braceorlinexxx{% \ifx\nchar\bgroup @@ -8677,7 +8677,7 @@ % Used so that the @top node doesn't have to be wrapped in an @ifnottex % conditional. -% \doignore goes to more effort to skip nested conditionals but we don't need +% \doignore goes to more effort to skip nested conditionals but we don't need % that here. \def\omittopnode{% \ifx\lastnode\wordTop @@ -8685,7 +8685,7 @@ } \def\wordTop{Top} -% Until the next @node or @bye command, divert output to a box that is not +% Until the next @node or @bye command, divert output to a box that is not % output. \def\ignorenode{\setbox\dummybox\vbox\bgroup\def\node{\egroup\node}% \ignorenodebye @@ -8752,7 +8752,7 @@ % automatically in xrefs, if the third arg is not explicitly specified. % This was provided as a "secret" @set xref-automatic-section-title % variable, now it's official. -% +% \parseargdef\xrefautomaticsectiontitle{% \def\temp{#1}% \ifx\temp\onword @@ -8768,7 +8768,7 @@ \fi\fi } -% +% % @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is % the node name, #2 the name of the Info cross-reference, #3 the printed % node name, #4 the name of the Info file, #5 the name of the printed @@ -8921,24 +8921,24 @@ \fi \else % node/anchor (non-float) references. - % + % % If we use \unhbox to print the node names, TeX does not insert % empty discretionaries after hyphens, which means that it will not % find a line break at a hyphen in a node names. Since some manuals % are best written with fairly long node names, containing hyphens, % this is a loss. Therefore, we give the text of the node name % again, so it is as if TeX is seeing it for the first time. - % + % \ifdim \wd\printedmanualbox > 0pt % Cross-manual reference with a printed manual name. - % + % \crossmanualxref{\cite{\printedmanual\unskip}}% % \else\ifdim \wd\infofilenamebox > 0pt % Cross-manual reference with only an info filename (arg 4), no % printed manual name (arg 5). This is essentially the same as % the case above; we output the filename, since we have nothing else. - % + % \crossmanualxref{\code{\infofilename\unskip}}% % \else @@ -8978,20 +8978,20 @@ \endgroup} % Output a cross-manual xref to #1. Used just above (twice). -% +% % Only include the text "Section ``foo'' in" if the foo is neither % missing or Top. Thus, @xref{,,,foo,The Foo Manual} outputs simply % "see The Foo Manual", the idea being to refer to the whole manual. -% +% % But, this being TeX, we can't easily compare our node name against the % string "Top" while ignoring the possible spaces before and after in % the input. By adding the arbitrary 7sp below, we make it much less % likely that a real node name would have the same width as "Top" (e.g., % in a monospaced font). Hopefully it will never happen in practice. -% +% % For the same basic reason, we retypeset the "Top" at every % reference, since the current font is indeterminate. -% +% \def\crossmanualxref#1{% \setbox\toprefbox = \hbox{Top\kern7sp}% \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}% @@ -9038,7 +9038,7 @@ \fi\fi\fi } -% \refx{NAME}{SUFFIX} - reference a cross-reference string named NAME. SUFFIX +% \refx{NAME}{SUFFIX} - reference a cross-reference string named NAME. SUFFIX % is output afterwards if non-empty. \def\refx#1#2{% \requireauxfile @@ -9070,9 +9070,9 @@ #2% Output the suffix in any case. } -% This is the macro invoked by entries in the aux file. Define a control -% sequence for a cross-reference target (we prepend XR to the control sequence -% name to avoid collisions). The value is the page number. If this is a float +% This is the macro invoked by entries in the aux file. Define a control +% sequence for a cross-reference target (we prepend XR to the control sequence +% name to avoid collisions). The value is the page number. If this is a float % type, we have more work to do. % \def\xrdef#1#2{% @@ -9088,10 +9088,10 @@ \bgroup \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% \egroup - % We put the \gdef inside a group to avoid the definitions building up on - % TeX's save stack, which can cause it to run out of space for aux files with + % We put the \gdef inside a group to avoid the definitions building up on + % TeX's save stack, which can cause it to run out of space for aux files with % thousands of lines. \gdef doesn't use the save stack, but \csname does - % when it defines an unknown control sequence as \relax. + % when it defines an unknown control sequence as \relax. % % Was that xref control sequence that we just defined for a float? \expandafter\iffloat\csname XR\safexrefname\endcsname @@ -9450,7 +9450,7 @@ % \ifimagevmode \medskip % space after a standalone image - \fi + \fi \ifx\centersub\centerV \egroup \fi \endgroup} @@ -10281,7 +10281,7 @@ \uppercase{.} \endgroup \else - \errhelp = \EMsimple + \errhelp = \EMsimple \errmessage{Unicode character U+#1 not supported, sorry}% \fi \else @@ -10314,7 +10314,7 @@ \countUTFz = "#1\relax \begingroup \parseXMLCharref - + % Give \u8:... its definition. The sequence of seven \expandafter's % expands after the \gdef three times, e.g. % @@ -10326,7 +10326,7 @@ \expandafter\expandafter \expandafter\expandafter \expandafter\gdef \UTFviiiTmp{#2}% - % + % \expandafter\ifx\csname uni:#1\endcsname \relax \else \message{Internal error, already defined: #1}% \fi @@ -10365,7 +10365,7 @@ \divide\countUTFz by 64 \countUTFy = \countUTFz % Save to be the future value of \countUTFz. \multiply\countUTFz by 64 - + % \countUTFz is now \countUTFx with the last 5 bits cleared. Subtract % in order to get the last five bits. \advance\countUTFx by -\countUTFz @@ -10400,7 +10400,7 @@ % U+0080..U+00FF = https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block) % U+0100..U+017F = https://en.wikipedia.org/wiki/Latin_Extended-A % U+0180..U+024F = https://en.wikipedia.org/wiki/Latin_Extended-B -% +% % Many of our renditions are less than wonderful, and all the missing % characters are available somewhere. Loading the necessary fonts % awaits user request. We can't truly support Unicode without @@ -11438,9 +11438,9 @@ \def\texinfochars{% \let< = \activeless \let> = \activegtr - \let~ = \activetilde + \let~ = \activetilde \let^ = \activehat - \markupsetuplqdefault \markupsetuprqdefault + \markupsetuplqdefault \markupsetuprqdefault \let\b = \strong \let\i = \smartitalic % in principle, all other definitions in \tex have to be undone too. diff --git a/lib/intprops.h b/lib/intprops.h index fe67c1f305..36c6359a21 100644 --- a/lib/intprops.h +++ b/lib/intprops.h @@ -22,6 +22,18 @@ #include +/* If the compiler lacks __has_builtin, define it well enough for this + source file only. */ +#ifndef __has_builtin +# define __has_builtin(x) _GL_HAS_##x +# if 5 <= __GNUC__ && !defined __ICC +# define _GL_HAS___builtin_add_overflow 1 +# else +# define _GL_HAS___builtin_add_overflow 0 +# endif +# define _GL_TEMPDEF___has_builtin +#endif + /* Return a value with the common real type of E and V and the value of V. Do not evaluate E. */ #define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v)) @@ -220,14 +232,24 @@ ? (a) < (min) >> (b) \ : (max) >> (b) < (a)) -/* True if __builtin_add_overflow (A, B, P) works when P is non-null. */ -#if 5 <= __GNUC__ && !defined __ICC -# define _GL_HAS_BUILTIN_OVERFLOW 1 +/* True if __builtin_add_overflow (A, B, P) and __builtin_sub_overflow + (A, B, P) work when P is non-null. */ +#if __has_builtin (__builtin_add_overflow) +# define _GL_HAS_BUILTIN_ADD_OVERFLOW 1 +#else +# define _GL_HAS_BUILTIN_ADD_OVERFLOW 0 +#endif + +/* True if __builtin_mul_overflow (A, B, P) works when P is non-null. */ +#ifdef __clang__ +/* Work around Clang bug . */ +# define _GL_HAS_BUILTIN_MUL_OVERFLOW 0 #else -# define _GL_HAS_BUILTIN_OVERFLOW 0 +# define _GL_HAS_BUILTIN_MUL_OVERFLOW _GL_HAS_BUILTIN_ADD_OVERFLOW #endif -/* True if __builtin_add_overflow_p (A, B, C) works. */ +/* True if __builtin_add_overflow_p (A, B, C) works, and similarly for + __builtin_mul_overflow_p and __builtin_mul_overflow_p. */ #define _GL_HAS_BUILTIN_OVERFLOW_P (7 <= __GNUC__) /* The _GL*_OVERFLOW macros have the same restrictions as the @@ -351,29 +373,33 @@ /* Store the low-order bits of A + B, A - B, A * B, respectively, into *R. Return 1 if the result overflows. See above for restrictions. */ -#define INT_ADD_WRAPV(a, b, r) \ - _GL_INT_OP_WRAPV (a, b, r, +, __builtin_add_overflow, \ - _GL_INT_ADD_RANGE_OVERFLOW) -#define INT_SUBTRACT_WRAPV(a, b, r) \ - _GL_INT_OP_WRAPV (a, b, r, -, __builtin_sub_overflow, \ - _GL_INT_SUBTRACT_RANGE_OVERFLOW) -#define INT_MULTIPLY_WRAPV(a, b, r) \ - _GL_INT_OP_WRAPV (a, b, r, *, _GL_BUILTIN_MUL_OVERFLOW, \ - _GL_INT_MULTIPLY_RANGE_OVERFLOW) - -/* Like __builtin_mul_overflow, but work around GCC bug 91450. */ -#define _GL_BUILTIN_MUL_OVERFLOW(a, b, r) \ - ((!_GL_SIGNED_TYPE_OR_EXPR (*(r)) && EXPR_SIGNED (a) && EXPR_SIGNED (b) \ - && _GL_INT_MULTIPLY_RANGE_OVERFLOW (a, b, 0, (__typeof__ (*(r))) -1)) \ - ? ((void) __builtin_mul_overflow (a, b, r), 1) \ - : __builtin_mul_overflow (a, b, r)) +#if _GL_HAS_BUILTIN_ADD_OVERFLOW +# define INT_ADD_WRAPV(a, b, r) __builtin_add_overflow (a, b, r) +# define INT_SUBTRACT_WRAPV(a, b, r) __builtin_sub_overflow (a, b, r) +#else +# define INT_ADD_WRAPV(a, b, r) \ + _GL_INT_OP_WRAPV (a, b, r, +, _GL_INT_ADD_RANGE_OVERFLOW) +# define INT_SUBTRACT_WRAPV(a, b, r) \ + _GL_INT_OP_WRAPV (a, b, r, -, _GL_INT_SUBTRACT_RANGE_OVERFLOW) +#endif +#if _GL_HAS_BUILTIN_MUL_OVERFLOW +/* Work around GCC bug 91450. */ +# define INT_MULTIPLY_WRAPV(a, b, r) \ + ((!_GL_SIGNED_TYPE_OR_EXPR (*(r)) && EXPR_SIGNED (a) && EXPR_SIGNED (b) \ + && _GL_INT_MULTIPLY_RANGE_OVERFLOW (a, b, 0, (__typeof__ (*(r))) -1)) \ + ? ((void) __builtin_mul_overflow (a, b, r), 1) \ + : __builtin_mul_overflow (a, b, r)) +#else +# define INT_MULTIPLY_WRAPV(a, b, r) \ + _GL_INT_OP_WRAPV (a, b, r, *, _GL_INT_MULTIPLY_RANGE_OVERFLOW) +#endif /* Nonzero if this compiler has GCC bug 68193 or Clang bug 25390. See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68193 https://llvm.org/bugs/show_bug.cgi?id=25390 For now, assume all versions of GCC-like compilers generate bogus - warnings for _Generic. This matters only for older compilers that - lack __builtin_add_overflow. */ + warnings for _Generic. This matters only for compilers that + lack relevant builtins. */ #if __GNUC__ # define _GL__GENERIC_BOGUS 1 #else @@ -381,13 +407,10 @@ #endif /* Store the low-order bits of A B into *R, where OP specifies - the operation. BUILTIN is the builtin operation, and OVERFLOW the - overflow predicate. Return 1 if the result overflows. See above - for restrictions. */ -#if _GL_HAS_BUILTIN_OVERFLOW -# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) builtin (a, b, r) -#elif 201112 <= __STDC_VERSION__ && !_GL__GENERIC_BOGUS -# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) \ + the operation and OVERFLOW the overflow predicate. Return 1 if the + result overflows. See above for restrictions. */ +#if 201112 <= __STDC_VERSION__ && !_GL__GENERIC_BOGUS +# define _GL_INT_OP_WRAPV(a, b, r, op, overflow) \ (_Generic \ (*(r), \ signed char: \ @@ -442,7 +465,7 @@ : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a,b,op,unsigned,st), 0))) # endif -# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) \ +# define _GL_INT_OP_WRAPV(a, b, r, op, overflow) \ (sizeof *(r) == sizeof (signed char) \ ? _GL_INT_OP_WRAPV_SMALLISH (a, b, r, op, overflow, \ signed char, SCHAR_MIN, SCHAR_MAX, \ @@ -563,4 +586,10 @@ : (tmin) / (a) < (b)) \ : (tmax) / (b) < (a))) +#ifdef _GL_TEMPDEF___has_builtin +# undef __has_builtin +# undef _GL_HAS___builtin_add_overflow +# undef _GL_TEMPDEF___has_builtin +#endif + #endif /* _GL_INTPROPS_H */ diff --git a/lib/regex_internal.c b/lib/regex_internal.c index b592f06725..0092cc2a46 100644 --- a/lib/regex_internal.c +++ b/lib/regex_internal.c @@ -1311,7 +1311,6 @@ re_node_set_insert (re_node_set *set, Idx elem) first element separately to skip a check in the inner loop. */ if (elem < set->elems[0]) { - idx = 0; for (idx = set->nelem; idx > 0; idx--) set->elems[idx] = set->elems[idx - 1]; } @@ -1716,15 +1715,19 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes, { if (newstate->entrance_nodes == &newstate->nodes) { - newstate->entrance_nodes = re_malloc (re_node_set, 1); - if (__glibc_unlikely (newstate->entrance_nodes == NULL)) + re_node_set *entrance_nodes = re_malloc (re_node_set, 1); + if (__glibc_unlikely (entrance_nodes == NULL)) { free_state (newstate); return NULL; } + newstate->entrance_nodes = entrance_nodes; if (re_node_set_init_copy (newstate->entrance_nodes, nodes) != REG_NOERROR) - return NULL; + { + free_state (newstate); + return NULL; + } nctx_nodes = 0; newstate->has_constraint = 1; } diff --git a/lib/verify.h b/lib/verify.h index afdc1ad81f..06e975ebf6 100644 --- a/lib/verify.h +++ b/lib/verify.h @@ -56,6 +56,16 @@ # undef _Static_assert #endif +/* If the compiler lacks __has_builtin, define it well enough for this + source file only. */ +#ifndef __has_builtin +# define __has_builtin(x) _GL_HAS_##x +# define _GL_HAS___builtin_unreachable (4 < __GNUC__ + (5 <= __GNUC_MINOR__)) +# define _GL_HAS___builtin_trap \ + (3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__))) +# define _GL_TEMPDEF___has_builtin +#endif + /* Each of these macros verifies that its argument R is nonzero. To be portable, R should be an integer constant expression. Unlike assert (R), there is no run-time overhead. @@ -260,24 +270,17 @@ template # define verify(R) _GL_VERIFY (R, "verify (" #R ")", -) #endif -#ifndef __has_builtin -# define __has_builtin(x) 0 -#endif - /* Assume that R always holds. Behavior is undefined if R is false, fails to evaluate, or has side effects. 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. */ -#if (__has_builtin (__builtin_unreachable) \ - || 4 < __GNUC__ + (5 <= __GNUC_MINOR__)) +#if __has_builtin (__builtin_unreachable) # define assume(R) ((R) ? (void) 0 : __builtin_unreachable ()) #elif 1200 <= _MSC_VER # define assume(R) __assume (R) -#elif ((defined GCC_LINT || defined lint) \ - && (__has_builtin (__builtin_trap) \ - || 3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__)))) +#elif (defined GCC_LINT || defined lint) && __has_builtin (__builtin_trap) /* Doing it this way helps various packages when configured with --enable-gcc-warnings, which compiles with -Dlint. It's nicer when 'assume' silences warnings even with older GCCs. */ @@ -287,6 +290,13 @@ template # define assume(R) ((R) ? (void) 0 : /*NOTREACHED*/ (void) 0) #endif +#ifdef _GL_TEMPDEF___has_builtin +# undef __has_builtin +# undef _GL_HAS___builtin_unreachable +# undef _GL_HAS___builtin_trap +# undef _GL_TEMPDEF___has_builtin +#endif + /* @assert.h omit end@ */ #endif commit 7c37b17b3d6a9be06fa25b19f5eccbc72c52f71c Author: Paul Eggert Date: Mon Sep 2 11:32:50 2019 -0700 * doc/lispref/files.texi (Standard File Names): Mention .emacs.d too. diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index c3b6c39b28..18a1f4908d 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi @@ -2822,10 +2822,10 @@ filter out a directory named @file{foo.elc}. name for a particular use---typically, to hold configuration data specified by the current user. Usually, such files should be located in the directory specified by @code{user-emacs-directory}, which is -typically @file{~/.config/emacs} by default (@pxref{Find +typically @file{~/.config/emacs/} or @file{~/.emacs.d/} by default (@pxref{Find Init,,How Emacs Finds Your Init File, emacs, The GNU Emacs Manual}). For example, abbrev definitions are stored by default in -@file{~/.config/emacs/abbrev_defs}. +@file{~/.config/emacs/abbrev_defs} or @file{~/.emacs.d/abbrev_defs}. The easiest way to specify such a file name is to use the function @code{locate-user-emacs-file}. commit f17d26eb0c551c4aabaf2088b8dca20a090e2f96 Author: Robert Pluim Date: Mon Sep 2 17:28:59 2019 +0200 Reword documentation markup description * etc/NEWS: Reword temporary note about documentation updates. diff --git a/etc/NEWS b/etc/NEWS index 8b16a8a40f..d5130e9f3c 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -16,10 +16,10 @@ You can narrow news to a specific version by calling 'view-emacs-news' with a prefix argument or by typing 'C-u C-h C-n'. Temporary note: -+++ indicates that all necessary documentation updates are complete. - (This means all relevant manuals in doc/ AND lisp doc-strings.) ++++ indicates that all relevant manuals in doc/ have been updated. --- means no change in the manuals is needed. -When you add a new item, use the appropriate mark if you are sure it applies, +When you add a new item, use the appropriate mark if you are sure it +applies, and please also update docstrings as needed. * Installation Changes in Emacs 27.1 commit 0458a9e776e528654b960c6bea81191e38ad5979 Author: Robert Pluim Date: Mon Sep 2 17:26:10 2019 +0200 Add 'nsm-trust-local-network' to NEWS * etc/NEWS: Describe 'nsm-trust-local-network', and warn against its use. diff --git a/etc/NEWS b/etc/NEWS index 9a3725b033..8b16a8a40f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -296,6 +296,14 @@ issued), you can either set 'network-security-protocol-checks' to nil, or adjust the elements in that variable to only happen on the 'high' security level (assuming you use the 'medium' level). +--- +** New user option 'nsm-trust-local-network'. +Allows skipping Network Security Manager checks for hosts on your +local subnet(s). It defaults to nil. Usually, there should be no +need to set this non-nil, and doing that risks opening your local +network connections to attacks. So be sure you know what you are +doing before changing the value. + +++ ** Native GnuTLS connections can now use client certificates. Previously, this support was only available when using the external