Re: [libvirt] [PATCH v2 3/6] util: virTypedParams{Filter, PickStrings}
On 21.05.2015 13:07, Pavel Boldin wrote: Add multikey API: * virTypedParamsFilter that returns all the parameters with specified name. * virTypedParamsPickStrings that returns a NULL-terminated `const char**' list with all the values for specified name and string type. Signed-off-by: Pavel Boldin pbol...@mirantis.com --- include/libvirt/libvirt-host.h | 10 src/libvirt_public.syms| 6 +++ src/util/virtypedparam.c | 107 + tests/virtypedparamtest.c | 96 4 files changed, 219 insertions(+) diff --git a/include/libvirt/libvirt-host.h b/include/libvirt/libvirt-host.h index 070550b..36267fc 100644 --- a/include/libvirt/libvirt-host.h +++ b/include/libvirt/libvirt-host.h @@ -249,6 +249,11 @@ virTypedParamsGet (virTypedParameterPtr params, int nparams, const char *name); int +virTypedParamsFilter(virTypedParameterPtr params, + int nparams, + const char *name, + virTypedParameterPtr **ret); +int virTypedParamsGetInt(virTypedParameterPtr params, int nparams, const char *name, @@ -283,6 +288,11 @@ virTypedParamsGetString (virTypedParameterPtr params, int nparams, const char *name, const char **value); +const char ** +virTypedParamsPickStrings(virTypedParameterPtr params, + int nparams, + const char *name, + size_t *picked); int virTypedParamsAddInt(virTypedParameterPtr *params, int *nparams, diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index ef3d2f0..8fc8c42 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -710,4 +710,10 @@ LIBVIRT_1.2.15 { virDomainDelIOThread; } LIBVIRT_1.2.14; +LIBVIRT_1.2.16 { +global: +virTypedParamsFilter; +virTypedParamsPickStrings; +} LIBVIRT_1.2.15; + # define new API here using predicted next version number diff --git a/src/util/virtypedparam.c b/src/util/virtypedparam.c index ec20b74..a3d959e 100644 --- a/src/util/virtypedparam.c +++ b/src/util/virtypedparam.c @@ -481,6 +481,58 @@ virTypedParamsGet(virTypedParameterPtr params, } +/** + * virTypedParamsFilter: + * @params: array of typed parameters + * @nparams: number of parameters in the @params array + * @name: name of the parameter to find + * @ret: pointer to the returned array + * + * + * Filters @params retaining only the parameters named @name in the + * resulting array @ret. Caller should free the @ret array but no the s/no/not/ + * items since they are pointing to the @params elements. + * + * Returns amount of elements in @ret on success, -1 on error. + */ +int +virTypedParamsFilter(virTypedParameterPtr params, + int nparams, + const char *name, + virTypedParameterPtr **ret) +{ +size_t i, max = 0, n = 0; s/max/alloc/ + +virResetLastError(); + +if (!params || !name || !ret) { +virReportError(VIR_ERR_INVALID_ARG, + _(Required argument is missing: %s), + !params ? params : !name ? name : ret); +goto error; We have a macro for that: virCheckNonNullArgGoto() +} + +for (i = 0; i nparams; i++) { +if (STREQ(params[i].field, name)) { +if (VIR_RESIZE_N(*ret, max, n, 1) 0) +goto error; + +(*ret)[n] = params[i]; + +n++; +} +} So if there's no match, @ret is untouched. This is not cool, consider the following code: virTypedParameterPtr *ret; if (virTypedParamsFilter(.., ret) 0) { error; } else { success; free(ret); } The free() may end up freeing a random pointer. + +return n; + + error: +if (ret) +VIR_FREE(*ret); +virDispatchError(NULL); +return -1; +} + + #define VIR_TYPED_PARAM_CHECK_TYPE(check_type) \ do { if (param-type != check_type) { \ virReportError(VIR_ERR_INVALID_ARG, \ @@ -749,6 +801,61 @@ virTypedParamsGetString(virTypedParameterPtr params, /** + * virTypedParamsPickStrings: + * @params: array of typed parameters + * @nparams: number of parameters in the @params array + * @name: name of the parameter to find + * @picked: pointer to the amount of picked strings. + * + * + * Finds typed parameters called @name. + * + * Returns a string list, which is a NULL terminated array of pointers to + * strings. Since a NULL is a valid parameter string value caller can ask + *
[libvirt] [PATCH v2 3/6] util: virTypedParams{Filter,PickStrings}
Add multikey API: * virTypedParamsFilter that returns all the parameters with specified name. * virTypedParamsPickStrings that returns a NULL-terminated `const char**' list with all the values for specified name and string type. Signed-off-by: Pavel Boldin pbol...@mirantis.com --- include/libvirt/libvirt-host.h | 10 src/libvirt_public.syms| 6 +++ src/util/virtypedparam.c | 107 + tests/virtypedparamtest.c | 96 4 files changed, 219 insertions(+) diff --git a/include/libvirt/libvirt-host.h b/include/libvirt/libvirt-host.h index 070550b..36267fc 100644 --- a/include/libvirt/libvirt-host.h +++ b/include/libvirt/libvirt-host.h @@ -249,6 +249,11 @@ virTypedParamsGet (virTypedParameterPtr params, int nparams, const char *name); int +virTypedParamsFilter(virTypedParameterPtr params, + int nparams, + const char *name, + virTypedParameterPtr **ret); +int virTypedParamsGetInt(virTypedParameterPtr params, int nparams, const char *name, @@ -283,6 +288,11 @@ virTypedParamsGetString (virTypedParameterPtr params, int nparams, const char *name, const char **value); +const char ** +virTypedParamsPickStrings(virTypedParameterPtr params, + int nparams, + const char *name, + size_t *picked); int virTypedParamsAddInt(virTypedParameterPtr *params, int *nparams, diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index ef3d2f0..8fc8c42 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -710,4 +710,10 @@ LIBVIRT_1.2.15 { virDomainDelIOThread; } LIBVIRT_1.2.14; +LIBVIRT_1.2.16 { +global: +virTypedParamsFilter; +virTypedParamsPickStrings; +} LIBVIRT_1.2.15; + # define new API here using predicted next version number diff --git a/src/util/virtypedparam.c b/src/util/virtypedparam.c index ec20b74..a3d959e 100644 --- a/src/util/virtypedparam.c +++ b/src/util/virtypedparam.c @@ -481,6 +481,58 @@ virTypedParamsGet(virTypedParameterPtr params, } +/** + * virTypedParamsFilter: + * @params: array of typed parameters + * @nparams: number of parameters in the @params array + * @name: name of the parameter to find + * @ret: pointer to the returned array + * + * + * Filters @params retaining only the parameters named @name in the + * resulting array @ret. Caller should free the @ret array but no the + * items since they are pointing to the @params elements. + * + * Returns amount of elements in @ret on success, -1 on error. + */ +int +virTypedParamsFilter(virTypedParameterPtr params, + int nparams, + const char *name, + virTypedParameterPtr **ret) +{ +size_t i, max = 0, n = 0; + +virResetLastError(); + +if (!params || !name || !ret) { +virReportError(VIR_ERR_INVALID_ARG, + _(Required argument is missing: %s), + !params ? params : !name ? name : ret); +goto error; +} + +for (i = 0; i nparams; i++) { +if (STREQ(params[i].field, name)) { +if (VIR_RESIZE_N(*ret, max, n, 1) 0) +goto error; + +(*ret)[n] = params[i]; + +n++; +} +} + +return n; + + error: +if (ret) +VIR_FREE(*ret); +virDispatchError(NULL); +return -1; +} + + #define VIR_TYPED_PARAM_CHECK_TYPE(check_type) \ do { if (param-type != check_type) { \ virReportError(VIR_ERR_INVALID_ARG, \ @@ -749,6 +801,61 @@ virTypedParamsGetString(virTypedParameterPtr params, /** + * virTypedParamsPickStrings: + * @params: array of typed parameters + * @nparams: number of parameters in the @params array + * @name: name of the parameter to find + * @picked: pointer to the amount of picked strings. + * + * + * Finds typed parameters called @name. + * + * Returns a string list, which is a NULL terminated array of pointers to + * strings. Since a NULL is a valid parameter string value caller can ask + * for exact amount of picked strings using @picked argument. + * + * Caller should free the returned array but not the items since they are + * taken from @params array. + */ +const char ** +virTypedParamsPickStrings(virTypedParameterPtr params, + int nparams, const char *name, + size_t *picked) +{ +const char **values = NULL; +size_t i, n; +int nfiltered; +virTypedParameterPtr *filtered = NULL; + +virResetLastError(); + +nfiltered =