Re: option abbreviation exceptions
Eric Blake byu.net> writes: > Certainly some inconsistent behavior. echo takes multiple arguments, but only > when they are the short options -[neE] (I guess it's okay that they don't have > long-option variants?). But when --help or --version is present, echo acts > like it takes exactly one argument. The usage text doesn't really portray > that. Would this usage text be acceptable at better describing the situation? Usage: /bin/echo [SHORT-OPTION]... [STRING]... or: /bin/echo LONG-OPTION Using 'git grep " OPTION"', I've come up with this additional list of programs where I think we are inconsistent: src/basename.c: or: %s OPTION\n\ 'basename --help --version' is rejected, but not 'basename --hel'. Should we treat "basename --oops" as equivalent to "basename -- --oops", rather than causing an error? src/chroot.c: or: %s OPTION\n\ $ chroot -- --hel chroot: cannot change root directory to --: No such file or directory Oops, there's a bug; the message should have mentioned --hel, not --. Meanwhile, should we treat "chroot --oops" like "chroot -- --oops"? src/dd.c: or: %s OPTION\n\ 'dd --help --version' is rejected, but not 'dd --hel'. src/dirname.c: or: %s OPTION\n\ Similar to basename. src/expr.c: or: %s OPTION\n\ 'expr --help --version' is rejected (but with a different error than with other coreutils), while 'expr --hel' works. src/factor.c: or: %s OPTION\n\ Unlike expr, 'factor --help --version' works. src/hostid.c: or: %s OPTION\n\ 'hostid --help --version' is rejected. But perhaps this usage should be written in one line, instead of two: Usage: hostid [OPTION] src/hostname.c: or: %s OPTION\n\ Like dirname, should 'hostname --oops' be treated as 'hostname -- --oops'? src/link.c: or: %s OPTION\n"), program_name, program_name); 'link --help --version' is rejected, but 'link --hel' works. src/nohup.c: or: %s OPTION\n\ 'nohup --help --version' is rejected, but 'nohup --hel' works. Also, should 'nohup --oops' behave like 'nohup -- --oops'? src/printenv.c: or: %s OPTION\n\ 'printenv --help --version' is rejected, but 'printenv --hel' works. src/printf.c: or: %s OPTION\n\ src/printf.c:Print ARGUMENT(s) according to FORMAT, or execute according to OPTION:\n\ $ /bin/printf --help --version --help/bin/printf: warning: ignoring excess arguments, starting with `--version' Ouch. This both printed to stdout, and to stderr. It would have been nicer to keep the error but do nothing on stdout, or to print both strings with no error. But this is one case where we have the extension already in place that '/bin/printf --oops' behaves like the intended '/bin/printf -- --oops', rather than issuing an error. I do like the Usage text, though - that is the cleanest way of describing how the presence of a single OPTION alters behavior. src/setuidgid.c:Usage: %s OPTION USER COMMAND [ARGUMENT]...\n\ src/setuidgid.c: or: %s OPTION\n\ Not installed. But this is another case where the Usage could be rendered better (the -g is optional, but can be used multiple times): Usage: %s [SHORT-OPTION]... USER COMMAND [ARGUMENT]... or: %s LONG-OPTION src/sleep.c: or: %s OPTION\n\ 'sleep --help --version' is rejected, but not 'sleep --hel'. src/test.c: or: [ OPTION\n\ Discussed in previous email. src/true.c: or: %s OPTION\n\ One of the few utilities where '/bin/true --hel' already treats --hel as ignored arguments, rather than an abbreviation for --help. src/truncate.c: printf (_("Usage: %s OPTION... FILE...\n"), program_name); Inconsistent formatting. Do we really want to require either -r or -s, or would it make sense to make OPTION optional, in which case the default is -s0? Also, would it make sense to extend this such that: $ echo hi > foo $ truncate --size=0 < foo resizes foo to 0 bytes, by way of ftruncate on stdin? If so, maybe it makes sense to render this as: Usage: truncate [OPTION]... [FILE]... src/unlink.c: or: %s OPTION\n"), program_name, program_name); 'unlink --help --version' is rejected, but not 'unlink --hel'. Should we treat 'unlink --oops' like 'unlink -- --oops'? src/yes.c: or: %s OPTION\n\ 'yes --help --version' is rejected, but 'yes --hel' gives help. Should we treat 'yes --oops' like 'yes -- --oops'? -- Eric Blake ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: option abbreviation exceptions
Eric Blake wrote: > Eric Blake byu.net> writes: > >> Some of these programs recognize the @option{--help} and @option{--version} >> -options only when one of them is the sole command line argument. >> +options only when one of them is the sole command line argument. For >> +these programs, abbreviations of the long options are not recognized. > > In subsequent testing, I realized this is not entirely true. Should I work on > a followup patch that makes this sentence true? Simplest might be to change "not recognized" to "not always recognized". > For example, > > $ /bin/echo --help --version | head -n1 > --help --version > $ /bin/echo --help | head -n1 > Usage: /bin/echo [OPTION]... [STRING]... > $ /bin/echo --he | head -n1 > Usage: /bin/echo [OPTION]... [STRING]... > $ /bin/echo -n -e hi\\n | head -n1 > hi > > Certainly some inconsistent behavior. echo takes multiple arguments, but only > when they are the short options -[neE] (I guess it's okay that they don't have > long-option variants?). Yes, I think so. coreutils' echo is so old and rarely used that it doesn't matter. People should be using printf instead. > But when --help or --version is present, echo acts > like it takes exactly one argument. The usage text doesn't really portray > that. The other thing that is awkward is that we are recognizing > abbreviations; it seems like it would make more sense for "echo --he" to > output "--he" rather than the help text. POSIX isn't much help here, either, > as it only specifies that portable apps can't use -n (but says nothing about - > e), and we are already violating the (lame) POSIX requirement that -e be on by > default, thus giving no guidance on whether we are better off requiring the > user to write "/bin/echo -ne" instead of "/bin/echo -n -e" when they want both > options. > > Another case in point: > > $ /bin/[ --help me | head -n1 > /bin/[: missing `]' > $ /bin/[ --help | head -n1 > Usage: test EXPRESSION > $ /bin/[ --hel | head -n1 > Usage: test EXPRESSION > > Should the last example also complain about missing `]', rather than printing > help text? test and [ have always had a conflicted relationship with --help/--version. Making [ accept no abbreviations does seem like it'd be an improvement. ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: option abbreviation exceptions
Eric Blake wrote: > Eric Blake byu.net> writes: > >> Certainly some inconsistent behavior. echo takes multiple arguments, but > only >> when they are the short options -[neE] (I guess it's okay that they don't > have >> long-option variants?). But when --help or --version is present, echo acts >> like it takes exactly one argument. The usage text doesn't really portray >> that. > > Would this usage text be acceptable at better describing the situation? > > Usage: /bin/echo [SHORT-OPTION]... [STRING]... > or: /bin/echo LONG-OPTION Sure. > Using 'git grep " OPTION"', I've come up with this additional list of programs > where I think we are inconsistent: > > src/basename.c: or: %s OPTION\n\ > > 'basename --help --version' is rejected, but not 'basename --hel'. Should we > treat "basename --oops" as equivalent to "basename -- --oops", rather than > causing an error? I'd rather not. Otherwise, basename --h3lp would not give a diagnostic, and "unlink --he" would try to unlink an unlikely file. In each of those cases, the result would be too "surprising". > src/chroot.c: or: %s OPTION\n\ > > $ chroot -- --hel > chroot: cannot change root directory to --: No such file or directory > > Oops, there's a bug; the message should have mentioned --hel, not --. Good catch. > Meanwhile, should we treat "chroot --oops" like "chroot -- --oops"? Probably not. Same reasoning as above. > src/dd.c: or: %s OPTION\n\ > src/dirname.c: or: %s OPTION\n\ > src/expr.c: or: %s OPTION\n\ > src/factor.c: or: %s OPTION\n\ > src/hostname.c: or: %s OPTION\n\ > src/link.c: or: %s OPTION\n"), program_name, program_name); > src/nohup.c: or: %s OPTION\n\ > src/printenv.c: or: %s OPTION\n\ > src/sleep.c: or: %s OPTION\n\ > src/unlink.c: or: %s OPTION\n"), program_name, program_name); > src/yes.c: or: %s OPTION\n\ same as above. > Unlike expr, 'factor --help --version' works. Consistency would be nice. > src/hostid.c: or: %s OPTION\n\ > > 'hostid --help --version' is rejected. But perhaps this usage should be > written in one line, instead of two: > > Usage: hostid [OPTION] Good idea. > src/printf.c: or: %s OPTION\n\ > src/printf.c:Print ARGUMENT(s) according to FORMAT, or execute according to > OPTION:\n\ > > $ /bin/printf --help --version > --help/bin/printf: warning: ignoring excess arguments, starting with > `--version' > > Ouch. This both printed to stdout, and to stderr. It would have been nicer > to > keep the error but do nothing on stdout, or to print both strings with no > error. But this is one case where we have the extension already in place > that '/bin/printf --oops' behaves like the intended '/bin/printf -- --oops', > rather than issuing an error. Yes, printf is a special case. > I do like the Usage text, though - that is the cleanest way of describing how > the presence of a single OPTION alters behavior. > > > src/setuidgid.c:Usage: %s OPTION USER COMMAND [ARGUMENT]...\n\ > src/setuidgid.c: or: %s OPTION\n\ > > Not installed. But this is another case where the Usage could be rendered > better (the -g is optional, but can be used multiple times): > > Usage: %s [SHORT-OPTION]... USER COMMAND [ARGUMENT]... > or: %s LONG-OPTION Yes, that's better. > src/true.c: or: %s OPTION\n\ > > One of the few utilities where '/bin/true --hel' already treats --hel as > ignored arguments, rather than an abbreviation for --help. yes, this is another beaten-to-death exception ;-) > src/truncate.c: printf (_("Usage: %s OPTION... FILE...\n"), > program_name); > > Inconsistent formatting. Do we really want to require either -r or -s, or > would it make sense to make OPTION optional, in which case the default is -s0? > Also, would it make sense to extend this such that: > > $ echo hi > foo > $ truncate --size=0 < foo > > resizes foo to 0 bytes, by way of ftruncate on stdin? If so, maybe it makes > sense to render this as: > > Usage: truncate [OPTION]... [FILE]... I'll let Pádraig field this one. ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: option abbreviation exceptions
Eric Blake wrote: > src/truncate.c: printf (_("Usage: %s OPTION... FILE...\n"), > program_name); > > Inconsistent formatting. Do we really want to require either -r or -s, or > would it make sense to make OPTION optional, in which case the default is > -s0? I'm not sure that's a desirable default. If one wants to truncate a file to 0, then the usual method is `> file`. Having this as a default seems a little arbitrary/dangerous. > Also, would it make sense to extend this such that: > > $ echo hi > foo > $ truncate --size=0 < foo > > resizes foo to 0 bytes, by way of ftruncate on stdin? If so, maybe it makes > sense to render this as: > > Usage: truncate [OPTION]... [FILE]... Is supporting stdin a useful enhancement? Maybe if you can get the shell to open different files based on some condition, though again that seems a little contrived. cheers, Pádraig. ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: option abbreviation exceptions
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 According to Pádraig Brady on 12/30/2008 2:46 AM: >> Usage: truncate [OPTION]... [FILE]... > > Is supporting stdin a useful enhancement? > Maybe if you can get the shell to open > different files based on some condition, > though again that seems a little contrived. if cond ; then foo=file1 else foo=file2 fi truncate -s0 <$foo - -- Don't work too hard, make some time for fun as well! Eric Blake e...@byu.net -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.9 (Cygwin) Comment: Public key at home.comcast.net/~ericblake/eblake.gpg Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAklaG2IACgkQ84KuGfSFAYBkhwCgkVAbg/b5mkkbNlembiDzpgeA tdUAoL6Kzb/4DqubvAOFgABV1RdeI1w3 =mkaW -END PGP SIGNATURE- ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: option abbreviation exceptions
On Tuesday 30 December 2008 15:00:18 Eric Blake wrote: > According to Pádraig Brady on 12/30/2008 2:46 AM: > >> Usage: truncate [OPTION]... [FILE]... > > > > Is supporting stdin a useful enhancement? er ... > > Maybe if you can get the shell to open > > different files based on some condition, > > though again that seems a little contrived. > > if cond ; then > foo=file1 > else > foo=file2 > fi > truncate -s0 <$foo This redirection is wonderful, but entirely counter-intuitive. By convention stdout is where writes occur, stdin is where reads occur. Modifying the file given as stdin is just a little unexpected. For good measure (all?) shells open stdin as read-only, which makes the operation fail -- ftruncate(0,0) gives "invalid argument". The redirection you need for a writable stdin under bash seems to be this one: truncate -s$SIZE 0>>$foo &:-) ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: option abbreviation exceptions
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 According to Jim Meyering on 12/29/2008 10:22 AM: >> Would this usage text be acceptable at better describing the situation? >> >> Usage: /bin/echo [SHORT-OPTION]... [STRING]... >> or: /bin/echo LONG-OPTION > > Sure. Here's a first patch that solves the issues that we agreed were trivial. OK to commit, or should I just push them to the next branch until we've had a day to think about it? I need to put more time into the other issues we discussed, such as: > Making [ accept no abbreviations does seem like it'd be an improvement. - -- Don't work too hard, make some time for fun as well! Eric Blake e...@byu.net -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.9 (Cygwin) Comment: Public key at home.comcast.net/~ericblake/eblake.gpg Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAklmCqkACgkQ84KuGfSFAYDdRgCfSK5XFHU2CTHRhXjlM8RlcBPp vmIAnAptf8cU+wM2ZtyAxddTp2YaVhDU =r4kg -END PGP SIGNATURE- From b1e1758b82550c4ee339e21d7a2763c160c24692 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Thu, 8 Jan 2009 06:33:16 -0700 Subject: [PATCH] option handling: make exceptions more consistent * doc/coreutils.texi (Common options): Not all utilities reject option abbreviations. * src/chroot.c (main): Report correct name on failure. * src/echo.c (usage): Clarify long option usage. * src/setuidgid.c (usage): Likewise. * src/hostid.c (usage): Condense. --- doc/coreutils.texi |2 +- src/chroot.c |5 +++-- src/echo.c |7 +-- src/hostid.c |5 ++--- src/setuidgid.c|6 +++--- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 51145de..1cc237c 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -681,7 +681,7 @@ Common options Some of these programs recognize the @option{--help} and @option{--version} options only when one of them is the sole command line argument. For -these programs, abbreviations of the long options are not recognized. +these programs, abbreviations of the long options are not always recognized. @table @samp diff --git a/src/chroot.c b/src/chroot.c index 1eb443c..6d3fddf 100644 --- a/src/chroot.c +++ b/src/chroot.c @@ -1,5 +1,5 @@ /* chroot -- run command or shell with special root directory - Copyright (C) 95, 96, 1997, 1999-2004, 2007-2008 + Copyright (C) 95, 96, 1997, 1999-2004, 2007-2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -83,7 +83,8 @@ main (int argc, char **argv) } if (chroot (argv[optind]) != 0) -error (EXIT_FAILURE, errno, _("cannot change root directory to %s"), argv[1]); +error (EXIT_FAILURE, errno, _("cannot change root directory to %s"), + argv[optind]); if (chdir ("/")) error (EXIT_FAILURE, errno, _("cannot chdir to root directory")); diff --git a/src/echo.c b/src/echo.c index d549cda..c4b7ca9 100644 --- a/src/echo.c +++ b/src/echo.c @@ -1,5 +1,5 @@ /* echo.c, derived from code echo.c in Bash. - Copyright (C) 87,89, 1991-1997, 1999-2005, 2007-2008 Free Software + Copyright (C) 87,89, 1991-1997, 1999-2005, 2007-2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -41,7 +41,10 @@ usage (int status) program_name); else { - printf (_("Usage: %s [OPTION]... [STRING]...\n"), program_name); + printf (_("\ +Usage: %s [SHORT-OPTION]... [STRING]...\n\ + or: %s LONG-OPTION\n\ +"), program_name, program_name); fputs (_("\ Echo the STRING(s) to standard output.\n\ \n\ diff --git a/src/hostid.c b/src/hostid.c index f3cabc4..4482bd5 100644 --- a/src/hostid.c +++ b/src/hostid.c @@ -1,6 +1,6 @@ /* print the hexadecimal identifier for the current host - Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2007-2008 Free + Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2007-2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -42,8 +42,7 @@ usage (int status) else { printf (_("\ -Usage: %s\n\ - or: %s OPTION\n\ +Usage: %s [OPTION]\n\ Print the numeric identifier (in hexadecimal) for the current host.\n\ \n\ "), diff --git a/src/setuidgid.c b/src/setuidgid.c index 057002c..beff04a 100644 --- a/src/setuidgid.c +++ b/src/setuidgid.c @@ -1,5 +1,5 @@ /* setuidgid - run a command with the UID and GID of a specified user - Copyright (C) 2003-2008 Free Software Foundation, Inc. + Copyright (C) 2003-2009 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 @@ -48,8 +48,8 @@ usage (int status) else { printf (_("\ -Usage: %s OPTION USER COMMAND [ARGUMENT]...\n\ - or: %s OPTION\n\ +Usage: %s [SHORT-OPTION]... USER COMMAND [ARGUMEN
Re: option abbreviation exceptions
Eric Blake wrote: > According to Jim Meyering on 12/29/2008 10:22 AM: >>> Would this usage text be acceptable at better describing the situation? >>> >>> Usage: /bin/echo [SHORT-OPTION]... [STRING]... >>> or: /bin/echo LONG-OPTION >> >> Sure. > > Here's a first patch that solves the issues that we agreed were trivial. > OK to commit, or should I just push them to the next branch until we've > had a day to think about it? Thanks! This looks fine, so you're welcome to push to master. or to next, if you'd prefer. ... > Subject: [PATCH] option handling: make exceptions more consistent ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: option abbreviation exceptions
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 According to Jim Meyering on 12/29/2008 10:02 AM: >> $ /bin/[ --help me | head -n1 >> /bin/[: missing `]' >> $ /bin/[ --help | head -n1 >> Usage: test EXPRESSION >> $ /bin/[ --hel | head -n1 >> Usage: test EXPRESSION >> >> Should the last example also complain about missing `]', rather than printing >> help text? > > test and [ have always had a conflicted relationship > with --help/--version. > > Making [ accept no abbreviations does seem like it'd be an improvement. > What do you think of this patch? It changes programs that take exactly one of the two mandated options to only recognize exactly "--help" or "--version" but not abbreviations. After the patch, I get: $ src/basename --oops src/basename: invalid option -- - Try `src/basename --help' for more information. $ src/basename --help me src/basename: invalid option -- - Try `src/basename --help' for more information. $ src/basename --hel src/basename: invalid option -- - Try `src/basename --help' for more information. $ src/basename --help | head -n2 Usage: src/basename NAME [SUFFIX] or: src/basename OPTION $ src/echo --he - --he In other words, most programs will treat --h identically to --oops, diagnosing it as an invalid option (since the application only takes one of two specific options), and exceptional programs, like echo or [, which react differently to invalid options, will react the same way to an abbreviation as to any other invalid option. - -- Don't work too hard, make some time for fun as well! Eric Blake e...@byu.net -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.9 (Cygwin) Comment: Public key at home.comcast.net/~ericblake/eblake.gpg Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAklo2EsACgkQ84KuGfSFAYCI7wCgxOjDYYv1iklsomt/HVvMr2dE nZgAoMw8w66MjdbPSyw9h90CtS8k4goE =HKir -END PGP SIGNATURE- >From b8f77e710856f8996cf0f149826691a0f75e71ec Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Sat, 10 Jan 2009 10:07:46 -0700 Subject: [PATCH] parse_long_options: don't accept abbreviations * long-options.c (long_options): Ignore abbreviations, so that /bin/echo --h prints --h rather than usage. --- ChangeLog |6 ++ lib/long-options.c | 13 +++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0c9bcfb..fad1240 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-01-10 Eric Blake + + parse_long_options: don't accept abbreviations + * long-options.c (long_options): Ignore abbreviations, so that + /bin/echo --h prints --h rather than usage. + 2009-01-09 Paolo Bonzini regex: fix glibc bug 9697 diff --git a/lib/long-options.c b/lib/long-options.c index 0286bdf..b605b68 100644 --- a/lib/long-options.c +++ b/lib/long-options.c @@ -1,7 +1,7 @@ /* Utility to accept --help and --version options as unobtrusively as possible. Copyright (C) 1993, 1994, 1998, 1999, 2000, 2002, 2003, 2004, 2005, - 2006 Free Software Foundation, Inc. + 2006, 2009 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 @@ -33,12 +33,21 @@ static struct option const long_options[] = { {"help", no_argument, NULL, 'h'}, + {"hel", no_argument, NULL, ' '}, + {"he", no_argument, NULL, ' '}, + {"h", no_argument, NULL, ' '}, {"version", no_argument, NULL, 'v'}, + {"versio", no_argument, NULL, ' '}, + {"versi", no_argument, NULL, ' '}, + {"vers", no_argument, NULL, ' '}, + {"ver", no_argument, NULL, ' '}, + {"ve", no_argument, NULL, ' '}, + {"v", no_argument, NULL, ' '}, {NULL, 0, NULL, 0} }; /* Process long options --help and --version, but only if argc == 2. - Be careful not to gobble up `--'. */ + Be careful not to gobble up `--'. Ignore abbreviations. */ void parse_long_options (int argc, -- 1.6.0.4 ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: option abbreviation exceptions
Eric Blake wrote: > According to Jim Meyering on 12/29/2008 10:02 AM: >>> $ /bin/[ --help me | head -n1 >>> /bin/[: missing `]' >>> $ /bin/[ --help | head -n1 >>> Usage: test EXPRESSION >>> $ /bin/[ --hel | head -n1 >>> Usage: test EXPRESSION >>> >>> Should the last example also complain about missing `]', rather than >>> printing >>> help text? >> >> test and [ have always had a conflicted relationship >> with --help/--version. >> >> Making [ accept no abbreviations does seem like it'd be an improvement. > > What do you think of this patch? It changes programs that take exactly > one of the two mandated options to only recognize exactly "--help" or > "--version" but not abbreviations. After the patch, I get: "[" feels like it should be the exception. I see treating --v like --version as a feature. a typing saver. But with "[", it's good to minimize the number of strings that make it act differently. Besides, why make everyone type it all out if there's no need? Then you don't have to "know" that a program accepts only --help and --version, and hence accepts no abbreviations, versus those that accept at least one more long option, which do provide the feature. Also, it'd mean adding a third option would have the side effect of enabling --h and --v recognition. > $ src/basename --oops > src/basename: invalid option -- - > Try `src/basename --help' for more information. > $ src/basename --help me > src/basename: invalid option -- - > Try `src/basename --help' for more information. > $ src/basename --hel > src/basename: invalid option -- - > Try `src/basename --help' for more information. > $ src/basename --help | head -n2 > Usage: src/basename NAME [SUFFIX] > or: src/basename OPTION > $ src/echo --he > --he > > In other words, most programs will treat --h identically to --oops, > diagnosing it as an invalid option (since the application only takes one > of two specific options), and exceptional programs, like echo or [, which > react differently to invalid options, will react the same way to an > abbreviation as to any other invalid option. BTW, "most" coreutils programs wouldn't be affected. Only those that accept no other long options are affected. In coreutils, it looks like ~28 programs would be affected: $ grep -l long-options.h *.c basename.c chroot.c cksum.c dd.c dirname.c echo.c expr.c getlimits.c hostid.c hostname.c link.c logname.c nice.c nohup.c printenv.c printf.c pwd.c setuidgid.c sleep.c sync.c test.c timeout.c tsort.c unlink.c uptime.c users.c whoami.c yes.c ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: option abbreviation exceptions
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 According to Jim Meyering on 1/10/2009 10:48 AM: > "[" feels like it should be the exception. > I see treating --v like --version as a feature. a typing saver. > But with "[", it's good to minimize the number of strings that > make it act differently. > > Besides, why make everyone type it all out if there's no need? Then maybe the better approach would be adding a parameter to parse_long_options (or rather, creating a new function with an extra parameter, and making parse_long_options default to calling it with the parameter at 0, but make echo and [ call it with the parameter set to 1), where having the parameter set controls whether --h is ignored (the exception, for echo) or treated as an abbreviation (the rule, for things like basename). Or, for echo and [, we could skip parse_long_options altogether, and hardcode this instead: argc == 2 && (STREQ (argv[1], "--help") || STREQ (argv[1], "--version")) > Then you don't have to "know" that a program accepts only > --help and --version, and hence accepts no abbreviations, > versus those that accept at least one more long option, which > do provide the feature. > > Also, it'd mean adding a third option would have > the side effect of enabling --h and --v recognition. That's kind of what happened with expr vs. factor. Since parse_long_options only recognizes exactly one argument as a long option, adding another option already has a side effect: $ src/factor --help | head -n1 Usage: src/factor [NUMBER]... $ src/factor --help --version | head -n1 Usage: src/factor [NUMBER]... $ src/expr --help | head -n1 Usage: src/expr EXPRESSION $ src/expr --help --version | head -n1 src/expr: syntax error expr currently uses parse_long_options, while factor does not; therefore factor is able to handle --help --version while expr is not. Maybe parse_long_options should be taught to recognize multiple options that all match an abbreviation of --help/--version, rather than expecting exactly one option? - -- Don't work too hard, make some time for fun as well! Eric Blake e...@byu.net -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.9 (Cygwin) Comment: Public key at home.comcast.net/~ericblake/eblake.gpg Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAklo4Y0ACgkQ84KuGfSFAYAkwwCcDzAlg75YBcUhuyPnkJ3oQKRb REkAn0ZCjFU2Wpe76N93RdtH7e/bJ+b/ =zkiz -END PGP SIGNATURE- ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: option abbreviation exceptions
Eric Blake wrote: > According to Jim Meyering on 1/10/2009 10:48 AM: >> "[" feels like it should be the exception. >> I see treating --v like --version as a feature. a typing saver. >> But with "[", it's good to minimize the number of strings that >> make it act differently. >> >> Besides, why make everyone type it all out if there's no need? > > Then maybe the better approach would be adding a parameter to > parse_long_options (or rather, creating a new function with an extra > parameter, and making parse_long_options default to calling it with the > parameter at 0, but make echo and [ call it with the parameter set to 1), > where having the parameter set controls whether --h is ignored (the > exception, for echo) or treated as an abbreviation (the rule, for things > like basename). > > Or, for echo and [, we could skip parse_long_options altogether, and > hardcode this instead: > > argc == 2 && (STREQ (argv[1], "--help") || STREQ (argv[1], "--version")) One of those approaches would be good. Whichever you prefer. >> Then you don't have to "know" that a program accepts only >> --help and --version, and hence accepts no abbreviations, >> versus those that accept at least one more long option, which >> do provide the feature. >> >> Also, it'd mean adding a third option would have >> the side effect of enabling --h and --v recognition. > > That's kind of what happened with expr vs. factor. Since > parse_long_options only recognizes exactly one argument as a long option, > adding another option already has a side effect: > > $ src/factor --help | head -n1 > Usage: src/factor [NUMBER]... > $ src/factor --help --version | head -n1 > Usage: src/factor [NUMBER]... > $ src/expr --help | head -n1 > Usage: src/expr EXPRESSION > $ src/expr --help --version | head -n1 > src/expr: syntax error > > expr currently uses parse_long_options, while factor does not; therefore > factor is able to handle --help --version while expr is not. I see it the other way ;-) factor mistakenly accepts the combination of --help --version. Actually, I see a small problem: factor doesn't document in --help output the relatively new --verbose option. And expr is similar to test and "[" in accepting arbitrary strings, so it minimizes the impact of accepting --help and --version. > Maybe parse_long_options should be taught to recognize multiple options > that all match an abbreviation of --help/--version, rather than expecting > exactly one option? I think of --help and --version are exclusive, since by definition each prints something and exits. So it doesn't make sense to use them together. ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: option abbreviation exceptions
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 According to Jim Meyering on 1/10/2009 2:32 PM: >>> "[" feels like it should be the exception. >>> I see treating --v like --version as a feature. a typing saver. >>> But with "[", it's good to minimize the number of strings that >>> make it act differently. >>> >> >> Or, for echo and [, we could skip parse_long_options altogether, and >> hardcode this instead: >> >> argc == 2 && (STREQ (argv[1], "--help") || STREQ (argv[1], "--version")) > > One of those approaches would be good. > Whichever you prefer. How about this patch for test/[, echo, and printf? Note that true (and false) already did this exact approach. And for all other applications, it makes sense to use parse_long_options (and allow abbreviations). I went ahead and pushed this to the next branch, to make it easier to test. Since that branch is subject to rebasing, we can remove (or rework) this patch as needed before making it official. - -- Don't work too hard, make some time for fun as well! Eric Blake e...@byu.net -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.9 (Cygwin) Comment: Public key at home.comcast.net/~ericblake/eblake.gpg Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAklt6RgACgkQ84KuGfSFAYDyYwCfZhI6SpvterrL+kGAag/Bd79T IGoAoKIdjUe0UfpSWUnflR0GQ52sSo6I =uEoe -END PGP SIGNATURE- >From 051319cc37fda1ca25d1db56c93ccc531e868496 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Tue, 13 Jan 2009 21:59:35 -0700 Subject: [PATCH] test, echo, printf: don't accept option abbreviation * src/test.c (main): Directly parse accepted options, thus avoiding abbreviations. * src/echo.c (main): Likewise. * src/printf.c (main): Likewise. --- src/echo.c | 19 +++ src/printf.c | 18 +++--- src/test.c | 27 ++- 3 files changed, 48 insertions(+), 16 deletions(-) diff --git a/src/echo.c b/src/echo.c index d549cda..caa231b 100644 --- a/src/echo.c +++ b/src/echo.c @@ -1,5 +1,5 @@ /* echo.c, derived from code echo.c in Bash. - Copyright (C) 87,89, 1991-1997, 1999-2005, 2007-2008 Free Software + Copyright (C) 87,89, 1991-1997, 1999-2005, 2007-2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -121,9 +121,20 @@ main (int argc, char **argv) atexit (close_stdout); - if (allow_options) -parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version, - usage, AUTHORS, (char const *) NULL); + /* We directly parse options, rather than use parse_long_options, in + order to avoid accepting abbreviations. */ + if (allow_options && argc == 2) +{ + if (STREQ (argv[1], "--help")) + usage (EXIT_SUCCESS); + + if (STREQ (argv[1], "--version")) + { + version_etc (stdout, PROGRAM_NAME, PACKAGE_NAME, Version, AUTHORS, + (char *) NULL); + exit (EXIT_SUCCESS); + } +} --argc; ++argv; diff --git a/src/printf.c b/src/printf.c index c509951..63351f0 100644 --- a/src/printf.c +++ b/src/printf.c @@ -1,5 +1,5 @@ /* printf - format and print data - Copyright (C) 1990-2008 Free Software Foundation, Inc. + Copyright (C) 1990-2009 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 @@ -645,8 +645,20 @@ main (int argc, char **argv) posixly_correct = (getenv ("POSIXLY_CORRECT") != NULL); - parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version, - usage, AUTHORS, (char const *) NULL); + /* We directly parse options, rather than use parse_long_options, in + order to avoid accepting abbreviations. */ + if (argc == 2) +{ + if (STREQ (argv[1], "--help")) + usage (EXIT_SUCCESS); + + if (STREQ (argv[1], "--version")) + { + version_etc (stdout, PROGRAM_NAME, PACKAGE_NAME, Version, AUTHORS, + (char *) NULL); + exit (EXIT_SUCCESS); + } +} /* The above handles --help and --version. Since there is no other invocation of getopt, handle `--' here. */ diff --git a/src/test.c b/src/test.c index 14d20fd..c56ab9e 100644 --- a/src/test.c +++ b/src/test.c @@ -2,7 +2,7 @@ /* Modified to run with the GNU shell by bfox. */ -/* Copyright (C) 1987-2005, 2007-2008 Free Software Foundation, Inc. +/* Copyright (C) 1987-2005, 2007-2009 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 @@ -819,16 +819,25 @@ main (int margc, char **margv) if (LBRACKET) { /* Recognize --help or --version, but only when invoked in the -"[" form, and when the last argument is not "]". POSIX -allows "[ --help" and "[ --version" to have the usual GNU -
Re: option abbreviation exceptions
Eric Blake wrote: > According to Jim Meyering on 1/10/2009 2:32 PM: "[" feels like it should be the exception. I see treating --v like --version as a feature. a typing saver. But with "[", it's good to minimize the number of strings that make it act differently. >>> >>> Or, for echo and [, we could skip parse_long_options altogether, and >>> hardcode this instead: >>> >>> argc == 2 && (STREQ (argv[1], "--help") || STREQ (argv[1], "--version")) >> >> One of those approaches would be good. >> Whichever you prefer. > > How about this patch for test/[, echo, and printf? Note that true (and > false) already did this exact approach. And for all other applications, > it makes sense to use parse_long_options (and allow abbreviations). > > I went ahead and pushed this to the next branch, to make it easier to > test. Since that branch is subject to rebasing, we can remove (or rework) > this patch as needed before making it official. Thanks! That change looks fine. I thought about NEWS, but it's not warranted, since these are all shell built-in commands, and I suspect that only command-line users would ever use abbreviated --version and --help options with them. ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils