]> code.delx.au - gnu-emacs/blobdiff - src/lread.c
Fix bug ref
[gnu-emacs] / src / lread.c
index 8a9088b8ed2c5ec530268ca0516dccde2314ee00..cb808b376772d4087536e393eb0fb8360ac87238 100644 (file)
@@ -25,11 +25,11 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <sys/file.h>
 #include <errno.h>
 #include <limits.h>    /* For CHAR_BIT.  */
 #include <sys/file.h>
 #include <errno.h>
 #include <limits.h>    /* For CHAR_BIT.  */
-#include <setjmp.h>
+#include <stat-time.h>
 #include "lisp.h"
 #include "intervals.h"
 #include "lisp.h"
 #include "intervals.h"
-#include "buffer.h"
 #include "character.h"
 #include "character.h"
+#include "buffer.h"
 #include "charset.h"
 #include "coding.h"
 #include <epaths.h>
 #include "charset.h"
 #include "coding.h"
 #include <epaths.h>
@@ -44,8 +44,11 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "msdos.h"
 #endif
 
 #include "msdos.h"
 #endif
 
+#ifdef HAVE_NS
+#include "nsterm.h"
+#endif
+
 #include <unistd.h>
 #include <unistd.h>
-#include <math.h>
 
 #ifdef HAVE_SETLOCALE
 #include <locale.h>
 
 #ifdef HAVE_SETLOCALE
 #include <locale.h>
@@ -75,7 +78,7 @@ static Lisp_Object Qascii_character, Qload, Qload_file_name;
 Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction;
 static Lisp_Object Qinhibit_file_name_operation;
 static Lisp_Object Qeval_buffer_list;
 Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction;
 static Lisp_Object Qinhibit_file_name_operation;
 static Lisp_Object Qeval_buffer_list;
-static Lisp_Object Qlexical_binding;
+Lisp_Object Qlexical_binding;
 static Lisp_Object Qfile_truename, Qdo_after_load_evaluation; /* ACM 2006/5/16 */
 
 /* Used instead of Qget_file_char while loading *.elc files compiled
 static Lisp_Object Qfile_truename, Qdo_after_load_evaluation; /* ACM 2006/5/16 */
 
 /* Used instead of Qget_file_char while loading *.elc files compiled
@@ -84,8 +87,6 @@ static Lisp_Object Qget_emacs_mule_file_char;
 
 static Lisp_Object Qload_force_doc_strings;
 
 
 static Lisp_Object Qload_force_doc_strings;
 
-extern Lisp_Object Qinternal_interpreter_environment;
-
 static Lisp_Object Qload_in_progress;
 
 /* The association list of objects read with the #n=object form.
 static Lisp_Object Qload_in_progress;
 
 /* The association list of objects read with the #n=object form.
@@ -154,10 +155,6 @@ static void readevalloop (Lisp_Object, FILE*, Lisp_Object, int,
                           Lisp_Object, Lisp_Object);
 static Lisp_Object load_unwind (Lisp_Object);
 static Lisp_Object load_descriptor_unwind (Lisp_Object);
                           Lisp_Object, Lisp_Object);
 static Lisp_Object load_unwind (Lisp_Object);
 static Lisp_Object load_descriptor_unwind (Lisp_Object);
-
-static void invalid_syntax (const char *) NO_RETURN;
-static void end_of_file_error (void) NO_RETURN;
-
 \f
 /* Functions that read one byte from the current source READCHARFUN
    or unreads one byte.  If the integer argument C is -1, it returns
 \f
 /* Functions that read one byte from the current source READCHARFUN
    or unreads one byte.  If the integer argument C is -1, it returns
@@ -188,7 +185,7 @@ static int readbyte_from_string (int, Lisp_Object);
 static int unread_char;
 
 static int
 static int unread_char;
 
 static int
-readchar (Lisp_Object readcharfun, int *multibyte)
+readchar (Lisp_Object readcharfun, bool *multibyte)
 {
   Lisp_Object tem;
   register int c;
 {
   Lisp_Object tem;
   register int c;
@@ -411,9 +408,9 @@ unreadchar (Lisp_Object readcharfun, int c)
     {
       if (load_each_byte)
        {
     {
       if (load_each_byte)
        {
-         BLOCK_INPUT;
+         block_input ();
          ungetc (c, instream);
          ungetc (c, instream);
-         UNBLOCK_INPUT;
+         unblock_input ();
        }
       else
        unread_char = c;
        }
       else
        unread_char = c;
@@ -434,28 +431,28 @@ readbyte_from_file (int c, Lisp_Object readcharfun)
 {
   if (c >= 0)
     {
 {
   if (c >= 0)
     {
-      BLOCK_INPUT;
+      block_input ();
       ungetc (c, instream);
       ungetc (c, instream);
-      UNBLOCK_INPUT;
+      unblock_input ();
       return 0;
     }
 
       return 0;
     }
 
-  BLOCK_INPUT;
+  block_input ();
   c = getc (instream);
 
 #ifdef EINTR
   /* Interrupted reads have been observed while reading over the network.  */
   while (c == EOF && ferror (instream) && errno == EINTR)
     {
   c = getc (instream);
 
 #ifdef EINTR
   /* Interrupted reads have been observed while reading over the network.  */
   while (c == EOF && ferror (instream) && errno == EINTR)
     {
-      UNBLOCK_INPUT;
+      unblock_input ();
       QUIT;
       QUIT;
-      BLOCK_INPUT;
+      block_input ();
       clearerr (instream);
       c = getc (instream);
     }
 #endif
 
       clearerr (instream);
       c = getc (instream);
     }
 #endif
 
-  UNBLOCK_INPUT;
+  unblock_input ();
 
   return (c == EOF ? -1 : c);
 }
 
   return (c == EOF ? -1 : c);
 }
