Commit e61b9b87 authored by Stefan Monnier's avatar Stefan Monnier
Browse files

(Vload_suffixes, default_suffixes): New vars.

(openp): Take a lisp list of suffixes.
Check for file-name-handlers even if the file was absolute already.
(syms_of_lread): Declare load-suffixes.
(Fload): Fix up call to openp.
Don't bother checking for file-name-handler at the very beginning.
parent f6333468
...@@ -91,8 +91,8 @@ int load_in_progress; ...@@ -91,8 +91,8 @@ int load_in_progress;
/* Directory in which the sources were found. */ /* Directory in which the sources were found. */
Lisp_Object Vsource_directory; Lisp_Object Vsource_directory;
/* Search path for files to be loaded. */ /* Search path and suffixes for files to be loaded. */
Lisp_Object Vload_path; Lisp_Object Vload_path, Vload_suffixes, default_suffixes;
/* File name of user's init file. */ /* File name of user's init file. */
Lisp_Object Vuser_init_file; Lisp_Object Vuser_init_file;
...@@ -646,13 +646,19 @@ Return t if file exists.") ...@@ -646,13 +646,19 @@ Return t if file exists.")
CHECK_STRING (file, 0); CHECK_STRING (file, 0);
/* If file name is magic, call the handler. */ /* If file name is magic, call the handler. */
/* This shouldn't be necessary any more now that `openp' handles it right.
handler = Ffind_file_name_handler (file, Qload); handler = Ffind_file_name_handler (file, Qload);
if (!NILP (handler)) if (!NILP (handler))
return call5 (handler, Qload, file, noerror, nomessage, nosuffix); return call5 (handler, Qload, file, noerror, nomessage, nosuffix); */
/* Do this after the handler to avoid /* Do this after the handler to avoid
the need to gcpro noerror, nomessage and nosuffix. the need to gcpro noerror, nomessage and nosuffix.
(Below here, we care only whether they are nil or not.) */ (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. */
file = Fsubstitute_in_file_name (file); file = Fsubstitute_in_file_name (file);
/* Avoid weird lossage with null string as arg, /* Avoid weird lossage with null string as arg,
...@@ -660,6 +666,7 @@ Return t if file exists.") ...@@ -660,6 +666,7 @@ Return t if file exists.")
if (XSTRING (file)->size > 0) if (XSTRING (file)->size > 0)
{ {
int size = STRING_BYTES (XSTRING (file)); int size = STRING_BYTES (XSTRING (file));
Lisp_Object tmp[2];
GCPRO1 (file); GCPRO1 (file);
...@@ -679,9 +686,11 @@ Return t if file exists.") ...@@ -679,9 +686,11 @@ Return t if file exists.")
} }
fd = openp (Vload_path, file, fd = openp (Vload_path, file,
(!NILP (nosuffix) ? "" (!NILP (nosuffix) ? Qnil
: ! NILP (must_suffix) ? ".elc.gz:.elc:.el.gz:.el" : !NILP (must_suffix) ? Vload_suffixes
: ".elc:.elc.gz:.el.gz:.el:"), : Fappend (2, (tmp[0] = Vload_suffixes,
tmp[1] = default_suffixes,
tmp))),
&found, 0); &found, 0);
UNGCPRO; UNGCPRO;
} }
...@@ -918,9 +927,11 @@ complete_filename_p (pathname) ...@@ -918,9 +927,11 @@ complete_filename_p (pathname)
/* Search for a file whose name is STR, looking in directories /* Search for a file whose name is STR, looking in directories
in the Lisp list PATH, and trying suffixes from SUFFIX. in the Lisp list PATH, and trying suffixes from SUFFIX.
SUFFIX is a string containing possible suffixes separated by colons.
On success, returns a file descriptor. On failure, returns -1. On success, returns a file descriptor. On failure, returns -1.
SUFFIXES is a list of strings containing possible suffixes.
The empty suffix is automatically added iff the list is empty.
EXEC_ONLY nonzero means don't open the files, EXEC_ONLY nonzero means don't open the files,
just look for one that is executable. In this case, just look for one that is executable. In this case,
returns 1 on success. returns 1 on success.
...@@ -934,9 +945,9 @@ complete_filename_p (pathname) ...@@ -934,9 +945,9 @@ complete_filename_p (pathname)
We do not check for remote files if EXEC_ONLY is nonzero. */ We do not check for remote files if EXEC_ONLY is nonzero. */
int int
openp (path, str, suffix, storeptr, exec_only) openp (path, str, suffixes, storeptr, exec_only)
Lisp_Object path, str; Lisp_Object path, str;
char *suffix; Lisp_Object suffixes;
Lisp_Object *storeptr; Lisp_Object *storeptr;
int exec_only; int exec_only;
{ {
...@@ -948,11 +959,19 @@ openp (path, str, suffix, storeptr, exec_only) ...@@ -948,11 +959,19 @@ openp (path, str, suffix, storeptr, exec_only)
int want_size; int want_size;
Lisp_Object filename; Lisp_Object filename;
struct stat st; struct stat st;
struct gcpro gcpro1, gcpro2, gcpro3; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
Lisp_Object string; Lisp_Object string, tail;
int max_suffix_len = 0;
for (tail = suffixes; CONSP (tail); tail = XCDR (tail))
{
CHECK_STRING (XCAR (tail), 0);
max_suffix_len = max (max_suffix_len,
STRING_BYTES (XSTRING (XCAR (tail))));
}
string = filename = Qnil; string = filename = Qnil;
GCPRO3 (str, string, filename); GCPRO5 (str, string, filename, path, suffixes);
if (storeptr) if (storeptr)
*storeptr = Qnil; *storeptr = Qnil;
...@@ -960,11 +979,9 @@ openp (path, str, suffix, storeptr, exec_only) ...@@ -960,11 +979,9 @@ openp (path, str, suffix, storeptr, exec_only)
if (complete_filename_p (str)) if (complete_filename_p (str))
absolute = 1; absolute = 1;
for (; !NILP (path); path = Fcdr (path)) for (; CONSP (path); path = XCDR (path))
{ {
char *nsuffix; filename = Fexpand_file_name (str, XCAR (path));
filename = Fexpand_file_name (str, Fcar (path));
if (!complete_filename_p (filename)) if (!complete_filename_p (filename))
/* If there are non-absolute elts in PATH (eg ".") */ /* If there are non-absolute elts in PATH (eg ".") */
/* Of course, this could conceivably lose if luser sets /* Of course, this could conceivably lose if luser sets
...@@ -978,17 +995,15 @@ openp (path, str, suffix, storeptr, exec_only) ...@@ -978,17 +995,15 @@ openp (path, str, suffix, storeptr, exec_only)
/* Calculate maximum size of any filename made from /* Calculate maximum size of any filename made from
this path element/specified file name and any possible suffix. */ this path element/specified file name and any possible suffix. */
want_size = strlen (suffix) + STRING_BYTES (XSTRING (filename)) + 1; want_size = max_suffix_len + STRING_BYTES (XSTRING (filename)) + 1;
if (fn_size < want_size) if (fn_size < want_size)
fn = (char *) alloca (fn_size = 100 + want_size); fn = (char *) alloca (fn_size = 100 + want_size);
nsuffix = suffix;
/* Loop over suffixes. */ /* Loop over suffixes. */
while (1) for (tail = NILP (suffixes) ? default_suffixes : suffixes;
CONSP (tail); tail = XCDR (tail))
{ {
char *esuffix = (char *) index (nsuffix, ':'); int lsuffix = STRING_BYTES (XSTRING (XCAR (tail)));
int lsuffix = esuffix ? esuffix - nsuffix : strlen (nsuffix);
Lisp_Object handler; Lisp_Object handler;
/* Concatenate path element/specified name with the suffix. /* Concatenate path element/specified name with the suffix.
...@@ -1009,22 +1024,24 @@ openp (path, str, suffix, storeptr, exec_only) ...@@ -1009,22 +1024,24 @@ openp (path, str, suffix, storeptr, exec_only)
} }
if (lsuffix != 0) /* Bug happens on CCI if lsuffix is 0. */ if (lsuffix != 0) /* Bug happens on CCI if lsuffix is 0. */
strncat (fn, nsuffix, lsuffix); strncat (fn, XSTRING (XCAR (tail))->data, lsuffix);
/* Check that the file exists and is not a directory. */ /* Check that the file exists and is not a directory. */
/* We used to only check for handlers on non-absolute file names:
if (absolute) if (absolute)
handler = Qnil; handler = Qnil;
else else
handler = Ffind_file_name_handler (filename, Qfile_exists_p); handler = Ffind_file_name_handler (filename, Qfile_exists_p);
if (! NILP (handler) && ! exec_only) It's not clear why that was the case and it breaks things like
(load "/bar.el") where the file is actually "/bar.el.gz". */
handler = Ffind_file_name_handler (filename, Qfile_exists_p);
if (!NILP (handler) && !exec_only)
{ {
int exists; int exists;
string = build_string (fn); string = build_string (fn);
exists = ! NILP (exec_only ? Ffile_executable_p (string) exists = !NILP (Ffile_readable_p (string));
: Ffile_readable_p (string)); if (exists && !NILP (Ffile_directory_p (build_string (fn))))
if (exists
&& ! NILP (Ffile_directory_p (build_string (fn))))
exists = 0; exists = 0;
if (exists) if (exists)
...@@ -1058,11 +1075,6 @@ openp (path, str, suffix, storeptr, exec_only) ...@@ -1058,11 +1075,6 @@ openp (path, str, suffix, storeptr, exec_only)
} }
} }
} }
/* Advance to next suffix. */
if (esuffix == 0)
break;
nsuffix += lsuffix + 1;
} }
if (absolute) if (absolute)
break; break;
...@@ -3531,6 +3543,14 @@ Each element is a string (directory name) or nil (try default directory).\n\ ...@@ -3531,6 +3543,14 @@ Each element is a string (directory name) or nil (try default directory).\n\
Initialized based on EMACSLOADPATH environment variable, if any,\n\ Initialized based on EMACSLOADPATH environment variable, if any,\n\
otherwise to default specified by file `epaths.h' when Emacs was built."); otherwise to default specified by file `epaths.h' when Emacs was built.");
DEFVAR_LISP ("load-suffixes", &Vload_suffixes,
"*List of suffixes to try for files to load.
This list should not include the empty string.");
Vload_suffixes = Fcons (build_string (".elc"),
Fcons (build_string (".el"), Qnil));
default_suffixes = Fcons (empty_string, Qnil);
staticpro (&default_suffixes);
DEFVAR_BOOL ("load-in-progress", &load_in_progress, DEFVAR_BOOL ("load-in-progress", &load_in_progress,
"Non-nil iff inside of `load'."); "Non-nil iff inside of `load'.");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment