1999-09-12 Donn Terry <donn@interix.com>
authorIan Lance Taylor <ian@airs.com>
Sun, 12 Sep 1999 18:14:07 +0000 (18:14 +0000)
committerIan Lance Taylor <ian@airs.com>
Sun, 12 Sep 1999 18:14:07 +0000 (18:14 +0000)
* ar.c (counted_name_mode): New static variable.
(counted_name_counter): New static variable.
(map_over_members): Handle counted mode.
(usage): Mention N modifier.
(main): Handle N modifier.
(delete_members): Handle counted mode.
* binutils.texi, ar.1: Document N modifier.

binutils/ChangeLog
binutils/ar.1
binutils/ar.c
binutils/binutils.texi

index 3abe0ae..3c48546 100644 (file)
@@ -1,5 +1,13 @@
 1999-09-12  Donn Terry  <donn@interix.com>
 
+       * ar.c (counted_name_mode): New static variable.
+       (counted_name_counter): New static variable.
+       (map_over_members): Handle counted mode.
+       (usage): Mention N modifier.
+       (main): Handle N modifier.
+       (delete_members): Handle counted mode.
+       * binutils.texi, ar.1: Document N modifier.
+
        * ar.c (print_contents): Change printing of member name for
        POSIX.2 conformance.
 
@@ -14,6 +22,7 @@
        (usage): Mention P modifier.
        (normalize): If full_pathname is true, don't do anything.
        (main): Accept P modifier.
+       (delete_members): Call normalize on command line parameter.
        * binutils.texi, ar.1: Document P modifier.
 
 1999-09-09  Andreas Schwab  <schwab@suse.de>
index 5a9a9d5..cd71a40 100644 (file)
@@ -14,10 +14,13 @@ ar \- create, modify, and extract from archives.
 .hy 0
 .na
 .BR ar " [\|" "-" "\|]"\c
-.I {dmpqrtx}[abcilosSuvV] \c
+.I {dmpqrtx}[abcfilNoPsSuvV] \c
 [\|\c
 .I membername\c
 \&\|] \c
+[\|\c
+.I count\c
+\&\|] \c
 .I archive\c
 \& \c
 .I files\c
@@ -385,18 +388,6 @@ modifier may be used to truncate file names when putting them in the
 archive.
 
 .TP
-.B P
-Use the full path name when matching names in the archive.
-.B ar
-can not create an archive with a full path name (such archives are not
-POSIX complaint), but other archive creators can.  This option will
-cause
-.B ar
-to match file names using a complete path name, which can be
-convenient when extracting a single file from an archive created by
-another tool.
-
-.TP
 .B i
 Insert new files \c
 .I before\c
@@ -418,6 +409,15 @@ member must be present as the \c
 This modifier is accepted but not used.
 
 .TP
+.B N
+Uses the
+.I count
+parameter.  This is used if there are multiple entries in the archive
+with the same name.  Extract or delete instance
+.I count
+of the given name from the archive.
+
+.TP
 .B o
 Preserve the \c
 .I original\c
@@ -426,6 +426,18 @@ you do not specify this modifier, files extracted from the archive
 will be stamped with the time of extraction.
 
 .TP
+.B P
+Use the full path name when matching names in the archive.
+.B ar
+can not create an archive with a full path name (such archives are not
+POSIX complaint), but other archive creators can.  This option will
+cause
+.B ar
+to match file names using a complete path name, which can be
+convenient when extracting a single file from an archive created by
+another tool.
+
+.TP
 .B s
 Write an object-file index into the archive, or update an existing one,
 even if no other change is made to the archive.  You may use this modifier
index 4fe166a..50d1edc 100644 (file)
@@ -147,6 +147,11 @@ enum pos
 static bfd **
 get_pos_bfd PARAMS ((bfd **, enum pos, const char *));
 
+/* For extract/delete only.  If COUNTED_NAME_MODE is true, we only
+   extract the COUNTED_NAME_COUNTER instance of that name.  */
+static boolean counted_name_mode = 0;
+static int counted_name_counter = 0;
+
 /* Whether to truncate names of files stored in the archive.  */
 static boolean ar_truncate = false;
 
@@ -176,6 +181,7 @@ map_over_members (arch, function, files, count)
      int count;
 {
   bfd *head;
+  int match_count;
 
   if (count == 0)
     {
@@ -186,6 +192,7 @@ map_over_members (arch, function, files, count)
        }
       return;
     }
+
   /* 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
@@ -196,6 +203,7 @@ map_over_members (arch, function, files, count)
     {
       boolean found = false;
 
+      match_count = 0;
       for (head = arch->next; head; head = head->next)
        {
          PROGRESS (1);
@@ -209,6 +217,15 @@ map_over_members (arch, function, files, count)
          if ((head->filename != NULL) &&
              (!strcmp (normalize (*files, arch), head->filename)))
            {
+             ++match_count;
+             if (counted_name_mode
+                 && match_count != counted_name_counter) 
+               {
+                 /* Counting, and didn't match on count; go on to the
+                     next one.  */
+                 continue;
+               }
+
              found = true;
              function (head);
            }
@@ -232,7 +249,8 @@ usage (help)
   if (! is_ranlib)
     {
       /* xgettext:c-format */
-      fprintf (s, _("Usage: %s [-]{dmpqrstx}[abcilosSuvV] [member-name] archive-file file...\n"), program_name);
+      fprintf (s, _("Usage: %s [-]{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"));
@@ -246,6 +264,7 @@ usage (help)
       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"));
@@ -340,6 +359,7 @@ main (argc, argv)
     } operation = none;
   int arg_index;
   char **files;
