util: typedparam: Simplify handling of lists of typed parameters

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@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Peter Krempa 2019-09-19 09:20:49 +02:00
parent 6b39203fac
commit 3377335508
3 changed files with 283 additions and 0 deletions

View File

@ -3232,6 +3232,15 @@ virTypedParameterAssign;
virTypedParameterToString;
virTypedParameterTypeFromString;
virTypedParameterTypeToString;
virTypedParamListAddBoolean;
virTypedParamListAddDouble;
virTypedParamListAddInt;
virTypedParamListAddLLong;
virTypedParamListAddString;
virTypedParamListAddUInt;
virTypedParamListAddULLong;
virTypedParamListFree;
virTypedParamListStealParams;
virTypedParamsCheck;
virTypedParamsCopy;
virTypedParamsDeserialize;

View File

@ -254,6 +254,23 @@ virTypedParameterAssignValueVArgs(virTypedParameterPtr param,
}
static int
virTypedParameterAssignValue(virTypedParameterPtr param,
bool copystr,
int type,
...)
{
int ret;
va_list ap;
va_start(ap, type);
ret = virTypedParameterAssignValueVArgs(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
virTypedParamListAddInt(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
virTypedParamListAddUInt(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
virTypedParamListAddLLong(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
virTypedParamListAddULLong(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
virTypedParamListAddString(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
virTypedParamListAddBoolean(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
virTypedParamListAddDouble(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;
}

View File

@ -24,6 +24,7 @@
#include "internal.h"
#include "virutil.h"
#include "virenum.h"
#include "virautoclean.h"
/**
* VIR_TYPED_PARAM_MULTIPLE:
@ -128,3 +129,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 virTypedParamListAddInt(virTypedParamListPtr list,
int value,
const char *namefmt,
...)
ATTRIBUTE_FMT_PRINTF(3, 4) ATTRIBUTE_RETURN_CHECK;
int virTypedParamListAddUInt(virTypedParamListPtr list,
unsigned int value,
const char *namefmt,
...)
ATTRIBUTE_FMT_PRINTF(3, 4) ATTRIBUTE_RETURN_CHECK;
int virTypedParamListAddLLong(virTypedParamListPtr list,
long long value,
const char *namefmt,
...)
ATTRIBUTE_FMT_PRINTF(3, 4) ATTRIBUTE_RETURN_CHECK;
int virTypedParamListAddULLong(virTypedParamListPtr list,
unsigned long long value,
const char *namefmt,
...)
ATTRIBUTE_FMT_PRINTF(3, 4) ATTRIBUTE_RETURN_CHECK;
int virTypedParamListAddString(virTypedParamListPtr list,
const char *value,
const char *namefmt,
...)
ATTRIBUTE_FMT_PRINTF(3, 4) ATTRIBUTE_RETURN_CHECK;
int virTypedParamListAddBoolean(virTypedParamListPtr list,
bool value,
const char *namefmt,
...)
ATTRIBUTE_FMT_PRINTF(3, 4) ATTRIBUTE_RETURN_CHECK;
int virTypedParamListAddDouble(virTypedParamListPtr list,
double value,
const char *namefmt,
...)
ATTRIBUTE_FMT_PRINTF(3, 4) ATTRIBUTE_RETURN_CHECK;