[libvirt] [PATCH 5/5] Improve virsh autocompletion (enum completer macro)

Solly Ross sross at redhat.com
Sun Mar 30 02:36:13 UTC 2014


This patch adds a utility macro which generates completers
for enum-type string options (i.e. those options which may
be one of a static set of strings).

Instead of having to manually implement a completers for such
options, the macro may be used as such:
`VSH_STRING_COMPLETER(ctl, SomeOption, "string1", "string2")`,
which generates a method `vshCompleteSomeOption` which returns
"string 1" and "string 2" as completion option.  The macro will
work with up to 63 different strings.
---
 tools/virsh-completer.c | 23 ++++++++++++++++++++++-
 tools/virsh-completer.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/tools/virsh-completer.c b/tools/virsh-completer.c
index fedf52b..2b32dd9 100644
--- a/tools/virsh-completer.c
+++ b/tools/virsh-completer.c
@@ -21,9 +21,31 @@
 #include <config.h>
 #include "virsh-completer.h"
 
+#include <stdarg.h>
+
 #include "conf/domain_conf.h"
 #include "viralloc.h"
 
+/* Utils - General */
+char **
+vshVarArgsToStringList(vshControl *ctl, unsigned int count, ...)
+{
+    va_list ap;
+    char **strs;
+
+    if (count == 0)
+        return NULL;
+
+    va_start(ap, count);
+
+    strs = vshCalloc(ctl, count, sizeof(char*));
+    for (int i = 0; i < count; i++)
+        strs[i] = vshStrdup(ctl, va_arg(ap, char*));
+
+    va_end(ap);
+
+    return strs;
+};
 
 /* Utils - Domain Listing */
 /* compare domains, pack NULLed ones at the end*/
@@ -329,4 +351,3 @@ vshCompleteDomain(unsigned int flags)
 
     return names;
 };
-
diff --git a/tools/virsh-completer.h b/tools/virsh-completer.h
index 828669b..7afd7b5 100644
--- a/tools/virsh-completer.h
+++ b/tools/virsh-completer.h
@@ -23,6 +23,53 @@
 
 # include "virsh.h"
 
+/* Utils - General */
+/* __VA_NARGS__:
+ *
+ * This macro determine the length (up to 63) of
+ * __VA_ARGS__ arguments passed to a macro.
+ */
+
+/* inspired by
+ * https://groups.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s */
+# define __VA_NARGS__(...) \
+             __VA_NARGS_FLATTEN__(__VA_ARGS__,INV_NUM_SEQ())
+#define __VA_NARGS_FLATTEN__(...) \
+             __VA_NARGS_IMPL__(__VA_ARGS__)
+#define __VA_NARGS_IMPL__( \
+    _1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16, \
+    _17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
+    _31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44, \
+    _45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58, \
+    _59,_60,_61,_62,_63, N, ...) N
+#define INV_NUM_SEQ() \
+    63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46, \
+    45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28, \
+    27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10, \
+    9,8,7,6,5,4,3,2,1,0
+
+/* VSH_STRING_COMPLETER:
+ *
+ * @ctl: a vshControl* or NULL
+ * @name: the name of the completer (unquoted)
+ * @__VA_ARGS__: the options as strings
+ *
+ * This macro creates a vshComplete[name] function
+ * suitable to for use as a custom option completer.
+ * The completer will return an array of strings with
+ * the values specified.
+ */
+# define VSH_STRING_COMPLETER(ctl, name, ...) \
+    static char ** \
+    vshComplete ## name (unsigned int flags ATTRIBUTE_UNUSED) \
+    { \
+        return vshVarArgsToStringList(ctl, __VA_NARGS__(__VA_ARGS__), \
+                                      __VA_ARGS__); \
+    }
+
+char ** vshVarArgsToStringList(vshControl *ctl, unsigned int count, ...);
+
+/* Utils - Domain */
 struct vshDomainList {
     virDomainPtr *domains;
     size_t ndomains;
@@ -33,7 +80,7 @@ void vshDomainListFree(vshDomainListPtr domlist);
 
 vshDomainListPtr vshDomainListCollect(vshControl *ctl, unsigned int flags);
 
+/* Common Completers */
 char ** vshCompleteDomain(unsigned int flags);
 
 #endif /* VIRSH_COMPLETER_H */
-
-- 
1.8.3.2




More information about the libvir-list mailing list