X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/27e498e6e5fea8ac64c90ac13678b537b7b12302..51caf50203be08ba6f15e0d72b777f036d6bee72:/src/lread.c diff --git a/src/lread.c b/src/lread.c index c4bc6fda81..a64f083a5a 100644 --- a/src/lread.c +++ b/src/lread.c @@ -1,7 +1,6 @@ /* Lisp parsing and input streams. -Copyright (C) 1985-1989, 1993-1995, 1997-2013 Free Software Foundation, -Inc. +Copyright (C) 1985-1989, 1993-1995, 1997-2013 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -145,7 +144,6 @@ static int read_emacs_mule_char (int, int (*) (int, Lisp_Object), static void readevalloop (Lisp_Object, FILE *, Lisp_Object, bool, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); -static void load_unwind (void *); /* Functions that read one byte from the current source READCHARFUN or unreads one byte. If the integer argument C is -1, it returns @@ -610,7 +608,7 @@ read_filtered_event (bool no_switch_frame, bool ascii_required, 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) @@ -623,8 +621,8 @@ read_filtered_event (bool no_switch_frame, bool ascii_required, 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. */ @@ -1040,10 +1038,12 @@ While the file is in the process of being loaded, the variable 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; @@ -1054,7 +1054,6 @@ Return t if the file exists and loads successfully. */) Lisp_Object handler; bool safe_p = 1; const char *fmode = "r"; - Lisp_Object tmp[2]; int version; #ifdef DOS_NT @@ -1087,19 +1086,23 @@ Return t if the file exists and loads successfully. */) 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; @@ -1112,20 +1115,28 @@ Return t if the file exists and loads successfully. */) 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); 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; } @@ -1163,6 +1174,17 @@ Return t if the file exists and loads successfully. */) #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 @@ -1178,11 +1200,7 @@ Return t if the file exists and loads successfully. */) 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); } @@ -1195,9 +1213,8 @@ Return t if the file exists and loads successfully. */) /* 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; @@ -1223,12 +1240,7 @@ Return t if the file exists and loads successfully. */) { 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); } @@ -1249,7 +1261,7 @@ Return t if the file exists and loads successfully. */) } if (result == 0 - && EMACS_TIME_LT (get_stat_mtime (&s1), get_stat_mtime (&s2))) + && timespec_cmp (get_stat_mtime (&s1), get_stat_mtime (&s2)) < 0) { /* Make the progress messages mention that source is newer. */ newer = 1; @@ -1274,7 +1286,10 @@ Return t if the file exists and loads successfully. */) 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); @@ -1284,26 +1299,28 @@ Return t if the file exists and loads successfully. */) 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 = emacs_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); @@ -1322,7 +1339,6 @@ Return t if the file exists and loads successfully. */) message_with_string ("Loading %s...", file, 1); } - record_unwind_protect_ptr (load_unwind, stream); specbind (Qload_file_name, found); specbind (Qinhibit_file_name_operation, Qnil); specbind (Qload_in_progress, Qt); @@ -1374,18 +1390,6 @@ Return t if the file exists and loads successfully. */) return Qt; } - -static void -load_unwind (void *arg) -{ - FILE *stream = arg; - if (stream != NULL) - { - block_input (); - fclose (stream); - unblock_input (); - } -} static bool complete_filename_p (Lisp_Object pathname) @@ -1495,7 +1499,8 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object 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. @@ -1506,7 +1511,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, ? 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: @@ -1516,12 +1521,22 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, 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)) { bool exists; - last_errno = ENOENT; if (NILP (predicate)) exists = !NILP (Ffile_readable_p (string)); else @@ -1576,7 +1591,10 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, { fd = emacs_open (pfn, O_RDONLY, 0); if (fd < 0) - last_errno = errno; + { + if (errno != ENOENT) + last_errno = errno; + } else { struct stat st; @@ -2558,9 +2576,8 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) 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); @@ -2574,11 +2591,12 @@ read1 (Lisp_Object readcharfun, int *pch, bool 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; } @@ -2590,7 +2608,10 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list) build them using function calls. */ Lisp_Object tmp; tmp = read_vector (readcharfun, 1); - make_byte_code (XVECTOR (tmp)); + struct Lisp_Vector* vec = XVECTOR (tmp); + if (vec->header.size==0) + invalid_syntax ("Empty byte-code object"); + make_byte_code (vec); return tmp; } if (c == '(') @@ -3222,7 +3243,7 @@ substitute_object_recurse (Lisp_Object object, Lisp_Object placeholder, Lisp_Obj 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); @@ -3516,7 +3537,7 @@ read_vector (Lisp_Object readcharfun, bool bytecodeflag) 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) @@ -4084,17 +4105,17 @@ defvar_kboard (struct Lisp_Kboard_Objfwd *ko_fwd, SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)ko_fwd); } -/* 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); @@ -4111,19 +4132,23 @@ load_path_check (void) so we can see if the site changed it later during dumping. */ static Lisp_Object dump_path; -/* 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. +/* 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. + + 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. + If !initialized, then just set dump_path and return PATH_DUMPLOADSEARCH. + If initialized, then if Vload_path != dump_path, return just Vload_path. (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.) + This can only be from a site-load file during dumping.) 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 @@ -4132,20 +4157,17 @@ static Lisp_Object dump_path; 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. 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 (bool changed) { + Lisp_Object lpath = Qnil; const char *normal; #ifdef CANNOT_DUMP @@ -4155,63 +4177,48 @@ init_lread (void) 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; + + normal = NILP (Vpurify_flag) ? PATH_LOADSEARCH : 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. */ + change it further. Changes can only be due to site-lisp + files that were processed during dumping. */ + /* FIXME? AFAICS, it does not make sense to change load-path in a + dumped site-lisp file, so maybe we should just drop this check. + E.g., if you add an element to load-path, you are going to be + adding it to PATH_DUMPLOADSEARCH, which refers to the source directory. + This will make no sense (and may not still exist) in an installed Emacs. + And the only change it is sensible to make to load-path is to add + something to the front, which you should do with configure's + --enable-locallisppath option if you really want to have it dumped. */ if (initialized) { - if (NILP (Fequal (dump_path, Vload_path))) + if (changed || 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 (); + /* Do not make any changes. */ + return Vload_path; } 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; + 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, @@ -4221,29 +4228,19 @@ init_lread (void) tem1 = Ffile_accessible_directory_p (tem); if (!NILP (tem1)) { - if (NILP (Fmember (tem, Vload_path))) + if (NILP (Fmember (tem, lpath))) { /* 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 = list1 (tem); + 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); - - /* Add leim under the installation dir, if it is accessible. */ - tem = Fexpand_file_name (build_string ("leim"), - Vinstallation_directory); - tem1 = Ffile_accessible_directory_p (tem); - if (!NILP (tem1)) - { - if (NILP (Fmember (tem, Vload_path))) - Vload_path = Fcons (tem, Vload_path); - } + lpath = nconc2 (lpath, dump_path); /* Add site-lisp under the installation dir, if it exists. */ if (!no_site_lisp) @@ -4253,14 +4250,14 @@ init_lread (void) 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, leim and site-lisp dirs under that directory. */ + the lisp and site-lisp dirs under that directory. */ if (NILP (Fequal (Vinstallation_directory, Vsource_directory))) { @@ -4282,14 +4279,8 @@ init_lread (void) tem = Fexpand_file_name (build_string ("lisp"), Vsource_directory); - if (NILP (Fmember (tem, Vload_path))) - Vload_path = Fcons (tem, Vload_path); - - tem = Fexpand_file_name (build_string ("leim"), - Vsource_directory); - - if (NILP (Fmember (tem, Vload_path))) - Vload_path = Fcons (tem, Vload_path); + if (NILP (Fmember (tem, lpath))) + lpath = Fcons (tem, lpath); if (!no_site_lisp) { @@ -4298,47 +4289,113 @@ init_lread (void) 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); } } } } /* Vinstallation_directory != Vsource_directory */ - } /* if Vinstallation_directory */ - - /* 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 (); + } /* if Vinstallation_directory */ - /* Add the site-lisp directories at the front. */ - if (!no_site_lisp) - { - Lisp_Object sitelisp; - sitelisp = decode_env_path (0, PATH_SITELOADSEARCH); - if (! NILP (sitelisp)) Vload_path = nconc2 (sitelisp, Vload_path); - } - } /* if dump_path == Vload_path */ + } /* if dump_path == Vload_path */ } 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 caused trouble - because it was copied from dump_path into Vload_path, above, - when Vinstallation_directory was non-nil. It should not be + 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. */ + lpath = decode_env_path (0, normal, 0); + dump_path = lpath; } -#endif /* !CANNOT_DUMP */ +#endif /* !CANNOT_DUMP */ + + return lpath; +} + +void +init_lread (void) +{ + /* First, set Vload_path. */ + + /* NB: Do not change Vload_path before calling load_path_default, + since it may check it against dump_path. + (This behavior could be changed.) */ + + /* We explicitly ignore EMACSLOADPATH when dumping. */ + if (NILP (Vpurify_flag) && egetenv ("EMACSLOADPATH")) + { + Lisp_Object elpath = decode_env_path ("EMACSLOADPATH", 0, 1); + + /* Check (non-nil) user-supplied elements. */ + load_path_check (elpath); + + /* If no nils in the environment variable, use as-is. + Otherwise, replace any nils with the default. */ + if (NILP (Fmemq (Qnil, elpath))) + { + Vload_path = elpath; + } + else + { + Lisp_Object elem, default_lpath = load_path_default (0); + + /* Check defaults, before adding site-lisp. */ + load_path_check (default_lpath); + + /* 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, 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); + } + } /* Fmemq (Qnil, Vload_path) */ + } + else /* Vpurify_flag || !EMACSLOADPATH */ + { +#ifdef CANNOT_DUMP + bool changed = 0; +#else + bool changed = initialized && NILP (Fequal (dump_path, Vload_path)); +#endif + + Vload_path = load_path_default (changed); + + /* 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, unless the + load-path has already been changed. + FIXME? Should we ignore changed here? */ + if (initialized && !no_site_lisp && !changed) + { + Lisp_Object sitelisp; + sitelisp = decode_env_path (0, PATH_SITELOADSEARCH, 0); + if (! NILP (sitelisp)) Vload_path = nconc2 (sitelisp, Vload_path); + } + } /* !Vpurify_flag && EMACSLOADPATH */ Vvalues = Qnil; @@ -4445,9 +4502,8 @@ were read in. */); 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. @@ -4563,7 +4619,7 @@ and is not meant for users to change. */); 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). */);