Imported Upstream version 4.1
[platform/upstream/make.git] / ar.c
diff --git a/ar.c b/ar.c
index afed591..675572a 100644 (file)
--- a/ar.c
+++ b/ar.c
@@ -1,5 +1,5 @@
 /* Interface to 'ar' archives for GNU Make.
-Copyright (C) 1988-2013 Free Software Foundation, Inc.
+Copyright (C) 1988-2014 Free Software Foundation, Inc.
 
 This file is part of GNU Make.
 
@@ -43,7 +43,7 @@ ar_name (const char *name)
     return 0;
 
   if (p[1] == '(' && end[-1] == ')')
-    fatal (NILF, _("attempt to use unsupported feature: '%s'"), name);
+    OS (fatal, NILF, _("attempt to use unsupported feature: '%s'"), name);
 
   return 1;
 }
@@ -120,7 +120,7 @@ ar_member_date (const char *name)
 int
 ar_touch (const char *name)
 {
-  error (NILF, _("touch archive member is not available on VMS"));
+  O (error, NILF, _("touch archive member is not available on VMS"));
   return -1;
 }
 #else
@@ -144,24 +144,24 @@ ar_touch (const char *name)
   switch (ar_member_touch (arname, memname))
     {
     case -1:
-      error (NILF, _("touch: Archive '%s' does not exist"), arname);
+      OS (error, NILF, _("touch: Archive '%s' does not exist"), arname);
       break;
     case -2:
-      error (NILF, _("touch: '%s' is not a valid archive"), arname);
+      OS (error, NILF, _("touch: '%s' is not a valid archive"), arname);
       break;
     case -3:
       perror_with_name ("touch: ", arname);
       break;
     case 1:
-      error (NILF,
-             _("touch: Member '%s' does not exist in '%s'"), memname, arname);
+      OSS (error, NILF,
+           _("touch: Member '%s' does not exist in '%s'"), memname, arname);
       break;
     case 0:
       val = 0;
       break;
     default:
-      error (NILF,
-             _("touch: Bad return code from ar_member_touch on '%s'"), name);
+      OS (error, NILF,
+          _("touch: Bad return code from ar_member_touch on '%s'"), name);
     }
 
   free (arname);
@@ -172,10 +172,20 @@ ar_touch (const char *name)
 \f
 /* State of an 'ar_glob' run, passed to 'ar_glob_match'.  */
 
+/* On VMS, (object) modules in libraries do not have suffixes. That is, to
+   find a match for a pattern, the pattern must not have any suffix. So the
+   suffix of the pattern is saved and the pattern is stripped (ar_glob).
+   If there is a match and the match, which is a module name, is added to
+   the chain, the saved suffix is added back to construct a source filename
+   (ar_glob_match). */
+
 struct ar_glob_state
   {
     const char *arname;
     const char *pattern;
+#ifdef VMS
+    char *suffix;
+#endif
     unsigned int size;
     struct nameseq *chain;
     unsigned int n;
@@ -196,7 +206,13 @@ ar_glob_match (int desc UNUSED, const char *mem, int truncated UNUSED,
     {
       /* We have a match.  Add it to the chain.  */
       struct nameseq *new = xcalloc (state->size);
-      new->name = strcache_add (concat (4, state->arname, "(", mem, ")"));
+#ifdef VMS
+      if (state->suffix)
+        new->name = strcache_add(
+            concat(5, state->arname, "(", mem, state->suffix, ")"));
+      else
+#endif
+        new->name = strcache_add(concat(4, state->arname, "(", mem, ")"));
       new->next = state->chain;
       state->chain = new;
       ++state->n;
@@ -248,7 +264,9 @@ ar_glob (const char *arname, const char *member_pattern, unsigned int size)
   struct nameseq *n;
   const char **names;
   unsigned int i;
-
+#ifdef VMS
+  char *vms_member_pattern;
+#endif
   if (! glob_pattern_p (member_pattern, 1))
     return 0;
 
@@ -256,11 +274,36 @@ ar_glob (const char *arname, const char *member_pattern, unsigned int size)
      ar_glob_match will accumulate them in STATE.chain.  */
   state.arname = arname;
   state.pattern = member_pattern;
+#ifdef VMS
+    {
+      /* In a copy of the pattern, find the suffix, save it and  remove it from
+         the pattern */
+      char *lastdot;
+      vms_member_pattern = xstrdup(member_pattern);
+      lastdot = strrchr(vms_member_pattern, '.');
+      state.suffix = lastdot;
+      if (lastdot)
+        {
+          state.suffix = xstrdup(lastdot);
+          *lastdot = 0;
+        }
+      state.pattern = vms_member_pattern;
+    }
+#endif
   state.size = size;
   state.chain = 0;
   state.n = 0;
   ar_scan (arname, ar_glob_match, &state);
 
+#ifdef VMS
+  /* Deallocate any duplicated string */
+  free(vms_member_pattern);
+  if (state.suffix)
+    {
+      free(state.suffix);
+    }
+#endif
+
   if (state.chain == 0)
     return 0;