emacs-devel
[Top][All Lists]
Advanced

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

locate-library, the NOSUFFIX arg and a [PATCH]


From: MON KEY
Subject: locate-library, the NOSUFFIX arg and a [PATCH]
Date: Tue, 19 Jan 2010 17:28:37 -0500

`locate-libary' is either broken, doesn't work as documented, or both.

(documentation 'locate-library)

,----
| It can omit the suffix (a.k.a. file-name extension) if NOSUFFIX is
| nil (which is the default, see below).
`----

,----
| Optional second arg NOSUFFIX non-nil means don't add suffixes `load-suffixes'
| to the specified name LIBRARY.
`----

Aren't these two statements mutually exclusive?

I don't think the docstring even reflects the intent of locate-library's
NOSUFFIX arg esp. as it doesn't appear to be _able_ to return a library name
sans extension when not called-interactively.

FWICG there is a problem occuring with the return value of
`load-file-rep-suffixes', which returns an empty string "" as the first elt of
its return value (unless bound otherwise).

This appears to be happening at the variables primitive definition per lread.c's
`Fcons'ing of `empty_unibyte_string'. Which among other things may be causing
problems like this:

(locate-file-completion-table load-path '("") "subr" #'(lambda (y)
(string-match-p ".*z" y)) 'nil)
=> "subr.el.gz"

Which, as it relates to locate-library, causes wonkiness with the local variable
`file'.  Following shows this with NOSUFFIX both t and nil:

(let (nosuffix)
  (append (unless nosuffix (get-load-suffixes))
          load-file-rep-suffixes))
=> (".elc" ".elc.gz" ".el" ".el.gz" "" ".gz")

(let ((nosuffix t))
  (append (unless nosuffix (get-load-suffixes))
          load-file-rep-suffixes))
=> ("" ".gz")

IOW, even if where the empty string problem is corrected, if my reading is
correct `locate-library' still won't perform according to the docstring as
written.

The attached patch corrects the problem without mucking with
`load-file-rep-suffixes' and changes the semanics of nosuffix to mean:

"When called from a program and NOSUFFIX is a boolean, string, or list of
strings, return LIBRARY's file-truename as if by `file-name-sans-extension'."

Following are examples of the behavior provided by the patch:

(locate-library "subr")
=> "/usr/share/emacs/23.1.90/lisp/subr.elc"

(locate-library "subr" ".elc")
=> "/usr/share/emacs/23.1.90/lisp/subr"

(locate-library "subr" ".el")
=> "/usr/share/emacs/23.1.90/lisp/subr"

(locate-library "subr.el" ".gz")
=> "/usr/share/emacs/23.1.90/lisp/subr"

(locate-library "subr" ".el.gz")
=> "/usr/share/emacs/23.1.90/lisp/subr"

(locate-library "subr" ".gz")
=> nil

(locate-library "subr" t)
=> "/usr/share/emacs/23.1.90/lisp/subr"

(apply 'locate-library "subr" '(nil nil t))
=> "/usr/share/emacs/23.1.90/lisp/subr.elc"

(apply 'locate-library "subr" '(".el.gz" nil t))
=> "/usr/share/emacs/23.1.90/lisp/subr"

(apply 'locate-library "subr" '(".elc" nil t))
=> "/usr/share/emacs/23.1.90/lisp/subr"

(let (with-symbolic)
  (shell-command (concat "ln -s "
                         (locate-file "subr.el.gz" load-path)
                         " ~/subr.el.gz"))
  (prog1
      (setq with-symbolic
            (list (locate-library "subr" t '("~/"))
                  (locate-library "subr" ".el" '("~/"))
                  (locate-library "subr" '(".el" ".el.gz" ".elc"
".bubba") '("~/"))
                  (locate-library "subr" nil '("~/"))
                  (locate-library "subr" ".elc" '("~/")) ;<- return nil
                  (apply 'locate-library "subr" '(".el" nil t))
                  (apply 'locate-library "subr" '(".el" nil t))
                  ;; follwing returns nil a PATH can't override intractive's
                  ;; load-path arg to `locate-file-completion-table'
                  (apply 'locate-library "subr" '(t '("~/") t))))
    (shell-command "rm -f ~/subr.el.gz")))

=> ("/usr/share/emacs/23.1.90/lisp/subr"
    "/usr/share/emacs/23.1.90/lisp/subr"
    "/usr/share/emacs/23.1.90/lisp/subr"
    "/home/MON/subr.el.gz"
    nil
    "/usr/share/emacs/23.1.90/lisp/subr"
    "/usr/share/emacs/23.1.90/lisp/subr"
    nil)

;;; ==============================
--- subr.el~99304~      2010-01-19 15:34:00.000000000 -0500
+++ subr.el     2010-01-19 17:05:24.000000000 -0500
@@ -1586,16 +1586,34 @@
                                        load-path (get-load-suffixes)))
                     nil nil
                     t))
-  (let ((file (locate-file library
-                          (or path load-path)
-                          (append (unless nosuffix (get-load-suffixes))
-                                  load-file-rep-suffixes))))
+  (let* ((lfrs (remove "" load-file-rep-suffixes))
+         (sfx  (cond ((booleanp nosuffix)
+                      (delete-dups (append lfrs (get-load-suffixes))))
+                     ((and nosuffix (stringp nosuffix))
+                      `(,nosuffix
+                        ,@(mapcar #'(lambda (z)
+                                      (concat nosuffix z))
+                                  lfrs)))
+                     ((consp nosuffix)
+                      (delete-dups (append nosuffix lfrs)))
+                     (t (append lfrs(get-load-suffixes)))))
+         (file (locate-file library
+                            (or path load-path)
+                            sfx)))
+    (when (and file nosuffix)
+      (setq file (file-truename file))
+      (setq file (concat (file-name-directory file)
+                         (if (string-match-p ".*.gz" file)
+                             (file-name-sans-extension
+                              (file-name-nondirectory
+                               (file-name-sans-extension file)))
+                             (file-name-sans-extension
+                              (file-name-nondirectory file))))))
     (if interactive-call
-       (if file
-           (message "Library is file %s" (abbreviate-file-name file))
-         (message "No library %s in search path" library)))
+        (if file
+            (message "Library is file %s" (abbreviate-file-name file))
+            (message "No library %s in search path" library)))
     file))
-
 
 ;;;; Specifying things to do later.

;;; ==============================

Attachment: subr.el.diff
Description: Binary data


reply via email to

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