]> git.eshelyaron.com Git - emacs.git/commitdiff
Don't store docstrings of preloaded .el files in etc/DOC
authorStefan Monnier <monnier@iro.umontreal.ca>
Fri, 31 Dec 2021 04:17:45 +0000 (23:17 -0500)
committerStefan Monnier <monnier@iro.umontreal.ca>
Fri, 31 Dec 2021 04:17:45 +0000 (23:17 -0500)
Since the location of those files changes between build time and
installation time, this requires to tweak the file name used in those
(#$ . NNN) references during the dump so they don't hardcode the build
directory.  We do it in the same way as was already done for those
same file names in `load-history`, except we convert them back to
absolute file names more lazily (i.e. when fetching the actual
docstring rather than at startup), which requires remembering the
`lisp-dir` computed at startup in the new `lisp-directory` variable.

* src/Makefile.in ($(etc)/DOC): Don't scan Lisp files any more.

* src/lread.c (Fload): Use relative file names for `load-file-name`
when preloading for the dump, like we already did for `current-load-list`.
(read_list): Don't zero-out dynamic docstring references during the
preload since they won't be filled later by Snarf-documentation any more.
(read1): Remove the hash-hack for doc references that were zeroed.

* lisp/startup.el (lisp-directory): New variable.
(command-line): Set it.

* src/doc.c (get_doc_string): Use `lisp-directory` for dynamic
docstring references using relative file names.
(syms_of_doc): Add `Qlisp_directory`.

* lib-src/make-docfile.c (scan_file): Don't handle `.el` or `.elc`
files any more.
(IS_SLASH): Remove macro, not used any more.
(skip_white, read_lisp_symbol, search_lisp_doc_at_eol)
(scan_lisp_file): Remove functions, not used any more.

* doc/lispref/loading.texi (Library Search): Mention `lisp-directory`.

doc/lispref/loading.texi
etc/NEWS
lib-src/make-docfile.c
lisp/emacs-lisp/bytecomp.el
lisp/startup.el
src/Makefile.in
src/doc.c
src/lread.c

index e4cd940ab2eff1d28244e96ca549d3029bd0bc94..3efcf055dcf6ebbb2115e34dad13c18479ac8081 100644 (file)
@@ -291,9 +291,10 @@ a directory) or @code{nil} (which stands for the current working
 directory).
 @end defvar
 
-  When Emacs starts up, it sets up the value of @code{load-path}
-in several steps.  First, it initializes @code{load-path} using
-default locations set when Emacs was compiled.  Normally, this
+  When Emacs starts up, it sets up the value of @code{load-path} in
+several steps.  First, it looks for the directory containing its own
+Lisp files, using default locations set when Emacs was compiled.
+It saves this directory in @code{lisp-directory}.  Normally, this
 is a directory something like
 
 @example
@@ -307,9 +308,11 @@ Emacs.  If Emacs cannot find them, it will not start correctly.
 
 If you run Emacs from the directory where it was built---that is, an
 executable that has not been formally installed---Emacs instead
-initializes @code{load-path} using the @file{lisp}
+initializes @code{lisp-directory} using the @file{lisp}
 directory in the directory containing the sources from which it
 was built.
+
+Emacs first initializes @code{load-path} with this @code{lisp-directory}.
 @c Though there should be no *.el files in builddir/lisp, so it's pointless.
 If you built Emacs in a separate directory from the
 sources, it also adds the lisp directories from the build directory.
@@ -396,6 +399,14 @@ a @file{site-load.el} or @file{site-init.el} file to customize the
 dumped Emacs (@pxref{Building Emacs}), any changes to @code{load-path}
 that these files make will be lost after dumping.
 
+@defvar lisp-directory
+This variable holds a string naming the directory which holds
+Emacs's own @code{.el} and @code{.elc} files.  This is usually the
+place where those files are located in the Emacs installation tree,
+unless Emacs is run from its build directory in which case it points
+to the @code{lisp} directory in source directory from which it was built.
+@end defvar
+
 @deffn Command locate-library library &optional nosuffix path interactive-call
 This command finds the precise file name for library @var{library}.  It
 searches for the library in the same way @code{load} does, and the
index bbe0aed3f758a43787d352ba453fd084d08486fa..f6ba0167e0f6a4c2c4677f7cb00ad12c2a4f711e 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -71,6 +71,11 @@ Unlike the default X and GTK build, the resulting Emacs binary will
 work on any underlying window system supported by GDK, such as
 Wayland and Broadway.
 
