*** version.c.orig	Sun May  9 15:41:24 1993
--- version.c	Mon May 10 10:27:07 1993
***************
*** 1,4 ****
! char *version_string = "3.65";
  
  /*
    Local variables:
--- 1,4 ----
! char *version_string = "3.65 (vpath+)";
  
  /*
    Local variables:
*** file.h.orig	Mon Jan 25 17:45:49 1993
--- file.h	Mon May 10 10:25:46 1993
***************
*** 26,31 ****
--- 26,32 ----
      char *name;
      struct dep *deps;
      struct commands *cmds;	/* Commands to execute for this target */
+     char *hname;                /* Hashed filename */
      char *stem;			/* Implicit stem, if an implicit
      				   rule has been used */
      struct dep *also_make;	/* Targets that are made by making this.  */
***************
*** 70,75 ****
--- 71,77 ----
      unsigned int intermediate:1;/* Nonzero if this is an intermediate file.  */
      unsigned int dontcare:1;	/* Nonzero if no complaint is to be made if
  				   this target cannot be remade.  */
+     unsigned int ignore_vpath:1;/* Nonzero if we threw out VPATH name */
    };
  
  /* Number of intermediate files entered.  */
***************
*** 81,87 ****
  
  extern struct file *lookup_file (), *enter_file ();
  extern void remove_intermediates (), snap_deps ();
! extern void rename_file (), file_hash_enter ();
  
  
  extern time_t f_mtime ();
--- 83,89 ----
  
  extern struct file *lookup_file (), *enter_file ();
  extern void remove_intermediates (), snap_deps ();
! extern void rehash_file (), file_hash_enter ();
  
  
  extern time_t f_mtime ();
*** file.c.orig	Wed Mar 10 15:24:57 1993
--- file.c	Mon May 10 10:25:46 1993
***************
*** 72,78 ****
    hashval %= FILE_BUCKETS;
  
    for (f = files[hashval]; f != 0; f = f->next)
!     if (streq (f->name, name))
        return f;
    return 0;
  }
--- 72,78 ----
    hashval %= FILE_BUCKETS;
  
    for (f = files[hashval]; f != 0; f = f->next)
!     if (streq (f->hname, name))
        return f;
    return 0;
  }
***************
*** 115,121 ****
    hashval %= FILE_BUCKETS;
  
    for (f = files[hashval]; f != 0; f = f->next)
!     if (streq (f->name, name))
        break;
  
    if (f != 0 && !f->double_colon)
--- 115,121 ----
    hashval %= FILE_BUCKETS;
  
    for (f = files[hashval]; f != 0; f = f->next)
!     if (streq (f->hname, name))
        break;
  
    if (f != 0 && !f->double_colon)
***************
*** 123,129 ****
  
    new = (struct file *) xmalloc (sizeof (struct file));
    bzero ((char *) new, sizeof (struct file));
!   new->name = name;
    new->update_status = -1;
  
    if (f == 0)
--- 123,129 ----
  
    new = (struct file *) xmalloc (sizeof (struct file));
    bzero ((char *) new, sizeof (struct file));
!   new->name = new->hname = name;
    new->update_status = -1;
  
    if (f == 0)
***************
*** 143,158 ****
    return new;
  }
  
! /* Rename FILE to NAME.  This is not as simple as resetting
!    the `name' member, since it must be put in a new hash bucket,
     and possibly merged with an existing file called NAME.  */
  
  void
! rename_file (file, name)
       register struct file *file;
       char *name;
  {
!   char *oldname = file->name;
    register unsigned int oldhash;
    register char *n;
  
--- 143,158 ----
    return new;
  }
  
! /* Rehash FILE to NAME.  This is not as simple as resetting
!    the `hname' member, since it must be put in a new hash bucket,
     and possibly merged with an existing file called NAME.  */
  
  void
