Signed-off-by: Pavel Hrdina <phrdina@xxxxxxxxxx> --- libvirt-lxc-override.c | 7 - libvirt-override.c | 413 ------------------------------------------------ libvirt-qemu-override.c | 7 - libvirt-utils.c | 406 +++++++++++++++++++++++++++++++++++++++++++++++ libvirt-utils.h | 51 ++++++ 5 files changed, 457 insertions(+), 427 deletions(-) diff --git a/libvirt-lxc-override.c b/libvirt-lxc-override.c index d0d9ffd..e0d3e60 100644 --- a/libvirt-lxc-override.c +++ b/libvirt-lxc-override.c @@ -47,13 +47,6 @@ extern void initcygvirtmod_lxc(void); do {} while (0) #endif -/* The two-statement sequence "Py_INCREF(Py_None); return Py_None;" - is so common that we encapsulate it here. Now, each use is simply - return VIR_PY_NONE; */ -#define VIR_PY_NONE (Py_INCREF (Py_None), Py_None) -#define VIR_PY_INT_FAIL (libvirt_intWrap(-1)) -#define VIR_PY_INT_SUCCESS (libvirt_intWrap(0)) - /************************************************************************ * * * Statistics * diff --git a/libvirt-override.c b/libvirt-override.c index b18196f..ff6f338 100644 --- a/libvirt-override.c +++ b/libvirt-override.c @@ -51,419 +51,6 @@ extern void initcygvirtmod(void); do {} while (0) #endif -/* The two-statement sequence "Py_INCREF(Py_None); return Py_None;" - is so common that we encapsulate it here. Now, each use is simply - return VIR_PY_NONE; */ -#define VIR_PY_NONE (Py_INCREF (Py_None), Py_None) -#define VIR_PY_INT_FAIL (libvirt_intWrap(-1)) -#define VIR_PY_INT_SUCCESS (libvirt_intWrap(0)) - -static char *py_str(PyObject *obj) -{ - PyObject *str = PyObject_Str(obj); - char *ret; - if (!str) { - PyErr_Print(); - PyErr_Clear(); - return NULL; - }; - libvirt_charPtrUnwrap(str, &ret); - return ret; -} - -/* Helper function to convert a virTypedParameter output array into a - * Python dictionary for return to the user. Return NULL on failure, - * after raising a python exception. */ -static PyObject * -getPyVirTypedParameter(const virTypedParameter *params, int nparams) -{ - PyObject *key, *val, *info; - size_t i; - - if ((info = PyDict_New()) == NULL) - return NULL; - - for (i = 0; i < nparams; i++) { - switch (params[i].type) { - case VIR_TYPED_PARAM_INT: - val = libvirt_intWrap(params[i].value.i); - break; - - case VIR_TYPED_PARAM_UINT: - val = libvirt_intWrap(params[i].value.ui); - break; - - case VIR_TYPED_PARAM_LLONG: - val = libvirt_longlongWrap(params[i].value.l); - break; - - case VIR_TYPED_PARAM_ULLONG: - val = libvirt_ulonglongWrap(params[i].value.ul); - break; - - case VIR_TYPED_PARAM_DOUBLE: - val = PyFloat_FromDouble(params[i].value.d); - break; - - case VIR_TYPED_PARAM_BOOLEAN: - val = PyBool_FromLong(params[i].value.b); - break; - - case VIR_TYPED_PARAM_STRING: - val = libvirt_constcharPtrWrap(params[i].value.s); - break; - - default: - /* Possible if a newer server has a bug and sent stuff we - * don't recognize. */ - PyErr_Format(PyExc_LookupError, - "Type value \"%d\" not recognized", - params[i].type); - val = NULL; - break; - } - - key = libvirt_constcharPtrWrap(params[i].field); - if (!key || !val) - goto cleanup; - - if (PyDict_SetItem(info, key, val) < 0) { - Py_DECREF(info); - goto cleanup; - } - - Py_DECREF(key); - Py_DECREF(val); - } - return info; - -cleanup: - Py_XDECREF(key); - Py_XDECREF(val); - return NULL; -} - -/* Allocate a new typed parameter array with the same contents and - * length as info, and using the array params of length nparams as - * hints on what types to use when creating the new array. The caller - * must clear the array before freeing it. Return NULL on failure, - * after raising a python exception. */ -static virTypedParameterPtr ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) -setPyVirTypedParameter(PyObject *info, - const virTypedParameter *params, int nparams) -{ - PyObject *key, *value; -#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 4 - int pos = 0; -#else - Py_ssize_t pos = 0; -#endif - virTypedParameterPtr temp = NULL, ret = NULL; - Py_ssize_t size; - size_t i; - - if ((size = PyDict_Size(info)) < 0) - return NULL; - - /* Libvirt APIs use NULL array and 0 size as a special case; - * setting should have at least one parameter. */ - if (size == 0) { - PyErr_Format(PyExc_LookupError, "Dictionary must not be empty"); - return NULL; - } - - if (VIR_ALLOC_N(ret, size) < 0) { - PyErr_NoMemory(); - return NULL; - } - - temp = &ret[0]; - while (PyDict_Next(info, &pos, &key, &value)) { - char *keystr = NULL; - - if (libvirt_charPtrUnwrap(key, &keystr) < 0 || - keystr == NULL) - goto cleanup; - - for (i = 0; i < nparams; i++) { - if (STREQ(params[i].field, keystr)) - break; - } - if (i == nparams) { - PyErr_Format(PyExc_LookupError, - "Attribute name \"%s\" could not be recognized", - keystr); - VIR_FREE(keystr); - goto cleanup; - } - - strncpy(temp->field, keystr, VIR_TYPED_PARAM_FIELD_LENGTH - 1); - temp->type = params[i].type; - VIR_FREE(keystr); - - switch (params[i].type) { - case VIR_TYPED_PARAM_INT: - if (libvirt_intUnwrap(value, &temp->value.i) < 0) - goto cleanup; - break; - - case VIR_TYPED_PARAM_UINT: - if (libvirt_uintUnwrap(value, &temp->value.ui) < 0) - goto cleanup; - break; - - case VIR_TYPED_PARAM_LLONG: - if (libvirt_longlongUnwrap(value, &temp->value.l) < 0) - goto cleanup; - break; - - case VIR_TYPED_PARAM_ULLONG: - if (libvirt_ulonglongUnwrap(value, &temp->value.ul) < 0) - goto cleanup; - break; - - case VIR_TYPED_PARAM_DOUBLE: - if (libvirt_doubleUnwrap(value, &temp->value.d) < 0) - goto cleanup; - break; - - case VIR_TYPED_PARAM_BOOLEAN: - { - bool b; - if (libvirt_boolUnwrap(value, &b) < 0) - goto cleanup; - temp->value.b = b; - break; - } - case VIR_TYPED_PARAM_STRING: - { - char *string_val; - if (libvirt_charPtrUnwrap(value, &string_val) < 0 || - !string_val) - goto cleanup; - temp->value.s = string_val; - break; - } - - default: - /* Possible if a newer server has a bug and sent stuff we - * don't recognize. */ - PyErr_Format(PyExc_LookupError, - "Type value \"%d\" not recognized", - params[i].type); - goto cleanup; - } - - temp++; - } - return ret; - -cleanup: - virTypedParamsFree(ret, size); - return NULL; -} - -/* While these appeared in libvirt in 1.0.2, we only - * need them in the python from 1.1.0 onwards */ -#if LIBVIR_CHECK_VERSION(1, 1, 0) -typedef struct { - const char *name; - int type; -} virPyTypedParamsHint; -typedef virPyTypedParamsHint *virPyTypedParamsHintPtr; - -# if PY_MAJOR_VERSION > 2 -# define libvirt_PyString_Check PyUnicode_Check -# else -# define libvirt_PyString_Check PyString_Check -# endif - -static int -virPyDictToTypedParamOne(virTypedParameterPtr *params, - int *n, - int *max, - virPyTypedParamsHintPtr hints, - int nhints, - const char *keystr, - PyObject *value) -{ - int rv = -1, type = -1; - size_t i; - - for (i = 0; i < nhints; i++) { - if (STREQ(hints[i].name, keystr)) { - type = hints[i].type; - break; - } - } - - if (type == -1) { - if (libvirt_PyString_Check(value)) { - type = VIR_TYPED_PARAM_STRING; - } else if (PyBool_Check(value)) { - type = VIR_TYPED_PARAM_BOOLEAN; - } else if (PyLong_Check(value)) { - unsigned long long ull = PyLong_AsUnsignedLongLong(value); - if (ull == (unsigned long long) -1 && PyErr_Occurred()) - type = VIR_TYPED_PARAM_LLONG; - else - type = VIR_TYPED_PARAM_ULLONG; -#if PY_MAJOR_VERSION < 3 - } else if (PyInt_Check(value)) { - if (PyInt_AS_LONG(value) < 0) - type = VIR_TYPED_PARAM_LLONG; - else - type = VIR_TYPED_PARAM_ULLONG; -#endif - } else if (PyFloat_Check(value)) { - type = VIR_TYPED_PARAM_DOUBLE; - } - } - - if (type == -1) { - PyErr_Format(PyExc_TypeError, - "Unknown type of \"%s\" field", keystr); - goto cleanup; - } - - switch ((virTypedParameterType) type) { - case VIR_TYPED_PARAM_INT: - { - int val; - if (libvirt_intUnwrap(value, &val) < 0 || - virTypedParamsAddInt(params, n, max, keystr, val) < 0) - goto cleanup; - break; - } - case VIR_TYPED_PARAM_UINT: - { - unsigned int val; - if (libvirt_uintUnwrap(value, &val) < 0 || - virTypedParamsAddUInt(params, n, max, keystr, val) < 0) - goto cleanup; - break; - } - case VIR_TYPED_PARAM_LLONG: - { - long long val; - if (libvirt_longlongUnwrap(value, &val) < 0 || - virTypedParamsAddLLong(params, n, max, keystr, val) < 0) - goto cleanup; - break; - } - case VIR_TYPED_PARAM_ULLONG: - { - unsigned long long val; - if (libvirt_ulonglongUnwrap(value, &val) < 0 || - virTypedParamsAddULLong(params, n, max, keystr, val) < 0) - goto cleanup; - break; - } - case VIR_TYPED_PARAM_DOUBLE: - { - double val; - if (libvirt_doubleUnwrap(value, &val) < 0 || - virTypedParamsAddDouble(params, n, max, keystr, val) < 0) - goto cleanup; - break; - } - case VIR_TYPED_PARAM_BOOLEAN: - { - bool val; - if (libvirt_boolUnwrap(value, &val) < 0 || - virTypedParamsAddBoolean(params, n, max, keystr, val) < 0) - goto cleanup; - break; - } - case VIR_TYPED_PARAM_STRING: - { - char *val;; - if (libvirt_charPtrUnwrap(value, &val) < 0 || - !val || - virTypedParamsAddString(params, n, max, keystr, val) < 0) { - VIR_FREE(val); - goto cleanup; - } - VIR_FREE(val); - break; - } - case VIR_TYPED_PARAM_LAST: - break; /* unreachable */ - } - - rv = 0; - - cleanup: - return rv; -} - - -/* Automatically convert dict into type parameters based on types reported - * by python. All integer types are converted into LLONG (in case of a negative - * value) or ULLONG (in case of a positive value). If you need different - * handling, use @hints to explicitly specify what types should be used for - * specific parameters. - */ -static int -ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) -virPyDictToTypedParams(PyObject *dict, - virTypedParameterPtr *ret_params, - int *ret_nparams, - virPyTypedParamsHintPtr hints, - int nhints) -{ - PyObject *key; - PyObject *value; -#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 4 - int pos = 0; -#else - Py_ssize_t pos = 0; -#endif - virTypedParameterPtr params = NULL; - int n = 0; - int max = 0; - int ret = -1; - char *keystr = NULL; - - *ret_params = NULL; - *ret_nparams = 0; - - if (PyDict_Size(dict) < 0) - return -1; - - while (PyDict_Next(dict, &pos, &key, &value)) { - if (libvirt_charPtrUnwrap(key, &keystr) < 0 || - !keystr) - goto cleanup; - - if (PyList_Check(value) || PyTuple_Check(value)) { - Py_ssize_t i, size = PySequence_Size(value); - - for (i = 0; i < size; i++) { - PyObject *v = PySequence_ITEM(value, i); - if (virPyDictToTypedParamOne(¶ms, &n, &max, - hints, nhints, keystr, v) < 0) - goto cleanup; - } - } else if (virPyDictToTypedParamOne(¶ms, &n, &max, - hints, nhints, keystr, value) < 0) - goto cleanup; - - VIR_FREE(keystr); - } - - *ret_params = params; - *ret_nparams = n; - params = NULL; - ret = 0; - -cleanup: - VIR_FREE(keystr); - virTypedParamsFree(params, n); - return ret; -} -#endif /* LIBVIR_CHECK_VERSION(1, 1, 0) */ - /* * Utility function to retrieve the number of node CPUs present. diff --git a/libvirt-qemu-override.c b/libvirt-qemu-override.c index ce6f4fd..c082324 100644 --- a/libvirt-qemu-override.c +++ b/libvirt-qemu-override.c @@ -47,13 +47,6 @@ extern void initcygvirtmod_qemu(void); do {} while (0) #endif -/* The two-statement sequence "Py_INCREF(Py_None); return Py_None;" - is so common that we encapsulate it here. Now, each use is simply - return VIR_PY_NONE; */ -#define VIR_PY_NONE (Py_INCREF (Py_None), Py_None) -#define VIR_PY_INT_FAIL (libvirt_intWrap(-1)) -#define VIR_PY_INT_SUCCESS (libvirt_intWrap(0)) - /******************************************* * Helper functions to avoid importing modules * for every callback diff --git a/libvirt-utils.c b/libvirt-utils.c index d1f6e70..651d74f 100644 --- a/libvirt-utils.c +++ b/libvirt-utils.c @@ -19,12 +19,21 @@ * */ +#include <Python.h> + +/* Ugly python defines that, which is also defined in errno.h */ +#undef _POSIC_C_SOURCE + +/* We want to see *_LAST enums. */ +#define VIR_ENUM_SENTINELS + #include <errno.h> #include <stddef.h> #include <stdlib.h> #include <unistd.h> #include <libvirt/libvirt.h> #include "libvirt-utils.h" +#include "typewrappers.h" /** * virAlloc: @@ -184,3 +193,400 @@ virTypedParamsFree(virTypedParameterPtr params, VIR_FREE(params); } #endif /* ! LIBVIR_CHECK_VERSION(1, 0, 2) */ + +char * +py_str(PyObject *obj) +{ + PyObject *str = PyObject_Str(obj); + char *ret; + if (!str) { + PyErr_Print(); + PyErr_Clear(); + return NULL; + }; + libvirt_charPtrUnwrap(str, &ret); + return ret; +} + +/* Helper function to convert a virTypedParameter output array into a + * Python dictionary for return to the user. Return NULL on failure, + * after raising a python exception. */ +PyObject * +getPyVirTypedParameter(const virTypedParameter *params, + int nparams) +{ + PyObject *key, *val, *info; + size_t i; + + if ((info = PyDict_New()) == NULL) + return NULL; + + for (i = 0; i < nparams; i++) { + switch (params[i].type) { + case VIR_TYPED_PARAM_INT: + val = libvirt_intWrap(params[i].value.i); + break; + + case VIR_TYPED_PARAM_UINT: + val = libvirt_intWrap(params[i].value.ui); + break; + + case VIR_TYPED_PARAM_LLONG: + val = libvirt_longlongWrap(params[i].value.l); + break; + + case VIR_TYPED_PARAM_ULLONG: + val = libvirt_ulonglongWrap(params[i].value.ul); + break; + + case VIR_TYPED_PARAM_DOUBLE: + val = PyFloat_FromDouble(params[i].value.d); + break; + + case VIR_TYPED_PARAM_BOOLEAN: + val = PyBool_FromLong(params[i].value.b); + break; + + case VIR_TYPED_PARAM_STRING: + val = libvirt_constcharPtrWrap(params[i].value.s); + break; + + default: + /* Possible if a newer server has a bug and sent stuff we + * don't recognize. */ + PyErr_Format(PyExc_LookupError, + "Type value \"%d\" not recognized", + params[i].type); + val = NULL; + break; + } + + key = libvirt_constcharPtrWrap(params[i].field); + if (!key || !val) + goto cleanup; + + if (PyDict_SetItem(info, key, val) < 0) { + Py_DECREF(info); + goto cleanup; + } + + Py_DECREF(key); + Py_DECREF(val); + } + return info; + + cleanup: + Py_XDECREF(key); + Py_XDECREF(val); + return NULL; +} + +/* Allocate a new typed parameter array with the same contents and + * length as info, and using the array params of length nparams as + * hints on what types to use when creating the new array. The caller + * must clear the array before freeing it. Return NULL on failure, + * after raising a python exception. */ +virTypedParameterPtr +setPyVirTypedParameter(PyObject *info, + const virTypedParameter *params, + int nparams) +{ + PyObject *key, *value; +#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 4 + int pos = 0; +#else + Py_ssize_t pos = 0; +#endif + virTypedParameterPtr temp = NULL, ret = NULL; + Py_ssize_t size; + size_t i; + + if ((size = PyDict_Size(info)) < 0) + return NULL; + + /* Libvirt APIs use NULL array and 0 size as a special case; + * setting should have at least one parameter. */ + if (size == 0) { + PyErr_Format(PyExc_LookupError, "Dictionary must not be empty"); + return NULL; + } + + if (VIR_ALLOC_N(ret, size) < 0) { + PyErr_NoMemory(); + return NULL; + } + + temp = &ret[0]; + while (PyDict_Next(info, &pos, &key, &value)) { + char *keystr = NULL; + + if (libvirt_charPtrUnwrap(key, &keystr) < 0 || + keystr == NULL) + goto cleanup; + + for (i = 0; i < nparams; i++) { + if (STREQ(params[i].field, keystr)) + break; + } + if (i == nparams) { + PyErr_Format(PyExc_LookupError, + "Attribute name \"%s\" could not be recognized", + keystr); + VIR_FREE(keystr); + goto cleanup; + } + + strncpy(temp->field, keystr, VIR_TYPED_PARAM_FIELD_LENGTH - 1); + temp->type = params[i].type; + VIR_FREE(keystr); + + switch (params[i].type) { + case VIR_TYPED_PARAM_INT: + if (libvirt_intUnwrap(value, &temp->value.i) < 0) + goto cleanup; + break; + + case VIR_TYPED_PARAM_UINT: + if (libvirt_uintUnwrap(value, &temp->value.ui) < 0) + goto cleanup; + break; + + case VIR_TYPED_PARAM_LLONG: + if (libvirt_longlongUnwrap(value, &temp->value.l) < 0) + goto cleanup; + break; + + case VIR_TYPED_PARAM_ULLONG: + if (libvirt_ulonglongUnwrap(value, &temp->value.ul) < 0) + goto cleanup; + break; + + case VIR_TYPED_PARAM_DOUBLE: + if (libvirt_doubleUnwrap(value, &temp->value.d) < 0) + goto cleanup; + break; + + case VIR_TYPED_PARAM_BOOLEAN: + { + bool b; + if (libvirt_boolUnwrap(value, &b) < 0) + goto cleanup; + temp->value.b = b; + break; + } + case VIR_TYPED_PARAM_STRING: + { + char *string_val; + if (libvirt_charPtrUnwrap(value, &string_val) < 0 || + !string_val) + goto cleanup; + temp->value.s = string_val; + break; + } + + default: + /* Possible if a newer server has a bug and sent stuff we + * don't recognize. */ + PyErr_Format(PyExc_LookupError, + "Type value \"%d\" not recognized", + params[i].type); + goto cleanup; + } + + temp++; + } + return ret; + +cleanup: + virTypedParamsFree(ret, size); + return NULL; +} + + +/* While these appeared in libvirt in 1.0.2, we only + * need them in the python from 1.1.0 onwards */ +#if LIBVIR_CHECK_VERSION(1, 1, 0) +int +virPyDictToTypedParamOne(virTypedParameterPtr *params, + int *n, + int *max, + virPyTypedParamsHintPtr hints, + int nhints, + const char *keystr, + PyObject *value) +{ + int rv = -1, type = -1; + size_t i; + + for (i = 0; i < nhints; i++) { + if (STREQ(hints[i].name, keystr)) { + type = hints[i].type; + break; + } + } + + if (type == -1) { + if (libvirt_PyString_Check(value)) { + type = VIR_TYPED_PARAM_STRING; + } else if (PyBool_Check(value)) { + type = VIR_TYPED_PARAM_BOOLEAN; + } else if (PyLong_Check(value)) { + unsigned long long ull = PyLong_AsUnsignedLongLong(value); + if (ull == (unsigned long long) -1 && PyErr_Occurred()) + type = VIR_TYPED_PARAM_LLONG; + else + type = VIR_TYPED_PARAM_ULLONG; +#if PY_MAJOR_VERSION < 3 + } else if (PyInt_Check(value)) { + if (PyInt_AS_LONG(value) < 0) + type = VIR_TYPED_PARAM_LLONG; + else + type = VIR_TYPED_PARAM_ULLONG; +#endif + } else if (PyFloat_Check(value)) { + type = VIR_TYPED_PARAM_DOUBLE; + } + } + + if (type == -1) { + PyErr_Format(PyExc_TypeError, + "Unknown type of \"%s\" field", keystr); + goto cleanup; + } + + switch ((virTypedParameterType) type) { + case VIR_TYPED_PARAM_INT: + { + int val; + if (libvirt_intUnwrap(value, &val) < 0 || + virTypedParamsAddInt(params, n, max, keystr, val) < 0) + goto cleanup; + break; + } + case VIR_TYPED_PARAM_UINT: + { + unsigned int val; + if (libvirt_uintUnwrap(value, &val) < 0 || + virTypedParamsAddUInt(params, n, max, keystr, val) < 0) + goto cleanup; + break; + } + case VIR_TYPED_PARAM_LLONG: + { + long long val; + if (libvirt_longlongUnwrap(value, &val) < 0 || + virTypedParamsAddLLong(params, n, max, keystr, val) < 0) + goto cleanup; + break; + } + case VIR_TYPED_PARAM_ULLONG: + { + unsigned long long val; + if (libvirt_ulonglongUnwrap(value, &val) < 0 || + virTypedParamsAddULLong(params, n, max, keystr, val) < 0) + goto cleanup; + break; + } + case VIR_TYPED_PARAM_DOUBLE: + { + double val; + if (libvirt_doubleUnwrap(value, &val) < 0 || + virTypedParamsAddDouble(params, n, max, keystr, val) < 0) + goto cleanup; + break; + } + case VIR_TYPED_PARAM_BOOLEAN: + { + bool val; + if (libvirt_boolUnwrap(value, &val) < 0 || + virTypedParamsAddBoolean(params, n, max, keystr, val) < 0) + goto cleanup; + break; + } + case VIR_TYPED_PARAM_STRING: + { + char *val;; + if (libvirt_charPtrUnwrap(value, &val) < 0 || + !val || + virTypedParamsAddString(params, n, max, keystr, val) < 0) { + VIR_FREE(val); + goto cleanup; + } + VIR_FREE(val); + break; + } + case VIR_TYPED_PARAM_LAST: + break; /* unreachable */ + } + + rv = 0; + + cleanup: + return rv; +} + + +/* Automatically convert dict into type parameters based on types reported + * by python. All integer types are converted into LLONG (in case of a negative + * value) or ULLONG (in case of a positive value). If you need different + * handling, use @hints to explicitly specify what types should be used for + * specific parameters. + */ +int +virPyDictToTypedParams(PyObject *dict, + virTypedParameterPtr *ret_params, + int *ret_nparams, + virPyTypedParamsHintPtr hints, + int nhints) +{ + PyObject *key; + PyObject *value; +#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION <= 4 + int pos = 0; +#else + Py_ssize_t pos = 0; +#endif + virTypedParameterPtr params = NULL; + int n = 0; + int max = 0; + int ret = -1; + char *keystr = NULL; + + *ret_params = NULL; + *ret_nparams = 0; + + if (PyDict_Size(dict) < 0) + return -1; + + while (PyDict_Next(dict, &pos, &key, &value)) { + if (libvirt_charPtrUnwrap(key, &keystr) < 0 || + !keystr) + goto cleanup; + + if (PyList_Check(value) || PyTuple_Check(value)) { + Py_ssize_t i, size = PySequence_Size(value); + + for (i = 0; i < size; i++) { + PyObject *v = PySequence_ITEM(value, i); + if (virPyDictToTypedParamOne(¶ms, &n, &max, + hints, nhints, keystr, v) < 0) + goto cleanup; + } + } else if (virPyDictToTypedParamOne(¶ms, &n, &max, + hints, nhints, keystr, value) < 0) + goto cleanup; + + VIR_FREE(keystr); + } + + *ret_params = params; + *ret_nparams = n; + params = NULL; + ret = 0; + +cleanup: + VIR_FREE(keystr); + virTypedParamsFree(params, n); + return ret; +} +#endif /* LIBVIR_CHECK_VERSION(1, 1, 0) */ diff --git a/libvirt-utils.h b/libvirt-utils.h index bef5489..9f80133 100644 --- a/libvirt-utils.h +++ b/libvirt-utils.h @@ -22,6 +22,9 @@ #ifndef __LIBVIRT_UTILS_H__ # define __LIBVIRT_UTILS_H__ +# include <Python.h> +# include <libvirt/libvirt.h> + # define STREQ(a,b) (strcmp(a,b) == 0) # ifndef MIN @@ -135,6 +138,22 @@ int virReallocN(void *ptrptr, size_t size, size_t count) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1); void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1); + +# if PY_MAJOR_VERSION > 2 +# define libvirt_PyString_Check PyUnicode_Check +# else +# define libvirt_PyString_Check PyString_Check +# endif + + +/* The two-statement sequence "Py_INCREF(Py_None); return Py_None;" + is so common that we encapsulate it here. Now, each use is simply + return VIR_PY_NONE; */ +#define VIR_PY_NONE (Py_INCREF (Py_None), Py_None) +#define VIR_PY_INT_FAIL (libvirt_intWrap(-1)) +#define VIR_PY_INT_SUCCESS (libvirt_intWrap(0)) + + /** * VIR_ALLOC: * @ptr: pointer to hold address of allocated memory @@ -216,4 +235,36 @@ void virTypedParamsClear(virTypedParameterPtr params, int nparams); void virTypedParamsFree(virTypedParameterPtr params, int nparams); # endif /* ! LIBVIR_CHECK_VERSION(1, 0, 2) */ +char * py_str(PyObject *obj); +PyObject * getPyVirTypedParameter(const virTypedParameter *params, + int nparams); +virTypedParameterPtr setPyVirTypedParameter(PyObject *info, + const virTypedParameter *params, + int nparams) +ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + + +# if LIBVIR_CHECK_VERSION(1, 1, 0) +typedef struct { + const char *name; + int type; +} virPyTypedParamsHint; +typedef virPyTypedParamsHint *virPyTypedParamsHintPtr; + + +int virPyDictToTypedPramaOne(virTypedParameterPtr *params, + int *n, + int *max, + virPyTypedParamsHintPtr hints, + int nhints, + const char *keystr, + PyObject *value); +int virPyDictToTypedParams(PyObject *dict, + virTypedParameterPtr *ret_params, + int *ret_nparams, + virPyTypedParamsHintPtr hints, + int nhints) +ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); +# endif /* LIBVIR_CHECK_VERSION(1, 1, 0) */ + #endif /* __LIBVIRT_UTILS_H__ */ -- 2.5.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list