all: output full usage only when requested via the --help option

When there are invalid options or arguments, all utilities printed the
full usage in addition to the original error diagnostic.  The quite
large text distracted the user's attention from the error message.

* find/defs.h (usage): Mark as _GL_ATTRIBUTE_NORETURN, and remove the
arguments FP and MSG.
* find/parser.c (parse_help): Factor out the usage text from here ...
* find/util.c (usage): ... to here.  Unless called with EXIT_SUCCESS,
just emit a short hint to try again with the --help option rather than
emitting the full usage.  Afterward, exit the program with the given
status.
(debugassoc): Sort array, as it is used in that order when outputting
the usage text.
(process_debug_options): Also output an error diagnostic when no
argument to -D is passed.
(show_valid_options): Always output to stdout, always output the header
line.  Update all callers.
* find/tree.c (build_expression): Update invocation of usage().
Also call it for syntax errors like unknown or invalid predicates
or invalid or missing arguments.
* locate/frcode.c (usage): Similar to the change in util.c (usage).
(main): Update invocation of usage().  Also output an error diagnostic
when an unexpected argument is passed.
* locate/locate.c (usage):  Similar to the change in util.c (usage).
(dolocate): Update invocation of usage().  Also output an error
diagnostic when an unexpected argument is passed.
* locate/updatedb.sh: Output "Try ... --help ..." when an invalid option
is passed.
* xargs/xargs.c (usage): Similar to the change in util.c (usage).
(parse_num, main): Update all callers, removing the now-obsolete
return or exit().
* NEWS (Improvements): Mention the change.
This commit is contained in:
Bernhard Voelker 2016-02-16 23:33:22 +01:00
parent 06c72d9009
commit 894d806c6c
9 changed files with 139 additions and 108 deletions

7
NEWS
View File

@ -20,6 +20,13 @@ database is now different to previous versions. However, you should
not rely on locate's output appearing in any particular order in any
case.
** Improvements
All utilities now only show the full usage text when requested via
the --help option. Previously, when the user passed invalid options
or arguments, the user's attention to the corresponding error
diagnostic was distracted by that lengthy text.
** Translations
Updated translations: Hungarian, Slovak, Dutch, German, Danish.

View File

@ -482,7 +482,7 @@ bool fd_leak_check_is_enabled (void);
struct predicate *insert_primary (const struct parser_table *entry, const char *arg);
struct predicate *insert_primary_noarg (const struct parser_table *entry);
struct predicate *insert_primary_withpred (const struct parser_table *entry, PRED_FUNC fptr, const char *arg);
void usage (FILE *fp, int status, char *msg);
void usage (int status) _GL_ATTRIBUTE_NORETURN;
extern bool check_nofollow(void);
void complete_pending_execs(struct predicate *p);
void complete_pending_execdirs (void);

View File

