On 10/8/2014 10:14 PM, John E. Malmberg wrote:
On 10/7/2014 11:43 PM, Paul Smith wrote:
Some of the same formatting notes as before; please check your code
against the style of the rest of the code.

Reformatted patch to GNU coding standard.

Rebuilt to add a fix to remake.c to call gpath_search correctly for a VMS path.

This gets the features/vpathgpath test to pass on VMS with VMS format gpaths.

This makes all the features tests that are currently applicable to VMS to pass.

Regards,
-John

>From 4b5a2da6ef5c5afe525cfb1eced42d2d284b8ad1 Mon Sep 17 00:00:00 2001
From: John Malmberg <wb8...@qsl.net>
Date: Tue, 7 Oct 2014 19:23:47 -0500
Subject: [PATCH] VMS Fix implicit rules and Unix Paths Oct 16

This fixes the implicit rules and Unix style pathname handling.
It also fixes some of the VMS style pathname handling, more work there
will be needed later.
TODO: There is at least another case insensitive platform besides VMS.
We need to find out why there is some extra VMS code for this.  This
indicates either the extra VMS code is not needed, or the case
insensitive support may not be complete on the other case insensitive platforms.

* default.c: default_suffix_rules[] was missing definitions.
  default.c: default_variables[] was missing definitions.
  TODO: As it is important that VMS DCL mode definitions must always be a
  superset of Unix definitions, a better way of maintaining the VMS DCL
  mode definitions should be devised.
* dir.c: (downcase_implace) New routine.  Existing downcase() routine
  is not reentrant.
  dir.c: Add future support for VMS 8.2+ _USE_STD_STAT macro which will
  disable a lot of VMS specific code from compiling.
  dir.c: (dir_file_exists_p) vmsify filename only if directory name has
  VMS directory delimiters.
  dir.c: (file_exists_p) Handle both VMS and Unix directories.
  dir.c: (file_impossible) Handle both VMS and Unix directories.  Keep
  track of if a VMS format path is needed for the return value.
* file.c: (lookup_file) Need to check if vmsify is needed, handle Unix paths.
* implicit.c: (pattern_search) Enable Unix paths.
* read.c: (parse_file_seq) Enable Unix paths.
* remake.c: (f_mtime) Fix gpath_search call for VMS paths.
* rule.c: (count_implicit_rule) Enable Unix paths, Fix VMS paths.
* vpath.c: (selective_vpath_search) Enable Unix paths.
---
 default.c  |   83 +++++++++++++++++++++++++
 dir.c      |  202 +++++++++++++++++++++++++++++++++++++++++++-----------------
 file.c     |   28 ++++++---
 implicit.c |   17 +++---
 read.c     |   22 ++++---
 remake.c   |   13 +++-
 vpath.c    |   40 +++++++++---
 7 files changed, 313 insertions(+), 92 deletions(-)

diff --git a/default.c b/default.c
index 3b6f7ae..93c993e 100644
--- a/default.c
+++ b/default.c
@@ -131,10 +131,47 @@ static struct pspec default_terminal_rules[] =
 static const char *default_suffix_rules[] =
   {
 #ifdef VMS
+    ".o",
+    "$(LINK.obj) $^ $(LOADLIBES) $(LDLIBS) -o $@",
+    ".obj",
+    "$(LINK.obj) $^ $(LOADLIBES) $(LDLIBS) -o $@",
+    ".s",
+    "$(LINK.s) $^ $(LOADLIBES) $(LDLIBS) -o $@",
+    ".S",
+    "$(LINK.S) $^ $(LOADLIBES) $(LDLIBS) -o $@",
+    ".c",
+    "$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@",
+    ".cc",
+    "$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@",
+    ".C",
+    "$(LINK.C) $^ $(LOADLIBES) $(LDLIBS) -o $@",
+    ".cpp",
+    "$(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $@",
+    ".f",
+    "$(LINK.f) $^ $(LOADLIBES) $(LDLIBS) -o $@",
+    ".m",
+    "$(LINK.m) $^ $(LOADLIBES) $(LDLIBS) -o $@",
+    ".p",
+    "$(LINK.p) $^ $(LOADLIBES) $(LDLIBS) -o $@",
+    ".F",
+    "$(LINK.F) $^ $(LOADLIBES) $(LDLIBS) -o $@",
+    ".r",
+    "$(LINK.r) $^ $(LOADLIBES) $(LDLIBS) -o $@",
+    ".mod",
+    "$(COMPILE.mod) -o $@ -e $@ $^",
+
+    ".def.sym",
+    "$(COMPILE.def) -o $@ $<",
+
+    ".sh",
+    "copy $< >$@",
+
     ".obj.exe",
     "$(LINK.obj) $^ $(LOADLIBES) $(LDLIBS) $(CRT0) /exe=$@",
     ".mar.exe",
     "$(COMPILE.mar) $^ \n $(LINK.obj) $(subst .mar,.obj,$^) $(LOADLIBES) $(LDLIBS) $(CRT0) /exe=$@",
+    ".s.o",
+    "$(COMPILE.s) -o $@ $<",
     ".s.exe",
     "$(COMPILE.s) $^ \n $(LINK.obj) $(subst .s,.obj,$^) $(LOADLIBES) $(LDLIBS) $(CRT0) /exe=$@",
     ".c.exe",
@@ -205,6 +242,27 @@ static const char *default_suffix_rules[] =
     ".tex.dvi",
     "$(TEX) $<",
 
+    ".cpp.o",
+    "$(COMPILE.cpp) $(OUTPUT_OPTION) $<",
+    ".f.o",
+    "$(COMPILE.f) $(OUTPUT_OPTION) $<",
+    ".m.o",
+    "$(COMPILE.m) $(OUTPUT_OPTION) $<",
+    ".p.o",
+    "$(COMPILE.p) $(OUTPUT_OPTION) $<",
+    ".r.o",
+    "$(COMPILE.r) $(OUTPUT_OPTION) $<",
+    ".mod.o",
+    "$(COMPILE.mod) -o $@ $<",
+
+    ".c.ln",
+    "$(LINT.c) -C$* $<",
+    ".y.ln",
+    "$(YACC.y) $< \n rename y_tab.c $@",
+
+    ".l.ln",
+    "@$(RM) $*.c\n $(LEX.l) $< > $*.c\n$(LINT.c) -i $*.c -o $@\n $(RM) $*.c",
+
 #else /* ! VMS */
 
     ".o",
@@ -413,19 +471,44 @@ static const char *default_variables[] =
     "LDLIBS", "",
 #endif
 
+    "LINK.o", "$(LD) $(LDFLAGS)",
     "LINK.obj", "$(LD) $(LDFLAGS)",
 #ifndef GCC_IS_NATIVE
     "CXXLINK.obj", "$(CXXLD) $(LDFLAGS)",
     "COMPILE.cxx", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
 #endif
     "COMPILE.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
+    "LINK.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
+    "COMPILE.m", "$(OBJC) $(OBJCFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
+    "LINK.m", "$(OBJC) $(OBJCFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
     "COMPILE.cc", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
+    "COMPILE.C", "$(COMPILE.cc)",
+    "COMPILE.cpp", "$(COMPILE.cc)",
+    "LINK.C", "$(LINK.cc)",
+    "LINK.cpp", "$(LINK.cc)",
     "YACC.y", "$(YACC) $(YFLAGS)",
     "LEX.l", "$(LEX) $(LFLAGS)",
+    "YACC.m", "$(YACC) $(YFLAGS)",
+    "LEX.m", "$(LEX) $(LFLAGS) -t",
     "COMPILE.for", "$(FC) $(FFLAGS) $(TARGET_ARCH)",
+    "COMPILE.f", "$(FC) $(FFLAGS) $(TARGET_ARCH) -c",
+    "LINK.f", "$(FC) $(FFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
+    "COMPILE.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
+    "LINK.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
+    "COMPILE.r", "$(FC) $(FFLAGS) $(RFLAGS) $(TARGET_ARCH) -c",
+    "LINK.r", "$(FC) $(FFLAGS) $(RFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
     "COMPILE.pas", "$(PC) $(PFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
+    "COMPILE.def", "$(M2C) $(M2FLAGS) $(DEFFLAGS) $(TARGET_ARCH)",
+    "COMPILE.mod", "$(M2C) $(M2FLAGS) $(MODFLAGS) $(TARGET_ARCH)",
+    "COMPILE.p", "$(PC) $(PFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
+    "LINK.p", "$(PC) $(PFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
     "COMPILE.mar", "$(MACRO) $(MACROFLAGS)",
     "COMPILE.s", "$(AS) $(ASFLAGS) $(TARGET_MACH)",
+    "LINK.S", "$(CC) $(ASFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_MACH)",
+    "COMPILE.S", "$(CC) $(ASFLAGS) $(CPPFLAGS) $(TARGET_MACH) -c",
+    "PREPROCESS.S", "$(CC) -E $(CPPFLAGS)",
+    "PREPROCESS.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -F",
+    "PREPROCESS.r", "$(FC) $(FFLAGS) $(RFLAGS) $(TARGET_ARCH) -F",
     "LINT.c", "$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(TARGET_ARCH)",
 
     "MV", "rename/new_version",
diff --git a/dir.c b/dir.c
index 7e00b8f..b414ef3 100644
--- a/dir.c
+++ b/dir.c
@@ -142,6 +142,32 @@ downcase (const char *filename)
 
 #ifdef VMS
 
+static char *
+downcase_inplace(char * filename)
+{
+  char *name;
+  name = filename;
+  while (*name != '\0')
+    {
+      *name = tolower ((unsigned char)*name);
+      ++name;
+    }
+  return filename;
+}
+
+#ifndef _USE_STD_STAT
+/* VMS 8.2 fixed the VMS stat output to have unique st_dev and st_ino
+   when _USE_STD_STAT is used on the compile line.
+
+   Prior to _USE_STD_STAT support, the st_dev is a pointer to thread
+   static memory containing the device of the last filename looked up.
+
+   Todo: find out if the ino_t still needs to be faked on a directory.
+ */
+
+/* Define this if the older VMS_INO_T is needed */
+#define VMS_INO_T 1
+
 static int
 vms_hash (const char *name)
 {
@@ -200,6 +226,10 @@ vmsstat_dir (const char *name, struct stat *st)
 
   return 0;
 }
+
+# define stat(__path, __sbuf) vmsstat_dir (__path, __sbuf)
+
+#endif /* _USE_STD_STAT */
 #endif /* VMS */
 
 /* Hash table of directories.  */
@@ -225,7 +255,7 @@ struct directory_contents
 # define FS_NTFS     0x2
 # define FS_UNKNOWN  0x4
 #else
-# ifdef VMS
+# ifdef VMS_INO_T
     ino_t ino[3];
 # else
     ino_t ino;
@@ -246,7 +276,7 @@ directory_contents_hash_1 (const void *key_0)
   ISTRING_HASH_1 (key->path_key, hash);
   hash ^= ((unsigned int) key->dev << 4) ^ (unsigned int) key->ctime;
 #else
-# ifdef VMS
+# ifdef VMS_INO_T
   hash = (((unsigned int) key->dev << 4)
           ^ ((unsigned int) key->ino[0]
              + (unsigned int) key->ino[1]
@@ -269,7 +299,7 @@ directory_contents_hash_2 (const void *key_0)
   ISTRING_HASH_2 (key->path_key, hash);
   hash ^= ((unsigned int) key->dev << 4) ^ (unsigned int) ~key->ctime;
 #else
-# ifdef VMS
+# ifdef VMS_INO_T
   hash = (((unsigned int) key->dev << 4)
           ^ ~((unsigned int) key->ino[0]
               + (unsigned int) key->ino[1]
@@ -308,7 +338,7 @@ directory_contents_hash_cmp (const void *xv, const void *yv)
   if (result)
     return result;
 #else
-# ifdef VMS
+# ifdef VMS_INO_T
   result = MAKECMP(x->ino[0], y->ino[0]);
   if (result)
     return result;
@@ -419,13 +449,6 @@ find_directory (const char *name)
   struct directory **dir_slot;
   struct directory dir_key;
 
-#ifdef VMS
-  if ((*name == '.') && (*(name+1) == 0))
-    name = "[]";
-  else
-    name = vmsify (name,1);
-#endif
-
   dir_key.name = name;
   dir_slot = (struct directory **) hash_find_slot (&directories, &dir_key);
   dir = *dir_slot;
@@ -439,7 +462,12 @@ find_directory (const char *name)
 
       dir = xmalloc (sizeof (struct directory));
 #if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
-      dir->name = strcache_add_len (downcase (name), p - name);
+      /* Todo: Why is this only needed on VMS? */
+      {
+        char *lname = downcase_inplace (xstrdup (name));
+        dir->name = strcache_add_len (lname, p - name);
+        free (lname);
+      }
 #else
       dir->name = strcache_add_len (name, p - name);
 #endif
@@ -447,9 +475,7 @@ find_directory (const char *name)
       /* The directory is not in the name hash table.
          Find its device and inode numbers, and look it up by them.  */
 
-#ifdef VMS
-      r = vmsstat_dir (name, &st);
-#elif defined(WINDOWS32)
+#if defined(WINDOWS32)
       {
         char tem[MAXPATHLEN], *tstart, *tend;
 
@@ -492,7 +518,7 @@ find_directory (const char *name)
           dc_key.path_key = w32_path = w32ify (name, 1);
           dc_key.ctime = st.st_ctime;
 #else
-# ifdef VMS
+# ifdef VMS_INO_T
           dc_key.ino[0] = st.st_ino[0];
           dc_key.ino[1] = st.st_ino[1];
           dc_key.ino[2] = st.st_ino[2];
@@ -537,7 +563,7 @@ find_directory (const char *name)
               else
                 dc->fs_flags = FS_UNKNOWN;
 #else
-# ifdef VMS
+# ifdef VMS_INO_T
               dc->ino[0] = st.st_ino[0];
               dc->ino[1] = st.st_ino[1];
               dc->ino[2] = st.st_ino[2];
@@ -602,11 +628,6 @@ dir_contents_file_exists_p (struct directory_contents *dir,
   if (filename != 0)
     _fnlwr (filename); /* lower case for FAT drives */
 #endif
-
-#ifdef VMS
-  filename = vmsify (filename,0);
-#endif
-
   if (filename != 0)
     {
       struct dirfile dirfile_key;
@@ -680,6 +701,9 @@ dir_contents_file_exists_p (struct directory_contents *dir,
 
 #if defined(VMS) && defined(HAVE_DIRENT_H)
       /* In VMS we get file versions too, which have to be stripped off */
+      /* Some versions of VMS return versions on Unix files even when
+         the feature option to strip them is set
+       */
       {
         char *p = strrchr (d->d_name, ';');
         if (p)
@@ -703,7 +727,8 @@ dir_contents_file_exists_p (struct directory_contents *dir,
         {
           df = xmalloc (sizeof (struct dirfile));
 #if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
-          df->name = strcache_add_len (downcase (d->d_name), len);
+          /* TODO: Why is this only needed on VMS? */
+          df->name = strcache_add_len (downcase_inplace (d->d_name), len);
 #else
           df->name = strcache_add_len (d->d_name, len);
 #endif
@@ -734,6 +759,15 @@ dir_contents_file_exists_p (struct directory_contents *dir,
 int
 dir_file_exists_p (const char *dirname, const char *filename)
 {
+#ifdef VMS
+  if ((filename != NULL) && (dirname != NULL))
+    {
+      int want_vmsify;
+      want_vmsify = (strpbrk (dirname, ":<[") != NULL);
+      if (want_vmsify)
+        filename = vmsify (filename, 0);
+    }
+#endif
   return dir_contents_file_exists_p (find_directory (dirname)->contents,
                                      filename);
 }
@@ -752,14 +786,24 @@ file_exists_p (const char *name)
     return ar_member_date (name) != (time_t) -1;
 #endif
 
+  dirend = strrchr (name, '/');
 #ifdef VMS
-  dirend = strrchr (name, ']');
   if (dirend == 0)
-    dirend = strrchr (name, ':');
+    {
+      dirend = strrchr (name, ']');
+      dirend == NULL ? dirend : dirend++;
+    }
   if (dirend == 0)
-    return dir_file_exists_p ("[]", name);
-#else /* !VMS */
-  dirend = strrchr (name, '/');
+    {
+      dirend = strrchr (name, '>');
+      dirend == NULL ? dirend : dirend++;
+    }
+  if (dirend == 0)
+    {
+      dirend = strrchr (name, ':');
+      dirend == NULL ? dirend : dirend++;
+    }
+#endif /* VMS */
 #ifdef HAVE_DOS_PATHS
   /* Forward and backslashes might be mixed.  We need the rightmost one.  */
   {
@@ -774,10 +818,9 @@ file_exists_p (const char *name)
   if (dirend == 0)
 #ifndef _AMIGA
     return dir_file_exists_p (".", name);
-#else /* !VMS && !AMIGA */
+#else /* !AMIGA */
     return dir_file_exists_p ("", name);
 #endif /* AMIGA */
-#endif /* VMS */
 
   slash = dirend;
   if (dirend == name)
@@ -796,7 +839,13 @@ file_exists_p (const char *name)
       p[dirend - name] = '\0';
       dirname = p;
     }
-  return dir_file_exists_p (dirname, slash + 1);
+#ifdef VMS
+  if (*slash == '/')
+    slash++;
+#else
+  slash++;
+#endif
+  return dir_file_exists_p (dirname, slash);
 }
 
 /* Mark FILENAME as 'impossible' for 'file_impossible_p'.
@@ -811,16 +860,25 @@ file_impossible (const char *filename)
   struct directory *dir;
   struct dirfile *new;
 
-#ifdef VMS
-  dirend = strrchr (p, ']');
-  if (dirend == 0)
-    dirend = strrchr (p, ':');
-  dirend++;
-  if (dirend == (char *)1)
-    dir = find_directory ("[]");
-#else
   dirend = strrchr (p, '/');
-# ifdef HAVE_DOS_PATHS
+#ifdef VMS
+  if (dirend == NULL)
+    {
+      dirend = strrchr (p, ']');
+      dirend == NULL ? dirend : dirend++;
+    }
+  if (dirend == NULL)
+    {
+      dirend = strrchr (p, '>');
+      dirend == NULL ? dirend : dirend++;
+    }
+  if (dirend == NULL)
+    {
+      dirend = strrchr (p, ':');
+      dirend == NULL ? dirend : dirend++;
+    }
+#endif
+#ifdef HAVE_DOS_PATHS
   /* Forward and backslashes might be mixed.  We need the rightmost one.  */
   {
     const char *bslash = strrchr (p, '\\');
@@ -830,14 +888,13 @@ file_impossible (const char *filename)
     if (!dirend && p[0] && p[1] == ':')
       dirend = p + 1;
   }
-# endif /* HAVE_DOS_PATHS */
+#endif /* HAVE_DOS_PATHS */
   if (dirend == 0)
-# ifdef _AMIGA
+#ifdef _AMIGA
     dir = find_directory ("");
-# else /* !VMS && !AMIGA */
+#else /* !AMIGA */
     dir = find_directory (".");
-# endif /* AMIGA */
-#endif /* VMS */
+#endif /* AMIGA */
   else
     {
       const char *dirname;
@@ -859,7 +916,14 @@ file_impossible (const char *filename)
           dirname = cp;
         }
       dir = find_directory (dirname);
+#ifdef VMS
+      if (*slash == '/')
+        filename = p = slash + 1;
+      else
+        filename = p = slash;
+#else
       filename = p = slash + 1;
+#endif
     }
 
   if (dir->contents == 0)
@@ -878,6 +942,7 @@ file_impossible (const char *filename)
   new = xmalloc (sizeof (struct dirfile));
   new->length = strlen (filename);
 #if defined(HAVE_CASE_INSENSITIVE_FS) && defined(VMS)
+  /* todo: Why is this only needed on VMS? */
   new->name = strcache_add_len (downcase (filename), new->length);
 #else
   new->name = strcache_add_len (filename, new->length);
@@ -895,13 +960,26 @@ file_impossible_p (const char *filename)
   struct directory_contents *dir;
   struct dirfile *dirfile;
   struct dirfile dirfile_key;
-
 #ifdef VMS
-  dirend = strrchr (filename, ']');
-  if (dirend == 0)
-    dir = find_directory ("[]")->contents;
-#else
+  int want_vmsify = 0;
+#endif
+
   dirend = strrchr (filename, '/');
+#ifdef VMS
+  if (dirend == NULL)
+    {
+      want_vmsify = (strpbrk (filename, "]>:^") != NULL);
+      dirend = strrchr (filename, ']');
+    }
+  if (dirend == NULL && want_vmsify)
+    {
+      dirend = strrchr (filename, '>');
+    }
+  if (dirend == NULL && want_vmsify)
+    {
+      dirend = strrchr (filename, ':');
+    }
+#endif
 #ifdef HAVE_DOS_PATHS
   /* Forward and backslashes might be mixed.  We need the rightmost one.  */
   {
@@ -916,10 +994,9 @@ file_impossible_p (const char *filename)
   if (dirend == 0)
 #ifdef _AMIGA
     dir = find_directory ("")->contents;
-#else /* !VMS && !AMIGA */
+#else /* !AMIGA */
     dir = find_directory (".")->contents;
 #endif /* AMIGA */
-#endif /* VMS */
   else
     {
       const char *dirname;
@@ -941,7 +1018,14 @@ file_impossible_p (const char *filename)
           dirname = cp;
         }
       dir = find_directory (dirname)->contents;
+#ifdef VMS
+      if (*slash == '/')
+        filename = slash + 1;
+      else
+        filename = slash;
+#else
       filename = slash + 1;
+#endif
     }
 
   if (dir == 0 || dir->dirfiles.ht_vec == 0)
@@ -955,7 +1039,8 @@ file_impossible_p (const char *filename)
   filename = downcase (filename);
 #endif
 #ifdef VMS
-  filename = vmsify (filename, 1);
+  if (want_vmsify)
+    filename = vmsify (filename, 1);
 #endif
 
   dirfile_key.name = filename;
@@ -1005,7 +1090,7 @@ print_dir_data_base (void)
               printf (_("# %s (key %s, mtime %d): could not be opened.\n"),
                       dir->name, dir->contents->path_key,dir->contents->mtime);
 #else  /* WINDOWS32 */
-#ifdef VMS
+#ifdef VMS_INO_T
               printf (_("# %s (device %d, inode [%d,%d,%d]): could not be opened.\n"),
                       dir->name, dir->contents->dev,
                       dir->contents->ino[0], dir->contents->ino[1],
@@ -1041,7 +1126,7 @@ print_dir_data_base (void)
               printf (_("# %s (key %s, mtime %d): "),
                       dir->name, dir->contents->path_key, dir->contents->mtime);
 #else  /* WINDOWS32 */
-#ifdef VMS
+#ifdef VMS_INO_T
               printf (_("# %s (device %d, inode [%d,%d,%d]): "),
                       dir->name, dir->contents->dev,
                       dir->contents->ino[0], dir->contents->ino[1],
@@ -1179,9 +1264,14 @@ read_dirstream (__ptr_t stream)
  * On MS-Windows, stat() "succeeds" for foo/bar/. where foo/bar is a
  * regular file; fix that here.
  */
-#if !defined(stat) && !defined(WINDOWS32)
+#if !defined(stat) && !defined(WINDOWS32) || defined(VMS)
 # ifndef VMS
 int stat (const char *path, struct stat *sbuf);
+# else
+    /* We are done with the fake stat.  Go back to the real stat */
+#   ifdef stat
+#     undef stat
+#   endif
 # endif
 # define local_stat stat
 #else
diff --git a/file.c b/file.c
index e1a8e80..f1865de 100644
--- a/file.c
+++ b/file.c
@@ -75,9 +75,12 @@ lookup_file (const char *name)
 {
   struct file *f;
   struct file file_key;
-#if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS)
+#ifdef VMS
+  int want_vmsify;
+#ifndef WANT_CASE_SENSITIVE_TARGETS
   char *lname;
 #endif
+#endif
 
   assert (*name != '\0');
 
@@ -85,6 +88,7 @@ lookup_file (const char *name)
      for names read from makefiles.  It is here for names passed
      on the command line.  */
 #ifdef VMS
+   want_vmsify = (strpbrk (name, "]>:^") != NULL);
 # ifndef WANT_CASE_SENSITIVE_TARGETS
   if (*name != '.')
     {
@@ -100,6 +104,8 @@ lookup_file (const char *name)
 
   while (name[0] == '[' && name[1] == ']' && name[2] != '\0')
       name += 2;
+  while (name[0] == '<' && name[1] == '>' && name[2] != '\0')
+      name += 2;
 #endif
   while (name[0] == '.'
 #ifdef HAVE_DOS_PATHS
@@ -120,15 +126,21 @@ lookup_file (const char *name)
     }
 
   if (*name == '\0')
-    /* It was all slashes after a dot.  */
-#if defined(VMS)
-    name = "[]";
-#elif defined(_AMIGA)
-    name = "";
+    {
+      /* It was all slashes after a dot.  */
+#if defined(_AMIGA)
+      name = "";
 #else
-    name = "./";
+      name = "./";
 #endif
-
+#if defined(VMS)
+      /* TODO - This section is probably not needed. */
+      if (want_vmsify)
+        {
+          name = "[]";
+        }
+#endif
+    }
   file_key.hname = name;
   f = hash_find_item (&files, &file_key);
 #if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS)
diff --git a/implicit.c b/implicit.c
index 8e1d541..8e17ff2 100644
--- a/implicit.c
+++ b/implicit.c
@@ -266,12 +266,15 @@ pattern_search (struct file *file, int archive,
       /* Set LASTSLASH to point at the last slash in FILENAME
          but not counting any slash at the end.  (foo/bar/ counts as
          bar/ in directory foo/, not empty in directory foo/bar/.)  */
+      lastslash = strrchr (filename, '/');
 #ifdef VMS
-      lastslash = strrchr (filename, ']');
-      if (lastslash == 0)
+      if (lastslash == NULL)
+        lastslash = strrchr (filename, ']');
+      if (lastslash == NULL)
+        lastslash = strrchr (filename, '>');
+      if (lastslash == NULL)
         lastslash = strrchr (filename, ':');
-#else
-      lastslash = strrchr (filename, '/');
+#endif
 #ifdef HAVE_DOS_PATHS
       /* Handle backslashes (possibly mixed with forward slashes)
          and the case of "d:file".  */
@@ -283,7 +286,6 @@ pattern_search (struct file *file, int archive,
           lastslash = filename + 1;
       }
 #endif
-#endif
       if (lastslash != 0 && lastslash[1] == '\0')
         lastslash = 0;
     }
@@ -339,10 +341,10 @@ pattern_search (struct file *file, int archive,
           if (lastslash)
             {
 #ifdef VMS
-              check_lastslash = (strchr (target, ']') == 0
-                                 && strchr (target, ':') == 0);
+              check_lastslash = strpbrk (target, "/]>:") == NULL;
 #else
               check_lastslash = strchr (target, '/') == 0;
+#endif
 #ifdef HAVE_DOS_PATHS
               /* Didn't find it yet: check for DOS-type directories.  */
               if (check_lastslash)
@@ -351,7 +353,6 @@ pattern_search (struct file *file, int archive,
                   check_lastslash = !(b || (target[0] && target[1] == ':'));
                 }
 #endif
-#endif
             }
           if (check_lastslash)
             {
diff --git a/read.c b/read.c
index 6ff4bcc..e8755b0 100644
--- a/read.c
+++ b/read.c
@@ -241,7 +241,8 @@ read_all_makefiles (const char **makefiles)
       static const char *default_makefiles[] =
 #ifdef VMS
         /* all lower case since readdir() (the vms version) 'lowercasifies' */
-        { "makefile.vms", "gnumakefile.", "makefile.", 0 };
+        /* TODO: Above is not always true, this needs more work */
+        { "makefile.vms", "gnumakefile", "makefile", 0 };
 #else
 #ifdef _AMIGA
         { "GNUmakefile", "Makefile", "SMakefile", 0 };
@@ -3099,12 +3100,19 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
       /* Strip leading "this directory" references.  */
       if (NONE_SET (flags, PARSEFS_NOSTRIP))
 #ifdef VMS
-        /* Skip leading '[]'s.  */
-        while (p - s > 2 && s[0] == '[' && s[1] == ']')
-#else
+        /* Skip leading '[]'s. should only be one set or bug somwhere else */
+        if (p - s > 2 && s[0] == '[' && s[1] == ']')
+          {
+            s += 2;
+          }
+        /* Skip leading '<>'s. should only be one set or bug somwhere else */
+        if (p - s > 2 && s[0] == '<' && s[1] == '>')
+          {
+            s += 2;
+          }
+#endif
         /* Skip leading './'s.  */
         while (p - s > 2 && s[0] == '.' && s[1] == '/')
-#endif
           {
             /* Skip "./" and all following slashes.  */
             s += 2;
@@ -3118,9 +3126,7 @@ parse_file_seq (char **stringp, unsigned int size, int stopmap,
       if (s == p)
         {
         /* The name was stripped to empty ("./"). */
-#if defined(VMS)
-          continue;
-#elif defined(_AMIGA)
+#if defined(_AMIGA)
           /* PDS-- This cannot be right!! */
           tp[0] = '\0';
           nlen = 0;
diff --git a/remake.c b/remake.c
index 299a2aa..20c5ae2 100644
--- a/remake.c
+++ b/remake.c
@@ -1,5 +1,5 @@
 /* Basic dependency engine for GNU Make.
-Copyright (C) 1988-2014 Free Software Foundation, Inc.
+Copyright (C) 1988-2013 Free Software Foundation, Inc.
 This file is part of GNU Make.
 
 GNU Make is free software; you can redistribute it and/or modify it under the
@@ -1325,6 +1325,8 @@ f_mtime (struct file *file, int search)
               || (file->name[0] == '-' && file->name[1] == 'l'
                   && (name = library_search (file->name, &mtime)) != 0))
             {
+              int name_len;
+
               if (mtime != UNKNOWN_MTIME)
                 /* vpath_search and library_search store UNKNOWN_MTIME
                    if they didn't need to do a stat call for their work.  */
@@ -1333,7 +1335,14 @@ f_mtime (struct file *file, int search)
               /* If we found it in VPATH, see if it's in GPATH too; if so,
                  change the name right now; if not, defer until after the
                  dependencies are updated. */
-              if (gpath_search (name, strlen (name) - strlen (file->name) - 1))
+#ifndef VMS
+              name_len = strlen (name) - strlen (file->name) - 1);
+#else
+              name_len = strlen (name) - strlen (file->name);
+              if (name[name_len - 1] == '/')
+                  name_len--;
+#endif
+              if (gpath_search (name, name_len))
                 {
                   rename_file (file, name);
                   check_renamed (file);
diff --git a/vpath.c b/vpath.c
index 1bcba04..49821ca 100644
--- a/vpath.c
+++ b/vpath.c
@@ -387,6 +387,10 @@ selective_vpath_search (struct vpath *path, const char *file,
         {
 #ifndef VMS
           *p++ = '/';
+#else
+          /* VMS: if this is not in VMS format, treat as Unix format */
+          if ((*p != ':') && (*p != ']') && (*p != '>'))
+            *p++ = '/';
 #endif
           memcpy (p, file, name_dplen);
           p += name_dplen;
@@ -405,6 +409,15 @@ selective_vpath_search (struct vpath *path, const char *file,
           memcpy (p + 1, filename, flen + 1);
         }
       else
+#else
+      /* VMS use a slash if no directory terminator present */
+      if (p != name && p[-1] != '/' && p[-1] != ':' &&
+          p[-1] != '>' && p[-1] != ']')
+        {
+          *p = '/';
+          memcpy (p + 1, filename, flen + 1);
+        }
+      else
 #endif
         memcpy (p, filename, flen + 1);
 
@@ -449,17 +462,20 @@ selective_vpath_search (struct vpath *path, const char *file,
              See if it actually exists.  */
 
 #ifdef VMS
-          exists_in_cache = exists = dir_file_exists_p (vpath[i], filename);
-#else
-          /* Clobber a null into the name at the last slash.
-             Now NAME is the name of the directory to look in.  */
-          *p = '\0';
-
-          /* We know the directory is in the hash table now because either
-             construct_vpath_list or the code just above put it there.
-             Does the file we seek exist in it?  */
-          exists_in_cache = exists = dir_file_exists_p (name, filename);
+          /* For VMS syntax just use the original vpath */
+          if (*p != '/')
+            exists_in_cache = exists = dir_file_exists_p (vpath[i], filename);
+          else
 #endif
+            {
+              /* Clobber a null into the name at the last slash.
+                 Now NAME is the name of the directory to look in.  */
+              *p = '\0';
+              /* We know the directory is in the hash table now because either
+                 construct_vpath_list or the code just above put it there.
+                 Does the file we seek exist in it?  */
+              exists_in_cache = exists = dir_file_exists_p (name, filename);
+            }
         }
 
       if (exists)
@@ -475,6 +491,10 @@ selective_vpath_search (struct vpath *path, const char *file,
 #ifndef VMS
           /* Put the slash back in NAME.  */
           *p = '/';
+#else
+          /* If the slash was removed, put it back */
+          if (*p == 0)
+            *p = '/';
 #endif
 
           if (exists_in_cache)  /* Makefile-mentioned file need not exist.  */
-- 
1.7.9

_______________________________________________
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make

Reply via email to