*** version.c.orig	Sun Nov  6 18:33:26 1994
--- version.c	Mon Nov  7 08:57:05 1994
***************
*** 1,4 ****
! char *version_string = "3.72.1";
  
  /*
    Local variables:
--- 1,4 ----
! char *version_string = "3.72.1 (vpath+)";
  
  /*
    Local variables:
*** file.h.orig	Mon Oct 24 18:47:43 1994
--- file.h	Mon Nov  7 08:59:15 1994
***************
*** 24,29 ****
--- 24,30 ----
    {
      struct file *next;
      char *name;
+     char *hname;                /* Hashed filename */
      struct dep *deps;
      struct commands *cmds;	/* Commands to execute for this target.  */
      int command_flags;		/* Flags OR'd in for cmds; see commands.h.  */
***************
*** 74,79 ****
--- 75,81 ----
      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.  */
***************
*** 85,91 ****
  
  extern struct file *lookup_file (), *enter_file ();
  extern void remove_intermediates (), snap_deps ();
! extern void rename_file (), file_hash_enter ();
  extern void set_command_state ();
  
  
--- 87,93 ----
  
  extern struct file *lookup_file (), *enter_file ();
  extern void remove_intermediates (), snap_deps ();
! extern void rehash_file (), file_hash_enter ();
  extern void set_command_state ();
  
  
*** file.c.orig	Thu Oct 27 02:02:43 1994
--- file.c	Mon Nov  7 08:56:19 1994
***************
*** 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;
  }
***************
*** 94,100 ****
    hashval %= FILE_BUCKETS;
  
    for (f = files[hashval]; f != 0; f = f->next)
!     if (streq (f->name, name))
        break;
  
    if (f != 0 && !f->double_colon)
--- 94,100 ----
    hashval %= FILE_BUCKETS;
  
    for (f = files[hashval]; f != 0; f = f->next)
!     if (streq (f->hname, name))
        break;
  
    if (f != 0 && !f->double_colon)
***************
*** 102,108 ****
  
    new = (struct file *) xmalloc (sizeof (struct file));
    bzero ((char *) new, sizeof (struct file));
!   new->name = name;
    new->update_status = -1;
  
    if (f == 0)
--- 102,108 ----
  
    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)
***************
*** 123,138 ****
    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;
  
--- 123,138 ----
    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;
  
***************
*** 169,177 ****
    /* 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.  */
--- 169,181 ----
    /* 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.  */
***************
*** 189,197 ****
  
    /* Give FILE its new name.  */
  
!   file->name = name;
    for (f = file->double_colon; f != 0; f = f->prev)
!     f->name = name;
  
    if (oldfile == 0)
      {
--- 193,201 ----
  
    /* Give FILE its new name.  */
  
!   file->hname = name;
    for (f = file->double_colon; f != 0; f = f->prev)
!     f->hname = name;
  
    if (oldfile == 0)
      {
***************
*** 275,280 ****
--- 279,285 ----
        MERGE (is_target);
        MERGE (cmd_target);
        MERGE (phony);
+       MERGE (ignore_vpath);
  #undef MERGE
  
        file->renamed = oldfile;
*** remake.c.orig	Sat Sep 10 11:04:57 1994
--- remake.c	Mon Nov  7 09:08:18 1994
***************
*** 546,558 ****
  
    if (!must_make)
      {
!       DEBUGPR ("No need to remake target `%s'.\n");
        file->update_status = 0;
        notice_finished_file (file);
        return 0;
      }
  
!   DEBUGPR ("Must remake target `%s'.\n");
  
    /* Now, take appropriate actions to remake the file.  */
    remake_file (file);
--- 546,588 ----
  
    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->update_status = 0;
        notice_finished_file (file);
+ 
+       /* 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);
***************
*** 932,938 ****
      {
        mtime = name_mtime (file->name);
  
!       if (mtime == (time_t) -1 && search)
  	{
  	  /* If name_mtime failed, search VPATH.  */
  	  char *name = file->name;
--- 962,968 ----
      {
        mtime = name_mtime (file->name);
  
!       if (mtime == (time_t) -1 && search && !file->ignore_vpath)
  	{
  	  /* If name_mtime failed, search VPATH.  */
  	  char *name = file->name;
***************
*** 945,953 ****
  		/* 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);
  	    }
  	}
      }
--- 975,983 ----
  		/* 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	Thu Sep 29 15:52:49 1994
--- implicit.c	Mon Nov  7 08:56:21 1994
***************
*** 151,157 ****
    register struct rule *rule;
    register struct dep *dep;
  
!   char *p;
  
  #ifndef	NO_ARCHIVES
    if (archive || ar_name (filename))
--- 151,157 ----
    register struct rule *rule;
    register struct dep *dep;
  
!   char *p, *vp;
  
  #ifndef	NO_ARCHIVES
    if (archive || ar_name (filename))
***************
*** 379,388 ****
  		}
  	      /* 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;
  		}
  
--- 379,390 ----
  		}
  	      /* 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;
  		}
  