+---
+** The docstrings of preloaded files are not in etc/DOC any more.
+Instead, they're fetched from the corresponding '.elc' file, as was already
+the case for all the non-preloaded files.
+
 \f
 * Startup Changes in Emacs 29.1
 
@@ -886,6 +891,9 @@ The input must be encoded text.
 \f
 * Lisp Changes in Emacs 29.1
 
++++
+** New variable 'lisp-directory' holds the directory of Emacs's own Lisp files.
+
 +++
 ** New facility for handling session state: 'multisession-value'.
 This can be used as a convenient way to store (simple) application
index d17c28be90bf43ddbccb29af3e4c7db215567802..913aa69aacc5cbe1a57a1daf57de3445ce93d4c7 100644 (file)
@@ -19,8 +19,8 @@ You should have received a copy of the GNU General Public License
 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 
 
-/* The arguments given to this program are all the C and Lisp source files
- of GNU Emacs.  .elc and .el and .c files are allowed.
+/* The arguments given to this program are all the C files
+ of GNU Emacs.  .c files are allowed.
  A .o file can also be specified; the .c file it was made from is used.
  This helps the makefile pass the correct list of files.
  Option -d DIR means change to DIR before looking for files.
@@ -62,13 +62,9 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
    Similarly, msdos defines this as sys_chdir, but we're not linking with the
    file where that function is defined.  */
 #undef chdir
-#define IS_SLASH(c)  ((c) == '/' || (c) == '\\' || (c) == ':')
-#else  /* not DOS_NT */
-#define IS_SLASH(c)  ((c) == '/')
 #endif /* not DOS_NT */
 
 static void scan_file (char *filename);
-static void scan_lisp_file (const char *filename, const char *mode);
 static void scan_c_file (char *filename, const char *mode);
 static void scan_c_stream (FILE *infile);
 static void start_globals (void);
@@ -238,16 +234,9 @@ put_filename (char *filename)
 static void
 scan_file (char *filename)
 {
-  ptrdiff_t len = strlen (filename);
-
   if (!generate_globals)
     put_filename (filename);
-  if (len > 4 && !strcmp (filename + len - 4, ".elc"))
-    scan_lisp_file (filename, "rb");
-  else if (len > 3 && !strcmp (filename + len - 3, ".el"))
-    scan_lisp_file (filename, "r");
-  else
-    scan_c_file (filename, "r");
+  scan_c_file (filename, "r");
 }
 
 static void
@@ -1225,453 +1214,4 @@ scan_c_stream (FILE *infile)
     fatal ("read error");
 }
 \f
