/* Lisp parsing and input streams.
-Copyright (C) 1985-1989, 1993-1995, 1997-2013 Free Software Foundation,
+Copyright (C) 1985-1989, 1993-1995, 1997-2015 Free Software Foundation,
Inc.
This file is part of GNU Emacs.
#include <config.h>
-#include <stdio.h>
+#include "sysstdio.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include "keyboard.h"
#include "frame.h"
#include "termhooks.h"
-#include "coding.h"
#include "blockinput.h"
#ifdef MSDOS
It must be set to nil before all top-level calls to read0. */
static Lisp_Object read_objects;
-/* List of descriptors now open for Fload. */
-static Lisp_Object load_descriptor_list;
-
/* File for get_file_char to read from. Use by load. */
static FILE *instream;
static void readevalloop (Lisp_Object, FILE *, Lisp_Object, bool,
Lisp_Object, Lisp_Object,
Lisp_Object, Lisp_Object);
-static Lisp_Object load_unwind (Lisp_Object);
-static Lisp_Object load_descriptor_unwind (Lisp_Object);
\f
/* Functions that read one byte from the current source READCHARFUN
or unreads one byte. If the integer argument C is -1, it returns
ptrdiff_t pt_byte = BUF_PT_BYTE (inbuffer);
+ if (! BUFFER_LIVE_P (inbuffer))
+ return -1;
+
if (pt_byte >= BUF_ZV_BYTE (inbuffer))
return -1;
return STRING_CHAR (buf);
}
+#define FROM_FILE_P(readcharfun) \
+ (EQ (readcharfun, Qget_file_char) \
+ || EQ (readcharfun, Qget_emacs_mule_file_char))
+
static void
skip_dyn_bytes (Lisp_Object readcharfun, ptrdiff_t n)
{
- if (EQ (readcharfun, Qget_file_char)
- || EQ (readcharfun, Qget_emacs_mule_file_char))
+ if (FROM_FILE_P (readcharfun))
{
block_input (); /* FIXME: Not sure if it's needed. */
fseek (instream, n, SEEK_CUR);
}
}
+static void
+skip_dyn_eof (Lisp_Object readcharfun)
+{
+ if (FROM_FILE_P (readcharfun))
+ {
+ block_input (); /* FIXME: Not sure if it's needed. */
+ fseek (instream, 0, SEEK_END);
+ unblock_input ();
+ }
+ else
+ while (READCHAR >= 0);
+}
+
/* Unread the character C in the way appropriate for the stream READCHARFUN.
If the stream is a user function, call it with the char as argument. */
{
unread_char = c;
}
- else if (EQ (readcharfun, Qget_file_char)
- || EQ (readcharfun, Qget_emacs_mule_file_char))
+ else if (FROM_FILE_P (readcharfun))
{
unread_char = c;
}
c = DECODE_CHAR (charset, code);
if (c < 0)
Fsignal (Qinvalid_read_syntax,
- Fcons (build_string ("invalid multibyte form"), Qnil));
+ list1 (build_string ("invalid multibyte form")));
return c;
}
bool error_nonascii, bool input_method, Lisp_Object seconds)
{
Lisp_Object val, delayed_switch_frame;
- EMACS_TIME end_time;
+ struct timespec end_time;
#ifdef HAVE_WINDOW_SYSTEM
if (display_hourglass_p)
if (NUMBERP (seconds))
{
double duration = extract_float (seconds);
- EMACS_TIME wait_time = EMACS_TIME_FROM_DOUBLE (duration);
- end_time = add_emacs_time (current_emacs_time (), wait_time);
+ struct timespec wait_time = dtotimespec (duration);
+ end_time = timespec_add (current_timespec (), wait_time);
}
/* Read until we get an acceptable event. */
{
if (error_nonascii)
{
- Vunread_command_events = Fcons (val, Qnil);
+ Vunread_command_events = list1 (val);
error ("Non-character input-event");
}
else
{
bool rv = 0;
enum {
- NOMINAL, AFTER_FIRST_DASH, AFTER_ASTERIX,
+ NOMINAL, AFTER_FIRST_DASH, AFTER_ASTERIX
} beg_end_state = NOMINAL;
bool in_file_vars = 0;
/* Callback for record_unwind_protect. Restore the old load list OLD,
after loading a file successfully. */
-static Lisp_Object
+static void
record_load_unwind (Lisp_Object old)
{
- return Vloads_in_progress = old;
+ Vloads_in_progress = old;
}
/* This handler function is used via internal_condition_case_1. */
return Qnil;
}
-static Lisp_Object
+static void
load_warn_old_style_backquotes (Lisp_Object file)
{
if (!NILP (Vold_style_backquotes))
args[1] = file;
Fmessage (2, args);
}
- return Qnil;
}
DEFUN ("get-load-suffixes", Fget_load_suffixes, Sget_load_suffixes, 0, 0, 0,
return value of `get-load-suffixes' is used, i.e. the file name is
required to have a non-empty suffix.
+When searching suffixes, this function normally stops at the first
+one that exists. If the option `load-prefer-newer' is non-nil,
+however, it tries all suffixes, and uses whichever file is the newest.
+
Loading a file records its definitions, and its `provide' and
`require' calls, in an element of `load-history' whose
car is the file name loaded. See `load-history'.
is bound to the file's name.
Return t if the file exists and loads successfully. */)
- (Lisp_Object file, Lisp_Object noerror, Lisp_Object nomessage, Lisp_Object nosuffix, Lisp_Object must_suffix)
+ (Lisp_Object file, Lisp_Object noerror, Lisp_Object nomessage,
+ Lisp_Object nosuffix, Lisp_Object must_suffix)
{
- register FILE *stream;
- register int fd = -1;
+ FILE *stream;
+ int fd;
+ int fd_index;
ptrdiff_t count = SPECPDL_INDEX ();
struct gcpro gcpro1, gcpro2, gcpro3;
Lisp_Object found, efound, hist_file_name;
Lisp_Object handler;
bool safe_p = 1;
const char *fmode = "r";
- Lisp_Object tmp[2];
int version;
#ifdef DOS_NT
else
file = Fsubstitute_in_file_name (file);
-
/* Avoid weird lossage with null string as arg,
since it would try to load a directory as a Lisp file. */
- if (SBYTES (file) > 0)
+ if (SCHARS (file) == 0)
{
- ptrdiff_t size = SBYTES (file);
-
+ fd = -1;
+ errno = ENOENT;
+ }
+ else
+ {
+ Lisp_Object suffixes;
found = Qnil;
GCPRO2 (file, found);
if (! NILP (must_suffix))
{
/* Don't insist on adding a suffix if FILE already ends with one. */
+ ptrdiff_t size = SBYTES (file);
if (size > 3
&& !strcmp (SSDATA (file) + size - 3, ".el"))
must_suffix = Qnil;
must_suffix = Qnil;
}
- fd = openp (Vload_path, file,
- (!NILP (nosuffix) ? Qnil
- : !NILP (must_suffix) ? Fget_load_suffixes ()
- : Fappend (2, (tmp[0] = Fget_load_suffixes (),
- tmp[1] = Vload_file_rep_suffixes,
- tmp))),
- &found, Qnil);
+ if (!NILP (nosuffix))
+ suffixes = Qnil;
+ else
+ {
+ suffixes = Fget_load_suffixes ();
+ if (NILP (must_suffix))
+ {
+ Lisp_Object arg[2];
+ arg[0] = suffixes;
+ arg[1] = Vload_file_rep_suffixes;
+ suffixes = Fappend (2, arg);
+ }
+ }
+
+ fd = openp (Vload_path, file, suffixes, &found, Qnil, load_prefer_newer);
UNGCPRO;
}
if (fd == -1)
{
if (NILP (noerror))
- xsignal2 (Qfile_error, build_string ("Cannot open load file"), file);
+ report_file_error ("Cannot open load file", file);
return Qnil;
}
#endif
}
+ if (fd < 0)
+ {
+ /* Pacify older GCC with --enable-gcc-warnings. */
+ IF_LINT (fd_index = 0);
+ }
+ else
+ {
+ fd_index = SPECPDL_INDEX ();
+ record_unwind_protect_int (close_file_unwind, fd);
+ }
+
/* Check if we're stuck in a recursive load cycle.
2000-09-21: It's not possible to just check for the file loaded
Lisp_Object tem;
for (tem = Vloads_in_progress; CONSP (tem); tem = XCDR (tem))
if (!NILP (Fequal (found, XCAR (tem))) && (++load_count > 3))
- {
- if (fd >= 0)
- emacs_close (fd);
- signal_error ("Recursive load", Fcons (found, Vloads_in_progress));
- }
+ signal_error ("Recursive load", Fcons (found, Vloads_in_progress));
record_unwind_protect (record_load_unwind, Vloads_in_progress);
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))
+ ? concat2 (Ffile_name_directory (file),
+ Ffile_name_nondirectory (found))
: found) ;
version = -1;
{
safe_p = 0;
if (!load_dangerous_libraries)
- {
- if (fd >= 0)
- emacs_close (fd);
- error ("File `%s' was not compiled in Emacs",
- SDATA (found));
- }
+ error ("File `%s' was not compiled in Emacs", SDATA (found));
else if (!NILP (nomessage) && !force_load_messages)
message_with_string ("File `%s' not compiled in Emacs", found, 1);
}
#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
- && EMACS_TIME_LT (get_stat_mtime (&s1), get_stat_mtime (&s2)))
- {
- /* 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;
}
}
Lisp_Object val;
if (fd >= 0)
- emacs_close (fd);
+ {
+ emacs_close (fd);
+ clear_unwind_protect (fd_index);
+ }
val = call4 (Vload_source_file_function, found, hist_file_name,
NILP (noerror) ? Qnil : Qt,
(NILP (nomessage) || force_load_messages) ? Qnil : Qt);
GCPRO3 (file, found, hist_file_name);
-#ifdef WINDOWSNT
- efound = ENCODE_FILE (found);
- /* If we somehow got here with fd == -2, meaning the file is deemed
- to be remote, don't even try to reopen the file locally; just
- force a failure instead. */
- if (fd >= 0)
+ if (fd < 0)
{
- emacs_close (fd);
- stream = fopen (SSDATA (efound), fmode);
+ /* We somehow got here with fd == -2, meaning the file is deemed
+ to be remote. Don't even try to reopen the file locally;
+ just force a failure. */
+ stream = NULL;
+ errno = EINVAL;
}
else
- stream = NULL;
-#else /* not WINDOWSNT */
- stream = fdopen (fd, fmode);
-#endif /* not WINDOWSNT */
- if (stream == 0)
{
+#ifdef WINDOWSNT
emacs_close (fd);
- error ("Failure to create stdio stream for %s", SDATA (file));
+ clear_unwind_protect (fd_index);
+ efound = ENCODE_FILE (found);
+ stream = emacs_fopen (SSDATA (efound), fmode);
+#else
+ stream = fdopen (fd, fmode);
+#endif
}
+ if (! stream)
+ report_file_error ("Opening stdio stream", file);
+ set_unwind_protect_ptr (fd_index, fclose_unwind, stream);
if (! NILP (Vpurify_flag))
Vpreloaded_file_list = Fcons (Fpurecopy (file), Vpreloaded_file_list);
message_with_string ("Loading %s...", file, 1);
}
- record_unwind_protect (load_unwind, make_save_pointer (stream));
- record_unwind_protect (load_descriptor_unwind, load_descriptor_list);
specbind (Qload_file_name, found);
specbind (Qinhibit_file_name_operation, Qnil);
- load_descriptor_list
- = Fcons (make_number (fileno (stream)), load_descriptor_list);
specbind (Qload_in_progress, Qt);
instream = stream;
return Qt;
}
-
-static Lisp_Object
-load_unwind (Lisp_Object arg) /* Used as unwind-protect function in load. */
-{
- FILE *stream = XSAVE_POINTER (arg, 0);
- if (stream != NULL)
- {
- block_input ();
- fclose (stream);
- unblock_input ();
- }
- return Qnil;
-}
-
-static Lisp_Object
-load_descriptor_unwind (Lisp_Object oldlist)
-{
- load_descriptor_list = oldlist;
- return Qnil;
-}
-
-/* Close all descriptors in use for Floads.
- This is used when starting a subprocess. */
-
-void
-close_load_descs (void)
-{
-#ifndef WINDOWSNT
- Lisp_Object tail;
- for (tail = load_descriptor_list; CONSP (tail); tail = XCDR (tail))
- emacs_close (XFASTINT (XCAR (tail)));
-#endif
-}
\f
static bool
complete_filename_p (Lisp_Object pathname)
(Lisp_Object filename, Lisp_Object path, Lisp_Object suffixes, Lisp_Object predicate)
{
Lisp_Object file;
- int fd = openp (path, filename, suffixes, &file, predicate);
- if (NILP (predicate) && fd > 0)
- close (fd);
+ int fd = openp (path, filename, suffixes, &file, predicate, false);
+ if (NILP (predicate) && fd >= 0)
+ emacs_close (fd);
return file;
}
/* Search for a file whose name is STR, looking in directories
in the Lisp list PATH, and trying suffixes from SUFFIX.
- On success, returns a file descriptor. On failure, returns -1.
+ On success, return a file descriptor (or 1 or -2 as described below).
+ On failure, return -1 and set errno.
SUFFIXES is a list of strings containing possible suffixes.
The empty suffix is automatically added if the list is empty.
PREDICATE non-nil means don't open the files,
just look for one that satisfies the predicate. In this case,
- returns 1 on success. The predicate can be a lisp function or
+ return 1 on success. The predicate can be a lisp function or
an integer to pass to `access' (in which case file-name-handlers
are ignored).
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,
+ or if PREDICATE is specified. */
int
-openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *storeptr, Lisp_Object predicate)
+openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
+ Lisp_Object *storeptr, Lisp_Object predicate, bool newer)
{
ptrdiff_t fn_size = 100;
char buf[100];
char *fn = buf;
- bool absolute = 0;
+ bool absolute;
ptrdiff_t want_length;
Lisp_Object filename;
- struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
- Lisp_Object string, tail, encoded_fn;
+ struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6, gcpro7;
+ Lisp_Object string, tail, encoded_fn, save_string;
ptrdiff_t max_suffix_len = 0;
+ int last_errno = ENOENT;
+ int save_fd = -1;
+
+ /* The last-modified time of the newest matching file found.
+ Initialize it to something less than all valid timestamps. */
+ struct timespec save_mtime = make_timespec (TYPE_MINIMUM (time_t), -1);
CHECK_STRING (str);
SBYTES (XCAR (tail)));
}
- string = filename = encoded_fn = Qnil;
- GCPRO6 (str, string, filename, path, suffixes, encoded_fn);
+ string = filename = encoded_fn = save_string = Qnil;
+ GCPRO7 (str, string, save_string, filename, path, suffixes, encoded_fn);
if (storeptr)
*storeptr = Qnil;
- if (complete_filename_p (str))
- absolute = 1;
+ absolute = complete_filename_p (str);
for (; CONSP (path); path = XCDR (path))
{
fn = alloca (fn_size = 100 + want_length);
/* Loop over suffixes. */
- for (tail = NILP (suffixes) ? Fcons (empty_unibyte_string, Qnil) : suffixes;
+ for (tail = NILP (suffixes) ? list1 (empty_unibyte_string) : suffixes;
CONSP (tail); tail = XCDR (tail))
{
- ptrdiff_t fnlen, lsuffix = SBYTES (XCAR (tail));
+ Lisp_Object suffix = XCAR (tail);
+ ptrdiff_t fnlen, lsuffix = SBYTES (suffix);
Lisp_Object handler;
/* Concatenate path element/specified name with the suffix.
? 2 : 0);
fnlen = SBYTES (filename) - prefixlen;
memcpy (fn, SDATA (filename) + prefixlen, fnlen);
- memcpy (fn + fnlen, SDATA (XCAR (tail)), lsuffix + 1);
+ memcpy (fn + fnlen, SDATA (suffix), lsuffix + 1);
fnlen += lsuffix;
/* Check that the file exists and is not a directory. */
/* We used to only check for handlers on non-absolute file names:
handler = Ffind_file_name_handler (filename, Qfile_exists_p);
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". */
- string = make_string (fn, fnlen);
+ /* make_string has its own ideas on when to return a unibyte
+ string and when a multibyte string, but we know better.
+ We must have a unibyte string when dumping, since
+ file-name encoding is shaky at best at that time, and in
+ particular default-file-name-coding-system is reset
+ several times during loadup. We therefore don't want to
+ encode the file before passing it to file I/O library
+ functions. */
+ if (!STRING_MULTIBYTE (filename) && !STRING_MULTIBYTE (suffix))
+ string = make_unibyte_string (fn, fnlen);
+ else
+ string = make_string (fn, fnlen);
handler = Ffind_file_name_handler (string, Qfile_exists_p);
if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate))
{
else
{
Lisp_Object tmp = call1 (predicate, string);
- exists = !NILP (tmp)
- && (EQ (tmp, Qdir_ok)
- || NILP (Ffile_directory_p (string)));
+ if (NILP (tmp))
+ exists = false;
+ else if (EQ (tmp, Qdir_ok)
+ || NILP (Ffile_directory_p (string)))
+ exists = true;
+ else
+ {
+ exists = false;
+ last_errno = EISDIR;
+ }
}
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);
/* Check that we can access or open it. */
if (NATNUMP (predicate))
- fd = (((XFASTINT (predicate) & ~INT_MAX) == 0
- && (faccessat (AT_FDCWD, pfn, XFASTINT (predicate),
+ {
+ fd = -1;
+ if (INT_MAX < XFASTINT (predicate))
+ last_errno = EINVAL;
+ else if (faccessat (AT_FDCWD, pfn, XFASTINT (predicate),
AT_EACCESS)
== 0)
- && ! file_directory_p (pfn))
- ? 1 : -1);
+ {
+ if (file_directory_p (pfn))
+ last_errno = EISDIR;
+ else
+ fd = 1;
+ }
+ }
else
{
- struct stat st;
fd = emacs_open (pfn, O_RDONLY, 0);
- if (0 <= fd
- && (fstat (fd, &st) != 0 || S_ISDIR (st.st_mode)))
+ if (fd < 0)
{
- emacs_close (fd);
- fd = -1;
+ if (errno != ENOENT)
+ last_errno = errno;
+ }
+ else
+ {
+ int err = (fstat (fd, &st) != 0 ? errno
+ : S_ISDIR (st.st_mode) ? EISDIR : 0);
+ if (err)
+ {
+ last_errno = err;
+ emacs_close (fd);
+ fd = -1;
+ }
}
}
if (fd >= 0)
{
- /* We succeeded; return this descriptor and filename. */
- if (storeptr)
- *storeptr = string;
- UNGCPRO;
- return fd;
+ if (newer && !NATNUMP (predicate))
+ {
+ struct timespec mtime = get_stat_mtime (&st);
+
+ if (timespec_cmp (mtime, save_mtime) <= 0)
+ emacs_close (fd);
+ else
+ {
+ if (0 <= 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 (0 <= save_fd && ! CONSP (XCDR (tail)))
+ {
+ if (storeptr)
+ *storeptr = save_string;
+ UNGCPRO;
+ return save_fd;
+ }
}
}
if (absolute)
}
UNGCPRO;
+ errno = last_errno;
return -1;
}
Vload_history);
}
-static Lisp_Object
-readevalloop_1 (Lisp_Object old)
+static void
+readevalloop_1 (int old)
{
- load_convert_to_unibyte = ! NILP (old);
- return Qnil;
+ load_convert_to_unibyte = old;
}
/* Signal an `end-of-file' error, if possible with file name
specbind (Qstandard_input, readcharfun); /* GCPROs readcharfun. */
specbind (Qcurrent_load_list, Qnil);
- record_unwind_protect (readevalloop_1, load_convert_to_unibyte ? Qt : Qnil);
+ record_unwind_protect_int (readevalloop_1, load_convert_to_unibyte);
load_convert_to_unibyte = !NILP (unibyte);
/* If lexical binding is active (either because it was specified in
lexical environment, otherwise, turn off lexical binding. */
lex_bound = find_symbol_value (Qlexical_binding);
specbind (Qinternal_interpreter_environment,
- NILP (lex_bound) || EQ (lex_bound, Qunbound)
- ? Qnil : Fcons (Qt, Qnil));
+ (NILP (lex_bound) || EQ (lex_bound, Qunbound)
+ ? Qnil : list1 (Qt)));
GCPRO4 (sourcename, readfun, start, end);
if (EQ (stream, Qt))
stream = Qread_char;
if (EQ (stream, Qread_char))
- return Fread_minibuffer (build_string ("Lisp expression: "), Qnil);
+ /* FIXME: ?! When is this used !? */
+ return call1 (intern ("read-minibuffer"),
+ build_string ("Lisp expression: "));
return read_internal_start (stream, Qnil, Qnil);
}
while (c == '0');
}
- while (-1 <= (digit = digit_to_number (c, radix)))
+ while ((digit = digit_to_number (c, radix)) >= -1)
{
if (digit == -1)
valid = 0;
if (c == '"')
{
Lisp_Object tmp, val;
- EMACS_INT size_in_chars
- = ((XFASTINT (length) + BOOL_VECTOR_BITS_PER_CHAR - 1)
- / BOOL_VECTOR_BITS_PER_CHAR);
+ EMACS_INT size_in_chars = bool_vector_bytes (XFASTINT (length));
+ unsigned char *data;
UNREAD (c);
tmp = read1 (readcharfun, pch, first_in_list);
== (SCHARS (tmp) - 1) * BOOL_VECTOR_BITS_PER_CHAR)))
invalid_syntax ("#&...");
- val = Fmake_bool_vector (length, Qnil);
- memcpy (XBOOL_VECTOR (val)->data, SDATA (tmp), size_in_chars);
+ val = make_uninit_bool_vector (XFASTINT (length));
+ data = bool_vector_uchar_data (val);
+ memcpy (data, SDATA (tmp), size_in_chars);
/* Clear the extraneous bits in the last byte. */
if (XINT (length) != size_in_chars * BOOL_VECTOR_BITS_PER_CHAR)
- XBOOL_VECTOR (val)->data[size_in_chars - 1]
+ data[size_in_chars - 1]
&= (1 << (XINT (length) % BOOL_VECTOR_BITS_PER_CHAR)) - 1;
return val;
}
/* Accept compiled functions at read-time so that we don't have to
build them using function calls. */
Lisp_Object tmp;
+ struct Lisp_Vector *vec;
tmp = read_vector (readcharfun, 1);
- make_byte_code (XVECTOR (tmp));
+ vec = XVECTOR (tmp);
+ if (vec->header.size == 0)
+ invalid_syntax ("Empty byte-code object");
+ make_byte_code (vec);
return tmp;
}
if (c == '(')
if (c == '@')
{
enum { extra = 100 };
- ptrdiff_t i, nskip = 0;
+ ptrdiff_t i, nskip = 0, digits = 0;
/* Read a decimal integer. */
while ((c = READCHAR) >= 0
{
if ((STRING_BYTES_BOUND - extra) / 10 <= nskip)
string_overflow ();
+ digits++;
nskip *= 10;
nskip += c - '0';
+ if (digits == 2 && nskip == 0)
+ { /* We've just seen #@00, which means "skip to end". */
+ skip_dyn_eof (readcharfun);
+ return Qnil;
+ }
}
if (nskip > 0)
/* We can't use UNREAD here, because in the code below we side-step
nskip--;
else
UNREAD (c);
-
+
if (load_force_doc_strings
- && (EQ (readcharfun, Qget_file_char)
- || EQ (readcharfun, Qget_emacs_mule_file_char)))
+ && (FROM_FILE_P (readcharfun)))
{
/* If we are supposed to force doc strings into core right now,
record the last string that we skipped,
if (c == '$')
return Vload_file_name;
if (c == '\'')
- return Fcons (Qfunction, Fcons (read0 (readcharfun), Qnil));
+ return list2 (Qfunction, read0 (readcharfun));
/* #:foo is the uninterned symbol named foo. */
if (c == ':')
{
goto retry;
case '\'':
- {
- return Fcons (Qquote, Fcons (read0 (readcharfun), Qnil));
- }
+ return list2 (Qquote, read0 (readcharfun));
case '`':
{
value = read0 (readcharfun);
new_backquote_flag = saved_new_backquote_flag;
- return Fcons (Qbackquote, Fcons (value, Qnil));
+ return list2 (Qbackquote, value);
}
}
case ',':
}
value = read0 (readcharfun);
- return Fcons (comma_type, Fcons (value, Qnil));
+ return list2 (comma_type, value);
}
else
{
if (BOOL_VECTOR_P (subtree))
return subtree; /* No sub-objects anyway. */
else if (CHAR_TABLE_P (subtree) || SUB_CHAR_TABLE_P (subtree)
- || COMPILEDP (subtree))
+ || COMPILEDP (subtree) || HASH_TABLE_P (subtree))
length = ASIZE (subtree) & PSEUDOVECTOR_SIZE_MASK;
else if (VECTORP (subtree))
length = ASIZE (subtree);
state = 0;
leading_digit = digit_to_number (*cp, base);
- if (0 <= leading_digit)
+ if (leading_digit >= 0)
{
state |= LEAD_INT;
do
++cp;
- while (0 <= digit_to_number (*cp, base));
+ while (digit_to_number (*cp, base) >= 0);
}
if (*cp == '.')
{
/* If the number uses integer and not float syntax, and is in C-language
range, use its value, preferably as a fixnum. */
- if (0 <= leading_digit && ! float_syntax)
+ if (leading_digit >= 0 && ! float_syntax)
{
uintmax_t n;
return vector;
}
-/* FLAG means check for ] to terminate rather than ) and . */
+/* FLAG means check for ']' to terminate rather than ')' and '.'. */
static Lisp_Object
read_list (bool flag, Lisp_Object readcharfun)
{
if (NILP (Vdoc_file_name))
/* We have not yet called Snarf-documentation, so assume
- this file is described in the DOC-MM.NN file
+ this file is described in the DOC file
and Snarf-documentation will fill in the right value later.
For now, replace the whole list with 0. */
doc_reference = 1;
{
if (doc_reference == 1)
return make_number (0);
- if (doc_reference == 2)
+ if (doc_reference == 2 && INTEGERP (XCDR (val)))
{
+ char *saved = NULL;
+ file_offset saved_position;
/* Get a doc string from the file we are loading.
If it's in saved_doc_string, get it from there.
&& pos < (saved_doc_string_position
+ saved_doc_string_length))
{
- ptrdiff_t start = pos - saved_doc_string_position;
- ptrdiff_t from, to;
-
- /* Process quoting with ^A,
- and find the end of the string,
- which is marked with ^_ (037). */
- for (from = start, to = start;
- saved_doc_string[from] != 037;)
- {
- int c = saved_doc_string[from++];
- if (c == 1)
- {
- c = saved_doc_string[from++];
- if (c == 1)
- saved_doc_string[to++] = c;
- else if (c == '0')
- saved_doc_string[to++] = 0;
- else if (c == '_')
- saved_doc_string[to++] = 037;
- }
- else
- saved_doc_string[to++] = c;
- }
-
- return make_unibyte_string (saved_doc_string + start,
- to - start);
+ saved = saved_doc_string;
+ saved_position = saved_doc_string_position;
}
/* Look in prev_saved_doc_string the same way. */
else if (pos >= prev_saved_doc_string_position
&& pos < (prev_saved_doc_string_position
+ prev_saved_doc_string_length))
{
- ptrdiff_t start =
- pos - prev_saved_doc_string_position;
+ saved = prev_saved_doc_string;
+ saved_position = prev_saved_doc_string_position;
+ }
+ if (saved)
+ {
+ ptrdiff_t start = pos - saved_position;
ptrdiff_t from, to;
/* Process quoting with ^A,
and find the end of the string,
which is marked with ^_ (037). */
for (from = start, to = start;
- prev_saved_doc_string[from] != 037;)
+ saved[from] != 037;)
{
- int c = prev_saved_doc_string[from++];
+ int c = saved[from++];
if (c == 1)
{
- c = prev_saved_doc_string[from++];
- if (c == 1)
- prev_saved_doc_string[to++] = c;
- else if (c == '0')
- prev_saved_doc_string[to++] = 0;
- else if (c == '_')
- prev_saved_doc_string[to++] = 037;
+ c = saved[from++];
+ saved[to++] = (c == 1 ? c
+ : c == '0' ? 0
+ : c == '_' ? 037
+ : c);
}
else
- prev_saved_doc_string[to++] = c;
+ saved[to++] = c;
}
- return make_unibyte_string (prev_saved_doc_string
- + start,
+ return make_unibyte_string (saved + start,
to - start);
}
else
}
invalid_syntax ("] in a list");
}
- tem = Fcons (elt, Qnil);
+ tem = list1 (elt);
if (!NILP (tail))
XSETCDR (tail, tem);
else
The value is t if a symbol was found and deleted, nil otherwise.
NAME may be a string or a symbol. If it is a symbol, that symbol
is deleted, if it belongs to OBARRAY--no other symbol is deleted.
-OBARRAY defaults to the value of the variable `obarray'. */)
+OBARRAY, if nil, defaults to the value of the variable `obarray'.
+usage: (unintern NAME OBARRAY) */)
(Lisp_Object name, Lisp_Object obarray)
{
register Lisp_Object string, tem;
\f
/* Return the symbol in OBARRAY whose names matches the string
of SIZE characters (SIZE_BYTE bytes) at PTR.
- If there is no such symbol in OBARRAY, return nil.
+ If there is no such symbol, return the integer bucket number of
+ where the symbol would be if it were present.
Also store the bucket number in oblookup_last_bucket_number. */
SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)ko_fwd);
}
\f
-/* Check that the elements of Vload_path exist. */
+/* Check that the elements of lpath exist. */
static void
-load_path_check (void)
+load_path_check (Lisp_Object lpath)
{
Lisp_Object path_tail;
/* The only elements that might not exist are those from
PATH_LOADSEARCH, EMACSLOADPATH. Anything else is only added if
it exists. */
- for (path_tail = Vload_path; !NILP (path_tail); path_tail = XCDR (path_tail))
+ for (path_tail = lpath; !NILP (path_tail); path_tail = XCDR (path_tail))
{
Lisp_Object dirfile;
dirfile = Fcar (path_tail);
}
}
-/* Record the value of load-path used at the start of dumping
- so we can see if the site changed it later during dumping. */
-static Lisp_Object dump_path;
+/* Return the default load-path, to be used if EMACSLOADPATH is unset.
+ This does not include the standard site-lisp directories
+ under the installation prefix (i.e., PATH_SITELOADSEARCH),
+ but it does (unless no_site_lisp is set) include site-lisp
+ directories in the source/build directories if those exist and we
+ are running uninstalled.
-/* Compute the default Vload_path, with the following logic:
- If CANNOT_DUMP:
- use EMACSLOADPATH env-var if set; otherwise use PATH_LOADSEARCH,
- prepending PATH_SITELOADSEARCH unless --no-site-lisp.
+ Uses the following logic:
+ If CANNOT_DUMP: Use PATH_LOADSEARCH.
The remainder is what happens when dumping works:
If purify-flag (ie dumping) just use PATH_DUMPLOADSEARCH.
- Otherwise use EMACSLOADPATH if set, else PATH_LOADSEARCH.
+ Otherwise use PATH_LOADSEARCH.
- If !initialized, then just set both Vload_path and dump_path.
- If initialized, then if Vload_path != dump_path, do nothing.
- (Presumably the load-path has already been changed by something.
- This can only be from a site-load file during dumping,
- or because EMACSLOADPATH is set.)
+ If !initialized, then just return PATH_DUMPLOADSEARCH.
+ If initialized:
If Vinstallation_directory is not nil (ie, running uninstalled):
If installation-dir/lisp exists and not already a member,
we must be running uninstalled. Reset the load-path
to just installation-dir/lisp. (The default PATH_LOADSEARCH
refers to the eventual installation directories. Since we
are not yet installed, we should not use them, even if they exist.)
- If installation-dir/lisp does not exist, just add dump_path at the
- end instead.
- Add installation-dir/leim (if exists and not already a member) at the front.
+ If installation-dir/lisp does not exist, just add
+ PATH_DUMPLOADSEARCH at the end instead.
Add installation-dir/site-lisp (if !no_site_lisp, and exists
and not already a member) at the front.
If installation-dir != source-dir (ie running an uninstalled,
out-of-tree build) AND install-dir/src/Makefile exists BUT
install-dir/src/Makefile.in does NOT exist (this is a sanity
- check), then repeat the above steps for source-dir/lisp,
- leim and site-lisp.
- Finally, add the site-lisp directories at the front (if !no_site_lisp).
-*/
+ check), then repeat the above steps for source-dir/lisp, site-lisp. */
-void
-init_lread (void)
+static Lisp_Object
+load_path_default (void)
{
+ Lisp_Object lpath = Qnil;
const char *normal;
#ifdef CANNOT_DUMP
normal = PATH_LOADSEARCH;
#ifdef HAVE_NS
- Vload_path = decode_env_path ("EMACSLOADPATH", loadpath ? loadpath : normal);
+ lpath = decode_env_path (0, loadpath ? loadpath : normal, 0);
#else
- Vload_path = decode_env_path ("EMACSLOADPATH", normal);
+ lpath = decode_env_path (0, normal, 0);
#endif
- load_path_check ();
-
- /* FIXME CANNOT_DUMP platforms should get source-dir/lisp etc added
- to their load-path too, AFAICS. I don't think we can tell the
- difference between initialized and !initialized in this case,
- so we'll have to do it unconditionally when Vinstallation_directory
- is non-nil. */
- if (!no_site_lisp && !egetenv ("EMACSLOADPATH"))
- {
- Lisp_Object sitelisp;
- sitelisp = decode_env_path (0, PATH_SITELOADSEARCH);
- if (! NILP (sitelisp)) Vload_path = nconc2 (sitelisp, Vload_path);
- }
#else /* !CANNOT_DUMP */
- if (NILP (Vpurify_flag))
- {
- normal = PATH_LOADSEARCH;
- /* If the EMACSLOADPATH environment variable is set, use its value.
- This doesn't apply if we're dumping. */
- if (egetenv ("EMACSLOADPATH"))
- Vload_path = decode_env_path ("EMACSLOADPATH", normal);
- }
- else
- normal = PATH_DUMPLOADSEARCH;
-
- /* In a dumped Emacs, we normally reset the value of Vload_path using
- PATH_LOADSEARCH, since the value that was dumped uses lisp/ in
- the source directory, instead of the path of the installed elisp
- libraries. However, if it appears that Vload_path has already been
- changed from the default that was saved before dumping, don't
- change it further. Changes can only be due to EMACSLOADPATH, or
- site-lisp files that were processed during dumping. */
+
+ normal = NILP (Vpurify_flag) ? PATH_LOADSEARCH : PATH_DUMPLOADSEARCH;
+
if (initialized)
{
- if (NILP (Fequal (dump_path, Vload_path)))
- {
- /* Do not make any changes, just check the elements exist. */
- /* Note: --no-site-lisp is ignored.
- I don't know what to do about this. */
- load_path_check ();
- }
- else
- {
#ifdef HAVE_NS
- const char *loadpath = ns_load_path ();
- Vload_path = decode_env_path (0, loadpath ? loadpath : normal);
+ const char *loadpath = ns_load_path ();
+ lpath = decode_env_path (0, loadpath ? loadpath : normal, 0);
#else
- Vload_path = decode_env_path (0, normal);
+ lpath = decode_env_path (0, normal, 0);
#endif
- if (!NILP (Vinstallation_directory))
- {
- Lisp_Object tem, tem1;
-
- /* Add to the path the lisp subdir of the installation
- dir, if it is accessible. Note: in out-of-tree builds,
- this directory is empty save for Makefile. */
- tem = Fexpand_file_name (build_string ("lisp"),
- Vinstallation_directory);
- tem1 = Ffile_accessible_directory_p (tem);
- if (!NILP (tem1))
+ if (!NILP (Vinstallation_directory))
+ {
+ Lisp_Object tem, tem1;
+
+ /* Add to the path the lisp subdir of the installation
+ dir, if it is accessible. Note: in out-of-tree builds,
+ this directory is empty save for Makefile. */
+ tem = Fexpand_file_name (build_string ("lisp"),
+ Vinstallation_directory);
+ tem1 = Ffile_accessible_directory_p (tem);
+ if (!NILP (tem1))
+ {
+ if (NILP (Fmember (tem, lpath)))
{
- if (NILP (Fmember (tem, Vload_path)))
- {
- /* We are running uninstalled. The default load-path
- points to the eventual installed lisp, leim
- directories. We should not use those now, even
- if they exist, so start over from a clean slate. */
- Vload_path = Fcons (tem, Qnil);
- }
+ /* We are running uninstalled. The default load-path
+ points to the eventual installed lisp directories.
+ We should not use those now, even if they exist,
+ so start over from a clean slate. */
+ lpath = list1 (tem);
}
- else
- /* That dir doesn't exist, so add the build-time
- Lisp dirs instead. */
- Vload_path = nconc2 (Vload_path, dump_path);
+ }
+ else
+ /* That dir doesn't exist, so add the build-time
+ Lisp dirs instead. */
+ {
+ Lisp_Object dump_path =
+ decode_env_path (0, PATH_DUMPLOADSEARCH, 0);
+ lpath = nconc2 (lpath, dump_path);
+ }
- /* Add leim under the installation dir, if it is accessible. */
- tem = Fexpand_file_name (build_string ("leim"),
+ /* Add site-lisp under the installation dir, if it exists. */
+ if (!no_site_lisp)
+ {
+ tem = Fexpand_file_name (build_string ("site-lisp"),
Vinstallation_directory);
tem1 = Ffile_accessible_directory_p (tem);
if (!NILP (tem1))
{
- if (NILP (Fmember (tem, Vload_path)))
- Vload_path = Fcons (tem, Vload_path);
+ if (NILP (Fmember (tem, lpath)))
+ lpath = Fcons (tem, lpath);
}
+ }
+
+ /* If Emacs was not built in the source directory,
+ and it is run from where it was built, add to load-path
+ the lisp and site-lisp dirs under that directory. */
+
+ if (NILP (Fequal (Vinstallation_directory, Vsource_directory)))
+ {
+ Lisp_Object tem2;
- /* Add site-lisp under the installation dir, if it exists. */
- if (!no_site_lisp)
+ tem = Fexpand_file_name (build_string ("src/Makefile"),
+ Vinstallation_directory);
+ tem1 = Ffile_exists_p (tem);
+
+ /* Don't be fooled if they moved the entire source tree
+ AFTER dumping Emacs. If the build directory is indeed
+ different from the source dir, src/Makefile.in and
+ src/Makefile will not be found together. */
+ tem = Fexpand_file_name (build_string ("src/Makefile.in"),
+ Vinstallation_directory);
+ tem2 = Ffile_exists_p (tem);
+ if (!NILP (tem1) && NILP (tem2))
{
- tem = Fexpand_file_name (build_string ("site-lisp"),
- Vinstallation_directory);
- tem1 = Ffile_accessible_directory_p (tem);
- if (!NILP (tem1))
+ tem = Fexpand_file_name (build_string ("lisp"),
+ Vsource_directory);
+
+ if (NILP (Fmember (tem, lpath)))
+ lpath = Fcons (tem, lpath);
+
+ if (!no_site_lisp)
{
- if (NILP (Fmember (tem, Vload_path)))
- Vload_path = Fcons (tem, Vload_path);
+ tem = Fexpand_file_name (build_string ("site-lisp"),
+ Vsource_directory);
+ tem1 = Ffile_accessible_directory_p (tem);
+ if (!NILP (tem1))
+ {
+ if (NILP (Fmember (tem, lpath)))
+ lpath = Fcons (tem, lpath);
+ }
}
}
+ } /* Vinstallation_directory != Vsource_directory */
- /* If Emacs was not built in the source directory,
- and it is run from where it was built, add to load-path
- the lisp, leim and site-lisp dirs under that directory. */
+ } /* if Vinstallation_directory */
+ }
+ else /* !initialized */
+ {
+ /* NORMAL refers to PATH_DUMPLOADSEARCH, ie the lisp dir in the
+ source directory. We used to add ../lisp (ie the lisp dir in
+ the build directory) at the front here, but that should not
+ be necessary, since in out of tree builds lisp/ is empty, save
+ for Makefile. */
+ lpath = decode_env_path (0, normal, 0);
+ }
+#endif /* !CANNOT_DUMP */
- if (NILP (Fequal (Vinstallation_directory, Vsource_directory)))
- {
- Lisp_Object tem2;
-
- tem = Fexpand_file_name (build_string ("src/Makefile"),
- Vinstallation_directory);
- tem1 = Ffile_exists_p (tem);
-
- /* Don't be fooled if they moved the entire source tree
- AFTER dumping Emacs. If the build directory is indeed
- different from the source dir, src/Makefile.in and
- src/Makefile will not be found together. */
- tem = Fexpand_file_name (build_string ("src/Makefile.in"),
- Vinstallation_directory);
- tem2 = Ffile_exists_p (tem);
- if (!NILP (tem1) && NILP (tem2))
- {
- tem = Fexpand_file_name (build_string ("lisp"),
- Vsource_directory);
+ return lpath;
+}
- if (NILP (Fmember (tem, Vload_path)))
- Vload_path = Fcons (tem, Vload_path);
+void
+init_lread (void)
+{
+ /* First, set Vload_path. */
- tem = Fexpand_file_name (build_string ("leim"),
- Vsource_directory);
+ /* Ignore EMACSLOADPATH when dumping. */
+#ifdef CANNOT_DUMP
+ bool use_loadpath = true;
+#else
+ bool use_loadpath = NILP (Vpurify_flag);
+#endif
- if (NILP (Fmember (tem, Vload_path)))
- Vload_path = Fcons (tem, Vload_path);
+ if (use_loadpath && egetenv ("EMACSLOADPATH"))
+ {
+ Vload_path = decode_env_path ("EMACSLOADPATH", 0, 1);
- if (!no_site_lisp)
- {
- tem = Fexpand_file_name (build_string ("site-lisp"),
- Vsource_directory);
- tem1 = Ffile_accessible_directory_p (tem);
- if (!NILP (tem1))
- {
- if (NILP (Fmember (tem, Vload_path)))
- Vload_path = Fcons (tem, Vload_path);
- }
- }
- }
- } /* Vinstallation_directory != Vsource_directory */
+ /* Check (non-nil) user-supplied elements. */
+ load_path_check (Vload_path);
- } /* if Vinstallation_directory */
+ /* If no nils in the environment variable, use as-is.
+ Otherwise, replace any nils with the default. */
+ if (! NILP (Fmemq (Qnil, Vload_path)))
+ {
+ Lisp_Object elem, elpath = Vload_path;
+ Lisp_Object default_lpath = load_path_default ();
- /* Check before adding the site-lisp directories.
- The install should have created them, but they are not
- required, so no need to warn if they are absent.
- Or we might be running before installation. */
- load_path_check ();
+ /* Check defaults, before adding site-lisp. */
+ load_path_check (default_lpath);
- /* Add the site-lisp directories at the front. */
+ /* Add the site-lisp directories to the front of the default. */
if (!no_site_lisp)
{
Lisp_Object sitelisp;
- sitelisp = decode_env_path (0, PATH_SITELOADSEARCH);
- if (! NILP (sitelisp)) Vload_path = nconc2 (sitelisp, Vload_path);
+ sitelisp = decode_env_path (0, PATH_SITELOADSEARCH, 0);
+ if (! NILP (sitelisp))
+ default_lpath = nconc2 (sitelisp, default_lpath);
+ }
+
+ Vload_path = Qnil;
+
+ /* Replace nils from EMACSLOADPATH by default. */
+ while (CONSP (elpath))
+ {
+ Lisp_Object arg[2];
+ elem = XCAR (elpath);
+ elpath = XCDR (elpath);
+ arg[0] = Vload_path;
+ arg[1] = NILP (elem) ? default_lpath : Fcons (elem, Qnil);
+ Vload_path = Fappend (2, arg);
}
- } /* if dump_path == Vload_path */
+ } /* Fmemq (Qnil, Vload_path) */
}
- else /* !initialized */
+ else
{
- /* NORMAL refers to PATH_DUMPLOADSEARCH, ie the lisp dir in the
- source directory. We used to add ../lisp (ie the lisp dir in
- the build directory) at the front here, but that caused trouble
- because it was copied from dump_path into Vload_path, above,
- when Vinstallation_directory was non-nil. It should not be
- necessary, since in out of tree builds lisp/ is empty, save
- for Makefile. */
- Vload_path = decode_env_path (0, normal);
- dump_path = Vload_path;
- /* No point calling load_path_check; load-path only contains essential
- elements from the source directory at this point. They cannot
- be missing unless something went extremely (and improbably)
- wrong, in which case the build will fail in obvious ways. */
+ Vload_path = load_path_default ();
+
+ /* Check before adding site-lisp directories.
+ The install should have created them, but they are not
+ required, so no need to warn if they are absent.
+ Or we might be running before installation. */
+ load_path_check (Vload_path);
+
+ /* Add the site-lisp directories at the front. */
+ if (initialized && !no_site_lisp)
+ {
+ Lisp_Object sitelisp;
+ sitelisp = decode_env_path (0, PATH_SITELOADSEARCH, 0);
+ if (! NILP (sitelisp)) Vload_path = nconc2 (sitelisp, Vload_path);
+ }
}
-#endif /* !CANNOT_DUMP */
Vvalues = Qnil;
load_in_progress = 0;
Vload_file_name = Qnil;
-
- load_descriptor_list = Qnil;
-
Vstandard_input = Qt;
Vloads_in_progress = Qnil;
}
DEFVAR_LISP ("load-path", Vload_path,
doc: /* List of directories to search for files to load.
-Each element is a string (directory name) or nil (try default directory).
-Initialized based on EMACSLOADPATH environment variable, if any,
-otherwise to default specified by file `epaths.h' when Emacs was built. */);
+Each element is a string (directory name) or nil (meaning `default-directory').
+Initialized during startup as described in Info node `(elisp)Library Search'. */);
DEFVAR_LISP ("load-suffixes", Vload_suffixes,
doc: /* List of suffixes for (compiled or source) Emacs Lisp files.
This list should not include the empty string.
`load' and related functions try to append these suffixes, in order,
to the specified file name if a Lisp suffix is allowed or required. */);
- Vload_suffixes = Fcons (build_pure_c_string (".elc"),
- Fcons (build_pure_c_string (".el"), Qnil));
+ Vload_suffixes = list2 (build_pure_c_string (".elc"),
+ build_pure_c_string (".el"));
DEFVAR_LISP ("load-file-rep-suffixes", Vload_file_rep_suffixes,
doc: /* List of suffixes that indicate representations of \
the same file.
in order to do so. However, if you want to customize which suffixes
the loading functions recognize as compression suffixes, you should
customize `jka-compr-load-suffixes' rather than the present variable. */);
- Vload_file_rep_suffixes = Fcons (empty_unibyte_string, Qnil);
+ Vload_file_rep_suffixes = list1 (empty_unibyte_string);
DEFVAR_BOOL ("load-in-progress", load_in_progress,
doc: /* Non-nil if inside of `load'. */);
DEFSYM (Qload_in_progress, "load-in-progress");
DEFVAR_LISP ("after-load-alist", Vafter_load_alist,
- doc: /* An alist of expressions to be evalled when particular files are loaded.
-Each element looks like (REGEXP-OR-FEATURE FORMS...).
+ doc: /* An alist of functions to be evalled when particular files are loaded.
+Each element looks like (REGEXP-OR-FEATURE FUNCS...).
REGEXP-OR-FEATURE is either a regular expression to match file names, or
a symbol \(a feature name).
When `load' is run and the file-name argument matches an element's
REGEXP-OR-FEATURE, or when `provide' is run and provides the symbol
-REGEXP-OR-FEATURE, the FORMS in the element are executed.
+REGEXP-OR-FEATURE, the FUNCS in the element are called.
An error in FORMS does not undo the load, but does prevent execution of
the rest of the FORMS. */);
You cannot count on them to still be there! */);
Vsource_directory
= Fexpand_file_name (build_string ("../"),
- Fcar (decode_env_path (0, PATH_DUMPLOADSEARCH)));
+ Fcar (decode_env_path (0, PATH_DUMPLOADSEARCH, 0)));
DEFVAR_LISP ("preloaded-file-list", Vpreloaded_file_list,
doc: /* List of files that were preloaded (when dumping Emacs). */);
Vold_style_backquotes = Qnil;
DEFSYM (Qold_style_backquotes, "old-style-backquotes");
- /* Vsource_directory was initialized in init_lread. */
+ 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 unless you explicitly specify one or the other. 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;
- load_descriptor_list = Qnil;
- staticpro (&load_descriptor_list);
+ /* Vsource_directory was initialized in init_lread. */
DEFSYM (Qcurrent_load_list, "current-load-list");
DEFSYM (Qstandard_input, "standard-input");
DEFSYM (Qdir_ok, "dir-ok");
DEFSYM (Qdo_after_load_evaluation, "do-after-load-evaluation");
- staticpro (&dump_path);
-
staticpro (&read_objects);
read_objects = Qnil;
staticpro (&seen_list);