* MAINTAINERS: Add myself as DWARF2 maintainer.
[deliverable/binutils-gdb.git] / binutils / ar.c
index fe1c6402222d4166f373de729a0abb3d2d55b281..42cc0c6914cb5228e3cad1568cf48568ce7506cf 100644 (file)
@@ -1,13 +1,13 @@
 /* ar.c - Archive modify and extract.
    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
 /* ar.c - Archive modify and extract.
    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
    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
    Free Software Foundation, Inc.
 
    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 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
 
    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.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
 \f
 /*
 \f
 /*
-   Bugs: should use getopt the way tar does (complete w/optional -) and
-   should have long options too. GNU ar used to check file against filesystem
-   in quick_update and replace operations (would check mtime). Doesn't warn
-   when name truncated. No way to specify pos_end. Error messages should be
-   more consistent.  */
+   Bugs: GNU ar used to check file against filesystem in quick_update and
+   replace operations (would check mtime). Doesn't warn when name truncated.
+   No way to specify pos_end. Error messages should be more consistent.  */
 
 
+#include "sysdep.h"
 #include "bfd.h"
 #include "libiberty.h"
 #include "progress.h"
 #include "bfd.h"
 #include "libiberty.h"
 #include "progress.h"
-#include "bucomm.h"
+#include "getopt.h"
 #include "aout/ar.h"
 #include "libbfd.h"
 #include "aout/ar.h"
 #include "libbfd.h"
+#include "bucomm.h"
 #include "arsup.h"
 #include "filenames.h"
 #include "binemul.h"
 #include "arsup.h"
 #include "filenames.h"
 #include "binemul.h"
+#include "plugin.h"
 #include <sys/stat.h>
 
 #ifdef __GO32___
 #include <sys/stat.h>
 
 #ifdef __GO32___
-#define EXT_NAME_LEN 3         /* bufflen of addition to name if it's MS-DOS */
+#define EXT_NAME_LEN 3         /* Bufflen of addition to name if it's MS-DOS.  */
 #else
 #else
-#define EXT_NAME_LEN 6         /* ditto for *NIX */
-#endif
-
-/* We need to open files in binary modes on system where that makes a
-   difference.  */
-#ifndef O_BINARY
-#define O_BINARY 0
+#define EXT_NAME_LEN 6         /* Ditto for *NIX.  */
 #endif
 
 #endif
 
-/* Kludge declaration from BFD!  This is ugly!  FIXME!  XXX */
-
-struct ar_hdr *
-  bfd_special_undocumented_glue (bfd * abfd, const char *filename);
-
-/* Static declarations */
+/* Static declarations.  */
 
 static void mri_emul (void);
 static const char *normalize (const char *, bfd *);
 
 static void mri_emul (void);
 static const char *normalize (const char *, bfd *);
@@ -68,11 +59,11 @@ static void replace_members
   (bfd *, char **files_to_replace, bfd_boolean quick);
 static void print_descr (bfd * abfd);
 static void write_archive (bfd *);
   (bfd *, char **files_to_replace, bfd_boolean quick);
 static void print_descr (bfd * abfd);
 static void write_archive (bfd *);
-static void ranlib_only (const char *archname);
-static void ranlib_touch (const char *archname);
+static int  ranlib_only (const char *archname);
+static int  ranlib_touch (const char *archname);
 static void usage (int);
 \f
 static void usage (int);
 \f
-/** Globals and flags */
+/** Globals and flags */
 
 static int mri_mode;
 
 
 static int mri_mode;
 
@@ -103,6 +94,11 @@ int newer_only = 0;
    if any of the members are object files.  */
 int write_armap = 0;
 
    if any of the members are object files.  */
 int write_armap = 0;
 
+/* Operate in deterministic mode: write zero for timestamps, uids,
+   and gids for archive members and the archive symbol table, and write
+   consistent file modes.  */
+int deterministic = 0;
+
 /* Nonzero means it's the name of an existing member; position new or moved
    files with respect to this one.  */
 char *posname = NULL;
 /* Nonzero means it's the name of an existing member; position new or moved
    files with respect to this one.  */
 char *posname = NULL;
@@ -116,6 +112,12 @@ enum pos
     pos_default, pos_before, pos_after, pos_end
   } postype = pos_default;
 
     pos_default, pos_before, pos_after, pos_end
   } postype = pos_default;
 
+enum operations
+  {
+    none = 0, del, replace, print_table,
+    print_files, extract, move, quick_append
+  } operation = none;
+
 static bfd **
 get_pos_bfd (bfd **, enum pos, const char *);
 
 static bfd **
 get_pos_bfd (bfd **, enum pos, const char *);
 
@@ -132,6 +134,29 @@ static bfd_boolean ar_truncate = FALSE;
    program.  */
 static bfd_boolean full_pathname = FALSE;
 
    program.  */
 static bfd_boolean full_pathname = FALSE;
 
+/* Whether to create a "thin" archive (symbol index only -- no files).  */
+static bfd_boolean make_thin_archive = FALSE;
+
+static int show_version = 0;
+
+static int show_help = 0;
+
+static const char *plugin_target = NULL;
+
+static const char *target = NULL;
+
+#define OPTION_PLUGIN 201
+#define OPTION_TARGET 202
+
+static struct option long_options[] =
+{
+  {"help", no_argument, &show_help, 1},
+  {"plugin", required_argument, NULL, OPTION_PLUGIN},
+  {"target", required_argument, NULL, OPTION_TARGET},
+  {"version", no_argument, &show_version, 1},
+  {NULL, no_argument, NULL, 0}
+};
+
 int interactive = 0;
 
 static void
 int interactive = 0;
 
 static void
