Code

Merge branch 'master' into ff/routeros
[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  **/
27 /* These two macros are basicly Py_BEGIN_ALLOW_THREADS and Py_BEGIN_ALLOW_THREADS
28  * from the other direction. If a Python thread calls a C function
29  * Py_BEGIN_ALLOW_THREADS is used to allow other python threads to run because
30  * we don't intend to call any Python functions.
31  *
32  * These two macros are used whenever a C thread intends to call some Python
33  * function, usually because some registered callback was triggered.
34  * Just like Py_BEGIN_ALLOW_THREADS it opens a block so these macros have to be
35  * used in pairs. They aquire the GIL, create a new Python thread state and swap
36  * the current thread state with the new one. This means this thread is now allowed
37  * to execute Python code. */
39 #define CPY_LOCK_THREADS {\
40         PyGILState_STATE gil_state;\
41         gil_state = PyGILState_Ensure();
43 #define CPY_RETURN_FROM_THREADS \
44         PyGILState_Release(gil_state);\
45         return
47 #define CPY_RELEASE_THREADS \
48         PyGILState_Release(gil_state);\
49 }
51 /* Python 2.4 has this macro, older versions do not. */
52 #ifndef Py_VISIT
53 #define Py_VISIT(o) do {\
54         int _vret;\
55         if ((o) != NULL) {\
56                 _vret = visit((o), arg);\
57                 if (_vret != 0)\
58                 return _vret;\
59         }\
60 } while (0)
61 #endif
63 /* Python 2.4 has this macro, older versions do not. */
64 #ifndef Py_CLEAR
65 #define Py_CLEAR(o) do {\
66         PyObject *tmp = o;\
67         (o) = NULL;\
68         Py_XDECREF(tmp);\
69 } while (0)
70 #endif
72 /* Python 2.4 has this macro, older versions do not. */
73 #ifndef Py_RETURN_NONE
74 # define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
75 #endif
77 /* This macro is a shortcut for calls like
78  * x = PyObject_Repr(x);
79  * This can't be done like this example because this would leak
80  * a reference the the original x and crash in case of x == NULL.
81  * This calling syntax is less than elegant but it works, saves
82  * a lot of lines and avoids potential refcount errors. */
84 #define CPY_SUBSTITUTE(func, a, ...) do {\
85         if ((a) != NULL) {\
86                 PyObject *__tmp = (a);\
87                 (a) = func(__VA_ARGS__);\
88                 Py_DECREF(__tmp);\
89         }\
90 } while(0)
92 /* Python3 compatibility layer. To keep the actual code as clean as possible
93  * do a lot of defines here. */
95 #if PY_MAJOR_VERSION >= 3
96 #define IS_PY3K
97 #endif
99 #ifdef IS_PY3K
101 #define PyInt_FromLong PyLong_FromLong
102 #define CPY_INIT_TYPE         PyVarObject_HEAD_INIT(NULL, 0)
103 #define IS_BYTES_OR_UNICODE(o) (PyUnicode_Check(o) || PyBytes_Check(o))
104 #define CPY_STRCAT_AND_DEL(a, b) do {\
105         CPY_STRCAT((a), (b));\
106         Py_XDECREF((b));\
107 } while (0)
108 static inline void CPY_STRCAT(PyObject **a, PyObject *b) {
109         PyObject *ret;
110         
111         if (!a || !*a)
112                 return;
113         
114         ret = PyUnicode_Concat(*a, b);
115         Py_DECREF(*a);
116         *a = ret;
119 #else
121 #define CPY_INIT_TYPE         PyObject_HEAD_INIT(NULL) 0,
122 #define IS_BYTES_OR_UNICODE(o) (PyUnicode_Check(o) || PyString_Check(o))
123 #define CPY_STRCAT_AND_DEL PyString_ConcatAndDel
124 #define CPY_STRCAT PyString_Concat
126 #endif
128 static inline const char *cpy_unicode_or_bytes_to_string(PyObject **o) {
129         if (PyUnicode_Check(*o)) {
130                 PyObject *tmp;
131                 tmp = PyUnicode_AsEncodedString(*o, NULL, NULL); /* New reference. */
132                 if (tmp == NULL)
133                         return NULL;
134                 Py_DECREF(*o);
135                 *o = tmp;
136         }
137 #ifdef IS_PY3K
138         return PyBytes_AsString(*o);
139 #else
140         return PyString_AsString(*o);
141 #endif
144 static inline PyObject *cpy_string_to_unicode_or_bytes(const char *buf) {
145 #ifdef IS_PY3K
146 /* Python3 preferrs unicode */
147         PyObject *ret;
148         ret = PyUnicode_Decode(buf, strlen(buf), NULL, NULL);
149         if (ret != NULL)
150                 return ret;
151         PyErr_Clear();
152         return PyBytes_FromString(buf);
153 #else
154         return PyString_FromString(buf);
155 #endif  
158  /* Python object declarations. */
160 typedef struct {
161         PyObject_HEAD        /* No semicolon! */
162         PyObject *parent;    /* Config */
163         PyObject *key;       /* String */
164         PyObject *values;    /* Sequence */
165         PyObject *children;  /* Sequence */
166 } Config;
168 PyTypeObject ConfigType;
170 typedef struct {
171         PyObject_HEAD        /* No semicolon! */
172         double time;
173         char host[DATA_MAX_NAME_LEN];
174         char plugin[DATA_MAX_NAME_LEN];
175         char plugin_instance[DATA_MAX_NAME_LEN];
176         char type[DATA_MAX_NAME_LEN];
177         char type_instance[DATA_MAX_NAME_LEN];
178 } PluginData;
180 PyTypeObject PluginDataType;
182 typedef struct {
183         PluginData data;
184         PyObject *values;    /* Sequence */
185         int interval;
186 } Values;
188 PyTypeObject ValuesType;
190 typedef struct {
191         PluginData data;
192         int severity;
193         char message[NOTIF_MAX_MSG_LEN];
194 } Notification;
196 PyTypeObject NotificationType;