This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

POSIX-compatible argument parsing for ar


This implements POSIX-compatible argument parsing for ar.  It is still
ad-hoc parsing, but that is the best we can do while still supporting the
legacy options.

Andreas.

2004-02-23  Andreas Schwab  <schwab@suse.de>

	* ar.c (main): Support POSIX-compatible argument parsing.

testsuite:

	* binutils-all/ar.exp (argument_parsing): New test.

Index: binutils/ar.c
===================================================================
RCS file: /cvs/src/src/binutils/ar.c,v
retrieving revision 1.33
diff -u -p -a -r1.33 ar.c
--- binutils/ar.c	15 Feb 2004 02:24:53 -0000	1.33
+++ binutils/ar.c	23 Feb 2004 15:38:36 -0000
@@ -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.
@@ -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);
 	}
 
@@ -587,8 +606,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++];
Index: binutils/testsuite/binutils-all/ar.exp
===================================================================
RCS file: /cvs/src/src/binutils/testsuite/binutils-all/ar.exp,v
retrieving revision 1.4
diff -u -p -a -r1.4 ar.exp
--- binutils/testsuite/binutils-all/ar.exp	11 Apr 2002 13:42:03 -0000	1.4
+++ binutils/testsuite/binutils-all/ar.exp	23 Feb 2004 15:38:36 -0000
@@ -1,4 +1,4 @@
-#   Copyright 1995, 1997 Free Software Foundation, Inc.
+#   Copyright 1995, 1997, 2004 Free Software Foundation, Inc.
 
 # 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
@@ -214,7 +214,43 @@ proc symbol_table { } {
     pass $testname
 }
 
+# Test POSIX-compatible argument parsing.
+
+proc argument_parsing { } {
+    global AR
+    global AS
+    global srcdir
+    global subdir
+
+    set testname "ar argument parsing"
+
+    if ![binutils_assemble $srcdir/$subdir/bintest.s tmpdir/bintest.o] {
+	unresolved $testname
+	return
+    }
+
+    if [is_remote host] {
+	set archive artest.a
+	set objfile [remote_download host tmpdir/bintest.o]
+	remote_file host delete $archive
+    } else {
+	set archive tmpdir/artest.a
+	set objfile tmpdir/bintest.o
+    }
+
+    remote_file build delete tmpdir/artest.a
+
+    set got [binutils_run $AR "-r -c $archive ${objfile}"]
+    if ![string match "" $got] {
+	fail $testname
+	return
+    }
+
+    pass $testname
+}
+
 # Run the tests.
 
 long_filenames
 symbol_table
+argument_parsing

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, Maxfeldstraße 5, 90409 Nürnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]