X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fcpython.h;h=4b8aa72143167864ff575147c5ef19949997ab50;hb=26e01e52629e0894e34ad3deb6c9fc921d145443;hp=001a3ae9829e0d0d7836222270f7427c8442bc65;hpb=0b030d276a8c0246e9a582d0d4041048044ac025;p=collectd.git diff --git a/src/cpython.h b/src/cpython.h index 001a3ae9..4b8aa721 100644 --- a/src/cpython.h +++ b/src/cpython.h @@ -24,6 +24,10 @@ * Sven Trenkel **/ +/* Some python versions don't include this by default. */ + +#include + /* These two macros are basicly Py_BEGIN_ALLOW_THREADS and Py_BEGIN_ALLOW_THREADS * from the other direction. If a Python thread calls a C function * Py_BEGIN_ALLOW_THREADS is used to allow other python threads to run because @@ -74,6 +78,20 @@ # define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None #endif +/* This macro is a shortcut for calls like + * x = PyObject_Repr(x); + * This can't be done like this example because this would leak + * a reference the the original x and crash in case of x == NULL. + * This calling syntax is less than elegant but it works, saves + * a lot of lines and avoids potential refcount errors. */ + +#define CPY_SUBSTITUTE(func, a, ...) do {\ + if ((a) != NULL) {\ + PyObject *__tmp = (a);\ + (a) = func(__VA_ARGS__);\ + Py_DECREF(__tmp);\ + }\ +} while(0) /* Python3 compatibility layer. To keep the actual code as clean as possible * do a lot of defines here. */ @@ -87,12 +105,26 @@ #define PyInt_FromLong PyLong_FromLong #define CPY_INIT_TYPE PyVarObject_HEAD_INIT(NULL, 0) #define IS_BYTES_OR_UNICODE(o) (PyUnicode_Check(o) || PyBytes_Check(o)) -#define CPY_STRCAT PyUnicode_Concat +#define CPY_STRCAT_AND_DEL(a, b) do {\ + CPY_STRCAT((a), (b));\ + Py_XDECREF((b));\ +} while (0) +static inline void CPY_STRCAT(PyObject **a, PyObject *b) { + PyObject *ret; + + if (!a || !*a) + return; + + ret = PyUnicode_Concat(*a, b); + Py_DECREF(*a); + *a = ret; +} #else #define CPY_INIT_TYPE PyObject_HEAD_INIT(NULL) 0, #define IS_BYTES_OR_UNICODE(o) (PyUnicode_Check(o) || PyString_Check(o)) +#define CPY_STRCAT_AND_DEL PyString_ConcatAndDel #define CPY_STRCAT PyString_Concat #endif @@ -106,7 +138,11 @@ static inline const char *cpy_unicode_or_bytes_to_string(PyObject **o) { Py_DECREF(*o); *o = tmp; } +#ifdef IS_PY3K return PyBytes_AsString(*o); +#else + return PyString_AsString(*o); +#endif } static inline PyObject *cpy_string_to_unicode_or_bytes(const char *buf) { @@ -117,11 +153,15 @@ static inline PyObject *cpy_string_to_unicode_or_bytes(const char *buf) { if (ret != NULL) return ret; PyErr_Clear(); -#endif return PyBytes_FromString(buf); +#else + return PyString_FromString(buf); +#endif } - /* Python object declarations. */ +void cpy_log_exception(const char *context); + +/* Python object declarations. */ typedef struct { PyObject_HEAD /* No semicolon! */ @@ -130,7 +170,6 @@ typedef struct { PyObject *values; /* Sequence */ PyObject *children; /* Sequence */ } Config; - PyTypeObject ConfigType; typedef struct { @@ -142,21 +181,29 @@ typedef struct { char type[DATA_MAX_NAME_LEN]; char type_instance[DATA_MAX_NAME_LEN]; } PluginData; - PyTypeObject PluginDataType; +#define PluginData_New() PyObject_CallFunctionObjArgs((PyObject *) &PluginDataType, (void *) 0) typedef struct { PluginData data; PyObject *values; /* Sequence */ - int interval; + PyObject *meta; /* dict */ + double interval; } Values; - PyTypeObject ValuesType; +#define Values_New() PyObject_CallFunctionObjArgs((PyObject *) &ValuesType, (void *) 0) typedef struct { PluginData data; int severity; char message[NOTIF_MAX_MSG_LEN]; } Notification; - PyTypeObject NotificationType; +#define Notification_New() PyObject_CallFunctionObjArgs((PyObject *) &NotificationType, (void *) 0) + +typedef PyLongObject Signed; +PyTypeObject SignedType; + +typedef PyLongObject Unsigned; +PyTypeObject UnsignedType; +