emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/compat 12774be87c 2/3: Fix using compat libraries uncom


From: ELPA Syncer
Subject: [elpa] externals/compat 12774be87c 2/3: Fix using compat libraries uncompiled
Date: Sun, 5 Jun 2022 10:57:25 -0400 (EDT)

branch: externals/compat
commit 12774be87c7d52640be4c3d54e65236ba69b9a0e
Author: Jonas Bernoulli <jonas@bernoul.li>
Commit: Philip Kaludercic <philipk@posteo.net>

    Fix using compat libraries uncompiled
    
    `compat-entwine' is called in two and only three distinct situations.
    
    1. When "compat.el" is being loaded without having been compiled
       before.  This can happen while a third-party library is being
       compiled, which requires `compat'.
    
    2. When "compat.el" is being evaluated, such as when using
       `eval-buffer'.
    
    3. When "compat.el" is being compiled.
    
    In all cases we need to detect where "compat.el" is located, because
    that also tells us where the "compat-XY.el" libraries are located and
    `compat-entwine' needs to read the contents of those files.  To detect
    the location of "compat.el" we consult various variables, which we
    expect to either be nil or "/path/to/compat.el".  We didn't use the
    correct variables.
    
    Some time ago Stefan added a call to `macro-file-name' to the front
    of that search, which fixes the search for Emacs 28.1.  Older Emacs
    releases lack that function, so for those we still ended up consulting
    the wrong variables.  To fix that use `current-load-list' directly,
    treating it the same way as `macro-file-name' does.
    
    If that gives us a non-nil value, then we are dealing with one of the
    first two cases and we are done.  Otherwise we are dealing with the
    third case and `byte-compile-current-file' gives us the correct value.
    
    One of these sources is always non-nil, so drop the variables we used
    to fall back to.
    
    Then we pass the version from `compat-entwine' to the
    `compat--generate-function' function by binding the new variable
    `compat--entwine-version'.  Previously this was done by binding
    `byte-compile-current-file`.  The caller then had to extract the
    version from the name of that file.
    
    Binding `byte-compile-current-file` was also part of the bug that
    prevented compilation of a third-party library, which depends on
    "compat-XY.el", when compat's libraries have not been compiled yet.
    
    To fix that we have to change the order of the possible sources of the
    version string in `compat--generate-function' functions.  As before we
    use the version explicitly specified for the function being processed,
    if any.  Then we use value of the new `compat--entwine-version'
    variable, if that is bound and non-nil, i.e., if the binding from
    `compat-entwine' is in effect.
    
    Previously we would have tried `byte-compile-current-file' at this
    point instead, but while that might be non-nil because we used to bind
    it in `compat--generate-function', it could also be non-nil because an
    arbitrary third-party library is being compiled.
    
    That is a problem if that third-party library depends on
    "compat-XY.el" and the latter hasn't been compiled before: The
    `compat--generate-function' function is called directly in that case,
    without the binding from `compat-entwine' in effect.  We need
    `byte-compile-current-file' to be some "compat-XY.el" library; not
    some arbitrary third-party library.
    
    Then we try `current-load-list' like in `compat-entwine', which here
    is some "compat-XY.el" library when some third-party library is being
    compiled and that requires that "compat-XY.el" library.
    
    Finally, if we could not determine a version any other way, then we
    know that some "compat-XY.el" library is being compiled.  In that
    case, and only then, we can get the version string from
    `byte-compile-current-file'.
---
 compat-macs.el | 54 ++++++++++++++++++++++++++++--------------------------
 compat.el      | 30 ++++++++++++++++++++----------
 2 files changed, 48 insertions(+), 36 deletions(-)

diff --git a/compat-macs.el b/compat-macs.el
index fec167a99a..85f31b8804 100644
--- a/compat-macs.el
+++ b/compat-macs.el
@@ -82,19 +82,22 @@ DEF-FN, INSTALL-FN, CHECK-FN, ATTR and TYPE."
          (max-version (plist-get attr :max-version))
          (feature (plist-get attr :feature))
          (cond (plist-get attr :cond))
-         (version (or (plist-get attr :version)
-                      (let ((file (or (bound-and-true-p 
byte-compile-current-file)
-                                      load-file-name
-                                      (buffer-file-name))))
-                        ;; Guess the version from the file the macro is
-                        ;; being defined in.
-                        (cond
-                         ((not file) emacs-version)
-                         ((string-match
-                           "compat-\\([[:digit:]]+\\)\\.\\(?:elc?\\)\\'"
-                           file)
-                          (concat (match-string 1 file) ".1"))
-                         ((error "No version number could be extracted"))))))
+         (version ; If you edit this, also edit `compat--generate-verbose'.
+          (or (plist-get attr :version)
+              (bound-and-true-p compat--entwine-version)
+              (let* ((file (car (last current-load-list)))
+                     (file (if (stringp file)
+                               ;; Some library, which requires compat-XY.el,
+                               ;; is being compiled and compat-XY.el has not
+                               ;; been compiled yet.
+                               file
+                             ;; compat-XY.el is being compiled.
+                             (bound-and-true-p byte-compile-current-file))))
+                (if (and file
+                         (string-match
+                          "compat-\\([[:digit:]]+\\)\\.\\(?:elc?\\)\\'" file))
+                    (concat (match-string 1 file) ".1")
+                  (error "BUG: No version number could be extracted")))))
          (realname (or (plist-get attr :realname)
                        (intern (format "compat--%S" name))))
          (check (cond
@@ -155,19 +158,18 @@ DEF-FN, INSTALL-FN, CHECK-FN, ATTR and TYPE."
          (max-version (plist-get attr :max-version))
          (feature (plist-get attr :feature))
          (cond (plist-get attr :cond))
-         (version (or (plist-get attr :version)
-                      (let ((file (or (bound-and-true-p 
byte-compile-current-file)
-                                      load-file-name
-                                      (buffer-file-name))))
-                        ;; Guess the version from the file the macro is
-                        ;; being defined in.
-                        (cond
-                         ((not file) emacs-version)
-                         ((string-match
-                           "compat-\\([[:digit:]]+\\)\\.\\(?:elc?\\)\\'"
-                           file)
-                          (concat (match-string 1 file) ".1"))
-                         ((error "No version number could be extracted"))))))
+         (version ; If you edit this, also edit `compat--generate-minimal'.
+          (or (plist-get attr :version)
+              (bound-and-true-p compat--entwine-version)
+              (let* ((file (car (last current-load-list)))
+                     (file (if (stringp file)
+                               file
+                             (bound-and-true-p byte-compile-current-file))))
+                (if (and file
+                         (string-match
+                          "compat-\\([[:digit:]]+\\)\\.\\(?:elc?\\)\\'" file))
+                    (concat (match-string 1 file) ".1")
+                  (error "BUG: No version number could be extracted")))))
          (realname (or (plist-get attr :realname)
                        (intern (format "compat--%S" name))))
          (body `(progn
diff --git a/compat.el b/compat.el
index ed60ba53ab..a5d6346af1 100644
--- a/compat.el
+++ b/compat.el
@@ -49,6 +49,7 @@
 ;; separately, by explicitly requiring the feature that defines them.
 (eval-when-compile
   (defvar compat--generate-function)
+  (defvar compat--entwine-version)
   (defmacro compat-entwine (version)
     (cond
      ((or (not (eq compat--generate-function 'compat--generate-minimal))
@@ -58,11 +59,24 @@
              (file (expand-file-name
                     (format "compat-%d.el" version)
                     (file-name-directory
-                     (or (if (fboundp 'macroexp-file-name)
-                             (macroexp-file-name)
-                           (or (bound-and-true-p byte-compile-current-file)
-                               load-file-name))
-                         (buffer-file-name)))))
+                     (or
+                      ;; Some third-party library, which requires
+                      ;; compat.el, is being compiled, loaded or
+                      ;; evaluated, and compat.el hasn't been compiled
+                      ;; yet.
+                      ;;   cd compat && make clean && cd ../other && \
+                      ;;   make clean all
+                      ;;
+                      ;; Or compat.el is being evaluated.
+                      ;;   cd compat && make clean && emacs -Q -L . compat.el
+                      ;;   M-x eval-buffer
+                      ;;
+                      ;; (Like `macroexp-file-name' from Emacs 28.1.)
+                      (let ((file (car (last current-load-list))))
+                        (and (stringp file) file))
+                      ;; compat.el is being compiled.
+                      ;;   cd compat && make clean all
+                      (bound-and-true-p byte-compile-current-file)))))
              defs)
         (with-temp-buffer
           (insert-file-contents file)
@@ -70,11 +84,7 @@
           (while (progn
                    (forward-comment 1)
                    (not (eobp)))
-            ;; We bind `byte-compile-current-file' before
-            ;; macro-expanding, so that `compat--generate-function'
-            ;; can correctly infer the compatibility version currently
-            ;; being processed.
-            (let ((byte-compile-current-file file)
+            (let ((compat--entwine-version (number-to-string version))
                   (form (read (current-buffer))))
               (cond
                ((memq (car-safe form)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]