+  int file_count;
   char *inarch_filename;
   int show_version;
 
@@ -507,6 +527,9 @@ main (argc, argv)
        case 'M':
          mri_mode = 1;
          break;
+       case 'N':
+         counted_name_mode = true;
+         break;
        case 'f':
          ar_truncate = true;
          break;
@@ -557,9 +580,19 @@ main (argc, argv)
       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."));
+         counted_name_counter = atoi (argv[arg_index++]);
+          if (counted_name_counter <= 0)
+           fatal (_("Value for `N' must be positive."));
+       }
+
       inarch_filename = argv[arg_index++];
 
       files = arg_index < argc ? argv + arg_index : NULL;
+      file_count = argc - arg_index;
 
 #if 0
       /* We don't use do_quick_append any more.  Too many systems
@@ -600,15 +633,15 @@ main (argc, argv)
       switch (operation)
        {
        case print_table:
-         map_over_members (arch, print_descr, files, argc - 3);
+         map_over_members (arch, print_descr, files, file_count);
          break;
 
        case print_files:
-         map_over_members (arch, print_contents, files, argc - 3);
+         map_over_members (arch, print_contents, files, file_count);
          break;
 
        case extract:
-         map_over_members (arch, extract_file, files, argc - 3);
+         map_over_members (arch, extract_file, files, file_count);
          break;
 
        case delete:
@@ -1089,6 +1122,8 @@ delete_members (arch, files_to_delete)
   bfd **current_ptr_ptr;
   boolean found;
   boolean something_changed = false;
+  int match_count;
+
   for (; *files_to_delete != NULL; ++files_to_delete)
     {
       /* In a.out systems, the armap is optional.  It's also called
@@ -1105,23 +1140,33 @@ delete_members (arch, files_to_delete)
        }
 
       found = false;
+      match_count = 0;
       current_ptr_ptr = &(arch->next);
       while (*current_ptr_ptr)
        {
-         if (strcmp (*files_to_delete, (*current_ptr_ptr)->filename) == 0)
-           {
-             found = true;
-             something_changed = true;
-             if (verbose)
-               printf ("d - %s\n",
-                       *files_to_delete);
-             *current_ptr_ptr = ((*current_ptr_ptr)->next);
-             goto next_file;
-           }
-         else
+         if (strcmp (normalize (*files_to_delete, arch),
+                     (*current_ptr_ptr)->filename) == 0)
            {
-             current_ptr_ptr = &((*current_ptr_ptr)->next);
+             ++match_count;
+             if (counted_name_mode
+                 && match_count != counted_name_counter) 
+               {
+                 /* Counting, and didn't match on count; go on to the
+                     next one.  */
+               }
+             else
+               {
+                 found = true;
+                 something_changed = true;
+                 if (verbose)
+                   printf ("d - %s\n",
+                           *files_to_delete);
+                 *current_ptr_ptr = ((*current_ptr_ptr)->next);
+                 goto next_file;
+               }
            }
+
+         current_ptr_ptr = &((*current_ptr_ptr)->next);
        }
 
       if (verbose && found == false)
index b2a3129..b08776b 100644 (file)
@@ -176,7 +176,7 @@ Create the files needed to build and use Dynamic Link Libraries
 @cindex archives
 @cindex collections of files
 @smallexample
-ar [-]@var{p}[@var{mod} [@var{relpos}]] @var{archive} [@var{member}@dots{}]
+ar [-]@var{p}[@var{mod} [@var{relpos}] [@var{count}]] @var{archive} [@var{member}@dots{}]
 ar -M [ <mri-script ]
 @end smallexample
 
@@ -234,7 +234,7 @@ program.
 @section Controlling @code{ar} on the command line
 
 @smallexample
-ar [-]@var{p}[@var{mod} [@var{relpos}]] @var{archive} [@var{member}@dots{}]
+ar [-]@var{p}[@var{mod} [@var{relpos}] [@var{count}]] @var{archive} [@var{member}@dots{}]
 @end smallexample
 
 @cindex Unix compatibility, @code{ar}
@@ -387,14 +387,6 @@ not compatible with the native @code{ar} program on some systems.  If
 this is a concern, the @samp{f} modifier may be used to truncate file
 names when putting them in the archive.
 
-@item P
-Use the full path name when matching names in the archive.  @sc{gnu}
-@code{ar} can not create an archive with a full path name (such archives
-are not POSIX complaint), but other archive creators can.  This option
-will cause @sc{gnu} @code{ar} to match file names using a complete path
-name, which can be convenient when extracting a single file from an
-archive created by another tool.
-
 @item i
 Insert new files @emph{before} an existing member of the
 archive.  If you use the modifier @samp{i}, the name of an existing archive
@@ -406,12 +398,25 @@ This modifier is accepted but not used.
 @c whaffor ar l modifier??? presumably compat; with
 @c what???---doc@@cygnus.com, 25jan91 
 
+@item N
+Uses the @var{count} parameter.  This is used if there are multiple
+entries in the archive with the same name.  Extract or delete instance
+@var{count} of the given name from the archive.
+
 @item o
 @cindex dates in archive
 Preserve the @emph{original} dates of members when extracting them.  If
 you do not specify this modifier, files extracted from the archive
 are stamped with the time of extraction.
 
+@item P
+Use the full path name when matching names in the archive.  @sc{gnu}
+@code{ar} can not create an archive with a full path name (such archives
+are not POSIX complaint), but other archive creators can.  This option
+will cause @sc{gnu} @code{ar} to match file names using a complete path
+name, which can be convenient when extracting a single file from an
+archive created by another tool.
+
 @item s
 @cindex writing archive index
 Write an object-file index into the archive, or update an existing one,