@@ -601,18 +598,9 @@ read_filtered_event (int no_switch_frame, int ascii_required,
   /* Compute timeout.  */
   if (NUMBERP (seconds))
     {
   /* Compute timeout.  */
   if (NUMBERP (seconds))
     {
-      EMACS_TIME wait_time;
-      int sec, usec;
       double duration = extract_float (seconds);
       double duration = extract_float (seconds);
-
-      if (0 < duration)
-       duration_to_sec_usec (duration, &sec, &usec);
-      else
-       sec = usec = 0;
-
-      EMACS_GET_TIME (end_time);
-      EMACS_SET_SECS_USECS (wait_time, sec, usec);
-      EMACS_ADD_TIME (end_time, end_time, wait_time);
+      EMACS_TIME wait_time = EMACS_TIME_FROM_DOUBLE (duration);
+      end_time = add_emacs_time (current_emacs_time (), wait_time);
     }
 
 /* Read until we get an acceptable event.  */
     }
 
 /* Read until we get an acceptable event.  */
@@ -765,9 +753,9 @@ DEFUN ("get-file-char", Fget_file_char, Sget_file_char, 0, 0, 0,
   (void)
 {
   register Lisp_Object val;
   (void)
 {
   register Lisp_Object val;
-  BLOCK_INPUT;
+  block_input ();
   XSETINT (val, getc (instream));
   XSETINT (val, getc (instream));
-  UNBLOCK_INPUT;
+  unblock_input ();
   return val;
 }
 
   return val;
 }
 
@@ -914,7 +902,7 @@ safe_to_load_p (int fd)
 
       if (i >= nbytes
          || fast_c_string_match_ignore_case (Vbytecomp_version_regexp,
 
       if (i >= nbytes
          || fast_c_string_match_ignore_case (Vbytecomp_version_regexp,
-                                             buf + i) < 0)
+                                             buf + i, nbytes - i) < 0)
        safe_p = 0;
     }
   if (safe_p)
        safe_p = 0;
     }
   if (safe_p)
@@ -1226,7 +1214,8 @@ Return t if the file exists and loads successfully.  */)
              SSET (efound, SBYTES (efound) - 1, 'c');
            }
 
              SSET (efound, SBYTES (efound) - 1, 'c');
            }
 
-         if (result == 0 && s1.st_mtime < s2.st_mtime)
+         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;
            {
              /* Make the progress messages mention that source is newer.  */
              newer = 1;
@@ -1361,9 +1350,9 @@ load_unwind (Lisp_Object arg)  /* Used as unwind-protect function in load.  */
   FILE *stream = (FILE *) XSAVE_VALUE (arg)->pointer;
   if (stream != NULL)
     {
   FILE *stream = (FILE *) XSAVE_VALUE (arg)->pointer;
   if (stream != NULL)
     {
-      BLOCK_INPUT;
+      block_input ();
       fclose (stream);
       fclose (stream);
-      UNBLOCK_INPUT;
+      unblock_input ();
     }
   return Qnil;
 }
     }
   return Qnil;
 }
@@ -1489,36 +1478,26 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto
         this path element/specified file name and any possible suffix.  */
       want_length = max_suffix_len + SBYTES (filename);
       if (fn_size <= want_length)
         this path element/specified file name and any possible suffix.  */
       want_length = max_suffix_len + SBYTES (filename);
       if (fn_size <= want_length)