-/* Read a file of Lisp code, compiled or interpreted.
- Looks for
-  (defun NAME ARGS DOCSTRING ...)
-  (defmacro NAME ARGS DOCSTRING ...)
-  (defsubst NAME ARGS DOCSTRING ...)
-  (autoload (quote NAME) FILE DOCSTRING ...)
-  (defvar NAME VALUE DOCSTRING)
-  (defconst NAME VALUE DOCSTRING)
-  (fset (quote NAME) (make-byte-code ... DOCSTRING ...))
-  (fset (quote NAME) #[... DOCSTRING ...])
-  (defalias (quote NAME) #[... DOCSTRING ...])
-  (custom-declare-variable (quote NAME) VALUE DOCSTRING ...)
- starting in column zero.
- (quote NAME) may appear as 'NAME as well.
-
- We also look for #@LENGTH CONTENTS^_ at the beginning of the line.
- When we find that, we save it for the following defining-form,
- and we use that instead of reading a doc string within that defining-form.
-
- For defvar, defconst, and fset we skip to the docstring with a kludgy
- formatting convention: all docstrings must appear on the same line as the
- initial open-paren (the one in column zero) and must contain a backslash
- and a newline immediately after the initial double-quote.  No newlines
- must appear between the beginning of the form and the first double-quote.
- For defun, defmacro, and autoload, we know how to skip over the
- arglist, but the doc string must still have a backslash and newline
- immediately after the double quote.
- The only source files that must follow this convention are preloaded
- uncompiled ones like loaddefs.el; aside from that, it is always the .elc
- file that we should look at, and they are no problem because byte-compiler
- output follows this convention.
- The NAME and DOCSTRING are output.
- NAME is preceded by `F' for a function or `V' for a variable.
- An entry is output only if DOCSTRING has \ newline just after the opening ".
- */
-
-static void
-skip_white (FILE *infile)
-{
-  int c;
-  do
-    c = getc (infile);
-  while (c_isspace (c));
-
-  ungetc (c, infile);
-}
-
-static void
-read_lisp_symbol (FILE *infile, char *buffer)
-{
-  int c;
-  char *fillp = buffer;
-
-  skip_white (infile);
-  while (true)
-    {
-      c = getc (infile);
-      if (c == '\\')
-       {
-         c = getc (infile);
-         if (c < 0)
-           return;
-         *fillp++ = c;
-       }
-      else if (c_isspace (c) || c == '(' || c == ')' || c < 0)
-       {
-         ungetc (c, infile);
-         *fillp = 0;
-         break;
-       }
-      else
-       *fillp++ = c;
-    }
-
-  if (! buffer[0])
-    fprintf (stderr, "## expected a symbol, got '%c'\n", c);
-
-  skip_white (infile);
-}
-
-static bool
-search_lisp_doc_at_eol (FILE *infile)
-{
-  int c = 0, c1 = 0, c2 = 0;
-
-  /* Skip until the end of line; remember two previous chars.  */
-  while (c != '\n' && c != '\r' && c != EOF)
-    {
-      c2 = c1;
-      c1 = c;
-      c = getc (infile);
-    }
-
-  /* If two previous characters were " and \,
-     this is a doc string.  Otherwise, there is none.  */
-  if (c2 != '"' || c1 != '\\')
-    {
-#ifdef DEBUG
-      fprintf (stderr, "## non-docstring found\n");
-#endif
-      ungetc (c, infile);
-      return false;
-    }
-  return true;
-}
-
-#define DEF_ELISP_FILE(fn)  { #fn, sizeof(#fn) - 1 }
-
-static void
-scan_lisp_file (const char *filename, const char *mode)
-{
-  FILE *infile;
-  int c;
-  char *saved_string = 0;
-  /* These are the only files that are loaded uncompiled, and must
-     follow the conventions of the doc strings expected by this
-     function.  These conventions are automatically followed by the
-     byte compiler when it produces the .elc files.  */
-  static struct {
-    const char *fn;
-    int fl;
-  } const uncompiled[] = {
-    DEF_ELISP_FILE (loaddefs.el),
-    DEF_ELISP_FILE (loadup.el),
-    DEF_ELISP_FILE (charprop.el),
-    DEF_ELISP_FILE (cp51932.el),
-    DEF_ELISP_FILE (eucjp-ms.el)
-  };
-  int i;
-  int flen = strlen (filename);
-
-  if (generate_globals)
-    fatal ("scanning lisp file when -g specified");
-  if (flen > 3 && !strcmp (filename + flen - 3, ".el"))
-    {
-      bool match = false;
-      for (i = 0; i < sizeof (uncompiled) / sizeof (uncompiled[0]); i++)
-       {
-         if (uncompiled[i].fl <= flen
-             && !strcmp (filename + flen - uncompiled[i].fl, uncompiled[i].fn)
-             && (flen == uncompiled[i].fl
-                 || IS_SLASH (filename[flen - uncompiled[i].fl - 1])))
-           {
-             match = true;
-             break;
-           }
-       }
-      if (!match)
-       fatal ("uncompiled lisp file %s is not supported", filename);
-    }
-
-  infile = fopen (filename, mode);
-  if (infile == NULL)
-    {
-      perror (filename);
-      exit (EXIT_FAILURE);
-    }
-
-  c = '\n';
-  while (!feof (infile))
-    {
-      char buffer[BUFSIZ];
-      char type;
-
-      /* If not at end of line, skip till we get to one.  */
-      if (c != '\n' && c != '\r')
-       {
-         c = getc (infile);
-         continue;
-       }
-      /* Skip the line break.  */
-      while (c == '\n' || c == '\r')
-       c = getc (infile);
-      /* Detect a dynamic doc string and save it for the next expression.  */
-      if (c == '#')
-       {
-         c = getc (infile);
-         if (c == '@')
-           {
-             ptrdiff_t length = 0;
-             ptrdiff_t i;
-
-             /* Read the length.  */
-             while ((c = getc (infile),
-                     c_isdigit (c)))
-               {
-                 if (INT_MULTIPLY_WRAPV (length, 10, &length)
-                     || INT_ADD_WRAPV (length, c - '0', &length)
-                     || SIZE_MAX < length)
-                   memory_exhausted ();
-               }
-
-             if (length <= 1)
-               fatal ("invalid dynamic doc string length");
-
-             if (c != ' ')
-               fatal ("space not found after dynamic doc string length");
-
-             /* The next character is a space that is counted in the length
-                but not part of the doc string.
-                We already read it, so just ignore it.  */
-             length--;
-
-             /* Read in the contents.  */
-             free (saved_string);
-             saved_string = xmalloc (length);
-             for (i = 0; i < length; i++)
-               saved_string[i] = getc (infile);
-             /* The last character is a ^_.
-                That is needed in the .elc file
-                but it is redundant in DOC.  So get rid of it here.  */
-             saved_string[length - 1] = 0;
-             /* Skip the line break.  */
-             while (c == '\n' || c == '\r')
-               c = getc (infile);
-             /* Skip the following line.  */
-             while (! (c == '\n' || c == '\r' || c < 0))
-               c = getc (infile);
-           }
-         continue;
-       }
-
-      if (c != '(')
-       continue;
-
-      read_lisp_symbol (infile, buffer);
-
-      if (! strcmp (buffer, "defun")
-         || ! strcmp (buffer, "defmacro")
-         || ! strcmp (buffer, "defsubst"))
-       {
-         type = 'F';
-         read_lisp_symbol (infile, buffer);
-
-         /* Skip the arguments: either "nil" or a list in parens.  */
-
-         c = getc (infile);
-         if (c == 'n') /* nil */
-           {
-             if ((c = getc (infile)) != 'i'
-                 || (c = getc (infile)) != 'l')
-               {
-                 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
-                          buffer, filename);
-                 continue;
-               }
-           }
-         else if (c != '(')
-           {
-             fprintf (stderr, "## unparsable arglist in %s (%s)\n",
-                      buffer, filename);
-             continue;
-           }
-         else
-           while (! (c == ')' || c < 0))
-             c = getc (infile);
-         skip_white (infile);
-
-         /* If the next three characters aren't `dquote bslash newline'
-            then we're not reading a docstring.
-          */
-         if ((c = getc (infile)) != '"'
-             || (c = getc (infile)) != '\\'
-             || ((c = getc (infile)) != '\n' && c != '\r'))
-           {
-#ifdef DEBUG
-             fprintf (stderr, "## non-docstring in %s (%s)\n",
-                      buffer, filename);
-#endif
-             continue;
-           }
-       }
-
-      /* defcustom can only occur in uncompiled Lisp files.  */
-      else if (! strcmp (buffer, "defvar")
-              || ! strcmp (buffer, "defconst")
-              || ! strcmp (buffer, "defcustom"))
-       {
-         type = 'V';
-         read_lisp_symbol (infile, buffer);
-
-         if (saved_string == 0)
-           if (!search_lisp_doc_at_eol (infile))
-             continue;
-       }
-
-      else if (! strcmp (buffer, "custom-declare-variable")
-              || ! strcmp (buffer, "defvaralias")
-              )
-       {
-         type = 'V';
-
-         c = getc (infile);
-         if (c == '\'')
-           read_lisp_symbol (infile, buffer);
-         else
-           {
-             if (c != '(')
-               {
-                 fprintf (stderr,
-                          "## unparsable name in custom-declare-variable in %s\n",
-                          filename);
-                 continue;
-               }
-             read_lisp_symbol (infile, buffer);
-             if (strcmp (buffer, "quote"))
-               {
-                 fprintf (stderr,
-                          "## unparsable name in custom-declare-variable in %s\n",
-                          filename);
-                 continue;
-               }
-             read_lisp_symbol (infile, buffer);
-             c = getc (infile);
-             if (c != ')')
-               {
-                 fprintf (stderr,
-                          "## unparsable quoted name in custom-declare-variable in %s\n",
-                          filename);
-                 continue;
-               }
-           }
-
-         if (saved_string == 0)
-           if (!search_lisp_doc_at_eol (infile))
-             continue;
-       }
-
-      else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias"))
-       {
-         type = 'F';
-
-         c = getc (infile);
-         if (c == '\'')
-           read_lisp_symbol (infile, buffer);
-         else
-           {
-             if (c != '(')
-               {
-                 fprintf (stderr, "## unparsable name in fset in %s\n",
-                          filename);
-                 continue;
-               }
-             read_lisp_symbol (infile, buffer);
-             if (strcmp (buffer, "quote"))
-               {
-                 fprintf (stderr, "## unparsable name in fset in %s\n",
-                          filename);
-                 continue;
-               }
-             read_lisp_symbol (infile, buffer);
-             c = getc (infile);
-             if (c != ')')
-               {
-                 fprintf (stderr,
-                          "## unparsable quoted name in fset in %s\n",
-                          filename);
-                 continue;
-               }
-           }
-
-         if (saved_string == 0)
-           if (!search_lisp_doc_at_eol (infile))
-             continue;
-       }
-
-      else if (! strcmp (buffer, "autoload"))
-       {
-         type = 'F';
-         c = getc (infile);
-         if (c == '\'')
-           read_lisp_symbol (infile, buffer);
-         else
-           {
-             if (c != '(')
-               {
-                 fprintf (stderr, "## unparsable name in autoload in %s\n",
-                          filename);
-                 continue;
-               }
-             read_lisp_symbol (infile, buffer);
-             if (strcmp (buffer, "quote"))
-               {
-                 fprintf (stderr, "## unparsable name in autoload in %s\n",
-                          filename);
-                 continue;
-               }
-             read_lisp_symbol (infile, buffer);
-             c = getc (infile);
-             if (c != ')')
-               {
-                 fprintf (stderr,
-                          "## unparsable quoted name in autoload in %s\n",
-                          filename);
-                 continue;
-               }
-           }
-         skip_white (infile);
-         c = getc (infile);
-         if (c != '\"')
-           {
-             fprintf (stderr, "## autoload of %s unparsable (%s)\n",
-                      buffer, filename);
-             continue;
-           }
-         read_c_string_or_comment (infile, 0, false, 0);
-
-         if (saved_string == 0)
-           if (!search_lisp_doc_at_eol (infile))
-             continue;
-       }
-
-#ifdef DEBUG
-      else if (! strcmp (buffer, "if")
-              || ! strcmp (buffer, "byte-code"))
-       continue;
-#endif
-
-      else
-       {
-#ifdef DEBUG
-         fprintf (stderr, "## unrecognized top-level form, %s (%s)\n",
-                  buffer, filename);
-#endif
-         continue;
-       }
-
-      /* At this point, we should either use the previous dynamic doc string in
-        saved_string or gobble a doc string from the input file.
-        In the latter case, the opening quote (and leading backslash-newline)
-        have already been read.  */
-
-      printf ("\037%c%s\n", type, buffer);
-      if (saved_string)
-       {
-         fputs (saved_string, stdout);
-         /* Don't use one dynamic doc string twice.  */
-         free (saved_string);
-         saved_string = 0;
-       }
-      else
-       read_c_string_or_comment (infile, 1, false, 0);
-    }
-  free (saved_string);
-  if (ferror (infile) || fclose (infile) != 0)
-    fatal ("%s: read error", filename);
-}
-
-
 /* make-docfile.c ends here */