@ -1233,39 +1233,7 @@ parse_help (const struct parser_table* entry, char **argv, int *arg_ptr)
(void) argv;
(void) arg_ptr;
usage (stdout, 0, NULL);
puts (_("\n\
default path is the current directory; default expression is -print\n\
expression may consist of: operators, options, tests, and actions:\n"));
puts (_("\
operators (decreasing precedence; -and is implicit where no others are given):\n\
( EXPR ) ! EXPR -not EXPR EXPR1 -a EXPR2 EXPR1 -and EXPR2\n\
EXPR1 -o EXPR2 EXPR1 -or EXPR2 EXPR1 , EXPR2\n"));
puts (_("\
positional options (always true): -daystart -follow -regextype\n\n\
normal options (always true, specified before other expressions):\n\
-depth --help -maxdepth LEVELS -mindepth LEVELS -mount -noleaf\n\
--version -xdev -ignore_readdir_race -noignore_readdir_race\n"));
puts (_("\
tests (N can be +N or -N or N): -amin N -anewer FILE -atime N -cmin N\n\
-cnewer FILE -ctime N -empty -false -fstype TYPE -gid N -group NAME\n\
-ilname PATTERN -iname PATTERN -inum N -iwholename PATTERN -iregex PATTERN\n\
-links N -lname PATTERN -mmin N -mtime N -name PATTERN -newer FILE"));
puts (_("\
-nouser -nogroup -path PATTERN -perm [-/]MODE -regex PATTERN\n\
-readable -writable -executable\n\
-wholename PATTERN -size N[bcwkMG] -true -type [bcdpflsD] -uid N\n\
-used N -user NAME -xtype [bcdpfls]"));
puts (_("\
-context CONTEXT\n"));
puts (_("\n\
actions: -delete -print0 -printf FORMAT -fprintf FILE FORMAT -print \n\
-fprint0 FILE -fprint FILE -ls -fls FILE -prune -quit\n\
-exec COMMAND ; -exec COMMAND {} + -ok COMMAND ;\n\
-execdir COMMAND ; -execdir COMMAND {} + -okdir COMMAND ;\n\
"));
explain_how_to_report_bugs (stdout, program_name);
exit (EXIT_SUCCESS);
usage (EXIT_SUCCESS);
}
static float

View File

@ -1286,7 +1286,7 @@ build_expression_tree (int argc, char *argv[], int end_of_leading_options)
if (!looks_like_expression (argv[i], false))
{
error (0, 0, _("paths must precede expression: %s"), argv[i]);
usage (stderr, 1, NULL);
usage (EXIT_FAILURE);
}
predicate_name = argv[i];
@ -1294,7 +1294,8 @@ build_expression_tree (int argc, char *argv[], int end_of_leading_options)
if (parse_entry == NULL)
{
/* Command line option not recognized */
error (EXIT_FAILURE, 0, _("unknown predicate `%s'"), predicate_name);
error (0, 0, _("unknown predicate `%s'"), predicate_name);
usage (EXIT_FAILURE);
}
/* We have recognised a test of the form -foo. Eat that,
@ -1314,20 +1315,21 @@ build_expression_tree (int argc, char *argv[], int end_of_leading_options)
/* The special parse function spat out the
* predicate. It must be invalid, or not tasty.
*/
error (EXIT_FAILURE, 0, _("invalid predicate `%s'"),
predicate_name);
error (0, 0, _("invalid predicate `%s'"), predicate_name);
usage (EXIT_FAILURE);
}
else
{
error (EXIT_FAILURE, 0, _("invalid argument `%s' to `%s'"),
error (0, 0, _("invalid argument `%s' to `%s'"),
argv[i], predicate_name);
usage (EXIT_FAILURE);
}
}
else
{
/* Command line option requires an argument */
error (EXIT_FAILURE, 0,
_("missing argument to `%s'"), predicate_name);
error (0, 0, _("missing argument to `%s'"), predicate_name);
usage (EXIT_FAILURE);
}
}
else

View File

@ -61,14 +61,14 @@ struct debug_option_assoc
};
static struct debug_option_assoc debugassoc[] =
{
{ "exec", DebugExec, "Show diagnostic information relating to -exec, -execdir, -ok and -okdir" },
{ "help", DebugHelp, "Explain the various -D options" },
{ "tree", DebugExpressionTree, "Display the expression tree" },
{ "opt", DebugExpressionTree|DebugTreeOpt, "Show diagnostic information relating to optimisation" },
{ "rates", DebugSuccessRates, "Indicate how often each predicate succeeded" },
{ "search",DebugSearch, "Navigate the directory tree verbosely" },
{ "stat", DebugStat, "Trace calls to stat(2) and lstat(2)" },
{ "rates", DebugSuccessRates, "Indicate how often each predicate succeeded" },
{ "opt", DebugExpressionTree|DebugTreeOpt, "Show diagnostic information relating to optimisation" },
{ "exec", DebugExec, "Show diagnostic information relating to -exec, -execdir, -ok and -okdir" },
{ "time", DebugTime, "Show diagnostic information relating to time-of-day and timestamp comparisons" }
{ "time", DebugTime, "Show diagnostic information relating to time-of-day and timestamp comparisons" },
{ "tree", DebugExpressionTree, "Display the expression tree" }
};
#define N_DEBUGASSOC (sizeof(debugassoc)/sizeof(debugassoc[0]))
@ -138,15 +138,15 @@ insert_primary_noarg (const struct parser_table *entry)
static void
show_valid_debug_options (FILE *fp, int full)
show_valid_debug_options (int full)
{
size_t i;
fputs (_("Valid arguments for -D:\n"), stdout);
if (full)
{
fprintf (fp, "Valid arguments for -D:\n");
for (i=0; i<N_DEBUGASSOC; ++i)
{
fprintf (fp, "%-10s %s\n",
fprintf (stdout, "%-10s %s\n",
debugassoc[i].name,
debugassoc[i].docstring);
}
@ -155,22 +155,64 @@ show_valid_debug_options (FILE *fp, int full)
{
for (i=0; i<N_DEBUGASSOC; ++i)
{
fprintf (fp, "%s%s", (i>0 ? "|" : ""), debugassoc[i].name);
fprintf (stdout, "%s%s", (i>0 ? ", " : ""), debugassoc[i].name);
}
}
}
void
usage (FILE *fp, int status, char *msg)
usage (int status)
{
if (msg)
fprintf (fp, "%s: %s\n", program_name, msg);
if (status != EXIT_SUCCESS)
{
fprintf (stderr, _("Try '%s --help' for more information.\n"), program_name);
exit (status);
}
fprintf (fp, _("Usage: %s [-H] [-L] [-P] [-Olevel] [-D "), program_name);
show_valid_debug_options (fp, 0);
fprintf (fp, _("] [path...] [expression]\n"));
if (0 != status)
exit (status);
#define HTL(t) fputs (t, stdout);
fprintf (stdout, _("\
Usage: %s [-H] [-L] [-P] [-Olevel] [-D debugopts] [path...] [expression]\n"),
program_name);
HTL (_("\n\
default path is the current directory; default expression is -print\n\
expression may consist of: operators, options, tests, and actions:\n"));
HTL (_("\
operators (decreasing precedence; -and is implicit where no others are given):\n\
( EXPR ) ! EXPR -not EXPR EXPR1 -a EXPR2 EXPR1 -and EXPR2\n\
EXPR1 -o EXPR2 EXPR1 -or EXPR2 EXPR1 , EXPR2\n"));
HTL (_("\
positional options (always true): -daystart -follow -regextype\n\n\
normal options (always true, specified before other expressions):\n\
-depth --help -maxdepth LEVELS -mindepth LEVELS -mount -noleaf\n\
--version -xdev -ignore_readdir_race -noignore_readdir_race\n"));
HTL (_("\
tests (N can be +N or -N or N): -amin N -anewer FILE -atime N -cmin N\n\
-cnewer FILE -ctime N -empty -false -fstype TYPE -gid N -group NAME\n\
-ilname PATTERN -iname PATTERN -inum N -iwholename PATTERN -iregex PATTERN\n\
-links N -lname PATTERN -mmin N -mtime N -name PATTERN -newer FILE"));
HTL (_("\n\
-nouser -nogroup -path PATTERN -perm [-/]MODE -regex PATTERN\n\
-readable -writable -executable\n\
-wholename PATTERN -size N[bcwkMG] -true -type [bcdpflsD] -uid N\n\
-used N -user NAME -xtype [bcdpfls]"));
HTL (_("\
-context CONTEXT\n"));
HTL (_("\n\
actions: -delete -print0 -printf FORMAT -fprintf FILE FORMAT -print \n\
-fprint0 FILE -fprint FILE -ls -fls FILE -prune -quit\n\
-exec COMMAND ; -exec COMMAND {} + -ok COMMAND ;\n\
-execdir COMMAND ; -execdir COMMAND {} + -okdir COMMAND ;\n\
\n"));
show_valid_debug_options (0);
HTL (_("\n\
Use '-D help' for a description of the options, or see find(1)\n\
\n"));
explain_how_to_report_bugs (stdout, program_name);
exit (status);
}
void
@ -827,11 +869,12 @@ process_debug_options (char *arg)
}
if (empty)
{
error(EXIT_FAILURE, 0, _("Empty argument to the -D option."));
error (0, 0, _("Empty argument to the -D option."));
usage (EXIT_FAILURE);
}
else if (options.debug_options & DebugHelp)
{
show_valid_debug_options (stdout, 1);
show_valid_debug_options (1);
exit (EXIT_SUCCESS);
}
}

