[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Problem mit symlinks, locate-library and load-history [Was: <Somethi
From: |
Alan Mackenzie |
Subject: |
Re: Problem mit symlinks, locate-library and load-history [Was: <Something else>] |
Date: |
Wed, 22 Mar 2006 14:04:30 +0000 (GMT) |
Hi, Richard!
On Mon, 20 Mar 2006, Richard Stallman wrote:
[ This was in the context of eval-after-load not finding an already
loaded file, because of confusion between suffixes ".el" and ".elc" and
confusion between symbolic links and true names. ]
>It could be useful to define a subroutine to do
> (assoc (file-truename (locate-library file)) load-history)))
>except do it correctly.
>Would someone like to do that, and ack?
Thinking about this a little more, there is confusion in the above,
certainly when used in eval-after-load: There is NO REASON why a loaded
file should have to be in load-path, and it seems that (locate-library
file) was used mainly to give a convenient search key for `alloc'.
I therefore propose the following function loaded-filename which does
nothing but search load-history for a file. It can be called like
this:
(loaded-filename "font-lock.el") => "/home/acm/emacs/emacs/lisp/font-lock.elc"
(any suffix in `load-suffixes' will do in place of the .el).
(loaded-filename "font-lock") => "/home/acm/emacs/emacs/lisp/font-lock.elc"
(There needn't be a suffix on the name).
(loaded-filename "font-lock.el" t) => nil
("font-lock.el", as such, has not been loaded)
(loaded-filename "~/emacs/emacs/lisp/font-lock") =>
"/home/acm/emacs/emacs/lisp/font-lock.elc"
The functions work fine in GNU. I'm not sure about MS-Windows (case
folding?) or VMS (version numbers?).
#########################################################################
(defun load-history-filename-element (filename &optional exact-suffix)
"Get the load-history element which matches the loaded Elisp file FILENAME.
Return nil if the file isn't found. The parameters have the same meaning as
those of the function `loaded-filename'."
(let* (supplied-basename-sans-ext
supplied-extension ; e.g. ".el" or "", NOT "el".
regexp
(loads load-history)
(load-elt (and loads (car loads))))
(if (file-name-absolute-p filename)
(progn
(setq filename (file-truename filename))
(setq supplied-basename-sans-ext
(file-name-sans-extension (file-name-nondirectory filename))))
(if (file-name-directory filename)
(error "loaded-filename: Relative file name has directory parts: %s"
filename))
(setq supplied-basename-sans-ext (file-name-sans-extension filename)))
(setq supplied-extension
(if (file-name-extension filename)
(concat "." (file-name-extension filename))
""))
(setq regexp
(concat (if (file-name-absolute-p filename) "^" "")
(if exact-suffix
(regexp-quote filename)
(concat supplied-basename-sans-ext
(regexp-opt (cons supplied-extension
load-suffixes))))
"$"))
(while (and loads
(or (null (car load-elt))
(not (string-match regexp (car load-elt)))
(not (string= supplied-basename-sans-ext
(file-name-sans-extension
(file-name-nondirectory (car load-elt)))))))
(setq loads (cdr loads)
load-elt (and loads (car loads))))
load-elt))
(defun loaded-filename (filename &optional exact-suffix)
"Get the absolute file name from which Elisp file FILENAME was loaded.
Return nil if the file isn't found. The returned file name will be a true
name \(i.e. with all its symbolic links having been chased out).
FILENAME is a string. It may be an absolute file name like
\"/usr/local/bin/emacs/lisp/foobar\", or a bare file name like \"foobar\" or
\"foobar.el\". It may not be a relative name containing a \"/\".
If EXACT-SUFFIX is non-nil, the function searches only for FILENAME.
Otherwise it also searches for the file names formed by replacing FILENAME's
suffix, if any, by each of the suffixes in `load-suffixes'."
(let ((elt (load-history-filename-element filename exact-suffix)))
(and elt (car elt))))
#########################################################################
--
Alan Mackenzie (Munich, Germany)