Merge pull request #1553 from aerusso/master
[collectd.git] / src / cpython.h
1 /**
2  * collectd - src/cpython.h
3  * Copyright (C) 2009  Sven Trenkel
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  * Authors:
24  *   Sven Trenkel <collectd at semidefinite.de>
25  **/
26
27 /* Some python versions don't include this by default. */
28
29 #include <longintrepr.h>
30
31 /* These two macros are basically Py_BEGIN_ALLOW_THREADS and Py_BEGIN_ALLOW_THREADS
32  * from the other direction. If a Python thread calls a C function
33  * Py_BEGIN_ALLOW_THREADS is used to allow other python threads to run because
34  * we don't intend to call any Python functions.
35  *
36  * These two macros are used whenever a C thread intends to call some Python
37  * function, usually because some registered callback was triggered.
38  * Just like Py_BEGIN_ALLOW_THREADS it opens a block so these macros have to be
39  * used in pairs. They acquire the GIL, create a new Python thread state and swap
40  * the current thread state with the new one. This means this thread is now allowed
41  * to execute Python code. */
42
43 #define CPY_LOCK_THREADS {\
44         PyGILState_STATE gil_state;\
45         gil_state = PyGILState_Ensure();
46
47 #define CPY_RETURN_FROM_THREADS \
48         PyGILState_Release(gil_state);\
49         return
50
51 #define CPY_RELEASE_THREADS \
52         PyGILState_Release(gil_state);\
53 }
54
55 /* Python 2.4 has this macro, older versions do not. */
56 #ifndef Py_VISIT
57 #define Py_VISIT(o) do {\
58         int _vret;\
59         if ((o) != NULL) {\
60                 _vret = visit((o), arg);\
61                 if (_vret != 0)\
62                 return _vret;\
63         }\
64 } while (0)
65 #endif
66
67 /* Python 2.4 has this macro, older versions do not. */
68 #ifndef Py_CLEAR
69 #define Py_CLEAR(o) do {\
70         PyObject *tmp = o;\
71         (o) = NULL;\
72         Py_XDECREF(tmp);\
73 } while (0)
74 #endif
75
76 /* Python 2.4 has this macro, older versions do not. */
77 #ifndef Py_RETURN_NONE
78 # define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
79 #endif
80
81 /* This macro is a shortcut for calls like
82  * x = PyObject_Repr(x);
83  * This can't be done like this example because this would leak
84  * a reference the the original x and crash in case of x == NULL.
85  * This calling syntax is less than elegant but it works, saves
86  * a lot of lines and avoids potential refcount errors. */
87
88 #define CPY_SUBSTITUTE(func, a, ...) do {\
89         if ((a) != NULL) {\
90                 PyObject *__tmp = (a);\
91                 (a) = func(__VA_ARGS__);\
92                 Py_DECREF(__tmp);\
93         }\
94 } while(0)
95
96 /* Python3 compatibility layer. To keep the actual code as clean as possible
97  * do a lot of defines here. */
98
99 #if PY_MAJOR_VERSION >= 3
100 #define IS_PY3K
101 #endif
102
103 #ifdef IS_PY3K
104
105 #define PyInt_FromLong PyLong_FromLong
106 #define CPY_INIT_TYPE         PyVarObject_HEAD_INIT(NULL, 0)
107 #define IS_BYTES_OR_UNICODE(o) (PyUnicode_Check(o) || PyBytes_Check(o))
108 #define CPY_STRCAT_AND_DEL(a, b) do {\
109         CPY_STRCAT((a), (b));\
110         Py_XDECREF((b));\
111 } while (0)
112 static inline void CPY_STRCAT(PyObject **a, PyObject *b) {
113         PyObject *ret;
114
115         if (!a || !*a)
116                 return;
117
118         ret = PyUnicode_Concat(*a, b);
119         Py_DECREF(*a);
120         *a = ret;
121 }
122
123 #else
124
125 #define CPY_INIT_TYPE         PyObject_HEAD_INIT(NULL) 0,
126 #define IS_BYTES_OR_UNICODE(o) (PyUnicode_Check(o) || PyString_Check(o))
127 #define CPY_STRCAT_AND_DEL PyString_ConcatAndDel
128 #define CPY_STRCAT PyString_Concat
129
130 #endif
131
132 static inline const char *cpy_unicode_or_bytes_to_string(PyObject **o) {
133         if (PyUnicode_Check(*o)) {
134                 PyObject *tmp;
135                 tmp = PyUnicode_AsEncodedString(*o, NULL, NULL); /* New reference. */
136                 if (tmp == NULL)
137                         return NULL;
138                 Py_DECREF(*o);
139                 *o = tmp;
140         }
141 #ifdef IS_PY3K
142         return PyBytes_AsString(*o);
143 #else
144         return PyString_AsString(*o);
145 #endif
146 }
147
148 static inline PyObject *cpy_string_to_unicode_or_bytes(const char *buf) {
149 #ifdef IS_PY3K
150 /* Python3 preferrs unicode */
151         PyObject *ret;
152         ret = PyUnicode_Decode(buf, strlen(buf), NULL, NULL);
153         if (ret != NULL)
154                 return ret;
155         PyErr_Clear();
156         return PyBytes_FromString(buf);
157 #else
158         return PyString_FromString(buf);
159 #endif
160 }
161
162 void cpy_log_exception(const char *context);
163
164 /* Python object declarations. */
165
166 typedef struct {
167         PyObject_HEAD        /* No semicolon! */
168         PyObject *parent;    /* Config */
169         PyObject *key;       /* String */
170         PyObject *values;    /* Sequence */
171         PyObject *children;  /* Sequence */
172 } Config;
173 PyTypeObject ConfigType;
174
175 typedef struct {
176         PyObject_HEAD        /* No semicolon! */
177         double time;
178         char host[DATA_MAX_NAME_LEN];
179         char plugin[DATA_MAX_NAME_LEN];
180         char plugin_instance[DATA_MAX_NAME_LEN];
181         char type[DATA_MAX_NAME_LEN];
182         char type_instance[DATA_MAX_NAME_LEN];
183 } PluginData;
184 PyTypeObject PluginDataType;
185 #define PluginData_New() PyObject_CallFunctionObjArgs((PyObject *) &PluginDataType, (void *) 0)
186
187 typedef struct {
188         PluginData data;
189         PyObject *values;    /* Sequence */
190         PyObject *meta;      /* dict */
191         double interval;
192 } Values;
193 PyTypeObject ValuesType;
194 #define Values_New() PyObject_CallFunctionObjArgs((PyObject *) &ValuesType, (void *) 0)
195
196 typedef struct {
197         PluginData data;
198         int severity;
199         char message[NOTIF_MAX_MSG_LEN];
200 } Notification;
201 PyTypeObject NotificationType;
202 #define Notification_New() PyObject_CallFunctionObjArgs((PyObject *) &NotificationType, (void *) 0)
203
204 typedef PyLongObject Signed;
205 PyTypeObject SignedType;
206
207 typedef PyLongObject Unsigned;
208 PyTypeObject UnsignedType;
209