From 53531e16bf7cfe4fe20a4fe132f8199dcd474245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1n=20Tomko?= Date: Mon, 29 Apr 2013 19:12:17 +0200 Subject: [PATCH] virsh: fix incorrect argument errors for long options For long options, print: * the option as specified by the user if it's unknown * the canonical long option if its argument is not a number (and should be) And for missing arguments, print both the short and the long option name. (Doing only one of those would require either parsing argv ourselves or let getopt print the errors, since we can't tell long and short options apart by optopt or longindex) https://bugzilla.redhat.com/show_bug.cgi?id=949373 Unsupported long option: $ virsh --pm Before: error: unsupported option '- After: error: unsupported option '--pm'. See --help. Missing parameter: $ virsh --deb Before: error: option '-d' requires an argument After: error: option '-d'/'--debug' requires an argument $ virsh -rd Before: error: option '-d' requires an argument After: error: option '-d'/'--debug' requires an argument Non-numeric parameter: $ virsh --deb duck Before: error: option -d takes a numeric argument After: error: option --debug takes a numeric argument --- tools/virsh.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index 6ec2f7b807..ac86608a1a 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -2978,7 +2978,8 @@ vshAllowedEscapeChar(char c) static bool vshParseArgv(vshControl *ctl, int argc, char **argv) { - int arg, len, debug; + int arg, len, debug, i; + int longindex = -1; struct option opt[] = { {"debug", required_argument, NULL, 'd'}, {"help", no_argument, NULL, 'h'}, @@ -2995,11 +2996,12 @@ vshParseArgv(vshControl *ctl, int argc, char **argv) /* Standard (non-command) options. The leading + ensures that no * argument reordering takes place, so that command options are * not confused with top-level virsh options. */ - while ((arg = getopt_long(argc, argv, "+:d:hqtc:vVrl:e:", opt, NULL)) != -1) { + while ((arg = getopt_long(argc, argv, "+:d:hqtc:vVrl:e:", opt, &longindex)) != -1) { switch (arg) { case 'd': if (virStrToLong_i(optarg, NULL, 10, &debug) < 0) { - vshError(ctl, "%s", _("option -d takes a numeric argument")); + vshError(ctl, _("option %s takes a numeric argument"), + longindex == -1 ? "-d" : "--debug"); exit(EXIT_FAILURE); } if (debug < VSH_ERR_DEBUG || debug > VSH_ERR_ERROR) @@ -3050,15 +3052,24 @@ vshParseArgv(vshControl *ctl, int argc, char **argv) } break; case ':': - vshError(ctl, _("option '-%c' requires an argument"), optopt); - exit(EXIT_FAILURE); + for (i = 0; opt[i].name != NULL; i++) { + if (opt[i].val == optopt) { + vshError(ctl, _("option '-%c'/'--%s' requires an argument"), + optopt, opt[i].name); + exit(EXIT_FAILURE); + } + } case '?': - vshError(ctl, _("unsupported option '-%c'. See --help."), optopt); + if (optopt) + vshError(ctl, _("unsupported option '-%c'. See --help."), optopt); + else + vshError(ctl, _("unsupported option '%s'. See --help."), argv[optind - 1]); exit(EXIT_FAILURE); default: vshError(ctl, _("unknown option")); exit(EXIT_FAILURE); } + longindex = -1; } if (argc > optind) {