Change regcache list to be an hash map
[deliverable/binutils-gdb.git] / binutils / arsup.c
index 59f64358a5f066a13e3c452ab4cf0453a0946b1a..0836496180a36c7fad96d5e7a187407c1393c593 100644 (file)
-/* arsup.c - Archive support for MRI compatibility */
+/* arsup.c - Archive support for MRI compatibility
+   Copyright (C) 1992-2019 Free Software Foundation, Inc.
 
-/*   Copyright (C) 1992 Free Software Foundation, Inc.
+   This file is part of GNU Binutils.
 
-This file is part of GNU Binutils.
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
 
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
 
 
 /* Contributed by Steve Chamberlain
-                 sac@cygnus.com
-
-This file looks after requests from arparse.y, to provide the MRI
-style librarian command syntax + 1 word LIST
+   sac@cygnus.com
 
-*/
+   This file looks after requests from arparse.y, to provide the MRI
+   style librarian command syntax + 1 word LIST.  */
 
+#include "sysdep.h"
 #include "bfd.h"
-#include "arsup.h"
-#include <sysdep.h>
+#include "libiberty.h"
+#include "filenames.h"
 #include "bucomm.h"
-extern bfd *inarch;
-extern int verbose;
+#include "arsup.h"
 
+static void map_over_list
+  (bfd *, void (*function) (bfd *, bfd *), struct list *);
+static void ar_directory_doer (bfd *, bfd *);
+static void ar_addlib_doer (bfd *, bfd *);
 
+extern int verbose;
+extern int deterministic;
 
-void
-DEFUN(map_over_list,(function, list),
-      void            (*function) () AND
-      struct list           *list)
+static bfd *obfd;
+static char *real_name;
+static FILE *outfile;
 
+static void
+map_over_list (bfd *arch, void (*function) (bfd *, bfd *), struct list *list)
 {
-  bfd            *head;
+  bfd *head;
+
+  if (list == NULL)
+    {
+      bfd *next;
 
-  if (list == 0) {
-    for (head = inarch->next; head; head = head->next){
-      function(head);
+      head = arch->archive_next;
+      while (head != NULL)
+       {
+         next = head->archive_next;
+         function (head, (bfd *) NULL);
+         head = next;
+       }
     }
-  }
-  else {
-    /*
-      This may appear to be a baroque way of accomplishing what we want.
-      however we have to iterate over the filenames in order to notice where
-      a filename is requested but does not exist in the archive.  Ditto
-      mapping over each file each time -- we want to hack multiple
-      references.
-      */
-    struct list *ptr = list;
-
-    for (ptr = list; ptr; ptr=ptr->next)
+  else
     {
-      boolean         found = false;
-      bfd *prev = inarch;
-      for (head = inarch->next; head; head = head->next) 
-      {
-       if ((head->filename != NULL) &&
-           (!strcmp(ptr->name, head->filename))) 
+      struct list *ptr;
+
+      /* This may appear to be a baroque way of accomplishing what we
+        want.  however we have to iterate over the filenames in order
+        to notice where a filename is requested but does not exist in
+        the archive.  Ditto mapping over each file each time -- we
+        want to hack multiple references.  */
+      for (ptr = list; ptr; ptr = ptr->next)
        {
-         found = true;
-         function(head, prev);
-
+         bfd_boolean found = FALSE;
+         bfd *prev = arch;
+
+         for (head = arch->archive_next; head; head = head->archive_next)
+           {
+             if (head->filename != NULL
+                 && FILENAME_CMP (ptr->name, head->filename) == 0)
+               {
+                 found = TRUE;
+                 function (head, prev);
+               }
+             prev = head;
+           }
+         if (! found)
+           fprintf (stderr, _("No entry %s in archive.\n"), ptr->name);
        }
-       prev = head;
-      }
-      if (!found)
-       fprintf(stderr, "No entry %s in archive.\n", ptr->name);
     }
-  }
 }
 
 
-FILE *outfile;
-void
-DEFUN(ar_directory_doer,(abfd),
-      bfd *abfd)
+
+static void
+ar_directory_doer (bfd *abfd, bfd *ignore ATTRIBUTE_UNUSED)
 {
-    print_arelt_descr(outfile, abfd, verbose);
+  print_arelt_descr(outfile, abfd, verbose, FALSE);
 }
 
 void
-DEFUN(ar_directory,(ar_name, list, output),
-      char *ar_name AND
-      struct list *list AND
-      char *output)
+ar_directory (char *ar_name, struct list *list, char *output)
 {
-  open_inarch(ar_name);
-  if (output)  {
-    outfile = fopen(output,"w");
-    if (outfile == 0) {
-      outfile =stdout;
-      fprintf(stderr,"Can't open file %s\n", output);
-      output = 0;
+  bfd *arch;
+
+  arch = open_inarch (ar_name, (char *) NULL);
+  if (output)
+    {
+      outfile = fopen(output,"w");
+      if (outfile == 0)
+       {
+         outfile = stdout;
+         fprintf (stderr,_("Can't open file %s\n"), output);
+         output = 0;
+       }
     }
-  }
-  else 
-   outfile = stdout;
+  else
+    outfile = stdout;
+
+  map_over_list (arch, ar_directory_doer, list);
+
+  bfd_close (arch);
 
-  map_over_list(ar_directory_doer, list);
-  bfd_close(inarch);
   if (output)
-   fclose(outfile);
+   fclose (outfile);
 }
 
 void
-DEFUN_VOID(prompt)
+prompt (void)
 {
   extern int interactive;
-  if (interactive) 
-  {
-    printf("AR >");
-    fflush(stdout); 
-  }
+
+  if (interactive)
+    {
+      printf ("AR >");
+      fflush (stdout);
+    }
 }
 
 void
-DEFUN_VOID(maybequit)
+maybequit (void)
 {
-if (!interactive) 
exit(9);
+  if (! interactive)
   xexit (9);
 }
 
 
-bfd *obfd;
-char *real_name ; 
 void
-DEFUN(ar_open,(name, t),
-      char *name AND
-      int t)
-
+ar_open (char *name, int t)
 {
-  char *tname = malloc(strlen(name)+10);
+  char *tname;
+  const char *bname = lbasename (name);
   real_name = name;
-  sprintf(tname, "%s-tmp", name);
-  obfd = bfd_openw(tname, NULL);
-
-  if (!obfd) {
-    fprintf(stderr,"%s: Can't open output archive %s\n", program_name,
-           tname);
-
-    maybequit();
-  }
-  else {
-    if (!t) {
-      bfd **ptr;
-      bfd *element;
-      bfd *ibfd;
-      ibfd = bfd_openr(name, NULL);
-      if (bfd_check_format(ibfd, bfd_archive) != true) {
-       fprintf(stderr,"%s: file %s is not an archive\n", program_name,
-               name);
-       maybequit();
-       return;
-      }
-      ptr = &(obfd->archive_head);
-      element = bfd_openr_next_archived_file(ibfd, NULL);
-
-      while (element) {
-       *ptr = element;
-       ptr = &element->next;
-       element = bfd_openr_next_archived_file(ibfd, element);
-      }
+
+  /* Prepend tmp- to the beginning, to avoid file-name clashes after
+     truncation on filesystems with limited namespaces (DOS).  */
+  if (asprintf (&tname, "%.*stmp-%s", (int) (bname - name), name, bname) == -1)
+    {
+      fprintf (stderr, _("%s: Can't allocate memory for temp name (%s)\n"),
+              program_name, strerror(errno));
+      maybequit ();
+      return;
     }
 
-    bfd_set_format(obfd, bfd_archive);
+  obfd = bfd_openw (tname, NULL);
 
-    obfd->has_armap = 1;
-  }
-}
+  if (!obfd)
+    {
+      fprintf (stderr,
+              _("%s: Can't open output archive %s\n"),
+              program_name,  tname);
 
+      maybequit ();
+    }
+  else
+    {
+      if (!t)
+       {
+         bfd **ptr;
+         bfd *element;
+         bfd *ibfd;
+
+         ibfd = bfd_openr (name, NULL);
+
+         if (!ibfd)
+           {
+             fprintf (stderr,_("%s: Can't open input archive %s\n"),
+                      program_name, name);
+             maybequit ();
+             return;
+           }
+
+         if (!bfd_check_format(ibfd, bfd_archive))
+           {
+             fprintf (stderr,
+                      _("%s: file %s is not an archive\n"),
+                      program_name, name);
+             maybequit ();
+             return;
+           }
+
+         ptr = &(obfd->archive_head);
+         element = bfd_openr_next_archived_file (ibfd, NULL);
+
+         while (element)
+           {
+             *ptr = element;
+             ptr = &element->archive_next;
+             element = bfd_openr_next_archived_file (ibfd, element);
+           }
+       }
 
-void
-DEFUN(ar_addlib_doer, (abfd, prev),
-      bfd *abfd AND
-      bfd *prev)
+      bfd_set_format (obfd, bfd_archive);
+
+      obfd->has_armap = 1;
+      obfd->is_thin_archive = 0;
+    }
+}
+
+static void
+ar_addlib_doer (bfd *abfd, bfd *prev)
 {
-  /* Add this module to the output bfd */
-  
-  prev->next = abfd->next;
-  abfd->next = obfd->archive_head;
+  /* Add this module to the output bfd.  */
+  if (prev != NULL)
+    prev->archive_next = abfd->archive_next;
+
+  abfd->archive_next = obfd->archive_head;
   obfd->archive_head = abfd;
 }
 
 void
-DEFUN(ar_addlib, (name, list),
-      char *name AND
-      struct list *list)
+ar_addlib (char *name, struct list *list)
 {
-  if (!obfd) {
-    fprintf(stderr, "%s: no output archive specified yet\n", program_name);
-    maybequit();
-  }
-  else {
-    if (open_inarch(name) ) {
-      map_over_list(ar_addlib_doer, list);
+  if (obfd == NULL)
+    {
+      fprintf (stderr, _("%s: no output archive specified yet\n"), program_name);
+      maybequit ();
     }
-    /* Don't close the bfd, since it will make the elements disasppear */
-  }
-}
+  else
+    {
+      bfd *arch;
 
+      arch = open_inarch (name, (char *) NULL);
+      if (arch != NULL)
+       map_over_list (arch, ar_addlib_doer, list);
 
+      /* Don't close the bfd, since it will make the elements disappear.  */
+    }
+}
 
 void
-DEFUN(ar_addmod, (list),
-      struct list *list)
+ar_addmod (struct list *list)
 {
-  if (!obfd) {
-    fprintf(stderr, "%s: no open output archive\n", program_name);
-    maybequit();
-  }
-  else 
-  {
-    while (list) {
-      bfd *abfd = bfd_openr(list->name, NULL);
-      if (!abfd)  {
-       fprintf(stderr,"%s: can't open file %s\n", program_name,
-               list->name);
-       maybequit();
-      }
-      else {
-       abfd->next = obfd->archive_head;
-       obfd->archive_head = abfd;
-      }
-      list = list->next;
+  if (!obfd)
+    {
+      fprintf (stderr, _("%s: no open output archive\n"), program_name);
+      maybequit ();
+    }
+  else
+    {
+      while (list)
+       {
+         bfd *abfd;
+
+#if BFD_SUPPORTS_PLUGINS         
+         abfd = bfd_openr (list->name, "plugin");
+#else
+         abfd = bfd_openr (list->name, NULL);
+#endif
+         if (!abfd)
+           {
+             fprintf (stderr, _("%s: can't open file %s\n"),
+                      program_name, list->name);
+             maybequit ();
+           }
+         else
+           {
+             abfd->archive_next = obfd->archive_head;
+             obfd->archive_head = abfd;
+           }
+         list = list->next;
+       }
     }
-  }
 }
 
 
-
 void
-DEFUN_VOID(ar_clear)
+ar_clear (void)
 {
-if (obfd) 
- obfd->archive_head = 0;
+  if (obfd)
   obfd->archive_head = 0;
 }
 
 void
-DEFUN(ar_delete, (list),
-      struct list *list)
+ar_delete (struct list *list)
 {
-  if (!obfd) {
-    fprintf(stderr, "%s: no open output archive\n", program_name);
-    maybequit();
-  }
-  else 
-  {
-    while (list) {
-      /* Find this name in the archive */
-      bfd *member = obfd->archive_head;
-      bfd **prev = &(obfd->archive_head);
-      int found = 0;
-      while (member) {
-       if (strcmp(member->filename, list->name) == 0) {
-         *prev = member->next;
-         found = 1;
-       }
-       else {
-         prev = &(member->next);
+  if (!obfd)
+    {
+      fprintf (stderr, _("%s: no open output archive\n"), program_name);
+      maybequit ();
+    }
+  else
+    {
+      while (list)
+       {
+         /* Find this name in the archive.  */
+         bfd *member = obfd->archive_head;
+         bfd **prev = &(obfd->archive_head);
+         int found = 0;
+
+         while (member)
+           {
+             if (FILENAME_CMP(member->filename, list->name) == 0)
+               {
+                 *prev = member->archive_next;
+                 found = 1;
+               }
+             else
+               prev = &(member->archive_next);
+
+             member = member->archive_next;
+           }
+
+         if (!found)
+           {
+             fprintf (stderr, _("%s: can't find module file %s\n"),
+                      program_name, list->name);
+             maybequit ();
+           }
+
+         list = list->next;
        }
-         member = member->next;
-      }
-      if (!found)  {
-       fprintf(stderr,"%s: can't find module file %s\n", program_name,
-               list->name);
-       maybequit();
-      }
-      list = list->next;
     }
-  }
 }
 
-
 void
-DEFUN_VOID(ar_save)
+ar_save (void)
 {
+  if (!obfd)
+    {
+      fprintf (stderr, _("%s: no open output archive\n"), program_name);
+      maybequit ();
+    }
+  else
+    {
+      char *ofilename = xstrdup (bfd_get_filename (obfd));
 
-  if (!obfd) {
-    fprintf(stderr, "%s: no open output archive\n", program_name);
-    maybequit();
-  }
-  else {
-    bfd_close(obfd);
-    unlink(real_name);
-    link(obfd->filename, real_name);
-    unlink(obfd->filename);
-    obfd = 0;
-  }
-}
+      if (deterministic > 0)
+        obfd->flags |= BFD_DETERMINISTIC_OUTPUT;
 
+      bfd_close (obfd);
 
+      smart_rename (ofilename, real_name, 0);
+      obfd = 0;
+      free (ofilename);
+    }
+}
 
 void
-DEFUN(ar_replace, (list),
-      struct list *list)
+ar_replace (struct list *list)
 {
-  if (!obfd) {
-    fprintf(stderr, "%s: no open output archive\n", program_name);
-    maybequit();
-  }
-  else 
-  {
-    while (list) {
-      /* Find this name in the archive */
-      bfd *member = obfd->archive_head;
-      bfd **prev = &(obfd->archive_head);
-      int found = 0;
-      while (member) 
-      {
-       if (strcmp(member->filename, list->name) == 0) 
-       {
-         /* Found the one to replace */
-         bfd *abfd = bfd_openr(list->name, 0);
-         if (!abfd) 
-         {
-           fprintf(stderr, "%s: can't open file %s\n", program_name, list->name);
-           maybequit();
-         }
-         else {
-           *prev = abfd;
-           abfd->next = member->next;
-           found = 1;
-         }
-       }
-       else {
-         prev = &(member->next);
-       }
-       member = member->next;
-      }
-      if (!found)  {
-       bfd *abfd = bfd_openr(list->name, 0);
-       fprintf(stderr,"%s: can't find module file %s\n", program_name,
-               list->name);
-       if (!abfd) 
-       {
-         fprintf(stderr, "%s: can't open file %s\n", program_name, list->name);
-         maybequit();
-       }
-       else 
+  if (!obfd)
+    {
+      fprintf (stderr, _("%s: no open output archive\n"), program_name);
+      maybequit ();
+    }
+  else
+    {
+      while (list)
        {
-         *prev = abfd;
+         /* Find this name in the archive.  */
+         bfd *member = obfd->archive_head;
+         bfd **prev = &(obfd->archive_head);
+         int found = 0;
+
+         while (member)
+           {
+             if (FILENAME_CMP (member->filename, list->name) == 0)
+               {
+                 /* Found the one to replace.  */
+                 bfd *abfd = bfd_openr (list->name, NULL);
+
+                 if (!abfd)
+                   {
+                     fprintf (stderr, _("%s: can't open file %s\n"),
+                              program_name, list->name);
+                     maybequit ();
+                   }
+                 else
+                   {
+                     *prev = abfd;
+                     abfd->archive_next = member->archive_next;
+                     found = 1;
+                   }
+               }
+             else
+               {
+                 prev = &(member->archive_next);
+               }
+             member = member->archive_next;
+           }
+
+         if (!found)
+           {
+             bfd *abfd = bfd_openr (list->name, NULL);
+
+             fprintf (stderr,_("%s: can't find module file %s\n"),
+                      program_name, list->name);
+             if (!abfd)
+               {
+                 fprintf (stderr, _("%s: can't open file %s\n"),
+                          program_name, list->name);
+                 maybequit ();
+               }
+             else
+               *prev = abfd;
+           }
+
+         list = list->next;
        }
-      }
-
-    list = list->next;
     }
-  }
 }
 
-/* And I added this one */
+/* And I added this one */
 void
-DEFUN_VOID(ar_list)
+ar_list (void)
 {
-  if (!obfd) 
-  {
-    fprintf(stderr, "%s: no open output archive\n", program_name);
-    maybequit();
-  }
-  else {
-    bfd *abfd;
-    outfile = stdout;
-    verbose =1 ;
-    printf("Current open archive is %s\n", obfd->filename);
-    for (abfd = obfd->archive_head;
-        abfd != (bfd *)NULL;
-        abfd = abfd->next) 
+  if (!obfd)
     {
-      ar_directory_doer(abfd);
+      fprintf (stderr, _("%s: no open output archive\n"), program_name);
+      maybequit ();
+    }
+  else
+    {
+      bfd *abfd;
+
+      outfile = stdout;
+      verbose =1 ;
+      printf (_("Current open archive is %s\n"), bfd_get_filename (obfd));
+
+      for (abfd = obfd->archive_head;
+          abfd != (bfd *)NULL;
+          abfd = abfd->archive_next)
+       ar_directory_doer (abfd, (bfd *) NULL);
     }
-  }
 }
 
+void
+ar_end (void)
+{
+  if (obfd)
+    {
+      bfd_cache_close (obfd);
+      unlink (bfd_get_filename (obfd));
+    }
+}
 
 void
-DEFUN(ar_extract,(list),
-      struct list *list)
+ar_extract (struct list *list)
 {
-  if (!obfd) 
-  {
-
-    fprintf(stderr, "%s: no open  archive\n", program_name);
-    maybequit();
-  }
-  else 
-  {
-    while (list) {
-      /* Find this name in the archive */
-      bfd *member = obfd->archive_head;
-      int found = 0;
-      while (member && !found) 
-      {
-       if (strcmp(member->filename, list->name) == 0) 
+  if (!obfd)
+    {
+      fprintf (stderr, _("%s: no open archive\n"), program_name);
+      maybequit ();
+    }
+  else
+    {
+      while (list)
        {
-         extract_file(member);
-         found = 1;
-         }
-
-       member = member->next;
-      }
-      if (!found)  {
-       bfd *abfd = bfd_openr(list->name, 0);
-       fprintf(stderr,"%s: can't find module file %s\n", program_name,
-               list->name);
-
-      }
-      list = list->next;
+         /* Find this name in the archive.  */
+         bfd *member = obfd->archive_head;
+         int found = 0;
+
+         while (member && !found)
+           {
+             if (FILENAME_CMP (member->filename, list->name) == 0)
+               {
+                 extract_file (member);
+                 found = 1;
+               }
+
+             member = member->archive_next;
+           }
+
+         if (!found)
+           {
+             bfd_openr (list->name, NULL);
+             fprintf (stderr, _("%s: can't find module file %s\n"),
+                      program_name, list->name);
+           }
+
+         list = list->next;
+       }
     }
-  }
 }
This page took 0.029824 seconds and 4 git commands to generate.