[prev in list] [next in list] [prev in thread] [next in thread] 

List:       coreutils-bug
Subject:    Re: 5.93 tail -N foo bar invalid option
From:       Paul Eggert <eggert () CS ! UCLA ! EDU>
Date:       2006-01-31 1:51:43
Message-ID: 87hd7ljhao.fsf () penguin ! cs ! ucla ! edu
[Download RAW message or body]

karl@freefriends.org (Karl Berry) writes:

> I just expected GNU tail -3 to behave the same as GNU head -3, since
> GNU is supposed to do things right :).

It depends on what you mean by "right", but I think GNU head -3
doesn't behave "right" either, if one expects options like "-3" to
"just work".  For example:

   $ head -v -3
   head: invalid option -- 3
   Try `head --help' for more information.

There is a similar problem with "head -v -34", "head -34n", and "head -3v4".
(Not to mention with "tail".)

The code to implement numeric options like "-34" is tricky due to the
desire to be backward-compatible with old, broken software and
standards.  If you explore it you'll always be able to find weird
corners.  I see no way to generalize them in a clean way.  It's
particularly tricky with "tail", since the old and new syntaxes are
flat-out incompatible.  I looked into adding support for "tail -3 a b
c", and the only way I could see to do it reliably (after about an
hour of trying to implement it in other ways) was to add a special
case for the exact usage "tail -DIGITS ARG ARG [ARG]....", where none
of the ARGs start with "-".  That's no way to run a railroad.

> The error `invalid option -- 3' just confused me more, since it's not
> the -3 that is invalid.

_That_ we can fix.  I installed the following.


2006-01-30  Paul Eggert  <eggert@cs.ucla.edu>

	* doc/coreutils.texi (tail invocation): In the obsolete usage, the
	count is optional, so put square brackets around it.
	* src/head.c (main): Use a better diagnostic when someone uses a
	trailing numeric option in an invalid way.  Problem reported by
	Karl Berry.
	* src/tail.c (parse_options): Likewise.

Index: doc/coreutils.texi
===================================================================
RCS file: /fetish/cu/doc/coreutils.texi,v
retrieving revision 1.307
diff -p -u -r1.307 coreutils.texi
--- doc/coreutils.texi	3 Jan 2006 00:45:06 -0000	1.307
+++ doc/coreutils.texi	31 Jan 2006 01:29:33 -0000
@@ -2551,7 +2551,7 @@ Always print file name headers.
 @end table
 
 For compatibility @command{tail} also supports an obsolete usage
-@samp{tail -@var{count}[bcl][f] [@var{file}]}, which is recognized
+@samp{tail -[@var{count}][bcl][f] [@var{file}]}, which is recognized
 only if it does not conflict with the usage described
 above.  This obsolete form uses exactly one option and at most one
 file.  In the option, @var{count} is an optional decimal number optionally
Index: src/head.c
===================================================================
RCS file: /fetish/cu/src/head.c,v
retrieving revision 1.104
diff -p -u -r1.104 head.c
--- src/head.c	3 Dec 2005 22:23:30 -0000	1.104
+++ src/head.c	31 Jan 2006 01:29:33 -0000
@@ -1,5 +1,5 @@
 /* head -- output first part of file(s)
-   Copyright (C) 89, 90, 91, 1995-2005 Free Software Foundation, Inc.
+   Copyright (C) 89, 90, 91, 1995-2006 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
@@ -973,7 +973,7 @@ main (int argc, char **argv)
 	      break;
 
 	    default:
-	      error (0, 0, _("unrecognized option `-%c'"), *a);
+	      error (0, 0, _("invalid trailing option -- %c"), *a);
 	      usage (EXIT_FAILURE);
 	    }
 	}
@@ -992,7 +992,8 @@ main (int argc, char **argv)
       argc--;
     }
 
-  while ((c = getopt_long (argc, argv, "c:n:qv", long_options, NULL)) != -1)
+  while ((c = getopt_long (argc, argv, "c:n:qv0123456789", long_options, NULL))
+	 != -1)
     {
       switch (c)
 	{
@@ -1029,6 +1030,8 @@ main (int argc, char **argv)
 	case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
 
 	default:
+	  if (ISDIGIT (c))
+	    error (0, 0, _("invalid trailing option -- %c"), c);
 	  usage (EXIT_FAILURE);
 	}
     }
Index: src/tail.c
===================================================================
RCS file: /fetish/cu/src/tail.c,v
retrieving revision 1.248
diff -p -u -r1.248 tail.c
--- src/tail.c	24 Jan 2006 10:32:32 -0000	1.248
+++ src/tail.c	31 Jan 2006 01:29:33 -0000
@@ -1455,7 +1455,8 @@ parse_options (int argc, char **argv,
 {
   int c;
 
-  while ((c = getopt_long (argc, argv, "c:n:fFqs:v", long_options, NULL))
+  while ((c = getopt_long (argc, argv, "c:n:fFqs:v0123456789",
+			   long_options, NULL))
 	 != -1)
     {
       switch (c)
@@ -1553,6 +1554,11 @@ parse_options (int argc, char **argv,
 
 	case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
 
+	case '0': case '1': case '2': case '3': case '4':
+	case '5': case '6': case '7': case '8': case '9':
+	  error (EXIT_FAILURE, 0,
+		 _("option used in invalid context -- %c"), c);
+
 	default:
 	  usage (EXIT_FAILURE);
 	}



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic