[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Problem mit symlinks, locate-library and load-history [PATCH]
From: |
Alan Mackenzie |
Subject: |
Re: Problem mit symlinks, locate-library and load-history [PATCH] |
Date: |
Wed, 10 May 2006 11:18:27 +0000 (GMT) |
Hi, Richard!
On Mon, 27 Mar 2006, Richard Stallman wrote:
>Your new function seems like a good idea. For full reliability, the
>regexps should use \\` and \\' rather than ^ and $. And I think it
>would be good for load-history-filename-element to use
>save-match-data.
>
I updated my Emacs copy yesterday. It is in ~acm/emacs/emacs, where
~acm/emacs is a symbolic link to /mnt/hda7.
I do: emacs-22.0.50.1 -Q
M-x load-file <ret> ~acm/emacs/emacs/lisp/progmodes/cc-mode.elc
C-h v load-history.
Then:
M-: (eval-after-load "cc-mode" '(beep)) fails.
M-: (eval-after-load "cc-fonts" '(beep)) beeps.
M-: (eval-after-load "english" '(beep)) fails.
Here are these file names as they appear in load-history:
1. "/home/acm/emacs/emacs/lisp/progmodes/cc-mode.elc"
2. "/mnt/hda7/emacs/lisp/progmodes/cc-fonts.elc"
3. "/mnt/hda7/emacs/lisp/language/english.elc"
1 and 2 are incompatible. 3 is plain wrong - the actual file is
english.el (english.elc doesn't exist; you can't compile english).
The reason this happens is that in Fload (lread.c):
(i) "language/english" is passed to openp, which returns the full file
name, including the extension ".el".
(ii) At preload time (`purify-flag'), the extension (".el" or ".elc")
is stripped from the filename before it's either:
o - (".elc") loaded; or
o - (".el") passed to load-with-code-conversion
(.../international/mule.el).
(iii) At this stage I get too confused to delve further. The
(preloaded) file names (relative file names based on ..../emacs/lisp)
get stored into load-history. Some of these names have the extension
".el", some have no extension, but I don't think any have ".elc".
(iv) When Emacs is started, command-line (startup.el) attempts to restore
the extensions. ".el" is left as is, otherwise ".elc" is appended.
This is chaotic - here is a fix:
#########################################################################
The patch here rationalizes load-history. It (probably) isn't enough on
its own to fix the eval-after-load bugs. For this I will also need the
function load-history-filename-element and so on, which I proposed on Wed
22 March, and you (RMS) tentatively approved on Mon, 27 Mar 2006 03:36:26
-0500.
With this patch, the names in load-history now look like this:
1. "/mnt/hda7/emacs/lisp/progmodes/cc-mode.elc"
2. "/mnt/hda7/emacs/lisp/progmodes/cc-fonts.elc"
3. "/mnt/hda7/emacs/lisp/language/english.el"
2006-05-10 Alan Mackenzie <address@hidden>
* lread.c (Vload_history): Enhance doc-string to say that the file
name is the absolute truename of the loaded file.
* lread.c (readevalloop): Call file-truename on the name for
load-history, except at preloading time.
* lread.c (Fload): At preloading time, preserve the extension of
the filename which goes into load-history. New variable
hist_file_name.
Index: src/lread.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/lread.c,v
retrieving revision 1.350
diff -c -r1.350 lread.c
*** src/lread.c 27 Feb 2006 02:04:35 -0000 1.350
--- src/lread.c 10 May 2006 10:50:59 -0000
***************
*** 718,725 ****
register int fd = -1;
int count = SPECPDL_INDEX ();
Lisp_Object temp;
! struct gcpro gcpro1, gcpro2;
! Lisp_Object found, efound;
/* 1 means we printed the ".el is newer" message. */
int newer = 0;
/* 1 means we are loading a compiled file. */
--- 718,725 ----
register int fd = -1;
int count = SPECPDL_INDEX ();
Lisp_Object temp;
! struct gcpro gcpro1, gcpro2, gcpro3;
! Lisp_Object found, efound, hist_file_name;
/* 1 means we printed the ".el is newer" message. */
int newer = 0;
/* 1 means we are loading a compiled file. */
***************
*** 727,732 ****
--- 727,733 ----
Lisp_Object handler;
int safe_p = 1;
char *fmode = "r";
+ Lisp_Object tmp[2];
#ifdef DOS_NT
fmode = "rt";
#endif /* DOS_NT */
***************
*** 743,749 ****
the need to gcpro noerror, nomessage and nosuffix.
(Below here, we care only whether they are nil or not.)
The presence of this call is the result of a historical accident:
! it used to be in every file-operations and when it got removed
everywhere, it accidentally stayed here. Since then, enough people
supposedly have things like (load "$PROJECT/foo.el") in their .emacs
that it seemed risky to remove. */
--- 744,750 ----
the need to gcpro noerror, nomessage and nosuffix.
(Below here, we care only whether they are nil or not.)
The presence of this call is the result of a historical accident:
! it used to be in every file-operation and when it got removed
everywhere, it accidentally stayed here. Since then, enough people
supposedly have things like (load "$PROJECT/foo.el") in their .emacs
that it seemed risky to remove. */
***************
*** 763,769 ****
if (SCHARS (file) > 0)
{
int size = SBYTES (file);
- Lisp_Object tmp[2];
found = Qnil;
GCPRO2 (file, found);
--- 764,769 ----
***************
*** 847,852 ****
--- 847,859 ----
Vloads_in_progress = Fcons (found, Vloads_in_progress);
}
+ /* Get the name for load-history. */
+ hist_file_name = (! NILP (Vpurify_flag)
+ ? Fconcat (2, (tmp[0] = Ffile_name_directory (file),
+ tmp[1] = Ffile_name_nondirectory (found),
+ tmp))
+ : found) ;
+
if (!bcmp (SDATA (found) + SBYTES (found) - 4,
".elc", 4))
/* Load .elc files directly, but not when they are
***************
*** 857,863 ****
struct stat s1, s2;
int result;
! GCPRO2 (file, found);
if (!safe_to_load_p (fd))
{
--- 864,870 ----
struct stat s1, s2;
int result;
! GCPRO3 (file, found, hist_file_name);
if (!safe_to_load_p (fd))
{
***************
*** 911,924 ****
if (fd >= 0)
emacs_close (fd);
! val = call4 (Vload_source_file_function, found, file,
NILP (noerror) ? Qnil : Qt,
NILP (nomessage) ? Qnil : Qt);
return unbind_to (count, val);
}
}
! GCPRO2 (file, found);
#ifdef WINDOWSNT
emacs_close (fd);
--- 918,931 ----
if (fd >= 0)
emacs_close (fd);
! val = call4 (Vload_source_file_function, found, hist_file_name,
NILP (noerror) ? Qnil : Qt,
NILP (nomessage) ? Qnil : Qt);
return unbind_to (count, val);
}
}
! GCPRO3 (file, found, hist_file_name);
#ifdef WINDOWSNT
emacs_close (fd);
***************
*** 957,963 ****
load_descriptor_list
= Fcons (make_number (fileno (stream)), load_descriptor_list);
load_in_progress++;
! readevalloop (Qget_file_char, stream, (! NILP (Vpurify_flag) ? file :
found),
Feval, 0, Qnil, Qnil, Qnil, Qnil);
unbind_to (count, Qnil);
--- 964,970 ----
load_descriptor_list
= Fcons (make_number (fileno (stream)), load_descriptor_list);
load_in_progress++;
! readevalloop (Qget_file_char, stream, hist_file_name,
Feval, 0, Qnil, Qnil, Qnil, Qnil);
unbind_to (count, Qnil);
***************
*** 1385,1390 ****
--- 1392,1405 ----
GCPRO4 (sourcename, readfun, start, end);
+ /* Try to ensure sourcename is a truename, except whilst preloading. */
+ if (NILP (Vpurify_flag) && !NILP (sourcename)
+ && Ffile_name_absolute_p (sourcename))
+ {
+ Lisp_Object Qfile_truename = intern ("file-truename") ;
+ if (!NILP (Ffboundp (Qfile_truename)))
+ sourcename = call1 (Qfile_truename, sourcename) ;
+ }
LOADHIST_ATTACH (sourcename);
continue_reading_p = 1;
***************
*** 3982,3987 ****
--- 3997,4006 ----
Each alist element is a list that starts with a file name,
except for one element (optional) that starts with nil and describes
definitions evaluated from buffers not visiting files.
+
+ The file name is absolute and is the true file name (i.e. it doesn't
+ contain symbolic links) of the loaded file.
+
The remaining elements of each list are symbols defined as variables
and cons cells of the form `(provide . FEATURE)', `(require . FEATURE)',
`(defun . FUNCTION)', `(autoload . SYMBOL)', and `(t . SYMBOL)'.
2006-05-10 Alan Mackenzie <address@hidden>
* startup.el (command-line): For names of preloaded files, don't
append ".elc" (now done in Fload), and call file-truename on the
lisp directory.
Index: lisp/startup.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/startup.el,v
retrieving revision 1.407
diff -c -r1.407 startup.el
*** lisp/startup.el 5 May 2006 14:05:54 -0000 1.407
--- lisp/startup.el 10 May 2006 10:51:05 -0000
***************
*** 644,661 ****
;; Convert preloaded file names to absolute.
(let ((lisp-dir
! (file-name-directory
! (locate-file "simple" load-path
! (get-load-suffixes)))))
(setq load-history
(mapcar (lambda (elt)
(if (and (stringp (car elt))
(not (file-name-absolute-p (car elt))))
(cons (concat lisp-dir
! (car elt)
! (if (string-match "[.]el$" (car elt))
! "" ".elc"))
(cdr elt))
elt))
load-history)))
--- 644,660 ----
;; Convert preloaded file names to absolute.
(let ((lisp-dir
! (file-truename
! (file-name-directory
! (locate-file "simple" load-path
! (get-load-suffixes))))))
(setq load-history
(mapcar (lambda (elt)
(if (and (stringp (car elt))
(not (file-name-absolute-p (car elt))))
(cons (concat lisp-dir
! (car elt))
(cdr elt))
elt))
load-history)))
#########################################################################
--
Alan.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: Problem mit symlinks, locate-library and load-history [PATCH],
Alan Mackenzie <=