mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-09-09 09:14:57 +00:00
virsh: simplify top-level option parsing
This makes 'virsh --conn test:///default help help' work right; previously, the abbreviation confused our hand-rolled option parsing. * tools/virsh.c (vshParseArgv): Use getopt_long feature, rather than (incorrectly) reparsing options ourselves.
This commit is contained in:
parent
227f5df842
commit
5405cffcb4
@ -11138,9 +11138,8 @@ vshUsage(void)
|
|||||||
static int
|
static int
|
||||||
vshParseArgv(vshControl *ctl, int argc, char **argv)
|
vshParseArgv(vshControl *ctl, int argc, char **argv)
|
||||||
{
|
{
|
||||||
char *last = NULL;
|
bool help = false;
|
||||||
int i, end = 0, help = 0;
|
int arg;
|
||||||
int arg, idx = 0;
|
|
||||||
struct option opt[] = {
|
struct option opt[] = {
|
||||||
{"debug", 1, 0, 'd'},
|
{"debug", 1, 0, 'd'},
|
||||||
{"help", 0, 0, 'h'},
|
{"help", 0, 0, 'h'},
|
||||||
@ -11153,46 +11152,10 @@ vshParseArgv(vshControl *ctl, int argc, char **argv)
|
|||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Standard (non-command) options. The leading + ensures that no
|
||||||
if (argc < 2)
|
* argument reordering takes place, so that command options are
|
||||||
return TRUE;
|
* not confused with top-level virsh options. */
|
||||||
|
while ((arg = getopt_long(argc, argv, "+d:hqtc:vrl:", opt, NULL)) != -1) {
|
||||||
/* look for begin of the command, for example:
|
|
||||||
* ./virsh --debug 5 -q command --cmdoption
|
|
||||||
* <--- ^ --->
|
|
||||||
* getopt() stuff | command suff
|
|
||||||
*/
|
|
||||||
for (i = 1; i < argc; i++) {
|
|
||||||
if (*argv[i] != '-') {
|
|
||||||
int valid = FALSE;
|
|
||||||
|
|
||||||
/* non "--option" argv, is it command? */
|
|
||||||
if (last) {
|
|
||||||
struct option *o;
|
|
||||||
int sz = strlen(last);
|
|
||||||
|
|
||||||
for (o = opt; o->name; o++) {
|
|
||||||
if (o->has_arg == 1){
|
|
||||||
if (sz == 2 && *(last + 1) == o->val)
|
|
||||||
/* valid virsh short option */
|
|
||||||
valid = TRUE;
|
|
||||||
else if (sz > 2 && STREQ(o->name, last + 2))
|
|
||||||
/* valid virsh long option */
|
|
||||||
valid = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!valid) {
|
|
||||||
end = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
last = argv[i];
|
|
||||||
}
|
|
||||||
end = end ? end : argc;
|
|
||||||
|
|
||||||
/* standard (non-command) options */
|
|
||||||
while ((arg = getopt_long(end, argv, "d:hqtc:vrl:", opt, &idx)) != -1) {
|
|
||||||
switch (arg) {
|
switch (arg) {
|
||||||
case 'd':
|
case 'd':
|
||||||
if (virStrToLong_i(optarg, NULL, 10, &ctl->debug) < 0) {
|
if (virStrToLong_i(optarg, NULL, 10, &ctl->debug) < 0) {
|
||||||
@ -11201,7 +11164,7 @@ vshParseArgv(vshControl *ctl, int argc, char **argv)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
help = 1;
|
help = true;
|
||||||
break;
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
ctl->quiet = TRUE;
|
ctl->quiet = TRUE;
|
||||||
@ -11213,7 +11176,8 @@ vshParseArgv(vshControl *ctl, int argc, char **argv)
|
|||||||
ctl->name = vshStrdup(ctl, optarg);
|
ctl->name = vshStrdup(ctl, optarg);
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
fprintf(stdout, "%s\n", VERSION);
|
/* FIXME - list a copyright blurb, as in GNU programs? */
|
||||||
|
puts(VERSION);
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
case 'r':
|
case 'r':
|
||||||
ctl->readonly = TRUE;
|
ctl->readonly = TRUE;
|
||||||
@ -11228,8 +11192,8 @@ vshParseArgv(vshControl *ctl, int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (help) {
|
if (help) {
|
||||||
if (end < argc) {
|
if (optind < argc) {
|
||||||
vshError(ctl, _("extra argument '%s'. See --help."), argv[end]);
|
vshError(ctl, _("extra argument '%s'. See --help."), argv[optind]);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11238,14 +11202,14 @@ vshParseArgv(vshControl *ctl, int argc, char **argv)
|
|||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc > end) {
|
if (argc > optind) {
|
||||||
/* parse command */
|
/* parse command */
|
||||||
ctl->imode = FALSE;
|
ctl->imode = FALSE;
|
||||||
if (argc - end == 1) {
|
if (argc - optind == 1) {
|
||||||
vshDebug(ctl, 2, "commands: \"%s\"\n", argv[end]);
|
vshDebug(ctl, 2, "commands: \"%s\"\n", argv[optind]);
|
||||||
return vshCommandStringParse(ctl, argv[end]);
|
return vshCommandStringParse(ctl, argv[optind]);
|
||||||
} else {
|
} else {
|
||||||
return vshCommandArgvParse(ctl, argc - end, argv + end);
|
return vshCommandArgvParse(ctl, argc - optind, argv + optind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
Loading…
Reference in New Issue
Block a user