binutils ChangeLog:
[deliverable/binutils-gdb.git] / binutils / ar.c
index 95e1c665b1229d6b21ff654dd9b4391a37fd1427..ec0657d638c222db5ccae30ffb74b5ff82a395b1 100644 (file)
@@ -1,6 +1,6 @@
 /* ar.c - Archive modify and extract.
    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003
+   2001, 2002, 2003, 2004
    Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
@@ -24,7 +24,7 @@
    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 consistant.  */
+   more consistent.  */
 
 #include "bfd.h"
 #include "libiberty.h"
@@ -103,7 +103,7 @@ int newer_only = 0;
 
 /* Controls the writing of an archive symbol table (in BSD: a __.SYMDEF
    member).  -1 means we've been explicitly asked to not write a symbol table;
-   +1 means we've been explictly asked to write it;
+   +1 means we've been explicitly asked to write it;
    0 is the default.
    Traditionally, the default in BSD has been to not write the table.
    However, for POSIX.2 compliance the default is now to write a symbol table
@@ -324,8 +324,8 @@ remove_output (void)
 {
   if (output_filename != NULL)
     {
-      if (output_bfd != NULL && output_bfd->iostream != NULL)
-       fclose ((FILE *) (output_bfd->iostream));
+      if (output_bfd != NULL)
+       bfd_cache_close (output_bfd);
       if (output_file != NULL)
        fclose (output_file);
       unlink (output_filename);
@@ -353,6 +353,7 @@ main (int argc, char **argv)
   char *inarch_filename;
   int show_version;
   int i;
+  int do_posix = 0;
 
 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
   setlocale (LC_MESSAGES, "");
@@ -459,107 +460,125 @@ main (int argc, char **argv)
   if (argc < 2)
     usage (0);
 
-  arg_ptr = argv[1];
+  arg_index = 1;
+  arg_ptr = argv[arg_index];
 
   if (*arg_ptr == '-')
-    ++arg_ptr;                 /* compatibility */
+    {
+      /* When the first option starts with '-' we support POSIX-compatible
+        option parsing.  */
+      do_posix = 1;
+      ++arg_ptr;                       /* compatibility */
+    }
 
-  while ((c = *arg_ptr++) != '\0')
+  do
     {
-      switch (c)
+      while ((c = *arg_ptr++) != '\0')
        {
-       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;
+             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);
            }
-       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);
        }
+
+      /* 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_version)
     print_version ("ar");
 
-  if (argc < 3)
+  ++arg_index;
+  if (arg_index >= argc)
     usage (0);
 
   if (mri_mode)
@@ -578,7 +597,7 @@ main (int argc, char **argv)
       if ((operation == none || operation == print_table)
          && write_armap == 1)
        {
-         ranlib_only (argv[2]);
+         ranlib_only (argv[arg_index]);
          xexit (0);
        }
 
@@ -588,8 +607,6 @@ main (int argc, char **argv)
       if (newer_only && operation != replace)
        fatal (_("`u' is only meaningful with the `r' option."));
 
-      arg_index = 2;
-
       if (postype != pos_default)
        posname = argv[arg_index++];
 
@@ -750,6 +767,8 @@ open_inarch (const char *archive_filename, const char *file)
          || ! bfd_set_format (arch, bfd_archive)
          || ! bfd_close (arch))
        bfd_fatal (archive_filename);
+      else if (!silent_create)
+        non_fatal (_("creating %s"), archive_filename);
 
       /* If we die creating a new archive, don't leave it around.  */
       output_filename = archive_filename;
@@ -802,7 +821,7 @@ print_contents (bfd *abfd)
 
   if (verbose)
     /* xgettext:c-format */
-    printf (_("\n<member %s>\n\n"), bfd_get_filename (abfd));
+    printf (_("\n<%s>\n\n"), bfd_get_filename (abfd));
 
   bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
 
@@ -991,7 +1010,7 @@ do_quick_append (const char *archive_filename, char **files_to_append)
   if (ar_truncate)
     temp->flags |= BFD_TRADITIONAL_FORMAT;
 
-  /* assume it's an achive, go straight to the end, sans $200 */
+  /* assume it's an archive, go straight to the end, sans $200 */
   fseek (ofile, 0, 2);
 
   for (; files_to_append && *files_to_append; ++files_to_append)
@@ -1305,7 +1324,9 @@ replace_members (bfd *arch, char **files_to_move, bfd_boolean quick)
 
       /* Add to the end of the archive.  */
       after_bfd = get_pos_bfd (&arch->next, pos_end, NULL);
-      if (ar_emul_append (after_bfd, *files_to_move, verbose))
+
+      if (get_file_size (* files_to_move) > 0
+         && ar_emul_append (after_bfd, *files_to_move, verbose))
        changed = TRUE;
 
     next_file:;
@@ -1324,6 +1345,8 @@ ranlib_only (const char *archname)
 {
   bfd *arch;
 
+  if (get_file_size (archname) < 1)
+    return;
   write_armap = 1;
   arch = open_inarch (archname, (char *) NULL);
   if (arch == NULL)
@@ -1344,6 +1367,8 @@ ranlib_touch (const char *archname)
   bfd *arch;
   char **matching;
 
+  if (get_file_size (archname) < 1)
+    return;
   f = open (archname, O_RDWR | O_BINARY, 0);
   if (f < 0)
     {
This page took 0.028181 seconds and 4 git commands to generate.