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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list