X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/a0b5606ec769968b10c765f8ff50f312d691ef62..51caf50203be08ba6f15e0d72b777f036d6bee72:/src/lread.c diff --git a/src/lread.c b/src/lread.c index 1f90970e93..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. @@ -609,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) @@ -622,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. */ @@ -1262,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; @@ -1500,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. @@ -1511,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: @@ -1521,7 +1521,18 @@ 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)) { @@ -2565,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); @@ -2581,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; } @@ -2597,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 == '(') @@ -3523,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) @@ -4091,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); @@ -4118,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 @@ -4139,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 @@ -4162,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, @@ -4228,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) @@ -4260,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))) { @@ -4289,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) { @@ -4305,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 */ + + 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) */ } -#endif /* !CANNOT_DUMP */ + 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; @@ -4452,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. @@ -4570,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). */);