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