Subject: Re: bug#5303: 23.1.91; Cannot load .emacs-history from savehist.el

From: Eli Zaretskii <[email-masked]>
Date: Thu, 21 Jan 2010 20:24:30 +0200

> From: Lennart Borgman <[email-masked]>
> Date: Thu, 21 Jan 2010 02:02:49 +0100
> Cc: Michael Albinus <[email-masked]>, [email-masked], [email-masked], 
> 	[email-masked]
> 
> On Wed, Jan 20, 2010 at 7:18 PM, Eli Zaretskii <[email-masked]> wrote:
> >
> > It doesn't happen for me with stock Emacs 23.1, so it _is_ a
> > regression.
> 
> A quick check with my old binaries shows that 2009-08-04 works but
> 2009-09-15 fails.
> 
> Some change in that period added tramp-completion-file-name-handler to
> file-name-handler-alist.
> Removing it from there makes (load "c:/emacs-history") succeed again.
> 
> Note however that tramp-completion-file-name-handler run the real handler.
> So it looks more like it is the presence of the pattern
> 
>   ("\\`\\([a-zA-Z]:\\)?/[^/]*\\'" . tramp-completion-file-name-handler)
> 
> in file-name-handler-alist that causes the problem. Which probably
> means that the problem is in `load' as Eli has suggested.

To fix the problem (which I also believe is in `load' or maybe between
`load' and `openp'), I need to better understand some of the code in
`load'.

Would someone who knows please help me answer the following questions
regarding the fragment below?  Stefan? Yidong? Richard? anyone?

The questions are:

  . Why do we test for ".elc" OR non-zero return value from
    safe_to_load_p?  What is the purpose of handling files without the
    .elc extension as byte-compiled?

  . Was safe_to_load_p intended to return non-zero value for invalid
    file descriptors such as -2?

  if (!bcmp (SDATA (found) + SBYTES (found) - 4,
	     ".elc", 4)
      || (version = safe_to_load_p (fd)) > 0)
    /* Load .elc files directly, but not when they are
       remote and have no handler!  */
    {
      if (fd != -2)
	{
	  struct stat s1, s2;
	  int result;

	  GCPRO3 (file, found, hist_file_name);

	  if (version < 0
	      && ! (version = safe_to_load_p (fd)))
	    {
	      safe_p = 0;
	      if (!load_dangerous_libraries)
		{
		  if (fd >= 0)
		    emacs_close (fd);
		  error ("File `%s' was not compiled in Emacs",
			 SDATA (found));
		}
	      else if (!NILP (nomessage) && !force_load_messages)
		message_with_string ("File `%s' not compiled in Emacs", found, 1);
	    }

	  compiled = 1;

	  efound = ENCODE_FILE (found);

#ifdef DOS_NT
	  fmode = "rb";
#endif /* DOS_NT */
	  stat ((char *)SDATA (efound), &s1);
	  SSET (efound, SBYTES (efound) - 1, 0);
	  result = stat ((char *)SDATA (efound), &s2);
	  SSET (efound, SBYTES (efound) - 1, 'c');

	  if (result >= 0 && (unsigned) s1.st_mtime < (unsigned) s2.st_mtime)
	    {
	      /* Make the progress messages mention that source is newer.  */
	      newer = 1;

	      /* If we won't print another message, mention this anyway.  */
	      if (!NILP (nomessage) && !force_load_messages)
		{
		  Lisp_Object msg_file;
		  msg_file = Fsubstring (found, make_number (0), make_number (-1));
		  message_with_string ("Source file `%s' newer than byte-compiled file",
				       msg_file, 1);
		}
	    }
	  UNGCPRO;
	}
    }
  else
    {
      /* We are loading a source file (*.el).  */
      if (!NILP (Vload_source_file_function))
	{
	  Lisp_Object val;

	  if (fd >= 0)
	    emacs_close (fd);
	  val = call4 (Vload_source_file_function, found, hist_file_name,
		       NILP (noerror) ? Qnil : Qt,
		       (NILP (nomessage) || force_load_messages) ? Qnil : Qt);
	  return unbind_to (count, val);
	}
    }