chiark / gitweb /
macro: introduce nice macro for disabling -Wmissing-prototypes warnigs
[elogind.git] / src / python-systemd / id128.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Zbigniew JÄ™drzejewski-Szmek <zbyszek@in.waw.pl>
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <Python.h>
23
24 #include <systemd/sd-messages.h>
25
26 #include "pyutil.h"
27 #include "log.h"
28 #include "util.h"
29 #include "macro.h"
30
31 PyDoc_STRVAR(module__doc__,
32              "Python interface to the libsystemd-id128 library.\n\n"
33              "Provides SD_MESSAGE_* constants and functions to query and generate\n"
34              "128-bit unique identifiers."
35 );
36
37 PyDoc_STRVAR(randomize__doc__,
38              "randomize() -> UUID\n\n"
39              "Return a new random 128-bit unique identifier.\n"
40              "Wraps sd_id128_randomize(3)."
41 );
42
43 PyDoc_STRVAR(get_machine__doc__,
44              "get_machine() -> UUID\n\n"
45              "Return a 128-bit unique identifier for this machine.\n"
46              "Wraps sd_id128_get_machine(3)."
47 );
48
49 PyDoc_STRVAR(get_boot__doc__,
50              "get_boot() -> UUID\n\n"
51              "Return a 128-bit unique identifier for this boot.\n"
52              "Wraps sd_id128_get_boot(3)."
53 );
54
55 static PyObject* make_uuid(sd_id128_t id) {
56         _cleanup_Py_DECREF_ PyObject
57                 *uuid = NULL, *UUID = NULL, *bytes = NULL,
58                 *args = NULL, *kwargs = NULL;
59
60         uuid = PyImport_ImportModule("uuid");
61         if (!uuid)
62                 return NULL;
63
64         UUID = PyObject_GetAttrString(uuid, "UUID");
65         bytes = PyBytes_FromStringAndSize((const char*) &id.bytes, sizeof(id.bytes));
66         args = Py_BuildValue("()");
67         kwargs = PyDict_New();
68         if (!UUID || !bytes || !args || !kwargs)
69                 return NULL;
70
71         if (PyDict_SetItemString(kwargs, "bytes", bytes) < 0)
72                 return NULL;
73
74         return PyObject_Call(UUID, args, kwargs);
75 }
76
77 #define helper(name)                                                    \
78         static PyObject *name(PyObject *self, PyObject *args) {         \
79                 sd_id128_t id;                                          \
80                 int r;                                                  \
81                                                                         \
82                 assert(args == NULL);                                   \
83                                                                         \
84                 r = sd_id128_##name(&id);                               \
85                 if (r < 0) {                                            \
86                         errno = -r;                                     \
87                         return PyErr_SetFromErrno(PyExc_IOError);       \
88                 }                                                       \
89                                                                         \
90                 return make_uuid(id);                                   \
91         }
92
93 helper(randomize)
94 helper(get_machine)
95 helper(get_boot)
96
97 static PyMethodDef methods[] = {
98         { "randomize", randomize, METH_NOARGS, randomize__doc__},
99         { "get_machine", get_machine, METH_NOARGS, get_machine__doc__},
100         { "get_boot", get_boot, METH_NOARGS, get_boot__doc__},
101         { NULL, NULL, 0, NULL }        /* Sentinel */
102 };
103
104 static int add_id(PyObject *module, const char* name, sd_id128_t id) {
105         PyObject *obj;
106
107         obj = make_uuid(id);
108         if (!obj)
109                 return -1;
110
111         return PyModule_AddObject(module, name, obj);
112 }
113
114 #if PY_MAJOR_VERSION < 3
115
116 DISABLE_WARNING_MISSING_PROTOTYPES;
117 PyMODINIT_FUNC initid128(void) {
118         PyObject *m;
119
120         m = Py_InitModule3("id128", methods, module__doc__);
121         if (m == NULL)
122                 return;
123
124         /* a series of lines like 'add_id() ;' follow */
125 #define JOINER ;
126 #include "id128-constants.h"
127 #undef JOINER
128         PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
129 }
130 REENABLE_WARNING;
131
132 #else
133
134 static struct PyModuleDef module = {
135         PyModuleDef_HEAD_INIT,
136         "id128", /* name of module */
137         module__doc__, /* module documentation, may be NULL */
138         -1, /* size of per-interpreter state of the module */
139         methods
140 };
141
142 DISABLE_WARNING_MISSING_PROTOTYPES;
143 PyMODINIT_FUNC PyInit_id128(void) {
144         PyObject *m;
145
146         m = PyModule_Create(&module);
147         if (m == NULL)
148                 return NULL;
149
150         if ( /* a series of lines like 'add_id() ||' follow */
151 #define JOINER ||
152 #include "id128-constants.h"
153 #undef JOINER
154             PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION)) {
155                 Py_DECREF(m);
156                 return NULL;
157         }
158
159         return m;
160 }
161 REENABLE_WARNING;
162
163 #endif