View File

@ -88,6 +88,7 @@
#include "findutils-version.h"
#include "bugreports.h"
#include "locatedb.h"
#include "gcc-function-attributes.h"
#if ENABLE_NLS
# include <libintl.h>
@ -142,13 +143,21 @@ static struct option const longopts[] =
extern char *version_string;
static void
usage (FILE *stream)
static void _GL_ATTRIBUTE_NORETURN
usage (int status)
{
fprintf (stream,
if (status != EXIT_SUCCESS)
{
fprintf (stderr, _("Try '%s --help' for more information.\n"), program_name);
exit (status);
}
fprintf (stdout,
_("Usage: %s [-0 | --null] [--version] [--help]\n"),
program_name);
explain_how_to_report_bugs (stream, program_name);
explain_how_to_report_bugs (stdout, program_name);
exit (status);
}
static long
@ -157,8 +166,8 @@ get_seclevel (char *s)
long result;
char *p;
/* Reset errno in oreder to be able to distinguish LONG_MAX/LONG_MIN
* from values whichare actually out of range
/* Reset errno in order to be able to distinguish LONG_MAX/LONG_MIN
* from values which are actually out of range.
*/
errno = 0;
@ -249,23 +258,21 @@ main (int argc, char **argv)
break;
case 'h':
usage (stdout);
return 0;
usage (EXIT_SUCCESS);
case 'v':
display_findutils_version ("frcode");
return 0;
default:
usage (stderr);
return 1;
usage (EXIT_FAILURE);
}
/* We expect to have no arguments. */
if (optind != argc)
{
usage (stderr);
return 1;
error (0, 0, _("no argument expected."));
usage (EXIT_FAILURE);
}

View File

@ -100,6 +100,7 @@
#include "printquoted.h"
#include "bugreports.h"
#include "splitstring.h"
#include "gcc-function-attributes.h"
#if ENABLE_NLS
@ -1382,10 +1383,16 @@ search_one_database (int argc,
extern char *version_string;
static void
usage (FILE *stream)
static void _GL_ATTRIBUTE_NORETURN
usage (int status)
{
fprintf (stream, _("\
if (status != EXIT_SUCCESS)
{
fprintf (stderr, _("Try '%s --help' for more information.\n"), program_name);
exit (status);
}
fprintf (stdout, _("\
Usage: %s [-d path | --database=path] [-e | -E | --[non-]existing]\n\
[-i | --ignore-case] [-w | --wholename] [-b | --basename] \n\
[--limit=N | -l N] [-S | --statistics] [-0 | --null] [-c | --count]\n\
@ -1394,8 +1401,11 @@ Usage: %s [-d path | --database=path] [-e | -E | --[non-]existing]\n\
[--max-database-age D] [--version] [--help]\n\
pattern...\n"),
program_name);
explain_how_to_report_bugs (stdout, program_name);
exit (status);
}
enum
{
REGEXTYPE_OPTION = CHAR_MAX + 1,
@ -1642,8 +1652,7 @@ dolocate (int argc, char **argv, int secure_db_fd)
break;
case 'h':
usage (stdout);
return 0;
usage (EXIT_SUCCESS);
case MAX_DB_AGE:
/* XXX: nothing in the test suite for this option. */
@ -1707,8 +1716,7 @@ dolocate (int argc, char **argv, int secure_db_fd)
break;
default:
usage (stderr);
return 1;
usage (EXIT_FAILURE);
}
}
@ -1737,8 +1745,8 @@ dolocate (int argc, char **argv, int secure_db_fd)
{
if (!just_count && optind == argc)
{
usage (stderr);
return 1;
error (0, 0, _("pattern argument expected"));
usage (EXIT_FAILURE);
}
}

View File

@ -84,7 +84,7 @@ do
--version) fail=0; echo "$version" || fail=1; exit $fail ;;
--help) fail=0; echo "$usage" || fail=1; exit $fail ;;
*) echo "updatedb: invalid option $opt
$usage" >&2
Try '$0 --help' for more information." >&2
exit 1 ;;
esac
done