-       fn = (char *) alloca (fn_size = 100 + want_length);
+       fn = alloca (fn_size = 100 + want_length);
 
       /* Loop over suffixes.  */
       for (tail = NILP (suffixes) ? Fcons (empty_unibyte_string, Qnil) : suffixes;
           CONSP (tail); tail = XCDR (tail))
        {
 
       /* Loop over suffixes.  */
       for (tail = NILP (suffixes) ? Fcons (empty_unibyte_string, Qnil) : suffixes;
           CONSP (tail); tail = XCDR (tail))
        {
-         ptrdiff_t lsuffix = SBYTES (XCAR (tail));
+         ptrdiff_t fnlen, lsuffix = SBYTES (XCAR (tail));
          Lisp_Object handler;
          int exists;
 
          /* Concatenate path element/specified name with the suffix.
             If the directory starts with /:, remove that.  */
          Lisp_Object handler;
          int exists;
 
          /* Concatenate path element/specified name with the suffix.
             If the directory starts with /:, remove that.  */
-         if (SCHARS (filename) > 2
-             && SREF (filename, 0) == '/'
-             && SREF (filename, 1) == ':')
-           {
-             strncpy (fn, SSDATA (filename) + 2,
-                      SBYTES (filename) - 2);
-             fn[SBYTES (filename) - 2] = 0;
-           }
-         else
-           {
-             strncpy (fn, SSDATA (filename),
-                      SBYTES (filename));
-             fn[SBYTES (filename)] = 0;
-           }
-
-         if (lsuffix != 0)  /* Bug happens on CCI if lsuffix is 0.  */
-           strncat (fn, SSDATA (XCAR (tail)), lsuffix);
-
+         int prefixlen = ((SCHARS (filename) > 2
+                           && SREF (filename, 0) == '/'
+                           && SREF (filename, 1) == ':')
+                          ? 2 : 0);
+         fnlen = SBYTES (filename) - prefixlen;
+         memcpy (fn, SDATA (filename) + prefixlen, fnlen);
+         memcpy (fn + fnlen, SDATA (XCAR (tail)), 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:
                if (absolute)
          /* Check that the file exists and is not a directory.  */
          /* We used to only check for handlers on non-absolute file names:
                if (absolute)
@@ -1527,7 +1506,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto
                  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".  */
                  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 = build_string (fn);
+         string = make_string (fn, fnlen);
          handler = Ffind_file_name_handler (string, Qfile_exists_p);
          if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate))
             {
          handler = Ffind_file_name_handler (string, Qfile_exists_p);
          if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate))
             {
@@ -1664,7 +1643,7 @@ readevalloop_1 (Lisp_Object old)
 /* Signal an `end-of-file' error, if possible with file name
    information.  */
 
 /* Signal an `end-of-file' error, if possible with file name
    information.  */
 
-static void
+static _Noreturn void
 end_of_file_error (void)
 {
   if (STRINGP (Vload_file_name))
 end_of_file_error (void)
 {
   if (STRINGP (Vload_file_name))
@@ -1699,6 +1678,17 @@ readevalloop (Lisp_Object readcharfun,
   int whole_buffer = 0;
   /* 1 on the first time around.  */
   int first_sexp = 1;
   int whole_buffer = 0;
   /* 1 on the first time around.  */
   int first_sexp = 1;
+  Lisp_Object macroexpand = intern ("internal-macroexpand-for-load");
+
+  if (NILP (Ffboundp (macroexpand))
+      /* Don't macroexpand in .elc files, since it should have been done
+        already.  We actually don't know whether we're in a .elc file or not,
+        so we use circumstancial evidence: .el files normally go through
+        Vload_source_file_function -> load-with-code-conversion
+        -> eval-buffer.  */
+      || EQ (readcharfun, Qget_file_char)
+      || EQ (readcharfun, Qget_emacs_mule_file_char))
+    macroexpand = Qnil;
 
   if (MARKERP (readcharfun))
     {
 
   if (MARKERP (readcharfun))
     {
@@ -1713,7 +1703,7 @@ readevalloop (Lisp_Object readcharfun,
 
   /* We assume START is nil when input is not from a buffer.  */
   if (! NILP (start) && !b)
 
   /* We assume START is nil when input is not from a buffer.  */
   if (! NILP (start) && !b)
-    abort ();
+    emacs_abort ();
 
   specbind (Qstandard_input, readcharfun); /* GCPROs readcharfun.  */
   specbind (Qcurrent_load_list, Qnil);
 
   specbind (Qstandard_input, readcharfun); /* GCPROs readcharfun.  */
   specbind (Qcurrent_load_list, Qnil);
@@ -1743,7 +1733,7 @@ readevalloop (Lisp_Object readcharfun,
     {
       ptrdiff_t count1 = SPECPDL_INDEX ();
 
     {
       ptrdiff_t count1 = SPECPDL_INDEX ();
 
-      if (b != 0 && NILP (BVAR (b, name)))
+      if (b != 0 && !BUFFER_LIVE_P (b))
        error ("Reading from killed buffer");
 
       if (!NILP (start))
        error ("Reading from killed buffer");
 
       if (!NILP (start))
@@ -1828,6 +1818,8 @@ readevalloop (Lisp_Object readcharfun,
       unbind_to (count1, Qnil);
 
       /* Now eval what we just read.  */
       unbind_to (count1, Qnil);
 
       /* Now eval what we just read.  */
+      if (!NILP (macroexpand))
+       val = call1 (macroexpand, val);
       val = eval_sub (val);
 
       if (printflag)
       val = eval_sub (val);
 
       if (printflag)
@@ -2032,7 +2024,7 @@ read_internal_start (Lisp_Object stream, Lisp_Object start, Lisp_Object end)
 /* Signal Qinvalid_read_syntax error.
    S is error string of length N (if > 0)  */
 
 /* Signal Qinvalid_read_syntax error.
    S is error string of length N (if > 0)  */
 
-static void
+static _Noreturn void
 invalid_syntax (const char *s)
 {
   xsignal1 (Qinvalid_read_syntax, build_string (s));
 invalid_syntax (const char *s)
 {
   xsignal1 (Qinvalid_read_syntax, build_string (s));
@@ -2371,9 +2363,9 @@ read_integer (Lisp_Object readcharfun, EMACS_INT radix)
 static Lisp_Object
 read1 (register Lisp_Object readcharfun, int *pch, int first_in_list)
 {
 static Lisp_Object
 read1 (register Lisp_Object readcharfun, int *pch, int first_in_list)
 {
-  register int c;
-  unsigned uninterned_symbol = 0;
-  int multibyte;
+  int c;
+  bool uninterned_symbol = 0;
+  bool multibyte;
 
   *pch = 0;
   load_each_byte = 0;
 
   *pch = 0;
   load_each_byte = 0;
@@ -2635,13 +2627,12 @@ read1 (register Lisp_Object readcharfun, int *pch, int first_in_list)
 
              if (saved_doc_string_size == 0)
                {
 
              if (saved_doc_string_size == 0)
                {
-                 saved_doc_string = (char *) xmalloc (nskip + extra);
+                 saved_doc_string = xmalloc (nskip + extra);
                  saved_doc_string_size = nskip + extra;
                }
              if (nskip > saved_doc_string_size)
                {
                  saved_doc_string_size = nskip + extra;
                }
              if (nskip > saved_doc_string_size)
                {
-                 saved_doc_string = (char *) xrealloc (saved_doc_string,
-                                                       nskip + extra);
+                 saved_doc_string = xrealloc (saved_doc_string, nskip + extra);
                  saved_doc_string_size = nskip + extra;
                }
 
                  saved_doc_string_size = nskip + extra;
                }
 
@@ -2688,13 +2679,13 @@ read1 (register Lisp_Object readcharfun, int *pch, int first_in_list)
              /* No symbol character follows, this is the empty
                 symbol.  */
              UNREAD (c);
              /* No symbol character follows, this is the empty
                 symbol.  */
              UNREAD (c);
-             return Fmake_symbol (build_string (""));
+             return Fmake_symbol (empty_unibyte_string);
            }
          goto read_symbol;
        }
       /* ## is the empty symbol.  */
       if (c == '#')
            }
          goto read_symbol;
        }
       /* ## is the empty symbol.  */
       if (c == '#')
-       return Fintern (build_string (""), Qnil);
+       return Fintern (empty_unibyte_string, Qnil);
       /* Reader forms that can reuse previously read objects.  */
       if (c >= '0' && c <= '9')
        {
       /* Reader forms that can reuse previously read objects.  */
       if (c >= '0' && c <= '9')
        {
@@ -2904,8 +2895,7 @@ read1 (register Lisp_Object readcharfun, int *pch, int first_in_list)
                ptrdiff_t offset = p - read_buffer;
                if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < read_buffer_size)
                  memory_full (SIZE_MAX);
                ptrdiff_t offset = p - read_buffer;
                if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < read_buffer_size)
                  memory_full (SIZE_MAX);
-               read_buffer = (char *) xrealloc (read_buffer,
-                                                read_buffer_size * 2);
+               read_buffer = xrealloc (read_buffer, read_buffer_size * 2);
                read_buffer_size *= 2;
                p = read_buffer + offset;
                end = read_buffer + read_buffer_size;
                read_buffer_size *= 2;
                p = read_buffer + offset;
                end = read_buffer + read_buffer_size;
@@ -3039,8 +3029,7 @@ read1 (register Lisp_Object readcharfun, int *pch, int first_in_list)
                  ptrdiff_t offset = p - read_buffer;
                  if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < read_buffer_size)
                    memory_full (SIZE_MAX);
                  ptrdiff_t offset = p - read_buffer;
                  if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < read_buffer_size)
                    memory_full (SIZE_MAX);
-                 read_buffer = (char *) xrealloc (read_buffer,
-                                                  read_buffer_size * 2);
+                 read_buffer = xrealloc (read_buffer, read_buffer_size * 2);
                  read_buffer_size *= 2;
                  p = read_buffer + offset;
                  end = read_buffer + read_buffer_size;
                  read_buffer_size *= 2;
                  p = read_buffer + offset;
                  end = read_buffer + read_buffer_size;
@@ -3070,8 +3059,7 @@ read1 (register Lisp_Object readcharfun, int *pch, int first_in_list)
              ptrdiff_t offset = p - read_buffer;
              if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < read_buffer_size)
                memory_full (SIZE_MAX);
              ptrdiff_t offset = p - read_buffer;
              if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < read_buffer_size)
                memory_full (SIZE_MAX);
-             read_buffer = (char *) xrealloc (read_buffer,
-                                              read_buffer_size * 2);
+             read_buffer = xrealloc (read_buffer, read_buffer_size * 2);
              read_buffer_size *= 2;
              p = read_buffer + offset;
              end = read_buffer + read_buffer_size;
              read_buffer_size *= 2;
              p = read_buffer + offset;
              end = read_buffer + read_buffer_size;
@@ -3210,8 +3198,8 @@ substitute_object_recurse (Lisp_Object object, Lisp_Object placeholder, Lisp_Obj
        /* Check for text properties in each interval.
           substitute_in_interval contains part of the logic.  */
 
        /* Check for text properties in each interval.
           substitute_in_interval contains part of the logic.  */
 
-       INTERVAL    root_interval = STRING_INTERVALS (subtree);
-       Lisp_Object arg           = Fcons (object, placeholder);
+       INTERVAL root_interval = string_intervals (subtree);
+       Lisp_Object arg = Fcons (object, placeholder);
 
        traverse_intervals_noorder (root_interval,
                                    &substitute_in_interval, arg);
 
        traverse_intervals_noorder (root_interval,
                                    &substitute_in_interval, arg);
@@ -3232,7 +3220,7 @@ substitute_in_interval (INTERVAL interval, Lisp_Object arg)
   Lisp_Object object      = Fcar (arg);
   Lisp_Object placeholder = Fcdr (arg);
 
   Lisp_Object object      = Fcar (arg);
   Lisp_Object placeholder = Fcdr (arg);
 
-  SUBSTITUTE (interval->plist, interval->plist = true_value);
+  SUBSTITUTE (interval->plist, set_interval_plist (interval, true_value));
 }
 
 \f
 }
 
 \f
@@ -3427,7 +3415,7 @@ read_vector (Lisp_Object readcharfun, int bytecodeflag)
              /* Delay handling the bytecode slot until we know whether
                 it is lazily-loaded (we can tell by whether the
                 constants slot is nil).  */
              /* Delay handling the bytecode slot until we know whether
                 it is lazily-loaded (we can tell by whether the
                 constants slot is nil).  */
-             ptr[COMPILED_CONSTANTS] = item;
+             ASET (vector, COMPILED_CONSTANTS, item);
              item = Qnil;
            }
          else if (i == COMPILED_CONSTANTS)
              item = Qnil;
            }
          else if (i == COMPILED_CONSTANTS)
@@ -3453,7 +3441,7 @@ read_vector (Lisp_Object readcharfun, int bytecodeflag)
                }
 
              /* Now handle the bytecode slot.  */
                }
 
              /* Now handle the bytecode slot.  */
-             ptr[COMPILED_BYTECODE] = bytestr;
+             ASET (vector, COMPILED_BYTECODE, bytestr);
            }
          else if (i == COMPILED_DOC_STRING
                   && STRINGP (item)
            }
          else if (i == COMPILED_DOC_STRING
                   && STRINGP (item)
@@ -3465,7 +3453,7 @@ read_vector (Lisp_Object readcharfun, int bytecodeflag)
                item = Fstring_as_multibyte (item);
            }
        }
                item = Fstring_as_multibyte (item);
            }
        }
-      ptr[i] = item;
+      ASET (vector, i, item);
       otem = XCONS (tem);
       tem = Fcdr (tem);
       free_cons (otem);
       otem = XCONS (tem);
       tem = Fcdr (tem);
       free_cons (otem);
@@ -3673,32 +3661,20 @@ check_obarray (Lisp_Object obarray)
    interned in the current obarray.  */
 
 Lisp_Object
    interned in the current obarray.  */
 
 Lisp_Object
-intern (const char *str)
+intern_1 (const char *str, ptrdiff_t len)
 {
 {
-  Lisp_Object tem;
-  ptrdiff_t len = strlen (str);
-  Lisp_Object obarray;
+  Lisp_Object obarray = check_obarray (Vobarray);
+  Lisp_Object tem = oblookup (obarray, str, len, len);
 
 
-  obarray = Vobarray;
-  if (!VECTORP (obarray) || ASIZE (obarray) == 0)
-    obarray = check_obarray (obarray);
-  tem = oblookup (obarray, str, len, len);
-  if (SYMBOLP (tem))
-    return tem;
-  return Fintern (make_string (str, len), obarray);
+  return SYMBOLP (tem) ? tem : Fintern (make_string (str, len), obarray);
 }
 
 Lisp_Object
 }
 
 Lisp_Object
