Add load-prefer-newer option, to load .el if newer than .elc
* src/lread.c (Fload): Pass load_prefer_newer to openp. Don't bother checking mtime if openp already did it. (openp): Add `newer' argument, to check all suffixes and find the newest file. (syms_of_lread) <load_prefer_newer>: New option. * src/callproc.c (call_process): * src/charset.c (load_charset_map_from_file): * src/emacs.c (init_cmdargs): * src/image.c (x_create_bitmap_from_file, x_find_image_file): * src/lisp.h (openp): * lread.c (Flocate_file_internal): * src/process.c (Fformat_network_address): * src/sound.c (Fplay_sound_internal): * src/w32.c (check_windows_init_file): * src/w32proc.c (sys_spawnve): Update for new arg spec of openp. * lisp/Makefile.in (BYTE_COMPILE_FLAGS): Set load-prefer-newer to t. * etc/NEWS: Mention this. Fixes: debbugs:2061
This commit is contained in:
parent
e82134b1e4
commit
1f41ee56ac
15 changed files with 138 additions and 58 deletions
5
etc/NEWS
5
etc/NEWS
|
|
@ -807,6 +807,11 @@ for something (not just adding elements to it), it ought not to affect you.
|
|||
|
||||
* Lisp Changes in Emacs 24.4
|
||||
|
||||
** New option `load-prefer-newer', if non-nil, means that when both
|
||||
.el and .elc versions of a file exist, rather than `load' always
|
||||
choosing the .elc version, it will choose whichever is newer
|
||||
(unless you explicitly specify one or the other).
|
||||
|
||||
** New function get-pos-property.
|
||||
|
||||
** New hook `pre-redisplay-function'.
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
2013-12-18 Glenn Morris <rgm@gnu.org>
|
||||
|
||||
* Makefile.in (BYTE_COMPILE_FLAGS): Set load-prefer-newer to t.
|
||||
|
||||
2013-12-18 Le Wang <l26wang@gmail.com>
|
||||
|
||||
* comint.el (comint-previous-matching-input-from-input): Retain
|
||||
|
|
@ -9,6 +13,8 @@
|
|||
|
||||
2013-12-18 Glenn Morris <rgm@gnu.org>
|
||||
|
||||
* cus-start.el (load-prefer-newer): New option.
|
||||
|
||||
* mail/emacsbug.el (report-emacs-bug):
|
||||
Only mention enable-multibyte-characters if non-standard.
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,8 @@ AUTOGEN_VCS = \
|
|||
BIG_STACK_DEPTH = 2200
|
||||
BIG_STACK_OPTS = --eval "(setq max-lisp-eval-depth $(BIG_STACK_DEPTH))"
|
||||
|
||||
BYTE_COMPILE_FLAGS = $(BIG_STACK_OPTS) $(BYTE_COMPILE_EXTRA_FLAGS)
|
||||
# Set load-prefer-newer for the benefit of the non-bootstrappers.
|
||||
BYTE_COMPILE_FLAGS = $(BIG_STACK_OPTS) --eval '(setq load-prefer-newer t)' $(BYTE_COMPILE_EXTRA_FLAGS)
|
||||
|
||||
# Files to compile before others during a bootstrap. This is done to
|
||||
# speed up the bootstrap process. They're ordered by size, so we use
|
||||
|
|
|
|||
|
|
@ -312,6 +312,7 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of
|
|||
;; :format "%[Current dir?%] %v"
|
||||
;; (const :tag " current dir" nil)
|
||||
;; (directory :format "%v"))))
|
||||
(load-prefer-newer lisp boolean "24.4")
|
||||
;; minibuf.c
|
||||
(enable-recursive-minibuffers minibuffer boolean)
|
||||
(history-length minibuffer
|
||||
|
|
|
|||
|
|
@ -1,5 +1,21 @@
|
|||
2013-12-18 Glenn Morris <rgm@gnu.org>
|
||||
|
||||
* lread.c (Fload): Pass load_prefer_newer to openp.
|
||||
Don't bother checking mtime if openp already did it.
|
||||
(openp): Add `newer' argument, to check all suffixes
|
||||
and find the newest file.
|
||||
(syms_of_lread) <load_prefer_newer>: New option. (Bug#2061)
|
||||
* callproc.c (call_process):
|
||||
* charset.c (load_charset_map_from_file):
|
||||
* emacs.c (init_cmdargs):
|
||||
* image.c (x_create_bitmap_from_file, x_find_image_file):
|
||||
* lisp.h (openp):
|
||||
* lread.c (Flocate_file_internal):
|
||||
* process.c (Fformat_network_address):
|
||||
* sound.c (Fplay_sound_internal):
|
||||
* w32.c (check_windows_init_file):
|
||||
* w32proc.c (sys_spawnve): Update for new arg spec of openp.
|
||||
|
||||
* emacs.c (standard_args) [HAVE_NS]: Remove -disable-font-backend.
|
||||
|
||||
2013-12-17 Eli Zaretskii <eliz@gnu.org>
|
||||
|
|
|
|||
|
|
@ -465,7 +465,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
|
|||
int ok;
|
||||
|
||||
GCPRO3 (buffer, current_dir, error_file);
|
||||
ok = openp (Vexec_path, args[0], Vexec_suffixes, &path, make_number (X_OK));
|
||||
ok = openp (Vexec_path, args[0], Vexec_suffixes, &path, make_number (X_OK), 0);
|
||||
UNGCPRO;
|
||||
if (ok < 0)
|
||||
report_file_error ("Searching for program", args[0]);
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
/* Basic character set support.
|
||||
Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
2005, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
National Institute of Advanced Industrial Science and Technology (AIST)
|
||||
Registration Number H14PRO021
|
||||
|
||||
Copyright (C) 2003, 2004
|
||||
National Institute of Advanced Industrial Science and Technology (AIST)
|
||||
Registration Number H13PRO009
|
||||
Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
||||
|
||||
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
2005, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
National Institute of Advanced Industrial Science and Technology (AIST)
|
||||
Registration Number H14PRO021
|
||||
|
||||
Copyright (C) 2003, 2004
|
||||
National Institute of Advanced Industrial Science and Technology (AIST)
|
||||
Registration Number H13PRO009
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
|
|
@ -493,7 +495,7 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile,
|
|||
count = SPECPDL_INDEX ();
|
||||
record_unwind_protect_nothing ();
|
||||
specbind (Qfile_name_handler_alist, Qnil);
|
||||
fd = openp (Vcharset_map_path, mapfile, suffixes, NULL, Qnil);
|
||||
fd = openp (Vcharset_map_path, mapfile, suffixes, NULL, Qnil, 0);
|
||||
fp = fd < 0 ? 0 : fdopen (fd, "r");
|
||||
if (!fp)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -424,7 +424,7 @@ init_cmdargs (int argc, char **argv, int skip_args, char *original_pwd)
|
|||
{
|
||||
Lisp_Object found;
|
||||
int yes = openp (Vexec_path, Vinvocation_name,
|
||||
Vexec_suffixes, &found, make_number (X_OK));
|
||||
Vexec_suffixes, &found, make_number (X_OK), 0);
|
||||
if (yes == 1)
|
||||
{
|
||||
/* Add /: to the front of the name
|
||||
|
|
|
|||
|
|
@ -327,7 +327,7 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file)
|
|||
}
|
||||
|
||||
/* Search bitmap-file-path for the file, if appropriate. */
|
||||
if (openp (Vx_bitmap_file_path, file, Qnil, &found, make_number (R_OK)) < 0)
|
||||
if (openp (Vx_bitmap_file_path, file, Qnil, &found, make_number (R_OK), 0) < 0)
|
||||
return -1;
|
||||
|
||||
filename = SSDATA (found);
|
||||
|
|
@ -2242,7 +2242,7 @@ x_find_image_file (Lisp_Object file)
|
|||
Vx_bitmap_file_path);
|
||||
|
||||
/* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
|
||||
fd = openp (search_path, file, Qnil, &file_found, Qnil);
|
||||
fd = openp (search_path, file, Qnil, &file_found, Qnil, 0);
|
||||
|
||||
if (fd == -1)
|
||||
file_found = Qnil;
|
||||
|
|
|
|||
|
|
@ -3791,7 +3791,7 @@ LOADHIST_ATTACH (Lisp_Object x)
|
|||
Vcurrent_load_list = Fcons (x, Vcurrent_load_list);
|
||||
}
|
||||
extern int openp (Lisp_Object, Lisp_Object, Lisp_Object,
|
||||
Lisp_Object *, Lisp_Object);
|
||||
Lisp_Object *, Lisp_Object, int);
|
||||
extern Lisp_Object string_to_number (char const *, int, bool);
|
||||
extern void map_obarray (Lisp_Object, void (*) (Lisp_Object, Lisp_Object),
|
||||
Lisp_Object);
|
||||
|
|
|
|||
121
src/lread.c
121
src/lread.c
|
|
@ -1129,7 +1129,7 @@ Return t if the file exists and loads successfully. */)
|
|||
}
|
||||
}
|
||||
|
||||
fd = openp (Vload_path, file, suffixes, &found, Qnil);
|
||||
fd = openp (Vload_path, file, suffixes, &found, Qnil, load_prefer_newer);
|
||||
UNGCPRO;
|
||||
}
|
||||
|
||||
|
|
@ -1252,29 +1252,36 @@ Return t if the file exists and loads successfully. */)
|
|||
#ifdef DOS_NT
|
||||
fmode = "rb";
|
||||
#endif /* DOS_NT */
|
||||
result = stat (SSDATA (efound), &s1);
|
||||
if (result == 0)
|
||||
{
|
||||
SSET (efound, SBYTES (efound) - 1, 0);
|
||||
result = stat (SSDATA (efound), &s2);
|
||||
SSET (efound, SBYTES (efound) - 1, 'c');
|
||||
}
|
||||
|
||||
if (result == 0
|
||||
&& timespec_cmp (get_stat_mtime (&s1), get_stat_mtime (&s2)) < 0)
|
||||
{
|
||||
/* Make the progress messages mention that source is newer. */
|
||||
newer = 1;
|
||||
/* openp already checked for newness, no point doing it again.
|
||||
FIXME would be nice to get a message when openp
|
||||
ignores suffix order due to load_prefer_newer. */
|
||||
if (!load_prefer_newer)
|
||||
{
|
||||
result = stat (SSDATA (efound), &s1);
|
||||
if (result == 0)
|
||||
{
|
||||
SSET (efound, SBYTES (efound) - 1, 0);
|
||||
result = stat (SSDATA (efound), &s2);
|
||||
SSET (efound, SBYTES (efound) - 1, 'c');
|
||||
}
|
||||
|
||||
/* If we won't print another message, mention this anyway. */
|
||||
if (!NILP (nomessage) && !force_load_messages)
|
||||
{
|
||||
Lisp_Object msg_file;
|
||||
msg_file = Fsubstring (found, make_number (0), make_number (-1));
|
||||
message_with_string ("Source file `%s' newer than byte-compiled file",
|
||||
msg_file, 1);
|
||||
}
|
||||
}
|
||||
if (result == 0
|
||||
&& timespec_cmp (get_stat_mtime (&s1), get_stat_mtime (&s2)) < 0)
|
||||
{
|
||||
/* Make the progress messages mention that source is newer. */
|
||||
newer = 1;
|
||||
|
||||
/* If we won't print another message, mention this anyway. */
|
||||
if (!NILP (nomessage) && !force_load_messages)
|
||||
{
|
||||
Lisp_Object msg_file;
|
||||
msg_file = Fsubstring (found, make_number (0), make_number (-1));
|
||||
message_with_string ("Source file `%s' newer than byte-compiled file",
|
||||
msg_file, 1);
|
||||
}
|
||||
}
|
||||
} /* !load_prefer_newer */
|
||||
UNGCPRO;
|
||||
}
|
||||
}
|
||||
|
|
@ -1413,7 +1420,7 @@ directories, make sure the PREDICATE function returns `dir-ok' for them. */)
|
|||
(Lisp_Object filename, Lisp_Object path, Lisp_Object suffixes, Lisp_Object predicate)
|
||||
{
|
||||
Lisp_Object file;
|
||||
int fd = openp (path, filename, suffixes, &file, predicate);
|
||||
int fd = openp (path, filename, suffixes, &file, predicate, 0);
|
||||
if (NILP (predicate) && fd >= 0)
|
||||
emacs_close (fd);
|
||||
return file;
|
||||
|
|
@ -1440,11 +1447,14 @@ static Lisp_Object Qdir_ok;
|
|||
nil is stored there on failure.
|
||||
|
||||
If the file we find is remote, return -2
|
||||
but store the found remote file name in *STOREPTR. */
|
||||
but store the found remote file name in *STOREPTR.
|
||||
|
||||
If NEWER is true, try all SUFFIXes and return the result for the
|
||||
newest file that exists. Does not apply to remote files. */
|
||||
|
||||
int
|
||||
openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
|
||||
Lisp_Object *storeptr, Lisp_Object predicate)
|
||||
Lisp_Object *storeptr, Lisp_Object predicate, int newer)
|
||||
{
|
||||
ptrdiff_t fn_size = 100;
|
||||
char buf[100];
|
||||
|
|
@ -1453,9 +1463,11 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
|
|||
ptrdiff_t want_length;
|
||||
Lisp_Object filename;
|
||||
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
|
||||
Lisp_Object string, tail, encoded_fn;
|
||||
Lisp_Object string, tail, encoded_fn, save_string;
|
||||
ptrdiff_t max_suffix_len = 0;
|
||||
int last_errno = ENOENT;
|
||||
struct timespec save_mtime;
|
||||
int save_fd = 0;
|
||||
|
||||
CHECK_STRING (str);
|
||||
|
||||
|
|
@ -1556,17 +1568,18 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
|
|||
|
||||
if (exists)
|
||||
{
|
||||
/* We succeeded; return this descriptor and filename. */
|
||||
if (storeptr)
|
||||
*storeptr = string;
|
||||
UNGCPRO;
|
||||
return -2;
|
||||
/* We succeeded; return this descriptor and filename. */
|
||||
if (storeptr)
|
||||
*storeptr = string;
|
||||
UNGCPRO;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int fd;
|
||||
const char *pfn;
|
||||
struct stat st;
|
||||
|
||||
encoded_fn = ENCODE_FILE (string);
|
||||
pfn = SSDATA (encoded_fn);
|
||||
|
|
@ -1597,7 +1610,6 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
|
|||
}
|
||||
else
|
||||
{
|
||||
struct stat st;
|
||||
int err = (fstat (fd, &st) != 0 ? errno
|
||||
: S_ISDIR (st.st_mode) ? EISDIR : 0);
|
||||
if (err)
|
||||
|
|
@ -1611,12 +1623,36 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
|
|||
|
||||
if (fd >= 0)
|
||||
{
|
||||
/* We succeeded; return this descriptor and filename. */
|
||||
if (storeptr)
|
||||
*storeptr = string;
|
||||
UNGCPRO;
|
||||
return fd;
|
||||
if (newer)
|
||||
{
|
||||
struct timespec mtime = get_stat_mtime (&st);
|
||||
|
||||
if (!save_fd || timespec_cmp (save_mtime, mtime) < 0)
|
||||
{
|
||||
if (save_fd) emacs_close (save_fd);
|
||||
save_fd = fd;
|
||||
save_mtime = mtime;
|
||||
save_string = string;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We succeeded; return this descriptor and filename. */
|
||||
if (storeptr)
|
||||
*storeptr = string;
|
||||
UNGCPRO;
|
||||
return fd;
|
||||
}
|
||||
}
|
||||
|
||||
/* No more suffixes. Return the newest. */
|
||||
if (newer && save_fd && ! CONSP (XCDR (tail)))
|
||||
{
|
||||
if (storeptr)
|
||||
*storeptr = save_string;
|
||||
UNGCPRO;
|
||||
return save_fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (absolute)
|
||||
|
|
@ -4632,6 +4668,17 @@ variables, this must be set in the first line of a file. */);
|
|||
Vold_style_backquotes = Qnil;
|
||||
DEFSYM (Qold_style_backquotes, "old-style-backquotes");
|
||||
|
||||
DEFVAR_BOOL ("load-prefer-newer", load_prefer_newer,
|
||||
doc: /* Non-nil means `load' prefers the newest version of a file.
|
||||
This applies when a filename suffix is not explicitly specified and
|
||||
`load' is trying various possible suffixes (see `load-suffixes' and
|
||||
`load-file-rep-suffixes'). Normally, it stops at the first file
|
||||
that exists. If this option is non-nil, it checks all suffixes and
|
||||
uses whichever file is newest.
|
||||
Note that if you customize this, obviously it will not affect files
|
||||
that are loaded before your customizations are read! */);
|
||||
load_prefer_newer = 0;
|
||||
|
||||
/* Vsource_directory was initialized in init_lread. */
|
||||
|
||||
DEFSYM (Qcurrent_load_list, "current-load-list");
|
||||
|
|
|
|||
|
|
@ -1530,7 +1530,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
|
|||
|
||||
tem = Qnil;
|
||||
GCPRO4 (name, program, buffer, current_dir);
|
||||
openp (Vexec_path, program, Vexec_suffixes, &tem, make_number (X_OK));
|
||||
openp (Vexec_path, program, Vexec_suffixes, &tem, make_number (X_OK), 0);
|
||||
UNGCPRO;
|
||||
if (NILP (tem))
|
||||
report_file_error ("Searching for program", program);
|
||||
|
|
|
|||
|
|
@ -1332,7 +1332,7 @@ Internal use only, use `play-sound' instead. */)
|
|||
{
|
||||
/* Open the sound file. */
|
||||
current_sound->fd = openp (list1 (Vdata_directory),
|
||||
attrs[SOUND_FILE], Qnil, &file, Qnil);
|
||||
attrs[SOUND_FILE], Qnil, &file, Qnil, 0);
|
||||
if (current_sound->fd < 0)
|
||||
sound_perror ("Could not open sound file");
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/* Utility and Unix shadow routines for GNU Emacs on the Microsoft Windows API.
|
||||
Copyright (C) 1994-1995, 2000-2013 Free Software Foundation, Inc.
|
||||
|
||||
Copyright (C) 1994-1995, 2000-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
|
|
@ -8602,7 +8603,7 @@ check_windows_init_file (void)
|
|||
need to ENCODE_FILE here, but we do need to convert the file
|
||||
names from UTF-8 to ANSI. */
|
||||
init_file = build_string ("term/w32-win");
|
||||
fd = openp (Vload_path, init_file, Fget_load_suffixes (), NULL, Qnil);
|
||||
fd = openp (Vload_path, init_file, Fget_load_suffixes (), NULL, Qnil, 0);
|
||||
if (fd < 0)
|
||||
{
|
||||
Lisp_Object load_path_print = Fprin1_to_string (Vload_path, Qnil);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/* Process support for GNU Emacs on the Microsoft Windows API.
|
||||
Copyright (C) 1992, 1995, 1999-2013 Free Software Foundation, Inc.
|
||||
|
||||
Copyright (C) 1992, 1995, 1999-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
|
|
@ -1592,7 +1593,7 @@ sys_spawnve (int mode, char *cmdname, char **argv, char **envp)
|
|||
program = build_string (cmdname);
|
||||
full = Qnil;
|
||||
GCPRO1 (program);
|
||||
openp (Vexec_path, program, Vexec_suffixes, &full, make_number (X_OK));
|
||||
openp (Vexec_path, program, Vexec_suffixes, &full, make_number (X_OK), 0);
|
||||
UNGCPRO;
|
||||
if (NILP (full))
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue