On 01/02/2018 12:12 PM, Michal Privoznik wrote: > Similarly to the previous commit, once we've presented an > --option for a command to the user it makes no sense to offer it > again. Therefore, we can prune all already specified options. For > instance, after this patch: > > virsh # migrate --verbose <TAB><TAB> > > will no longer offer --verbose option. > > Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> > --- > tools/vsh.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 59 insertions(+), 1 deletion(-) > > diff --git a/tools/vsh.c b/tools/vsh.c > index 49e8033bd..f061783e0 100644 > --- a/tools/vsh.c > +++ b/tools/vsh.c > @@ -2769,6 +2769,60 @@ vshCompleterFilter(char ***list, > } > > > +static int > +vshReadlineOptionsPrune(char ***list, > + vshCmd *last) > +{ > + char **newList = NULL; > + size_t newList_len = 0; > + size_t list_len; > + size_t i; > + > + if (!list || !*list) > + return -1; > + > + if (!last->opts) > + return 0; > + > + list_len = virStringListLength((const char **) *list); > + > + if (VIR_ALLOC_N(newList, list_len + 1) < 0) > + return -1; > + > + for (i = 0; i < list_len; i++) { > + const char *list_opt = STRSKIP((*list)[i], "--"); > + bool exist = false; > + vshCmdOpt *opt = last->opts; > + > + /* Should never happen (TM) */ > + if (!list_opt) > + return -1; But if it does, then you'll lean newList As reported by everyone's favorite tool! John > + > + while (opt) { > + if (STREQ(opt->def->name, list_opt)) { > + exist = true; > + break; > + } > + > + opt = opt->next; > + } > + > + if (exist) { > + VIR_FREE((*list)[i]); > + continue; > + } > + > + VIR_STEAL_PTR(newList[newList_len], (*list)[i]); > + newList_len++; > + } > + > + ignore_value(VIR_REALLOC_N_QUIET(newList, newList_len + 1)); > + VIR_FREE(*list); > + *list = newList; > + return 0; > +} > + > + > static char * > vshReadlineParse(const char *text, int state) > { > @@ -2817,9 +2871,13 @@ vshReadlineParse(const char *text, int state) > if (!cmd) { > list = vshReadlineCommandGenerator(text); > } else { > - if (!opt || opt->type != VSH_OT_DATA) > + if (!opt || opt->type != VSH_OT_DATA) { > list = vshReadlineOptionsGenerator(text, cmd); > > + if (vshReadlineOptionsPrune(&list, partial) < 0) > + goto cleanup; > + } > + > if (opt && opt->completer) { > char **completer_list = opt->completer(autoCompleteOpaque, > partial, > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list