-intern_c_string (const char *str)
+intern_c_string_1 (const char *str, ptrdiff_t len)
 {
 {
-  Lisp_Object tem;
-  ptrdiff_t len = strlen (str);
-  Lisp_Object obarray;
+  Lisp_Object obarray = check_obarray (Vobarray);
+  Lisp_Object tem = oblookup (obarray, str, len, len);
 
 
-  obarray = Vobarray;
-  if (!VECTORP (obarray) || ASIZE (obarray) == 0)
-    obarray = check_obarray (obarray);
-  tem = oblookup (obarray, str, len, len);
   if (SYMBOLP (tem))
     return tem;
 
   if (SYMBOLP (tem))
     return tem;
 
@@ -3706,9 +3682,9 @@ intern_c_string (const char *str)
     /* Creating a non-pure string from a string literal not
        implemented yet.  We could just use make_string here and live
        with the extra copy.  */
     /* Creating a non-pure string from a string literal not
        implemented yet.  We could just use make_string here and live
        with the extra copy.  */
-    abort ();
+    emacs_abort ();
 
 
-  return Fintern (make_pure_c_string (str), obarray);
+  return Fintern (make_pure_c_string (str, len), obarray);
 }
 \f
 DEFUN ("intern", Fintern, Sintern, 1, 2, 0,
 }
 \f
 DEFUN ("intern", Fintern, Sintern, 1, 2, 0,
@@ -3748,11 +3724,11 @@ it defaults to the value of `obarray'.  */)
       SET_SYMBOL_VAL (XSYMBOL (sym), sym);
     }
 
       SET_SYMBOL_VAL (XSYMBOL (sym), sym);
     }
 
-  ptr = &XVECTOR (obarray)->contents[XINT (tem)];
+  ptr = aref_addr (obarray, XINT(tem));
   if (SYMBOLP (*ptr))
   if (SYMBOLP (*ptr))
-    XSYMBOL (sym)->next = XSYMBOL (*ptr);
+    set_symbol_next (sym, XSYMBOL (*ptr));
   else
   else
-    XSYMBOL (sym)->next = 0;
+    set_symbol_next (sym, NULL);
   *ptr = sym;
   return sym;
 }
   *ptr = sym;
   return sym;
 }
@@ -3827,25 +3803,29 @@ OBARRAY defaults to the value of the variable `obarray'.  */)
 
   hash = oblookup_last_bucket_number;
 
 
   hash = oblookup_last_bucket_number;
 
-  if (EQ (XVECTOR (obarray)->contents[hash], tem))
+  if (EQ (AREF (obarray, hash), tem))
     {
       if (XSYMBOL (tem)->next)
     {
       if (XSYMBOL (tem)->next)
-       XSETSYMBOL (XVECTOR (obarray)->contents[hash], XSYMBOL (tem)->next);
+       {
+         Lisp_Object sym;
+         XSETSYMBOL (sym, XSYMBOL (tem)->next);
+         ASET (obarray, hash, sym);
+       }
       else
       else
-       XSETINT (XVECTOR (obarray)->contents[hash], 0);
+       ASET (obarray, hash, make_number (0));
     }
   else
     {
       Lisp_Object tail, following;
 
     }
   else
     {
       Lisp_Object tail, following;
 
-      for (tail = XVECTOR (obarray)->contents[hash];
+      for (tail = AREF (obarray, hash);
           XSYMBOL (tail)->next;
           tail = following)
        {
          XSETSYMBOL (following, XSYMBOL (tail)->next);
          if (EQ (following, tem))
            {
           XSYMBOL (tail)->next;
           tail = following)
        {
          XSETSYMBOL (following, XSYMBOL (tail)->next);
          if (EQ (following, tem))
            {
-             XSYMBOL (tail)->next = XSYMBOL (following)->next;
+             set_symbol_next (tail, XSYMBOL (following)->next);
              break;
            }
        }
              break;
            }
        }
@@ -3868,16 +3848,13 @@ oblookup (Lisp_Object obarray, register const char *ptr, ptrdiff_t size, ptrdiff
   register Lisp_Object tail;
   Lisp_Object bucket, tem;
 
   register Lisp_Object tail;
   Lisp_Object bucket, tem;
 
-  if (!VECTORP (obarray)
-      || (obsize = ASIZE (obarray)) == 0)
-    {
-      obarray = check_obarray (obarray);
-      obsize = ASIZE (obarray);
-    }
+  obarray = check_obarray (obarray);
+  obsize = ASIZE (obarray);
+
   /* This is sometimes needed in the middle of GC.  */
   obsize &= ~ARRAY_MARK_FLAG;
   hash = hash_string (ptr, size_byte) % obsize;
   /* This is sometimes needed in the middle of GC.  */
   obsize &= ~ARRAY_MARK_FLAG;
   hash = hash_string (ptr, size_byte) % obsize;
-  bucket = XVECTOR (obarray)->contents[hash];
+  bucket = AREF (obarray, hash);
   oblookup_last_bucket_number = hash;
   if (EQ (bucket, make_number (0)))
     ;
   oblookup_last_bucket_number = hash;
   if (EQ (bucket, make_number (0)))
     ;
@@ -3905,7 +3882,7 @@ map_obarray (Lisp_Object obarray, void (*fn) (Lisp_Object, Lisp_Object), Lisp_Ob
   CHECK_VECTOR (obarray);
   for (i = ASIZE (obarray) - 1; i >= 0; i--)
     {
   CHECK_VECTOR (obarray);
   for (i = ASIZE (obarray) - 1; i >= 0; i--)
     {
-      tail = XVECTOR (obarray)->contents[i];
+      tail = AREF (obarray, i);
       if (SYMBOLP (tail))
        while (1)
          {
       if (SYMBOLP (tail))
        while (1)
          {
@@ -3949,7 +3926,7 @@ init_obarray (void)
   initial_obarray = Vobarray;
   staticpro (&initial_obarray);
 
   initial_obarray = Vobarray;
   staticpro (&initial_obarray);
 
-  Qunbound = Fmake_symbol (make_pure_c_string ("unbound"));
+  Qunbound = Fmake_symbol (build_pure_c_string ("unbound"));
   /* Set temporary dummy values to Qnil and Vpurify_flag to satisfy the
      NILP (Vpurify_flag) check in intern_c_string.  */
   Qnil = make_number (-1); Vpurify_flag = make_number (1);
   /* Set temporary dummy values to Qnil and Vpurify_flag to satisfy the
      NILP (Vpurify_flag) check in intern_c_string.  */
   Qnil = make_number (-1); Vpurify_flag = make_number (1);
@@ -3958,13 +3935,12 @@ init_obarray (void)
   /* Fmake_symbol inits fields of new symbols with Qunbound and Qnil,
      so those two need to be fixed manually.  */
   SET_SYMBOL_VAL (XSYMBOL (Qunbound), Qunbound);
   /* Fmake_symbol inits fields of new symbols with Qunbound and Qnil,
      so those two need to be fixed manually.  */
   SET_SYMBOL_VAL (XSYMBOL (Qunbound), Qunbound);
-  XSYMBOL (Qunbound)->function = Qunbound;
-  XSYMBOL (Qunbound)->plist = Qnil;
-  /* XSYMBOL (Qnil)->function = Qunbound; */
+  set_symbol_function (Qunbound, Qunbound);
+  set_symbol_plist (Qunbound, Qnil);
   SET_SYMBOL_VAL (XSYMBOL (Qnil), Qnil);
   XSYMBOL (Qnil)->constant = 1;
   XSYMBOL (Qnil)->declared_special = 1;
   SET_SYMBOL_VAL (XSYMBOL (Qnil), Qnil);
   XSYMBOL (Qnil)->constant = 1;
   XSYMBOL (Qnil)->declared_special = 1;
-  XSYMBOL (Qnil)->plist = Qnil;
+  set_symbol_plist (Qnil, Qnil);
 
   Qt = intern_c_string ("t");
   SET_SYMBOL_VAL (XSYMBOL (Qt), Qt);
 
   Qt = intern_c_string ("t");
   SET_SYMBOL_VAL (XSYMBOL (Qt), Qt);
@@ -3976,17 +3952,18 @@ init_obarray (void)
 
   DEFSYM (Qvariable_documentation, "variable-documentation");
 
 
   DEFSYM (Qvariable_documentation, "variable-documentation");
 
-  read_buffer = (char *) xmalloc (size);
+  read_buffer = xmalloc (size);
   read_buffer_size = size;
 }
 \f
 void
 defsubr (struct Lisp_Subr *sname)
 {
   read_buffer_size = size;
 }
 \f
 void
 defsubr (struct Lisp_Subr *sname)
 {
-  Lisp_Object sym;
+  Lisp_Object sym, tem;
   sym = intern_c_string (sname->symbol_name);
   XSETTYPED_PVECTYPE (sname, size, PVEC_SUBR);
   sym = intern_c_string (sname->symbol_name);
   XSETTYPED_PVECTYPE (sname, size, PVEC_SUBR);
-  XSETSUBR (XSYMBOL (sym)->function, sname);
+  XSETSUBR (tem, sname);
+  set_symbol_function (sym, tem);
 }
 
 #ifdef NOTDEF /* Use fset in subr.el now!  */
 }
 
 #ifdef NOTDEF /* Use fset in subr.el now!  */
@@ -4019,7 +3996,7 @@ defvar_int (struct Lisp_Intfwd *i_fwd,
    nil if address contains 0.  */
 void
 defvar_bool (struct Lisp_Boolfwd *b_fwd,
    nil if address contains 0.  */
 void
 defvar_bool (struct Lisp_Boolfwd *b_fwd,
-            const char *namestring, int *address)
+            const char *namestring, bool *address)
 {
   Lisp_Object sym;
   sym = intern_c_string (namestring);
 {
   Lisp_Object sym;
   sym = intern_c_string (namestring);
@@ -4073,62 +4050,105 @@ defvar_kboard (struct Lisp_Kboard_Objfwd *ko_fwd,
   SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)ko_fwd);
 }
 \f
   SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)ko_fwd);
 }
 \f
+/* Check that the elements of Vload_path exist.  */
+
+static void
+load_path_check (void)
+{
+  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))
+    {
+      Lisp_Object dirfile;
+      dirfile = Fcar (path_tail);
+      if (STRINGP (dirfile))
+        {
+          dirfile = Fdirectory_file_name (dirfile);
+          if (access (SSDATA (dirfile), 0) < 0)
+            dir_warning ("Warning: Lisp directory `%s' does not exist.\n",
+                         XCAR (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;
 
 /* 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;
 
+/* 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.
+   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.
+
+   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 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.
+   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).
+*/
+
 void
 init_lread (void)
 {
   const char *normal;
 void
 init_lread (void)
 {
   const char *normal;
-  int turn_off_warning = 0;
-
-  /* Compute the default Vload-path, with the following logic:
-     If CANNOT_DUMP just use PATH_LOADSEARCH.
-     Else if purify-flag (ie dumping) start from PATH_DUMPLOADSEARCH;
-     otherwise start from 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.)
-     Also do nothing if Vinstallation_directory is nil.
-     Otherwise:
-       Remove site-lisp directories from the front of load-path.
-       Add installation-dir/lisp (if exists and not already a member),
-         at the front, and turn off warnings about missing directories
-         (because we are presumably running uninstalled).
-         If it does not exist, 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 previously removed site-lisp directories back
-       at the front (if !no_site_lisp).
-
-     We then warn about any of the load-path elements that do not
-     exist.  The only ones that might not exist are those from
-     PATH_LOADSEARCH, and perhaps dump_path.
-
-     Having done all this, we then throw it all away if purify-flag is
-     nil (ie, not dumping) and EMACSLOADPATH is set, and just
-     unconditionally use the latter value instead.
-     So AFAICS the only net results of all the previous steps will be
-     possibly to issue some irrelevant warnings.
-
-     FIXME? There's a case for saying that if we are running
-     uninstalled, the eventual installation directories should not yet
-     be included in load-path.
-  */
+
 #ifdef CANNOT_DUMP
 #ifdef CANNOT_DUMP
+#ifdef HAVE_NS
+  const char *loadpath = ns_load_path ();
+#endif
+
   normal = PATH_LOADSEARCH;
   normal = PATH_LOADSEARCH;
-  Vload_path = decode_env_path (0, normal);
+#ifdef HAVE_NS
+  Vload_path = decode_env_path ("EMACSLOADPATH", loadpath ? loadpath : normal);
 #else
 #else
+  Vload_path = decode_env_path ("EMACSLOADPATH", normal);
+#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))
   if (NILP (Vpurify_flag))
-    normal = PATH_LOADSEARCH;
+    {
+      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;
 
   else
     normal = PATH_DUMPLOADSEARCH;
 
@@ -4137,183 +4157,155 @@ init_lread (void)
      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
      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.  */
+     change it further.  Changes can only be due to EMACSLOADPATH, or
+     site-lisp files that were processed during dumping.  */
   if (initialized)
     {
   if (initialized)
     {
-      if (! NILP (Fequal (dump_path, Vload_path)))
+      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);
+#else
          Vload_path = decode_env_path (0, normal);
          Vload_path = decode_env_path (0, normal);
-         if (no_site_lisp || !NILP (Vinstallation_directory))
+#endif
+         if (!NILP (Vinstallation_directory))
            {
            {
-             Lisp_Object tem, tem1, sitelisp;
-
-             /* Remove "site-lisp" dirs from front of path temporarily
-                and store them in sitelisp, then conc them on at the
-                end so they're always first in path.
-                Note that this won't work if you used a
-                --enable-locallisppath element that does not happen
-                to contain "site-lisp" in its name.
-             */
-             sitelisp = Qnil;
-             while (1)
-               {
-                 tem = Fcar (Vload_path);
-                 tem1 = Fstring_match (build_string ("site-lisp"),
-                                       tem, Qnil);
-                 if (!NILP (tem1))
-                   {
-                     Vload_path = Fcdr (Vload_path);
-                     sitelisp = Fcons (tem, sitelisp);
-                   }
-                 else
-                   break;
-               }
-
-             if (!NILP (Vinstallation_directory))
-               {
-                 /* Add to the path the lisp subdir of the
-                    installation dir, if it exists.  */
-                 tem = Fexpand_file_name (build_string ("lisp"),
-                                          Vinstallation_directory);
-                 tem1 = Ffile_exists_p (tem);
-                 if (!NILP (tem1))
-                   {
-                     if (NILP (Fmember (tem, Vload_path)))
-                       {
-                         turn_off_warning = 1;
-                         Vload_path = Fcons (tem, Vload_path);
-                       }
-                   }
-                 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 exists.  */
-                 tem = Fexpand_file_name (build_string ("leim"),
-                                          Vinstallation_directory);
-                 tem1 = Ffile_exists_p (tem);
-                 if (!NILP (tem1))
-                   {
-                     if (NILP (Fmember (tem, Vload_path)))
-                       Vload_path = Fcons (tem, Vload_path);
-                   }
-
-                 /* 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_exists_p (tem);
-                     if (!NILP (tem1))
-                       {
-                         if (NILP (Fmember (tem, Vload_path)))
-                           Vload_path = Fcons (tem, Vload_path);
-                       }
-                   }
-
-                 /* 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 (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);
-
-                         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 (!no_site_lisp)
-                           {
-                             tem = Fexpand_file_name (build_string ("site-lisp"),
-                                                      Vsource_directory);
-
-                             if (NILP (Fmember (tem, Vload_path)))
-                               Vload_path = Fcons (tem, Vload_path);
-                           }
-                       }
-                   } /* Vinstallation_directory != Vsource_directory */
-               }     /* if Vinstallation_directory */
-             if (!NILP (sitelisp) && !no_site_lisp)
-               Vload_path = nconc2 (Fnreverse (sitelisp), Vload_path);
-           } /* if Vinstallation_directory || no_site_lisp */
-       }     /* if dump_path == Vload_path */
+             Lisp_Object tem, tem1;
+
+              /* Add to the path the lisp subdir of the installation
+                 dir, if it exists.  Note: in out-of-tree builds,
+                 this directory is empty save for Makefile.  */
+              tem = Fexpand_file_name (build_string ("lisp"),
+                                       Vinstallation_directory);
+              tem1 = Ffile_exists_p (tem);
+              if (!NILP (tem1))
+                {
+                  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);
+                    }
+                }
+              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 exists. */
+              tem = Fexpand_file_name (build_string ("leim"),
+                                       Vinstallation_directory);
+              tem1 = Ffile_exists_p (tem);
+              if (!NILP (tem1))
+                {
+                  if (NILP (Fmember (tem, Vload_path)))
+                    Vload_path = Fcons (tem, Vload_path);
+                }
+
+              /* 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_exists_p (tem);
+                  if (!NILP (tem1))
+                    {
+                      if (NILP (Fmember (tem, Vload_path)))
+                        Vload_path = Fcons (tem, Vload_path);
+                    }
+                }
+
+              /* 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 (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);
+
+                      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 (!no_site_lisp)
+                        {
+                          tem = Fexpand_file_name (build_string ("site-lisp"),
+                                                   Vsource_directory);
+                          tem1 = Ffile_exists_p (tem);
+                          if (!NILP (tem1))
+                            {
+                              if (NILP (Fmember (tem, Vload_path)))
+                                Vload_path = Fcons (tem, Vload_path);
+                            }
+                        }
+                    }
+                } /* 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 ();
+
+          /* 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 */
     }
   else                          /* !initialized */
     {
     }
   else                          /* !initialized */
     {
-      /* NORMAL refers to the lisp dir in the source directory.  */
-      /* We used to add ../lisp 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 be unnecessary.  */
+      /* 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;
       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.  */
     }
     }
-#endif  /* CANNOT_DUMP */
-
-#if (!(defined (WINDOWSNT) || (defined (HAVE_NS))))
-  /* When Emacs is invoked over network shares on NT, PATH_LOADSEARCH is
-     almost never correct, thereby causing a warning to be printed out that
-     confuses users.  Since PATH_LOADSEARCH is always overridden by the
-     EMACSLOADPATH environment variable below, disable the warning on NT.  */
-
-  /* HAVE_NS also uses EMACSLOADPATH.  */
-
-  /* Warn if dirs in the *standard* path don't exist.  */
-  if (!turn_off_warning)
-    {
-      Lisp_Object path_tail;
-
-      for (path_tail = Vload_path;
-          !NILP (path_tail);
-          path_tail = XCDR (path_tail))
-       {
-         Lisp_Object dirfile;
-         dirfile = Fcar (path_tail);
-         if (STRINGP (dirfile))
-           {
-             dirfile = Fdirectory_file_name (dirfile);
-              /* Do we really need to warn about missing site-lisp dirs?
-                 It's true that the installation should have created
-                 them and added subdirs.el, but it's harmless if they
-                 are not there.  */
-             if (access (SSDATA (dirfile), 0) < 0)
-               dir_warning ("Warning: Lisp directory `%s' does not exist.\n",
-                            XCAR (path_tail));
-           }
-       }
-    }
-#endif /* !(WINDOWSNT || HAVE_NS) */
-
-  /* If the EMACSLOADPATH environment variable is set, use its value.
-     This doesn't apply if we're dumping.  */
-#ifndef CANNOT_DUMP
-  if (NILP (Vpurify_flag)
-      && egetenv ("EMACSLOADPATH"))
-#endif
-    Vload_path = decode_env_path ("EMACSLOADPATH", normal);
+#endif  /* !CANNOT_DUMP */
 
   Vvalues = Qnil;
 
 
   Vvalues = Qnil;
 
@@ -4337,12 +4329,10 @@ dir_warning (const char *format, Lisp_Object dirname)
   /* Don't log the warning before we've initialized!!  */
   if (initialized)
     {
   /* Don't log the warning before we've initialized!!  */
   if (initialized)
     {
-      char *buffer;
-      ptrdiff_t message_len;
       USE_SAFE_ALLOCA;
       USE_SAFE_ALLOCA;
-      SAFE_ALLOCA (buffer, char *,
-                  SBYTES (dirname) + strlen (format) - (sizeof "%s" - 1) + 1);
-      message_len = esprintf (buffer, format, SDATA (dirname));
+      char *buffer = SAFE_ALLOCA (SBYTES (dirname)
+                                 + strlen (format) - (sizeof "%s" - 1) + 1);
+      ptrdiff_t message_len = esprintf (buffer, format, SDATA (dirname));
       message_dolog (buffer, message_len, 0, STRING_MULTIBYTE (dirname));
       SAFE_FREE ();
     }
       message_dolog (buffer, message_len, 0, STRING_MULTIBYTE (dirname));
       SAFE_FREE ();
     }
@@ -4427,8 +4417,8 @@ otherwise to default specified by file `epaths.h' when Emacs was built.  */);
 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.  */);
 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 (make_pure_c_string (".elc"),
-                         Fcons (make_pure_c_string (".el"), Qnil));
+  Vload_suffixes = Fcons (build_pure_c_string (".elc"),
+                         Fcons (build_pure_c_string (".el"), Qnil));
   DEFVAR_LISP ("load-file-rep-suffixes", Vload_file_rep_suffixes,
               doc: /* List of suffixes that indicate representations of \
 the same file.
   DEFVAR_LISP ("load-file-rep-suffixes", Vload_file_rep_suffixes,
               doc: /* List of suffixes that indicate representations of \
 the same file.
@@ -4561,10 +4551,9 @@ from the file, and matches them against this regular expression.
 When the regular expression matches, the file is considered to be safe
 to load.  See also `load-dangerous-libraries'.  */);
   Vbytecomp_version_regexp
 When the regular expression matches, the file is considered to be safe
 to load.  See also `load-dangerous-libraries'.  */);
   Vbytecomp_version_regexp
-    = make_pure_c_string ("^;;;.\\(in Emacs version\\|bytecomp version FSF\\)");
+    = build_pure_c_string ("^;;;.\\(in Emacs version\\|bytecomp version FSF\\)");
 
 
-  Qlexical_binding = intern ("lexical-binding");
-  staticpro (&Qlexical_binding);
+  DEFSYM (Qlexical_binding, "lexical-binding");
   DEFVAR_LISP ("lexical-binding", Vlexical_binding,
               doc: /* Whether to use lexical binding when evaluating code.
 Non-nil means that the code in the current buffer should be evaluated
   DEFVAR_LISP ("lexical-binding", Vlexical_binding,
               doc: /* Whether to use lexical binding when evaluating code.
 Non-nil means that the code in the current buffer should be evaluated
@@ -4572,6 +4561,7 @@ with lexical binding.
 This variable is automatically set from the file variables of an
 interpreted Lisp file read using `load'.  Unlike other file local
 variables, this must be set in the first line of a file.  */);
 This variable is automatically set from the file variables of an
 interpreted Lisp file read using `load'.  Unlike other file local
 variables, this must be set in the first line of a file.  */);
+  Vlexical_binding = Qnil;
   Fmake_variable_buffer_local (Qlexical_binding);
 
   DEFVAR_LISP ("eval-buffer-list", Veval_buffer_list,
   Fmake_variable_buffer_local (Qlexical_binding);
 
   DEFVAR_LISP ("eval-buffer-list", Veval_buffer_list,