]> git.eshelyaron.com Git - emacs.git/commitdiff
Add load-prefer-newer option, to load .el if newer than .elc
authorGlenn Morris <rgm@gnu.org>
Wed, 18 Dec 2013 03:21:48 +0000 (19:21 -0800)
committerGlenn Morris <rgm@gnu.org>
Wed, 18 Dec 2013 03:21:48 +0000 (19:21 -0800)
* 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
15 files changed:
etc/NEWS
lisp/ChangeLog
lisp/Makefile.in
lisp/cus-start.el
src/ChangeLog
src/callproc.c
src/charset.c
src/emacs.c
src/image.c
src/lisp.h
src/lread.c
src/process.c
src/sound.c
src/w32.c
src/w32proc.c

index 0977accff3f6ff98f49c4d8cc70b3e2de45281a4..4ab3cd31380dc4bc6a690864cd6fe8ef16f98449 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -807,6 +807,11 @@ for something (not just adding elements to it), it ought not to affect you.
 \f
 * 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'.
index 126f10ae79b36f958eec397c24b020c7a510dfb8..435581799b673279e7cbd8b7034b94f0a8260c31 100644 (file)
@@ -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.
 
index 2ac2f3e8d6bb13447281cfb4631f1227724366fd..39452edcbf45882572994a20513a47658f563338 100644 (file)
@@ -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
index 8e94e85f84cb96e0e1b8e0cbbb7b35194804ccff..32013b71125e2053b80833563520f6813036418f 100644 (file)
@@ -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
index 5933f145b488a450dc0f197b5bfb226b3eddf835..937b5c7c4c4dbe47c1fb3aaf9f1715d356e5f4d3 100644 (file)
@@ -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>
index b44f680b3524c6931352900cee479f64ee052b3b..0d30fe549ea1caa763bed399d2df251c37b5a4c1 100644 (file)
@@ -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]);
index 2ef060228eeb8eddd2b352182bed7032e9e65d16..1e14475f111cbe775667e54d33c1a86646c3d9df 100644 (file)
@@ -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)
     {
index 89e04b12b458d80a7a157cd8d59147b241e324b6..791e0524e1533bd80998cdf82e5733ec0cb72781 100644 (file)
@@ -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
index e1c6e5df3cd35efdb720ff199a3c0444af7a0cbd..85f29329bd307ff61c434a966a94b10f7bb6ff7e 100644 (file)
@@ -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;
index 1e68b152dfc6962c586da87a89b1407f891de929..e53d25b3fcb9e689572584f4cf2caeda78945f00 100644 (file)
@@ -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);
index 2bada06f2adc39c6b9c69cb5349c84087ed299c1..c24af0cf9cde0d1530ce0f5d53f47d70c424d6b5 100644 (file)
@@ -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");
index dac4b14dceaafedb4c355b89020d17e07bd87860..bef1e6d68f3339fe184c68e2380ec1d9e91a05b5 100644 (file)
@@ -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);
index f8c6b483056270996d38f5ee38232835da3f8db3..e84f7415cd33ba88b20fba0098f80c37acc9b2a0 100644 (file)
@@ -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");
 
index 159085e7f50df5ace82e5c1434efc493dd5386fa..dde74bfcdd988857e063e751dc7bdbb8f404b572 100644 (file)
--- a/src/w32.c
+++ b/src/w32.c
@@ -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);
index 7d4fb9825fa55cae91eba3859f41823cda76ef27..2b583efba5612a92c357190011b6ac4b2bcfa074 100644 (file)
@@ -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))
        {