Introduce a new set of helpers including a new data structure which simplifies keeping and construction of lists of typed parameters. The use of VIR_RESIZE_N in the virTypedParamsAdd API has performance benefits but requires passing around 3 arguments. Use of them lead to a set of macros with embedded jumps used in the qemu statistics code. This patch introduces 'virTypedParamList' type which aggregates the necessary list-keeping variables and also a new set of functions to add new typed parameters to a list. These new helpers use printf-like format string and arguments to format the argument name as the stats code often uses indexed typed parameters. The accessor function then allows extracting the typed parameter list in the same format as virTypedParamsAdd* functions would do. One additional benefit is also that the list function can easily be used with VIR_AUTOPTR. Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx> --- src/libvirt_private.syms | 9 ++ src/util/virtypedparam.c | 222 +++++++++++++++++++++++++++++++++++++++ src/util/virtypedparam.h | 61 +++++++++++ 3 files changed, 292 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 8af9e7c95e..8f6d0492d6 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3232,6 +3232,15 @@ virTypedParameterAssign; virTypedParameterToString; virTypedParameterTypeFromString; virTypedParameterTypeToString; +virTypedParamListAddB; +virTypedParamListAddD; +virTypedParamListAddI; +virTypedParamListAddLL; +virTypedParamListAddS; +virTypedParamListAddUI; +virTypedParamListAddULL; +virTypedParamListFree; +virTypedParamListStealParams; virTypedParamsCheck; virTypedParamsCopy; virTypedParamsDeserialize; diff --git a/src/util/virtypedparam.c b/src/util/virtypedparam.c index 720b88dd10..785495460f 100644 --- a/src/util/virtypedparam.c +++ b/src/util/virtypedparam.c @@ -254,6 +254,23 @@ virTypedParameterAssignValueAP(virTypedParameterPtr param, } +static int +virTypedParameterAssignValue(virTypedParameterPtr param, + bool copystr, + int type, + ...) +{ + int ret; + va_list ap; + + va_start(ap, type); + ret = virTypedParameterAssignValueAP(param, type, ap, copystr); + va_end(ap); + + return ret; +} + + /* Assign name, type, and the appropriately typed arg to param; in the * case of a string, the caller is assumed to have malloc'd a string, * or can pass NULL to have this function malloc an empty string. @@ -725,3 +742,208 @@ virTypedParamsSerialize(virTypedParameterPtr params, virTypedParamsRemoteFree(params_val, nparams); return rv; } + + +void +virTypedParamListFree(virTypedParamListPtr list) +{ + if (!list) + return; + + virTypedParamsFree(list->par, list->npar); + VIR_FREE(list); +} + + +size_t +virTypedParamListStealParams(virTypedParamListPtr list, + virTypedParameterPtr *params) +{ + size_t ret = list->npar; + + VIR_STEAL_PTR(*params, list->par); + list->npar = 0; + list->par_alloc = 0; + + return ret; +} + + +static int ATTRIBUTE_FMT_PRINTF(2, 0) +virTypedParamSetNameVPrintf(virTypedParameterPtr par, + const char *fmt, + va_list ap) +{ + if (vsnprintf(par->field, VIR_TYPED_PARAM_FIELD_LENGTH, fmt, ap) > VIR_TYPED_PARAM_FIELD_LENGTH) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Field name too long")); + return -1; + } + + return 0; +} + + +static virTypedParameterPtr +virTypedParamListExtend(virTypedParamListPtr list) +{ + if (VIR_RESIZE_N(list->par, list->par_alloc, list->npar, 1) < 0) + return NULL; + + list->npar++; + + return list->par + (list->npar - 1); +} + + +int +virTypedParamListAddI(virTypedParamListPtr list, + int value, + const char *namefmt, + ...) +{ + virTypedParameterPtr par; + va_list ap; + int ret; + + if (!(par = virTypedParamListExtend(list)) || + virTypedParameterAssignValue(par, true, VIR_TYPED_PARAM_INT, value) < 0) + return -1; + + va_start(ap, namefmt); + ret = virTypedParamSetNameVPrintf(par, namefmt, ap); + va_end(ap); + + return ret; +} + + +int +virTypedParamListAddUI(virTypedParamListPtr list, + unsigned int value, + const char *namefmt, + ...) +{ + virTypedParameterPtr par; + va_list ap; + int ret; + + if (!(par = virTypedParamListExtend(list)) || + virTypedParameterAssignValue(par, true, VIR_TYPED_PARAM_UINT, value) < 0) + return -1; + + va_start(ap, namefmt); + ret = virTypedParamSetNameVPrintf(par, namefmt, ap); + va_end(ap); + + return ret; +} + + +int +virTypedParamListAddLL(virTypedParamListPtr list, + long long value, + const char *namefmt, + ...) +{ + virTypedParameterPtr par; + va_list ap; + int ret; + + if (!(par = virTypedParamListExtend(list)) || + virTypedParameterAssignValue(par, true, VIR_TYPED_PARAM_LLONG, value) < 0) + return -1; + + va_start(ap, namefmt); + ret = virTypedParamSetNameVPrintf(par, namefmt, ap); + va_end(ap); + + return ret; +} + + +int +virTypedParamListAddULL(virTypedParamListPtr list, + unsigned long long value, + const char *namefmt, + ...) +{ + virTypedParameterPtr par; + va_list ap; + int ret; + + if (!(par = virTypedParamListExtend(list)) || + virTypedParameterAssignValue(par, true, VIR_TYPED_PARAM_ULLONG, value) < 0) + return -1; + + va_start(ap, namefmt); + ret = virTypedParamSetNameVPrintf(par, namefmt, ap); + va_end(ap); + + return ret; +} + + +int +virTypedParamListAddS(virTypedParamListPtr list, + const char *value, + const char *namefmt, + ...) +{ + virTypedParameterPtr par; + va_list ap; + int ret; + + if (!(par = virTypedParamListExtend(list)) || + virTypedParameterAssignValue(par, true, VIR_TYPED_PARAM_STRING, value) < 0) + return -1; + + va_start(ap, namefmt); + ret = virTypedParamSetNameVPrintf(par, namefmt, ap); + va_end(ap); + + return ret; +} + + +int +virTypedParamListAddB(virTypedParamListPtr list, + bool value, + const char *namefmt, + ...) +{ + virTypedParameterPtr par; + va_list ap; + int ret; + + if (!(par = virTypedParamListExtend(list)) || + virTypedParameterAssignValue(par, true, VIR_TYPED_PARAM_BOOLEAN, value) < 0) + return -1; + + va_start(ap, namefmt); + ret = virTypedParamSetNameVPrintf(par, namefmt, ap); + va_end(ap); + + return ret; +} + + +int +virTypedParamListAddD(virTypedParamListPtr list, + double value, + const char *namefmt, + ...) +{ + virTypedParameterPtr par; + va_list ap; + int ret; + + if (!(par = virTypedParamListExtend(list)) || + virTypedParameterAssignValue(par, true, VIR_TYPED_PARAM_DOUBLE, value) < 0) + return -1; + + va_start(ap, namefmt); + ret = virTypedParamSetNameVPrintf(par, namefmt, ap); + va_end(ap); + + return ret; +} diff --git a/src/util/virtypedparam.h b/src/util/virtypedparam.h index cad6953f5d..2f6fad9d1a 100644 --- a/src/util/virtypedparam.h +++ b/src/util/virtypedparam.h @@ -24,6 +24,7 @@ #include "internal.h" #include "virutil.h" #include "virenum.h" +#include "virautoclean.h" /** * VIR_TYPED_PARAM_MULTIPLE: @@ -94,6 +95,15 @@ int virTypedParamsCopy(virTypedParameterPtr *dst, virTypedParameterPtr src, int nparams); + +int virTypedParamsAddPrintf(virTypedParameterPtr *params, + int *nparams, + int *maxparams, + const char *namefmt, + int type, + ...) + ATTRIBUTE_FMT_PRINTF(4, 0) ATTRIBUTE_RETURN_CHECK; + char *virTypedParameterToString(virTypedParameterPtr param); void virTypedParamsRemoteFree(virTypedParameterRemotePtr remote_params_val, @@ -128,3 +138,54 @@ VIR_ENUM_DECL(virTypedParameter); VIR_FREE(_value); \ } \ } while (0) + +typedef struct _virTypedParamList virTypedParamList; +typedef virTypedParamList *virTypedParamListPtr; + +struct _virTypedParamList { + virTypedParameterPtr par; + size_t npar; + size_t par_alloc; +}; + +void virTypedParamListFree(virTypedParamListPtr list); +VIR_DEFINE_AUTOPTR_FUNC(virTypedParamList, virTypedParamListFree); + +size_t virTypedParamListStealParams(virTypedParamListPtr list, + virTypedParameterPtr *params); + +int virTypedParamListAddI(virTypedParamListPtr list, + int value, + const char *namefmt, + ...) + ATTRIBUTE_FMT_PRINTF(3, 4) ATTRIBUTE_RETURN_CHECK; +int virTypedParamListAddUI(virTypedParamListPtr list, + unsigned int value, + const char *namefmt, + ...) + ATTRIBUTE_FMT_PRINTF(3, 4) ATTRIBUTE_RETURN_CHECK; +int virTypedParamListAddLL(virTypedParamListPtr list, + long long value, + const char *namefmt, + ...) + ATTRIBUTE_FMT_PRINTF(3, 4) ATTRIBUTE_RETURN_CHECK; +int virTypedParamListAddULL(virTypedParamListPtr list, + unsigned long long value, + const char *namefmt, + ...) + ATTRIBUTE_FMT_PRINTF(3, 4) ATTRIBUTE_RETURN_CHECK; +int virTypedParamListAddS(virTypedParamListPtr list, + const char *value, + const char *namefmt, + ...) + ATTRIBUTE_FMT_PRINTF(3, 4) ATTRIBUTE_RETURN_CHECK; +int virTypedParamListAddB(virTypedParamListPtr list, + bool value, + const char *namefmt, + ...) + ATTRIBUTE_FMT_PRINTF(3, 4) ATTRIBUTE_RETURN_CHECK; +int virTypedParamListAddD(virTypedParamListPtr list, + double value, + const char *namefmt, + ...) + ATTRIBUTE_FMT_PRINTF(3, 4) ATTRIBUTE_RETURN_CHECK; -- 2.21.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list