[libvirt] [PATCH 1/2 v2]virsh: introduce member excludeOption in vshCmdOptDef and improve auto complete with it

Chen Hanxiao chenhanxiao at cn.fujitsu.com
Tue Oct 29 04:08:10 UTC 2013


From: Chen Hanxiao <chenhanxiao at cn.fujitsu.com>

If we need to exclude one parameters from another,
we could use this member to specify one.

With this flag, we could archive what Eric comment on:
https://www.redhat.com/archives/libvir-list/2013-October/msg00965.html
1. COMMAND <TAB> or COMMAND --<TAB>
Auto complete will NOT show option that marked as VSH_OT_ALIAS
2. COMMAND --sh<TAB>
Auto complete will show --shareable
(this one was marked as VSH_OT_ALIAS)
3. COMMAND --mode XXX <TAB> or COMMAND --mode XXX --sh<TAB>
Auto complete will NOT show --shareable
(we set new member exclude_option for mode)
4. COMMAND --shareable --mo<TAB>
Auto complete will NOT show --mode
(we set new member exclude_option for mode)

Signed-off-by: Chen Hanxiao <chenhanxiao at cn.fujitsu.com>
---
v2:
use camelCase for struct members
enable excludeOption to hold more than one options by
a comma seperated string.

 tools/virsh.c | 34 ++++++++++++++++++++++++++++++++++
 tools/virsh.h |  1 +
 2 files changed, 35 insertions(+)

diff --git a/tools/virsh.c b/tools/virsh.c
index bad78c9..f26e567 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -2686,11 +2686,16 @@ vshReadlineOptionsGenerator(const char *text, int state)
     static int list_index, len;
     static const vshCmdDef *cmd = NULL;
     const char *name;
+    size_t size_opt = 0;
+    static char *excludeStr = NULL;
+    char *tmp_str = NULL;
+    const char *excludeOption;
 
     if (!state) {
         /* determine command name */
         char *p;
         char *cmdname;
+        size_t length = 0;
 
         if (!(p = strchr(rl_line_buffer, ' ')))
             return NULL;
@@ -2698,7 +2703,29 @@ vshReadlineOptionsGenerator(const char *text, int state)
         cmdname = vshCalloc(NULL, (p - rl_line_buffer) + 1, 1);
         memcpy(cmdname, rl_line_buffer, p - rl_line_buffer);
 
+        /* collect exclude options */
+        VIR_FREE(excludeStr);
         cmd = vshCmddefSearch(cmdname);
+        while ((name = cmd->opts[size_opt].name)) {
+            if ((strstr(rl_line_buffer, name)) &&
+                 (excludeOption = cmd->opts[size_opt].excludeOption)) {
+                if (excludeStr)
+                    length = strlen(excludeStr) + 2;
+
+                tmp_str = vshCalloc(NULL, length + strlen(excludeOption) + 2, 1);
+
+                if (excludeStr) {
+                    memcpy(tmp_str, excludeStr, length - 2);
+                    strcat(tmp_str, ",");
+                }
+                strcat(tmp_str, excludeOption);
+                excludeStr = vshStrdup(NULL, tmp_str);
+                VIR_FREE(tmp_str);
+                length = 0;
+            }
+            size_opt++;
+        }
+
         list_index = 0;
         len = strlen(text);
         VIR_FREE(cmdname);
@@ -2720,6 +2747,13 @@ vshReadlineOptionsGenerator(const char *text, int state)
             /* ignore non --option */
             continue;
 
+        if (len == 2 && opt->type == VSH_OT_ALIAS)
+            continue;
+
+        /* ignore confict options */
+        if ((excludeStr) &&(strstr(excludeStr, name)))
+            continue;
+
         if (len > 2) {
             if (STRNEQLEN(name, text + 2, len - 2))
                 continue;
diff --git a/tools/virsh.h b/tools/virsh.h
index b843788..c916911 100644
--- a/tools/virsh.h
+++ b/tools/virsh.h
@@ -173,6 +173,7 @@ struct _vshCmdOptDef {
                                  * the name of a later public option */
     vshCompleter completer;         /* option completer */
     unsigned int completer_flags;   /* option completer flags */
+    const char *excludeOption;    /* check the exclusion of option, string seperate by ',' */
 };
 
 /*
-- 
1.8.2.1




More information about the libvir-list mailing list