! rehash_file (file, name)
       register struct file *file;
       char *name;
  {
!   char *oldname = file->hname;
    register unsigned int oldhash;
    register char *n;
  
***************
*** 189,197 ****
    /* Look for an existing file under the new name.  */
  
    for (oldfile = files[newbucket]; oldfile != 0; oldfile = oldfile->next)
!     if (streq (oldfile->name, name))
        break;
  
    if (oldhash != 0 && (newbucket != oldbucket || oldfile != 0))
      {
        /* Remove FILE from its hash bucket.  */
--- 189,201 ----
    /* Look for an existing file under the new name.  */
  
    for (oldfile = files[newbucket]; oldfile != 0; oldfile = oldfile->next)
!     if (streq (oldfile->hname, name))
        break;
  
+   /* If the old file is the same as the new file, something's wrong.  */
+   if (oldfile == file)
+     fatal ("File `%s' renamed to itself! (VPATH+ error?)", name);
+ 
    if (oldhash != 0 && (newbucket != oldbucket || oldfile != 0))
      {
        /* Remove FILE from its hash bucket.  */
***************
*** 210,216 ****
    /* Give FILE its new name.  */
  
    for (f = file; f != 0; f = f->prev)
!     f->name = name;
  
    if (oldfile == 0)
      {
--- 214,220 ----
    /* Give FILE its new name.  */
  
    for (f = file; f != 0; f = f->prev)
!     f->hname = name;
  
    if (oldfile == 0)
      {
***************
*** 294,299 ****
--- 298,304 ----
        MERGE (is_target);
        MERGE (cmd_target);
        MERGE (phony);
+       MERGE (ignore_vpath);
  #undef MERGE
  
        file->renamed = oldfile;
*** remake.c.orig	Mon Apr 12 16:52:45 1993
--- remake.c	Mon May 10 10:25:47 1993
***************
*** 531,545 ****
  
    if (!must_make)
      {
!       DEBUGPR ("No need to remake target `%s'.\n");
        file->command_state = cs_finished;
        file->update_status = 0;
        file->updated = 1;
        return 0;
      }
  
!   DEBUGPR ("Must remake target `%s'.\n");
  
    /* Now, take appropriate actions to remake the file.  */
    remake_file (file);
  
--- 531,574 ----
  
    if (!must_make)
      {
!       if (debug_flag)
!         {
!           print_spaces(depth);
!           printf("No need to remake target `%s'", file->name);
!           if (!streq(file->name, file->hname))
!               printf("; using VPATH name `%s'", file->hname);
!           printf(".\n");
!           fflush(stdout);
!         }
! 
        file->command_state = cs_finished;
        file->update_status = 0;
        file->updated = 1;
+ 
+       /* Since we don't need to remake the file, convert it to use the
+          VPATH filename if we found one.  hfile will be either the
+          local name if no VPATH or the VPATH name if one was found.  */
+ 
+       while (file)
+         {
+           file->name = file->hname;
+           file = file->prev;
+         }
+ 
        return 0;
      }
  
!   if (debug_flag)
!     {
!       print_spaces(depth);
!       printf("Must remake target `%s'", file->name);
!       if (!streq(file->name, file->hname))
!           printf("; ignoring VPATH name `%s'", file->hname);
!       printf(".\n");
!       fflush(stdout);
!     }
  
+   file->ignore_vpath = 1;
    /* Now, take appropriate actions to remake the file.  */
    remake_file (file);
  
***************
*** 906,912 ****
      {
        mtime = name_mtime (file->name);
  
!       if (mtime == (time_t) -1 && search)
  	{
  	  /* If name_mtime failed, search VPATH.  */
  	  char *name = file->name;
--- 935,941 ----
      {
        mtime = name_mtime (file->name);
  
!       if (mtime == (time_t) -1 && search && !file->ignore_vpath)
  	{
  	  /* If name_mtime failed, search VPATH.  */
  	  char *name = file->name;
***************
*** 919,927 ****
  		/* vpath_search and library_search store zero in MTIME
  		   if they didn't need to do a stat call for their work.  */
  		file->last_mtime = mtime;
! 	      rename_file (file, name);
  	      check_renamed (file);
! 	      return file_mtime (file);
  	    }
  	}
      }
--- 948,956 ----
  		/* vpath_search and library_search store zero in MTIME
  		   if they didn't need to do a stat call for their work.  */
  		file->last_mtime = mtime;
! 	      rehash_file (file, name);
  	      check_renamed (file);
! 	      mtime = name_mtime (name);
  	    }
  	}
      }
*** implicit.c.orig	Wed Mar 10 15:41:03 1993
--- implicit.c	Mon May 10 10:25:47 1993
***************
*** 142,148 ****
    register struct rule *rule;
    register struct dep *dep;
  
!   char *p;
  
  #ifndef	NO_ARCHIVES
    if (archive || ar_name (filename))
--- 142,148 ----
    register struct rule *rule;
    register struct dep *dep;
  
!   char *p, *vp;
  
  #ifndef	NO_ARCHIVES
    if (archive || ar_name (filename))
***************
*** 380,389 ****
  		}
  	      /* This code, given FILENAME = "lib/foo.o", dependency name
  		 "lib/foo.c", and VPATH=src, searches for "src/lib/foo.c".  */
! 	      if (vpath_search (&p, (time_t *) 0))
  		{
! 		  DEBUGP2 ("Found dependency as `%s'.%s\n", p, "");
! 		  found_files[deps_found++] = p;
  		  continue;
  		}
  
--- 380,391 ----
  		}
  	      /* This code, given FILENAME = "lib/foo.o", dependency name
  		 "lib/foo.c", and VPATH=src, searches for "src/lib/foo.c".  */
! 	      vp = p;
! 	      if (vpath_search (&vp, (time_t *) 0))
  		{
! 		  DEBUGP2 ("Found dependency `%s' as VPATH `%s'\n", p, vp);
! 		  strcpy(vp, p);
! 		  found_files[deps_found++] = vp;
  		  continue;
  		}
  