@@ -153,7 +178,7 @@ map_over_members (bfd *arch, void (*function)(bfd *), char **files, int count)
 
   if (count == 0)
     {
 
   if (count == 0)
     {
-      for (head = arch->next; head; head = head->next)
+      for (head = arch->archive_next; head; head = head->archive_next)
        {
          PROGRESS (1);
          function (head);
        {
          PROGRESS (1);
          function (head);
@@ -172,18 +197,27 @@ map_over_members (bfd *arch, void (*function)(bfd *), char **files, int count)
       bfd_boolean found = FALSE;
 
       match_count = 0;
       bfd_boolean found = FALSE;
 
       match_count = 0;
-      for (head = arch->next; head; head = head->next)
+      for (head = arch->archive_next; head; head = head->archive_next)
        {
        {
+         const char * filename;
+
          PROGRESS (1);
          PROGRESS (1);
-         if (head->filename == NULL)
+         filename = head->filename;
+         if (filename == NULL)
            {
              /* Some archive formats don't get the filenames filled in
                 until the elements are opened.  */
              struct stat buf;
              bfd_stat_arch_elt (head, &buf);
            }
            {
              /* Some archive formats don't get the filenames filled in
                 until the elements are opened.  */
              struct stat buf;
              bfd_stat_arch_elt (head, &buf);
            }
-         if ((head->filename != NULL) &&
-             (!FILENAME_CMP (normalize (*files, arch), head->filename)))
+         else if (bfd_is_thin_archive (arch))
+           {
+             /* Thin archives store full pathnames.  Need to normalize.  */
+             filename = normalize (filename, arch);
+           }
+
+         if (filename != NULL
+             && !FILENAME_CMP (normalize (*files, arch), filename))
            {
              ++match_count;
              if (counted_name_mode
            {
              ++match_count;
              if (counted_name_mode
@@ -198,6 +232,7 @@ map_over_members (bfd *arch, void (*function)(bfd *), char **files, int count)
              function (head);
            }
        }
              function (head);
            }
        }
+
       if (!found)
        /* xgettext:c-format */
        fprintf (stderr, _("no entry %s in archive\n"), *files);
       if (!found)
        /* xgettext:c-format */
        fprintf (stderr, _("no entry %s in archive\n"), *files);
@@ -213,53 +248,88 @@ usage (int help)
 
   s = help ? stdout : stderr;
 
 
   s = help ? stdout : stderr;
 
-  if (! is_ranlib)
-    {
-      /* xgettext:c-format */
-      fprintf (s, _("Usage: %s [emulation options] [-]{dmpqrstx}[abcfilNoPsSuvV] [member-name] [count] archive-file file...\n"),
-              program_name);
-      /* xgettext:c-format */
-      fprintf (s, _("       %s -M [<mri-script]\n"), program_name);
-      fprintf (s, _(" commands:\n"));
-      fprintf (s, _("  d            - delete file(s) from the archive\n"));
-      fprintf (s, _("  m[ab]        - move file(s) in the archive\n"));
-      fprintf (s, _("  p            - print file(s) found in the archive\n"));
-      fprintf (s, _("  q[f]         - quick append file(s) to the archive\n"));
-      fprintf (s, _("  r[ab][f][u]  - replace existing or insert new file(s) into the archive\n"));
-      fprintf (s, _("  t            - display contents of archive\n"));
-      fprintf (s, _("  x[o]         - extract file(s) from the archive\n"));
-      fprintf (s, _(" command specific modifiers:\n"));
-      fprintf (s, _("  [a]          - put file(s) after [member-name]\n"));
-      fprintf (s, _("  [b]          - put file(s) before [member-name] (same as [i])\n"));
-      fprintf (s, _("  [N]          - use instance [count] of name\n"));
-      fprintf (s, _("  [f]          - truncate inserted file names\n"));
-      fprintf (s, _("  [P]          - use full path names when matching\n"));
-      fprintf (s, _("  [o]          - preserve original dates\n"));
-      fprintf (s, _("  [u]          - only replace files that are newer than current archive contents\n"));
-      fprintf (s, _(" generic modifiers:\n"));
-      fprintf (s, _("  [c]          - do not warn if the library had to be created\n"));
-      fprintf (s, _("  [s]          - create an archive index (cf. ranlib)\n"));
-      fprintf (s, _("  [S]          - do not build a symbol table\n"));
-      fprintf (s, _("  [v]          - be verbose\n"));
-      fprintf (s, _("  [V]          - display the version number\n"));
-      fprintf (s, _("  @<file>      - read options from <file>\n"));
-      ar_emul_usage (s);
-    }
-  else
-    {
-      /* xgettext:c-format */
-      fprintf (s, _("Usage: %s [options] archive\n"), program_name);
-      fprintf (s, _(" Generate an index to speed access to archives\n"));
-      fprintf (s, _(" The options are:\n\
-  @<file>                      Read options from <file>\n\
+#if BFD_SUPPORTS_PLUGINS
+  /* xgettext:c-format */
+  const char *command_line
+    = _("Usage: %s [emulation options] [-]{dmpqrstx}[abcDfilMNoPsSTuvV]"
+       " [--plugin <name>] [member-name] [count] archive-file file...\n");
+
+#else
+  /* xgettext:c-format */
+  const char *command_line
+    = _("Usage: %s [emulation options] [-]{dmpqrstx}[abcDfilMNoPsSTuvV]"
+       " [member-name] [count] archive-file file...\n");
+#endif
+  fprintf (s, command_line, program_name);
+
+  /* xgettext:c-format */
+  fprintf (s, _("       %s -M [<mri-script]\n"), program_name);
+  fprintf (s, _(" commands:\n"));
+  fprintf (s, _("  d            - delete file(s) from the archive\n"));
+  fprintf (s, _("  m[ab]        - move file(s) in the archive\n"));
+  fprintf (s, _("  p            - print file(s) found in the archive\n"));
+  fprintf (s, _("  q[f]         - quick append file(s) to the archive\n"));
+  fprintf (s, _("  r[ab][f][u]  - replace existing or insert new file(s) into the archive\n"));
+  fprintf (s, _("  s            - act as ranlib\n"));
+  fprintf (s, _("  t            - display contents of archive\n"));
+  fprintf (s, _("  x[o]         - extract file(s) from the archive\n"));
+  fprintf (s, _(" command specific modifiers:\n"));
+  fprintf (s, _("  [a]          - put file(s) after [member-name]\n"));
+  fprintf (s, _("  [b]          - put file(s) before [member-name] (same as [i])\n"));
+  fprintf (s, _("  [D]          - use zero for timestamps and uids/gids\n"));
+  fprintf (s, _("  [N]          - use instance [count] of name\n"));
+  fprintf (s, _("  [f]          - truncate inserted file names\n"));
+  fprintf (s, _("  [P]          - use full path names when matching\n"));
+  fprintf (s, _("  [o]          - preserve original dates\n"));
+  fprintf (s, _("  [u]          - only replace files that are newer than current archive contents\n"));
+  fprintf (s, _(" generic modifiers:\n"));
+  fprintf (s, _("  [c]          - do not warn if the library had to be created\n"));
+  fprintf (s, _("  [s]          - create an archive index (cf. ranlib)\n"));
+  fprintf (s, _("  [S]          - do not build a symbol table\n"));
+  fprintf (s, _("  [T]          - make a thin archive\n"));
+  fprintf (s, _("  [v]          - be verbose\n"));
+  fprintf (s, _("  [V]          - display the version number\n"));
+  fprintf (s, _("  @<file>      - read options from <file>\n"));
+  fprintf (s, _("  --target=BFDNAME - specify the target object format as BFDNAME\n"));
+#if BFD_SUPPORTS_PLUGINS
+  fprintf (s, _(" optional:\n"));
+  fprintf (s, _("  --plugin <p> - load the specified plugin\n"));
+#endif
+
+  ar_emul_usage (s);
+
+  list_supported_targets (program_name, s);
+
+  if (REPORT_BUGS_TO[0] && help)
+    fprintf (s, _("Report bugs to %s\n"), REPORT_BUGS_TO);
+
+  xexit (help ? 0 : 1);
+}
+
+static void
+ranlib_usage (int help)
+{
+  FILE *s;
+
+  s = help ? stdout : stderr;
+
+  /* xgettext:c-format */
+  fprintf (s, _("Usage: %s [options] archive\n"), program_name);
+  fprintf (s, _(" Generate an index to speed access to archives\n"));
+  fprintf (s, _(" The options are:\n\
+  @<file>                      Read options from <file>\n"));
+#if BFD_SUPPORTS_PLUGINS
+  fprintf (s, _("\
+  --plugin <name>              Load the specified plugin\n"));
+#endif
+  fprintf (s, _("\
+  -t                           Update the archive's symbol map timestamp\n\
   -h --help                    Print this help message\n\
   -h --help                    Print this help message\n\
-  -V --version                 Print version information\n"));
-    }
+  -v --version                 Print version information\n"));
 
 
-  list_supported_targets (program_name, stderr);
+  list_supported_targets (program_name, s);
 
 
-  if (help)
+  if (REPORT_BUGS_TO[0] && help)
     fprintf (s, _("Report bugs to %s\n"), REPORT_BUGS_TO);
 
   xexit (help ? 0 : 1);
     fprintf (s, _("Report bugs to %s\n"), REPORT_BUGS_TO);
 
   xexit (help ? 0 : 1);
@@ -276,21 +346,7 @@ normalize (const char *file, bfd *abfd)
   if (full_pathname)
     return file;
 
   if (full_pathname)
     return file;
 
-  filename = strrchr (file, '/');
-#ifdef HAVE_DOS_BASED_FILE_SYSTEM
-  {
-    /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
-    char *bslash = strrchr (file, '\\');
-    if (filename == NULL || (bslash != NULL && bslash > filename))
-      filename = bslash;
-    if (filename == NULL && file[0] != '\0' && file[1] == ':')
-      filename = file + 1;
-  }
-#endif
-  if (filename != (char *) NULL)
-    filename++;
-  else
-    filename = file;
+  filename = lbasename (file);
 
   if (ar_truncate
       && abfd != NULL
 
   if (ar_truncate
       && abfd != NULL
@@ -327,28 +383,233 @@ remove_output (void)
     }
 }
 
     }
 }
 
-/* The option parsing should be in its own function.
-   It will be when I have getopt working.  */
+static char **
+decode_options (int argc, char **argv)
+{
+  int c;
+
+  /* Convert old-style tar call by exploding option element and rearranging
+     options accordingly.  */
+
+  if (argc > 1 && argv[1][0] != '-')
+    {
+      int new_argc;            /* argc value for rearranged arguments */
+      char **new_argv;         /* argv value for rearranged arguments */
+      char *const *in;         /* cursor into original argv */
+      char **out;              /* cursor into rearranged argv */
+      const char *letter;      /* cursor into old option letters */
+      char buffer[3];          /* constructed option buffer */
+
+      /* Initialize a constructed option.  */
+
+      buffer[0] = '-';
+      buffer[2] = '\0';
+
+      /* Allocate a new argument array, and copy program name in it.  */
+
+      new_argc = argc - 1 + strlen (argv[1]);
+      new_argv = xmalloc ((new_argc + 1) * sizeof (*argv));
+      in = argv;
+      out = new_argv;
+      *out++ = *in++;
+
+      /* Copy each old letter option as a separate option.  */
+
+      for (letter = *in++; *letter; letter++)
+       {
+         buffer[1] = *letter;
+         *out++ = xstrdup (buffer);
+       }
+
+      /* Copy all remaining options.  */
+
+      while (in < argv + argc)
+       *out++ = *in++;
+      *out = NULL;
+
+      /* Replace the old option list by the new one.  */
+
+      argc = new_argc;
+      argv = new_argv;
+    }
+
+  while ((c = getopt_long (argc, argv, "hdmpqrtxlcoVsSuvabiMNfPTD",
+                          long_options, NULL)) != EOF)
+    {
+      switch (c)
+        {
+        case 'd':
+        case 'm':
+        case 'p':
+        case 'q':
+        case 'r':
+        case 't':
+        case 'x':
+          if (operation != none)
+            fatal (_("two different operation options specified"));
+         break;
+       }
+
+      switch (c)
+        {
+        case 'h':
+         show_help = 1;
+         break;
+        case 'd':
+          operation = del;
+          operation_alters_arch = TRUE;
+          break;
+        case 'm':
+          operation = move;
+          operation_alters_arch = TRUE;
+          break;
+        case 'p':
+          operation = print_files;
+          break;
+        case 'q':
+          operation = quick_append;
+          operation_alters_arch = TRUE;
+          break;
+        case 'r':
+          operation = replace;
+          operation_alters_arch = TRUE;
+          break;
+        case 't':
+          operation = print_table;
+          break;
+        case 'x':
+          operation = extract;
+          break;
+        case 'l':
+          break;
+        case 'c':
+          silent_create = 1;
+          break;
+        case 'o':
+          preserve_dates = 1;
+          break;
+        case 'V':
+          show_version = TRUE;
+          break;
+        case 's':
+          write_armap = 1;
+          break;
+        case 'S':
+          write_armap = -1;
+          break;
+        case 'u':
+          newer_only = 1;
+          break;
+        case 'v':
+          verbose = 1;
+          break;
+        case 'a':
+          postype = pos_after;
+          break;
+        case 'b':
+          postype = pos_before;
+          break;
+        case 'i':
+          postype = pos_before;
+          break;
+        case 'M':
+          mri_mode = 1;
+          break;
+        case 'N':
+          counted_name_mode = TRUE;
+          break;
+        case 'f':
+          ar_truncate = TRUE;
+          break;
+        case 'P':
+          full_pathname = TRUE;
+          break;
+        case 'T':
+          make_thin_archive = TRUE;
+          break;
+        case 'D':
+          deterministic = TRUE;
+          break;
+       case OPTION_PLUGIN:
+#if BFD_SUPPORTS_PLUGINS
+         plugin_target = "plugin";
+         bfd_plugin_set_plugin (optarg);
+#else
+         fprintf (stderr, _("sorry - this program has been built without plugin support\n"));
+         xexit (1);
+#endif
+         break;
+       case OPTION_TARGET:
+         target = optarg;
+         break;
+       case 0:         /* A long option that just sets a flag.  */
+         break;
+        default:
+          usage (0);
+        }
+    }
+
+  return &argv[optind];
+}
+
+static void
+ranlib_main (int argc, char **argv)
+{
+  int arg_index, status = 0;
+  bfd_boolean touch = FALSE;
+  int c;
+
+  while ((c = getopt_long (argc, argv, "hHvVt", long_options, NULL)) != EOF)
+    {
+      switch (c)
+        {
+       case 'h':
+       case 'H':
+         show_help = 1;
+         break;
+       case 't':
+         touch = TRUE;
+         break;
+       case 'v':
+       case 'V':
+         show_version = 1;
+         break;
+        }
+    }
+
+  if (argc < 2)
+    ranlib_usage (0);
+
+  if (show_help)
+    usage (1);
+
+  if (show_version)
+    print_version ("ranlib");
+
+  arg_index = optind;
+
+  while (arg_index < argc)
+    {
+      if (! touch)
+        status |= ranlib_only (argv[arg_index]);
+      else
+        status |= ranlib_touch (argv[arg_index]);
+      ++arg_index;
+    }
+
+  xexit (status);
+}
 
 int main (int, char **);
 
 int
 main (int argc, char **argv)
 {
 
 int main (int, char **);
 
 int
 main (int argc, char **argv)
 {
-  char *arg_ptr;
-  char c;
-  enum
-    {
-      none = 0, delete, replace, print_table,
-      print_files, extract, move, quick_append
-    } operation = none;
   int arg_index;
   char **files;
   int file_count;
   char *inarch_filename;
   int arg_index;
   char **files;
   int file_count;
   char *inarch_filename;
-  int show_version;
   int i;
   int i;
-  int do_posix = 0;
 
 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
   setlocale (LC_MESSAGES, "");
 
 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
   setlocale (LC_MESSAGES, "");
@@ -361,28 +622,16 @@ main (int argc, char **argv)
 
   program_name = argv[0];
   xmalloc_set_program_name (program_name);
 
   program_name = argv[0];
   xmalloc_set_program_name (program_name);
+#if BFD_SUPPORTS_PLUGINS
+  bfd_plugin_set_program_name (program_name);
+#endif
 
   expandargv (&argc, &argv);
 
   if (is_ranlib < 0)
     {
 
   expandargv (&argc, &argv);
 
   if (is_ranlib < 0)
     {
-      char *temp;
+      const char *temp = lbasename (program_name);
 
 
-      temp = strrchr (program_name, '/');
-#ifdef HAVE_DOS_BASED_FILE_SYSTEM
-      {
-       /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
-       char *bslash = strrchr (program_name, '\\');
-       if (temp == NULL || (bslash != NULL && bslash > temp))
-         temp = bslash;
-       if (temp == NULL && program_name[0] != '\0' && program_name[1] == ':')
-         temp = program_name + 1;
-      }
-#endif
-      if (temp == NULL)
-       temp = program_name;
-      else
-       ++temp;
       if (strlen (temp) >= 6
          && FILENAME_CMP (temp + strlen (temp) - 6, "ranlib") == 0)
        is_ranlib = 1;
       if (strlen (temp) >= 6
          && FILENAME_CMP (temp + strlen (temp) - 6, "ranlib") == 0)
        is_ranlib = 1;
@@ -390,26 +639,11 @@ main (int argc, char **argv)
        is_ranlib = 0;
     }
 
        is_ranlib = 0;
     }
 
-  if (argc > 1 && argv[1][0] == '-')
-    {
-      if (strcmp (argv[1], "--help") == 0)
-       usage (1);
-      else if (strcmp (argv[1], "--version") == 0)
-       {
-         if (is_ranlib)
-           print_version ("ranlib");
-         else
-           print_version ("ar");
-       }
-    }
-
   START_PROGRESS (program_name, 0);
 
   bfd_init ();
   set_default_bfd_target ();
 
   START_PROGRESS (program_name, 0);
 
   bfd_init ();
   set_default_bfd_target ();
 
-  show_version = 0;
-
   xatexit (remove_output);
 
   for (i = 1; i < argc; i++)
   xatexit (remove_output);
 
   for (i = 1; i < argc; i++)
@@ -419,164 +653,20 @@ main (int argc, char **argv)
   argc -= (i - 1);
 
   if (is_ranlib)
   argc -= (i - 1);
 
   if (is_ranlib)
-    {
-      bfd_boolean touch = FALSE;
-
-      if (argc < 2
-         || strcmp (argv[1], "--help") == 0
-         || strcmp (argv[1], "-h") == 0
-         || strcmp (argv[1], "-H") == 0)
-       usage (0);
-      if (strcmp (argv[1], "-V") == 0
-         || strcmp (argv[1], "-v") == 0
-         || strncmp (argv[1], "--v", 3) == 0)
-       print_version ("ranlib");
-      arg_index = 1;
-      if (strcmp (argv[1], "-t") == 0)
-       {
-         ++arg_index;
-         touch = TRUE;
-       }
-      while (arg_index < argc)
-       {
-         if (! touch)
-           ranlib_only (argv[arg_index]);
-         else
-           ranlib_touch (argv[arg_index]);
-         ++arg_index;
-       }
-      xexit (0);
-    }
-
-  if (argc == 2 && strcmp (argv[1], "-M") == 0)
-    {
-      mri_emul ();
-      xexit (0);
-    }
+    ranlib_main (argc, argv);
 
   if (argc < 2)
     usage (0);
 
 
   if (argc < 2)
     usage (0);
 
-  arg_index = 1;
-  arg_ptr = argv[arg_index];
-
-  if (*arg_ptr == '-')
-    {
-      /* When the first option starts with '-' we support POSIX-compatible
-        option parsing.  */
-      do_posix = 1;
-      ++arg_ptr;                       /* compatibility */
-    }
-
-  do
-    {
-      while ((c = *arg_ptr++) != '\0')
-       {
-         switch (c)
-           {
-           case 'd':
-           case 'm':
-           case 'p':
-           case 'q':
-           case 'r':
-           case 't':
-           case 'x':
-             if (operation != none)
-               fatal (_("two different operation options specified"));
-             switch (c)
-               {
-               case 'd':
-                 operation = delete;
-                 operation_alters_arch = TRUE;
-                 break;
-               case 'm':
-                 operation = move;
-                 operation_alters_arch = TRUE;
-                 break;
-               case 'p':
-                 operation = print_files;
-                 break;
-               case 'q':
-                 operation = quick_append;
-                 operation_alters_arch = TRUE;
-                 break;
-               case 'r':
-                 operation = replace;
-                 operation_alters_arch = TRUE;
-                 break;
-               case 't':
-                 operation = print_table;
-                 break;
-               case 'x':
-                 operation = extract;
-                 break;
-               }
-           case 'l':
-             break;
-           case 'c':
-             silent_create = 1;
-             break;
-           case 'o':
-             preserve_dates = 1;
-             break;
-           case 'V':
-             show_version = TRUE;
-             break;
-           case 's':
-             write_armap = 1;
-             break;
-           case 'S':
-             write_armap = -1;
-             break;
-           case 'u':
-             newer_only = 1;
-             break;
-           case 'v':
-             verbose = 1;
-             break;
-           case 'a':
-             postype = pos_after;
-             break;
-           case 'b':
-             postype = pos_before;
-             break;
-           case 'i':
-             postype = pos_before;
-             break;
-           case 'M':
-             mri_mode = 1;
-             break;
-           case 'N':
-             counted_name_mode = TRUE;
-             break;
-           case 'f':
-             ar_truncate = TRUE;
-             break;
-           case 'P':
-             full_pathname = TRUE;
-             break;
-           default:
-             /* xgettext:c-format */
-             non_fatal (_("illegal option -- %c"), c);
-             usage (0);
-           }
-       }
+  argv = decode_options (argc, argv);
 
 
-      /* With POSIX-compatible option parsing continue with the next
-        argument if it starts with '-'.  */
-      if (do_posix && arg_index + 1 < argc && argv[arg_index + 1][0] == '-')
-       arg_ptr = argv[++arg_index] + 1;
-      else
-       do_posix = 0;
-    }
-  while (do_posix);
+  if (show_help)
+    usage (1);
 
   if (show_version)
     print_version ("ar");
 
 
   if (show_version)
     print_version ("ar");
 
-  ++arg_index;
-  if (arg_index >= argc)
-    usage (0);
+  arg_index = 0;
 
   if (mri_mode)
     {
 
   if (mri_mode)
     {
@@ -597,10 +687,7 @@ main (int argc, char **argv)
 
       if ((operation == none || operation == print_table)
          && write_armap == 1)
 
       if ((operation == none || operation == print_table)
          && write_armap == 1)
-       {
-         ranlib_only (argv[arg_index]);
-         xexit (0);
-       }
+       xexit (ranlib_only (argv[arg_index]));
 
       if (operation == none)
        fatal (_("no operation specified"));
 
       if (operation == none)
        fatal (_("no operation specified"));
@@ -608,13 +695,16 @@ main (int argc, char **argv)
       if (newer_only && operation != replace)
        fatal (_("`u' is only meaningful with the `r' option."));
 
       if (newer_only && operation != replace)
        fatal (_("`u' is only meaningful with the `r' option."));
 
+      if (newer_only && deterministic)
+       fatal (_("`u' is not meaningful with the `D' option."));
+
       if (postype != pos_default)
        posname = argv[arg_index++];
 
       if (counted_name_mode)
        {
       if (postype != pos_default)
        posname = argv[arg_index++];
 
       if (counted_name_mode)
        {
-         if (operation != extract && operation != delete)
-            fatal (_("`N' is only meaningful with the `x' and `d' options."));
+         if (operation != extract && operation != del)
+           fatal (_("`N' is only meaningful with the `x' and `d' options."));
          counted_name_counter = atoi (argv[arg_index++]);
          if (counted_name_counter <= 0)
            fatal (_("Value for `N' must be positive."));
          counted_name_counter = atoi (argv[arg_index++]);
          if (counted_name_counter <= 0)
            fatal (_("Value for `N' must be positive."));
@@ -622,12 +712,17 @@ main (int argc, char **argv)
 
       inarch_filename = argv[arg_index++];
 
 
       inarch_filename = argv[arg_index++];
 
-      files = arg_index < argc ? argv + arg_index : NULL;
-      file_count = argc - arg_index;
+      for (file_count = 0; argv[arg_index + file_count] != NULL; file_count++)
+       continue;
+
+      files = (file_count > 0) ? argv + arg_index : NULL;
 
       arch = open_inarch (inarch_filename,
                          files == NULL ? (char *) NULL : files[0]);
 
 
       arch = open_inarch (inarch_filename,
                          files == NULL ? (char *) NULL : files[0]);
 
+      if (operation == extract && bfd_is_thin_archive (arch))
+       fatal (_("`x' cannot be used on thin archives."));
+
       switch (operation)
        {
        case print_table:
       switch (operation)
        {
        case print_table:
@@ -642,7 +737,7 @@ main (int argc, char **argv)
          map_over_members (arch, extract_file, files, file_count);
          break;
 
          map_over_members (arch, extract_file, files, file_count);
          break;
 
-       case delete:
+       case del:
          if (files != NULL)
            delete_members (arch, files);
          else
          if (files != NULL)
            delete_members (arch, files);
          else
@@ -680,7 +775,6 @@ main (int argc, char **argv)
 bfd *
 open_inarch (const char *archive_filename, const char *file)
 {
 bfd *
 open_inarch (const char *archive_filename, const char *file)
 {
-  const char *target;
   bfd **last_one;
   bfd *next_one;
   struct stat sbuf;
   bfd **last_one;
   bfd *next_one;
   struct stat sbuf;
@@ -689,7 +783,8 @@ open_inarch (const char *archive_filename, const char *file)
 
   bfd_set_error (bfd_error_no_error);
 
 
   bfd_set_error (bfd_error_no_error);
 
-  target = NULL;
+  if (target == NULL)
+    target = plugin_target;
 
   if (stat (archive_filename, &sbuf) != 0)
     {
 
   if (stat (archive_filename, &sbuf) != 0)
     {
@@ -700,8 +795,8 @@ open_inarch (const char *archive_filename, const char *file)
         stat() works just fine in v2.x, so I think this should be
         removed.  For now, I enable it for DJGPP v2. -- EZ.  */
 
         stat() works just fine in v2.x, so I think this should be
         removed.  For now, I enable it for DJGPP v2. -- EZ.  */
 
-/* KLUDGE ALERT! Temporary fix until I figger why
-   stat() is wrong ... think it's buried in GO32's IDT - Jax */
+      /* KLUDGE ALERT! Temporary fix until I figger why
+        stat() is wrong ... think it's buried in GO32's IDT - Jax */
       if (errno != ENOENT)
        bfd_fatal (archive_filename);
 #endif
       if (errno != ENOENT)
        bfd_fatal (archive_filename);
 #endif
@@ -720,7 +815,7 @@ open_inarch (const char *archive_filename, const char *file)
        {
          bfd *obj;
 
        {
          bfd *obj;
 
-         obj = bfd_openr (file, NULL);
+         obj = bfd_openr (file, target);
          if (obj != NULL)
            {
              if (bfd_check_format (obj, bfd_object))
          if (obj != NULL)
            {
              if (bfd_check_format (obj, bfd_object))
@@ -760,7 +855,7 @@ open_inarch (const char *archive_filename, const char *file)
       xexit (1);
     }
 
       xexit (1);
     }
 
-  last_one = &(arch->next);
+  last_one = &(arch->archive_next);
   /* Read all the contents right away, regardless.  */
   for (next_one = bfd_openr_next_archived_file (arch, NULL);
        next_one;
   /* Read all the contents right away, regardless.  */
   for (next_one = bfd_openr_next_archived_file (arch, NULL);
        next_one;
@@ -768,7 +863,7 @@ open_inarch (const char *archive_filename, const char *file)
     {
       PROGRESS (1);
       *last_one = next_one;
     {
       PROGRESS (1);
       *last_one = next_one;
-      last_one = &next_one->next;
+      last_one = &next_one->archive_next;
     }
   *last_one = (bfd *) NULL;
   if (bfd_get_error () != bfd_error_no_more_archived_files)
     }
   *last_one = (bfd *) NULL;
   if (bfd_get_error () != bfd_error_no_more_archived_files)
@@ -779,17 +874,16 @@ open_inarch (const char *archive_filename, const char *file)
 static void
 print_contents (bfd *abfd)
 {
 static void
 print_contents (bfd *abfd)
 {
-  int ncopied = 0;
-  char *cbuf = xmalloc (BUFSIZE);
+  size_t ncopied = 0;
+  char *cbuf = (char *) xmalloc (BUFSIZE);
   struct stat buf;
   struct stat buf;
-  long size;
+  size_t size;
   if (bfd_stat_arch_elt (abfd, &buf) != 0)
     /* xgettext:c-format */
     fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
 
   if (verbose)
   if (bfd_stat_arch_elt (abfd, &buf) != 0)
     /* xgettext:c-format */
     fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
 
   if (verbose)
-    /* xgettext:c-format */
-    printf (_("\n<%s>\n\n"), bfd_get_filename (abfd));
+    printf ("\n<%s>\n\n", bfd_get_filename (abfd));
 
   bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
 
 
   bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
 
@@ -797,8 +891,8 @@ print_contents (bfd *abfd)
   while (ncopied < size)
     {
 
   while (ncopied < size)
     {
 
-      int nread;
-      int tocopy = size - ncopied;
+      size_t nread;
+      size_t tocopy = size - ncopied;
       if (tocopy > BUFSIZE)
        tocopy = BUFSIZE;
 
       if (tocopy > BUFSIZE)
        tocopy = BUFSIZE;
 
@@ -807,7 +901,12 @@ print_contents (bfd *abfd)
        /* xgettext:c-format */
        fatal (_("%s is not a valid archive"),
               bfd_get_filename (bfd_my_archive (abfd)));
        /* xgettext:c-format */
        fatal (_("%s is not a valid archive"),
               bfd_get_filename (bfd_my_archive (abfd)));
-      fwrite (cbuf, 1, nread, stdout);
+
+      /* fwrite in mingw32 may return int instead of size_t. Cast the
+        return value to size_t to avoid comparison between signed and
+        unsigned values.  */
+      if ((size_t) fwrite (cbuf, 1, nread, stdout) != nread)
+       fatal ("stdout: %s", strerror (errno));
       ncopied += tocopy;
     }
   free (cbuf);
       ncopied += tocopy;
     }
   free (cbuf);
@@ -827,10 +926,10 @@ void
 extract_file (bfd *abfd)
 {
   FILE *ostream;
 extract_file (bfd *abfd)
 {
   FILE *ostream;
-  char *cbuf = xmalloc (BUFSIZE);
-  int nread, tocopy;
-  long ncopied = 0;
-  long size;
+  char *cbuf = (char *) xmalloc (BUFSIZE);
+  size_t nread, tocopy;
+  size_t ncopied = 0;
+  size_t size;
   struct stat buf;
 
   if (bfd_stat_arch_elt (abfd, &buf) != 0)
   struct stat buf;
 
   if (bfd_stat_arch_elt (abfd, &buf) != 0)
@@ -838,10 +937,6 @@ extract_file (bfd *abfd)
     fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
   size = buf.st_size;
 
     fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
   size = buf.st_size;
 
-  if (size < 0)
-    /* xgettext:c-format */
-    fatal (_("stat returns negative size for %s"), bfd_get_filename (abfd));
-
   if (verbose)
     printf ("x - %s\n", bfd_get_filename (abfd));
 
   if (verbose)
     printf ("x - %s\n", bfd_get_filename (abfd));
 
@@ -890,7 +985,12 @@ extract_file (bfd *abfd)
 
            output_file = ostream;
          }
 
            output_file = ostream;
          }
-       fwrite (cbuf, 1, nread, ostream);
+
+       /* fwrite in mingw32 may return int instead of size_t. Cast
+          the return value to size_t to avoid comparison between
+          signed and unsigned values.  */
+       if ((size_t) fwrite (cbuf, 1, nread, ostream) != nread)
+         fatal ("%s: %s", output_filename, strerror (errno));
        ncopied += tocopy;
       }
 
        ncopied += tocopy;
       }
 
@@ -918,12 +1018,15 @@ write_archive (bfd *iarch)
 {
   bfd *obfd;
   char *old_name, *new_name;
 {
   bfd *obfd;
   char *old_name, *new_name;
-  bfd *contents_head = iarch->next;
+  bfd *contents_head = iarch->archive_next;
 
 
-  old_name = xmalloc (strlen (bfd_get_filename (iarch)) + 1);
+  old_name = (char *) xmalloc (strlen (bfd_get_filename (iarch)) + 1);
   strcpy (old_name, bfd_get_filename (iarch));
   new_name = make_tempname (old_name);
 
   strcpy (old_name, bfd_get_filename (iarch));
   new_name = make_tempname (old_name);
 
+  if (new_name == NULL)
+    bfd_fatal ("could not create temporary file whilst writing archive");
+
   output_filename = new_name;
 
   obfd = bfd_openw (new_name, bfd_get_target (iarch));
   output_filename = new_name;
 
   obfd = bfd_openw (new_name, bfd_get_target (iarch));
@@ -946,6 +1049,12 @@ write_archive (bfd *iarch)
       obfd->flags |= BFD_TRADITIONAL_FORMAT;
     }
 
       obfd->flags |= BFD_TRADITIONAL_FORMAT;
     }
 
+  if (deterministic)
+    obfd->flags |= BFD_DETERMINISTIC_OUTPUT;
+
+  if (make_thin_archive || bfd_is_thin_archive (iarch))
+    bfd_is_thin_archive (obfd) = 1;
+
   if (!bfd_set_archive_head (obfd, contents_head))
     bfd_fatal (old_name);
 
   if (!bfd_set_archive_head (obfd, contents_head))
     bfd_fatal (old_name);
 
@@ -960,6 +1069,7 @@ write_archive (bfd *iarch)
 
   if (smart_rename (new_name, old_name, 0) != 0)
     xexit (1);
 
   if (smart_rename (new_name, old_name, 0) != 0)
     xexit (1);
+  free (old_name);
 }
 
 /* Return a pointer to the pointer to the entry which should be rplacd'd
 }
 
 /* Return a pointer to the pointer to the entry which should be rplacd'd
@@ -987,15 +1097,15 @@ get_pos_bfd (bfd **contents, enum pos default_pos, const char *default_posname)
   if (realpos == pos_end)
     {
       while (*after_bfd)
   if (realpos == pos_end)
     {
       while (*after_bfd)
-       after_bfd = &((*after_bfd)->next);
+       after_bfd = &((*after_bfd)->archive_next);
     }
   else
     {
     }
   else
     {
-      for (; *after_bfd; after_bfd = &(*after_bfd)->next)
+      for (; *after_bfd; after_bfd = &(*after_bfd)->archive_next)
        if (FILENAME_CMP ((*after_bfd)->filename, realposname) == 0)
          {
            if (realpos == pos_after)
        if (FILENAME_CMP ((*after_bfd)->filename, realposname) == 0)
          {
            if (realpos == pos_after)
-             after_bfd = &(*after_bfd)->next;
+             after_bfd = &(*after_bfd)->archive_next;
            break;
          }
     }
            break;
          }
     }
@@ -1027,7 +1137,7 @@ delete_members (bfd *arch, char **files_to_delete)
 
       found = FALSE;
       match_count = 0;
 
       found = FALSE;
       match_count = 0;
-      current_ptr_ptr = &(arch->next);
+      current_ptr_ptr = &(arch->archive_next);
       while (*current_ptr_ptr)
        {
          if (FILENAME_CMP (normalize (*files_to_delete, arch),
       while (*current_ptr_ptr)
        {
          if (FILENAME_CMP (normalize (*files_to_delete, arch),
@@ -1047,12 +1157,12 @@ delete_members (bfd *arch, char **files_to_delete)
                  if (verbose)
                    printf ("d - %s\n",
                            *files_to_delete);
                  if (verbose)
                    printf ("d - %s\n",
                            *files_to_delete);
-                 *current_ptr_ptr = ((*current_ptr_ptr)->next);
+                 *current_ptr_ptr = ((*current_ptr_ptr)->archive_next);
                  goto next_file;
                }
            }
 
                  goto next_file;
                }
            }
 
-         current_ptr_ptr = &((*current_ptr_ptr)->next);
+         current_ptr_ptr = &((*current_ptr_ptr)->archive_next);
        }
 
       if (verbose && !found)
        }
 
       if (verbose && !found)
@@ -1081,7 +1191,7 @@ move_members (bfd *arch, char **files_to_move)
 
   for (; *files_to_move; ++files_to_move)
     {
 
   for (; *files_to_move; ++files_to_move)
     {
-      current_ptr_ptr = &(arch->next);
+      current_ptr_ptr = &(arch->archive_next);
       while (*current_ptr_ptr)
        {
          bfd *current_ptr = *current_ptr_ptr;
       while (*current_ptr_ptr)
        {
          bfd *current_ptr = *current_ptr_ptr;
@@ -1090,14 +1200,14 @@ move_members (bfd *arch, char **files_to_move)
            {
              /* Move this file to the end of the list - first cut from
                 where it is.  */
            {
              /* Move this file to the end of the list - first cut from
                 where it is.  */
-             bfd *link;
-             *current_ptr_ptr = current_ptr->next;
+             bfd *link_bfd;
+             *current_ptr_ptr = current_ptr->archive_next;
 
              /* Now glue to end */
 
              /* Now glue to end */
-             after_bfd = get_pos_bfd (&arch->next, pos_end, NULL);
-             link = *after_bfd;
+             after_bfd = get_pos_bfd (&arch->archive_next, pos_end, NULL);
+             link_bfd = *after_bfd;
              *after_bfd = current_ptr;
              *after_bfd = current_ptr;
-             current_ptr->next = link;
+             current_ptr->archive_next = link_bfd;
 
              if (verbose)
                printf ("m - %s\n", *files_to_move);
 
              if (verbose)
                printf ("m - %s\n", *files_to_move);
@@ -1105,7 +1215,7 @@ move_members (bfd *arch, char **files_to_move)
              goto next_file;
            }
 
              goto next_file;
            }
 
-         current_ptr_ptr = &((*current_ptr_ptr)->next);
+         current_ptr_ptr = &((*current_ptr_ptr)->archive_next);
        }
       /* xgettext:c-format */
       fatal (_("no entry %s in archive %s!"), *files_to_move, arch->filename);
        }
       /* xgettext:c-format */
       fatal (_("no entry %s in archive %s!"), *files_to_move, arch->filename);
@@ -1130,7 +1240,7 @@ replace_members (bfd *arch, char **files_to_move, bfd_boolean quick)
     {
       if (! quick)
        {
     {
       if (! quick)
        {
-         current_ptr = &arch->next;
+         current_ptr = &arch->archive_next;
          while (*current_ptr)
            {
              current = *current_ptr;
          while (*current_ptr)
            {
              current = *current_ptr;
@@ -1160,26 +1270,27 @@ replace_members (bfd *arch, char **files_to_move, bfd_boolean quick)
                        goto next_file;
                    }
 
                        goto next_file;
                    }
 
-                 after_bfd = get_pos_bfd (&arch->next, pos_after,
+                 after_bfd = get_pos_bfd (&arch->archive_next, pos_after,
                                           current->filename);
                  if (ar_emul_replace (after_bfd, *files_to_move,
                                           current->filename);
                  if (ar_emul_replace (after_bfd, *files_to_move,
-                                      verbose))
+                                      target, verbose))
                    {
                      /* Snip out this entry from the chain.  */
                    {
                      /* Snip out this entry from the chain.  */
-                     *current_ptr = (*current_ptr)->next;
+                     *current_ptr = (*current_ptr)->archive_next;
                      changed = TRUE;
                    }
 
                  goto next_file;
                }
                      changed = TRUE;
                    }
 
                  goto next_file;
                }
-             current_ptr = &(current->next);
+             current_ptr = &(current->archive_next);
            }
        }
 
       /* Add to the end of the archive.  */
            }
        }
 
       /* Add to the end of the archive.  */
-      after_bfd = get_pos_bfd (&arch->next, pos_end, NULL);
+      after_bfd = get_pos_bfd (&arch->archive_next, pos_end, NULL);
 
 
-      if (ar_emul_append (after_bfd, *files_to_move, verbose))
+      if (ar_emul_append (after_bfd, *files_to_move, target,
+                         verbose, make_thin_archive))
        changed = TRUE;
 
     next_file:;
        changed = TRUE;
 
     next_file:;
@@ -1193,23 +1304,24 @@ replace_members (bfd *arch, char **files_to_move, bfd_boolean quick)
     output_filename = NULL;
 }
 
     output_filename = NULL;
 }
 
-static void
+static int
 ranlib_only (const char *archname)
 {
   bfd *arch;
 
   if (get_file_size (archname) < 1)
 ranlib_only (const char *archname)
 {
   bfd *arch;
 
   if (get_file_size (archname) < 1)
-    return;
+    return 1;
   write_armap = 1;
   arch = open_inarch (archname, (char *) NULL);
   if (arch == NULL)
     xexit (1);
   write_archive (arch);
   write_armap = 1;
   arch = open_inarch (archname, (char *) NULL);
   if (arch == NULL)
     xexit (1);
   write_archive (arch);
+  return 0;
 }
 
 /* Update the timestamp of the symbol map of an archive.  */
 
 }
 
 /* Update the timestamp of the symbol map of an archive.  */
 
-static void
+static int
 ranlib_touch (const char *archname)
 {
 #ifdef __GO32__
 ranlib_touch (const char *archname)
 {
 #ifdef __GO32__
@@ -1221,7 +1333,7 @@ ranlib_touch (const char *archname)
   char **matching;
 
   if (get_file_size (archname) < 1)
   char **matching;
 
   if (get_file_size (archname) < 1)
-    return;
+    return 1;
   f = open (archname, O_RDWR | O_BINARY, 0);
   if (f < 0)
     {
   f = open (archname, O_RDWR | O_BINARY, 0);
   if (f < 0)
     {
@@ -1252,6 +1364,7 @@ ranlib_touch (const char *archname)
   if (! bfd_close (arch))
     bfd_fatal (archname);
 #endif
   if (! bfd_close (arch))
     bfd_fatal (archname);
 #endif
+  return 0;
 }
 
 /* Things which are interesting to map over all or some of the files: */
 }
 
 /* Things which are interesting to map over all or some of the files: */
This page took 0.036505 seconds and 4 git commands to generate.