index 11107ec0f6dc421e76fc4406955d04028af2b94d..a64af022d4f6768a52dc69752e2c89f00e1611d6 100644 (file)
@@ -4926,13 +4926,13 @@ binding slots have been popped."
   ;; if it weren't for the fact that we need to figure out when a defalias
   ;; defines a macro, so as to add it to byte-compile-macro-environment.
   ;;
-  ;; FIXME: we also use this hunk-handler to implement the function's dynamic
-  ;; docstring feature.  We could actually implement it more elegantly in
-  ;; byte-compile-lambda so it applies to all lambdas, but the problem is that
-  ;; the resulting .elc format will not be recognized by make-docfile, so
-  ;; either we stop using DOC for the docstrings of preloaded elc files (at the
-  ;; cost of around 24KB on 32bit hosts, double on 64bit hosts) or we need to
-  ;; build DOC in a more clever way (e.g. handle anonymous elements).
+  ;; FIXME: we also use this hunk-handler to implement the function's
+  ;; dynamic docstring feature (via byte-compile-file-form-defmumble).
+  ;; We should actually implement it (more elegantly) in
+  ;; byte-compile-lambda so it applies to all lambdas.  We did it here
+  ;; so the resulting .elc format was recognizable by make-docfile,
+  ;; but since then we stopped using DOC for the docstrings of
+  ;; preloaded elc files so that obstacle is gone.
   (let ((byte-compile-free-references nil)
         (byte-compile-free-assignments nil))
     (pcase form
index b79467339b2f9d0d013d73fce50f913424071948..727432a4cbe6ed7916610b558eab04125e2a4cd9 100644 (file)
@@ -1056,6 +1056,9 @@ the `--debug-init' option to view a complete error backtrace."
     (when debug-on-error-should-be-set
       (setq debug-on-error debug-on-error-from-init-file))))
 
+(defvar lisp-directory nil
+  "Directory containing the Lisp files that come with GNU Emacs.")
+
 (defun command-line ()
   "A subroutine of `normal-top-level'.
 Amongst another things, it parses the command-line arguments."
@@ -1087,8 +1090,7 @@ Amongst another things, it parses the command-line arguments."
   (let ((simple-file-name
         ;; Look for simple.el or simple.elc and use their directory
         ;; as the place where all Lisp files live.
-        (locate-file "simple" load-path (get-load-suffixes)))
-       lisp-dir)
+        (locate-file "simple" load-path (get-load-suffixes))))
     ;; Don't abort if simple.el cannot be found, but print a warning.
     ;; Although in most usage we are going to cryptically abort a moment
     ;; later anyway, due to missing required bidi data files (eg bug#13430).
@@ -1104,12 +1106,13 @@ please check its value")
          (unless (file-readable-p lispdir)
            (princ (format "Lisp directory %s not readable?" lispdir))
            (terpri)))
-      (setq lisp-dir (file-truename (file-name-directory simple-file-name)))
+      (setq lisp-directory
+            (file-truename (file-name-directory simple-file-name)))
       (setq load-history
            (mapcar (lambda (elt)
                      (if (and (stringp (car elt))
                               (not (file-name-absolute-p (car elt))))
-                         (cons (concat lisp-dir
+                         (cons (concat lisp-directory
                                        (car elt))
                                (cdr elt))
                        elt))
index ea4a7207ffb86ba15cc00d90fbbf72224c567594..76e4675c2a71b3a39e4f23fac9dd48c0bc2f9307 100644 (file)
@@ -642,13 +642,11 @@ endif
 ## for the first time, this prevents any variation between configurations
 ## in the contents of the DOC file.
 ##
-$(etc)/DOC: lisp.mk $(libsrc)/make-docfile$(EXEEXT) $(doc_obj) $(lisp)
+$(etc)/DOC: $(libsrc)/make-docfile$(EXEEXT) $(doc_obj)
        $(AM_V_GEN)$(MKDIR_P) $(etc)
        $(AM_V_at)rm -f $(etc)/DOC
        $(AM_V_at)$(libsrc)/make-docfile -d $(srcdir) \
          $(SOME_MACHINE_OBJECTS) $(doc_obj) > $(etc)/DOC
-       $(AM_V_at)$(libsrc)/make-docfile -a $(etc)/DOC -d $(lispsource) \
-         $(shortlisp)
 
 $(libsrc)/make-docfile$(EXEEXT) $(libsrc)/make-fingerprint$(EXEEXT): \
   $(lib)/libgnu.a
index 6be023bb934f497602c09f46f51ae34a34b6d366..129d3a517b7b06fd3e21c2e7791766f45bc1262f 100644 (file)
--- a/src/doc.c
+++ b/src/doc.c
@@ -84,16 +84,19 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
   char *from, *to, *name, *p, *p1;
   Lisp_Object file, pos;
   ptrdiff_t count = SPECPDL_INDEX ();
+  Lisp_Object dir;
   USE_SAFE_ALLOCA;
 
   if (FIXNUMP (filepos))
     {
       file = Vdoc_file_name;
+      dir = Vdoc_directory;
       pos = filepos;
     }
   else if (CONSP (filepos))
     {
       file = XCAR (filepos);
+      dir = Fsymbol_value (Qlisp_directory);
       pos = XCDR (filepos);
     }
   else
@@ -101,7 +104,7 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
 
   EMACS_INT position = eabs (XFIXNUM (pos));
 
-  if (!STRINGP (Vdoc_directory))
+  if (!STRINGP (dir))
     return Qnil;
 
   if (!STRINGP (file))
@@ -113,7 +116,7 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
   Lisp_Object tem = Ffile_name_absolute_p (file);
   file = ENCODE_FILE (file);
   Lisp_Object docdir
-    = NILP (tem) ? ENCODE_FILE (Vdoc_directory) : empty_unibyte_string;
+    = NILP (tem) ? ENCODE_FILE (dir) : empty_unibyte_string;
   ptrdiff_t docdir_sizemax = SBYTES (docdir) + 1;
   if (will_dump_p ())
     docdir_sizemax = max (docdir_sizemax, sizeof sibling_etc);
@@ -703,6 +706,7 @@ See variable `text-quoting-style'.  */)
 void
 syms_of_doc (void)
 {
+  DEFSYM (Qlisp_directory, "lisp-directory");
   DEFSYM (Qsubstitute_command_keys, "substitute-command-keys");
   DEFSYM (Qfunction_documentation, "function-documentation");
   DEFSYM (Qgrave, "grave");
index 49925764146ae3274307993fbae845ce6040ad95..55b3d473dceb04acfbef1da58795643a9385dcae 100644 (file)
@@ -1545,7 +1545,7 @@ Return t if the file exists and loads successfully.  */)
        message_with_string ("Loading %s...", file, 1);
     }
 
-  specbind (Qload_file_name, found_eff);
+  specbind (Qload_file_name, hist_file_name);
   specbind (Qload_true_file_name, found);
   specbind (Qinhibit_file_name_operation, Qnil);
   specbind (Qload_in_progress, Qt);
@@ -3224,23 +3224,6 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
                    Fstring_as_unibyte (AREF (tmp, COMPILED_BYTECODE)));
            }
 
-         if (COMPILED_DOC_STRING < ASIZE (tmp)
-             && EQ (AREF (tmp, COMPILED_DOC_STRING), make_fixnum (0)))
-           {
-             /* read_list found a docstring like '(#$ . 5521)' and treated it
-                as 0.  This placeholder 0 would lead to accidental sharing in
-                purecopy's hash-consing, so replace it with a (hopefully)
-                unique integer placeholder, which is negative so that it is
-                not confused with a DOC file offset (the USE_LSB_TAG shift
-                relies on the fact that VALMASK is one bit narrower than
-                INTMASK).  Eventually Snarf-documentation should replace the
-                placeholder with the actual docstring.  */
-             verify (INTMASK & ~VALMASK);
-             EMACS_UINT hash = ((XHASH (tmp) >> USE_LSB_TAG)
-                                | (INTMASK - INTMASK / 2));
-             ASET (tmp, COMPILED_DOC_STRING, make_ufixnum (hash));
-           }
-
          XSETPVECTYPE (vec, PVEC_COMPILED);
          return tmp;
        }
@@ -4208,31 +4191,13 @@ read_list (bool flag, Lisp_Object readcharfun)
 
       /* While building, if the list starts with #$, treat it specially.  */
       if (EQ (elt, Vload_file_name)
-         && ! NILP (elt)
-         && !NILP (Vpurify_flag))
+         && ! NILP (elt))
        {
-         if (NILP (Vdoc_file_name))
-           /* We have not yet called Snarf-documentation, so assume
-              this file is described in the DOC file
-              and Snarf-documentation will fill in the right value later.
-              For now, replace the whole list with 0.  */
-           doc_reference = 1;
-         else
-           /* We have already called Snarf-documentation, so make a relative
-              file name for this file, so it can be found properly
-              in the installed Lisp directory.
-              We don't use Fexpand_file_name because that would make
-              the directory absolute now.  */
-           {
-             AUTO_STRING (dot_dot_lisp, "../lisp/");
-             elt = concat2 (dot_dot_lisp, Ffile_name_nondirectory (elt));
-           }
+         if (!NILP (Vpurify_flag))
+           doc_reference = 0;
+         else if (load_force_doc_strings)
+           doc_reference = 2;
        }
-      else if (EQ (elt, Vload_file_name)
-              && ! NILP (elt)
-              && load_force_doc_strings)
-       doc_reference = 2;
-
       if (ch)
        {
          if (flag > 0)
@@ -4253,8 +4218,6 @@ read_list (bool flag, Lisp_Object readcharfun)
 
              if (ch == ')')
                {
-                 if (doc_reference == 1)
-                   return make_fixnum (0);
                  if (doc_reference == 2 && FIXNUMP (XCDR (val)))
                    {
                      char *saved = NULL;