View File

@ -67,6 +67,7 @@
#include "fdleak.h"
#include "bugreports.h"
#include "findutils-version.h"
#include "gcc-function-attributes.h"
#if ENABLE_NLS
# include <libintl.h>
@ -224,7 +225,7 @@ static void wait_for_proc_all (void);
static void increment_proc_max (int);
static void decrement_proc_max (int);
static long parse_num (char *str, int option, long min, long max, int fatal);
static void usage (FILE * stream);
static void usage (int status) _GL_ATTRIBUTE_NORETURN;
static char
@ -532,8 +533,7 @@ main (int argc, char **argv)
break;
case 'h':
usage (stdout);
return 0;
usage (EXIT_SUCCESS);
case 'I': /* POSIX */
case 'i': /* deprecated */
@ -652,8 +652,7 @@ main (int argc, char **argv)
break;
default:
usage (stderr);
return 1;
usage (EXIT_FAILURE);
}
}
@ -1613,7 +1612,7 @@ parse_num (char *str, int option, long int min, long int max, int fatal)
{
fprintf (stderr, _("%s: invalid number \"%s\" for -%c option\n"),
program_name, str, option);
usage (stderr);
usage (EXIT_FAILURE);
exit (EXIT_FAILURE);
}
else if (val < min)
@ -1621,40 +1620,36 @@ parse_num (char *str, int option, long int min, long int max, int fatal)
fprintf (stderr, _("%s: value %s for -%c option should be >= %ld\n"),
program_name, str, option, min);
if (fatal)
{
usage (stderr);
exit (EXIT_FAILURE);
}
else
{
val = min;
}
usage (EXIT_FAILURE);
val = min;
}
else if (max >= 0 && val > max)
{
fprintf (stderr, _("%s: value %s for -%c option should be <= %ld\n"),
program_name, str, option, max);
if (fatal)
{
usage (stderr);
exit (EXIT_FAILURE);
}
else
{
val = max;
}
usage (EXIT_FAILURE);
val = max;
}
return val;
}
static void
usage (FILE *stream)
usage (int status)
{
fprintf (stream,
if (status != EXIT_SUCCESS)
{
fprintf (stderr, _("Try '%s --help' for more information.\n"), program_name);
exit (status);
}
fprintf (stdout,
_("Usage: %s [OPTION]... COMMAND [INITIAL-ARGS]...\n"),
program_name);
#define HTL(t) fputs (t, stream);
#define HTL(t) fputs (t, stdout);
HTL (_("Run COMMAND with arguments INITIAL-ARGS and more arguments read from input.\n"
"\n"));
@ -1694,5 +1689,6 @@ usage (FILE *stream)
HTL (_(" --help display this help and exit\n"));
HTL (_(" --version output version information and exit\n\n"));
explain_how_to_report_bugs (stream, program_name);
explain_how_to_report_bugs (stdout, program_name);
exit (status);
}