summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libvirt-lxc-override.c7
-rw-r--r--libvirt-override.c413
-rw-r--r--libvirt-qemu-override.c7
-rw-r--r--libvirt-utils.c406
-rw-r--r--libvirt-utils.h51
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 4274b76..7b5c567 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(&params, &n, &max,
- hints, nhints, keystr, v) < 0)
- goto cleanup;
- }
- } else if (virPyDictToTypedParamOne(&params, &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(&params, &n, &max,
+ hints, nhints, keystr, v) < 0)
+ goto cleanup;
+ }
+ } else if (virPyDictToTypedParamOne(&params, &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__ */