]> code.delx.au - gnu-emacs/blobdiff - src/lread.c
Fixed a bug in w32-long-file-name.
[gnu-emacs] / src / lread.c
index 9518631ba6dd309583c80a29baf2afcf338df7ca..a64f083a5acbde2cb113f2493e8714757283d5b4 100644 (file)
@@ -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.
 
@@ -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);
 }
 \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);
@@ -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).  */);