--- version.c.orig	Fri Jan 22 19:08:41 1993
+++ version.c	Wed Mar 10 14:56:22 1993
@@ -1,4 +1,4 @@
-char *version_string = "3.63";
+char *version_string = "3.63 (vpath+)";
 
 /*
   Local variables:
--- file.h.orig	Sun Aug  2 07:28:01 1992
+++ file.h	Wed Mar 10 14:38:04 1993
@@ -25,6 +25,7 @@
     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.  */
@@ -69,6 +70,7 @@
     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.  */
@@ -80,7 +82,7 @@
 
 extern struct file *lookup_file (), *enter_file ();
 extern void remove_intermediates (), snap_deps ();
-extern void rename_file (), file_hash_enter ();
+extern void rehash_file (), file_hash_enter ();
 
 
 extern time_t f_mtime ();
--- file.c.orig	Tue Dec 22 17:31:13 1992
+++ file.c	Wed Mar 10 14:38:04 1993
@@ -71,7 +71,7 @@
   hashval %= FILE_BUCKETS;
 
   for (f = files[hashval]; f != 0; f = f->next)
-    if (streq (f->name, name))
+    if (streq (f->hname, name))
       return f;
   return 0;
 }
@@ -114,7 +114,7 @@
   hashval %= FILE_BUCKETS;
 
   for (f = files[hashval]; f != 0; f = f->next)
-    if (streq (f->name, name))
+    if (streq (f->hname, name))
       break;
 
   if (f != 0 && !f->double_colon)
@@ -122,7 +122,7 @@
 
   new = (struct file *) xmalloc (sizeof (struct file));
   bzero ((char *) new, sizeof (struct file));
-  new->name = name;
+  new->name = new->hname = name;
   new->update_status = -1;
 
   if (f == 0)
@@ -142,16 +142,16 @@
   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,
+/* 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
-rename_file (file, name)
+rehash_file (file, name)
      register struct file *file;
      char *name;
 {
-  char *oldname = file->name;
+  char *oldname = file->hname;
   register unsigned int oldhash;
   register char *n;
 
@@ -187,9 +187,13 @@
   /* Look for an existing file under the new name.  */
 
   for (oldfile = files[newhash]; oldfile != 0; oldfile = oldfile->next)
-    if (streq (oldfile->name, name))
+    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 && (newhash != oldhash || oldfile != 0))
     {
       /* Remove FILE from its hash bucket.  */
@@ -210,7 +214,7 @@
   /* Give FILE its new name.  */
 
   for (f = file; f != 0; f = f->prev)
-    f->name = name;
+    f->hname = name;
 
   if (oldfile == 0)
     {
@@ -294,6 +298,7 @@
       MERGE (is_target);
       MERGE (cmd_target);
       MERGE (phony);
+      MERGE (ignore_vpath);
 #undef MERGE
 
       file->renamed = oldfile;
--- remake.c.orig	Fri Jan 22 17:02:48 1993
+++ remake.c	Wed Mar 10 14:55:40 1993
@@ -503,15 +503,44 @@
 
   if (!must_make)
     {
-      DEBUGPR ("No need to remake target `%s'.\n");
+      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;
     }
 
-  DEBUGPR ("Must remake target `%s'.\n");
+  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);
 
@@ -878,7 +907,7 @@
     {
       mtime = name_mtime (file->name);
 
-      if (mtime == (time_t) -1 && search)
+      if (mtime == (time_t) -1 && search && !file->ignore_vpath)
 	{
 	  /* If name_mtime failed, search VPATH.  */
 	  char *name = file->name;
@@ -887,9 +916,9 @@
 	      || (name[0] == '-' && name[1] == 'l'
 		  && library_search (&name)))
 	    {
-	      rename_file (file, name);
+	      rehash_file (file, name);
 	      check_renamed (file);
-	      return file_mtime (file);
+	      mtime = name_mtime (name);
 	    }
 	}
     }
--- implicit.c.orig	Wed Jan  6 17:57:30 1993
+++ implicit.c	Wed Mar 10 15:59:12 1993
@@ -142,7 +142,7 @@
   register struct rule *rule;
   register struct dep *dep;
 
-  char *p;
+  char *p, *vp;
 
 #ifndef	NO_ARCHIVES
   if (archive || ar_name (filename))
@@ -371,10 +371,12 @@
 		}
 	      /* 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))
+	      vp = p;
+	      if (vpath_search (&vp))
 		{
-		  DEBUGP2 ("Found dependency as `%s'.%s\n", p, "");
-		  found_files[deps_found++] = p;
+		  DEBUGP2 ("Found dependency `%s' as `%s'\n", p, vp);
+		  strcpy(vp, p);
+		  found_files[deps_found++] = vp;
 		  continue;
 		}
 
