xref: /freebsd-src/contrib/libucl/python/src/uclmodule.c (revision 273c26a3c3bea87a241d6879abd4f991db180bf0)
139ee7a7aSBaptiste Daroussin // Attempts to load a UCL structure from a string
239ee7a7aSBaptiste Daroussin #include <ucl.h>
339ee7a7aSBaptiste Daroussin #include <Python.h>
439ee7a7aSBaptiste Daroussin 
5*273c26a3SBaptiste Daroussin static PyObject *SchemaError;
6*273c26a3SBaptiste Daroussin 
739ee7a7aSBaptiste Daroussin static PyObject *
8d9f0ce31SBaptiste Daroussin _basic_ucl_type (ucl_object_t const *obj)
9d9f0ce31SBaptiste Daroussin {
10d9f0ce31SBaptiste Daroussin 	switch (obj->type) {
11d9f0ce31SBaptiste Daroussin 	case UCL_INT:
1239ee7a7aSBaptiste Daroussin 		return Py_BuildValue ("L", (long long)ucl_object_toint (obj));
13d9f0ce31SBaptiste Daroussin 	case UCL_FLOAT:
1439ee7a7aSBaptiste Daroussin 		return Py_BuildValue ("d", ucl_object_todouble (obj));
15d9f0ce31SBaptiste Daroussin 	case UCL_STRING:
1639ee7a7aSBaptiste Daroussin 		return Py_BuildValue ("s", ucl_object_tostring (obj));
17d9f0ce31SBaptiste Daroussin 	case UCL_BOOLEAN:
18*273c26a3SBaptiste Daroussin 		return PyBool_FromLong (ucl_object_toboolean (obj));
19d9f0ce31SBaptiste Daroussin 	case UCL_TIME:
2039ee7a7aSBaptiste Daroussin 		return Py_BuildValue ("d", ucl_object_todouble (obj));
21*273c26a3SBaptiste Daroussin 	case UCL_NULL:
22*273c26a3SBaptiste Daroussin 		Py_RETURN_NONE;
2339ee7a7aSBaptiste Daroussin 	}
2439ee7a7aSBaptiste Daroussin 	return NULL;
2539ee7a7aSBaptiste Daroussin }
2639ee7a7aSBaptiste Daroussin 
2739ee7a7aSBaptiste Daroussin static PyObject *
28d9f0ce31SBaptiste Daroussin _iterate_valid_ucl (ucl_object_t const *obj)
29d9f0ce31SBaptiste Daroussin {
3039ee7a7aSBaptiste Daroussin 	const ucl_object_t *tmp;
3139ee7a7aSBaptiste Daroussin 	ucl_object_iter_t it = NULL;
3239ee7a7aSBaptiste Daroussin 
3339ee7a7aSBaptiste Daroussin 	tmp = obj;
3439ee7a7aSBaptiste Daroussin 
35d9f0ce31SBaptiste Daroussin 	while ((obj = ucl_object_iterate (tmp, &it, false))) {
3639ee7a7aSBaptiste Daroussin 		PyObject *val;
3739ee7a7aSBaptiste Daroussin 
3839ee7a7aSBaptiste Daroussin 		val = _basic_ucl_type(obj);
3939ee7a7aSBaptiste Daroussin 		if (!val) {
4039ee7a7aSBaptiste Daroussin 			PyObject *key = NULL;
41d9f0ce31SBaptiste Daroussin 
4239ee7a7aSBaptiste Daroussin 			if (obj->key != NULL) {
4339ee7a7aSBaptiste Daroussin 				key = Py_BuildValue("s", ucl_object_key(obj));
4439ee7a7aSBaptiste Daroussin 			}
4539ee7a7aSBaptiste Daroussin 
4639ee7a7aSBaptiste Daroussin 			if (obj->type == UCL_OBJECT) {
4739ee7a7aSBaptiste Daroussin 				const ucl_object_t *cur;
4839ee7a7aSBaptiste Daroussin 				ucl_object_iter_t it_obj = NULL;
49d9f0ce31SBaptiste Daroussin 
50d9f0ce31SBaptiste Daroussin 				val = PyDict_New();
51d9f0ce31SBaptiste Daroussin 
52d9f0ce31SBaptiste Daroussin 				while ((cur = ucl_object_iterate (obj, &it_obj, true))) {
5339ee7a7aSBaptiste Daroussin 					PyObject *keyobj = Py_BuildValue("s",ucl_object_key(cur));
5439ee7a7aSBaptiste Daroussin 					PyDict_SetItem(val, keyobj, _iterate_valid_ucl(cur));
5539ee7a7aSBaptiste Daroussin 				}
56d9f0ce31SBaptiste Daroussin 			} else if (obj->type == UCL_ARRAY) {
5739ee7a7aSBaptiste Daroussin 				const ucl_object_t *cur;
5839ee7a7aSBaptiste Daroussin 				ucl_object_iter_t it_obj = NULL;
59d9f0ce31SBaptiste Daroussin 
60d9f0ce31SBaptiste Daroussin 				val = PyList_New(0);
61d9f0ce31SBaptiste Daroussin 
62d9f0ce31SBaptiste Daroussin 				while ((cur = ucl_object_iterate (obj, &it_obj, true))) {
6339ee7a7aSBaptiste Daroussin 					PyList_Append(val, _iterate_valid_ucl(cur));
6439ee7a7aSBaptiste Daroussin 				}
65d9f0ce31SBaptiste Daroussin 			} else if (obj->type == UCL_USERDATA) {
6639ee7a7aSBaptiste Daroussin 				// XXX: this should be
6739ee7a7aSBaptiste Daroussin 				// PyBytes_FromStringAndSize; where is the
6839ee7a7aSBaptiste Daroussin 				// length from?
6939ee7a7aSBaptiste Daroussin 				val = PyBytes_FromString(obj->value.ud);
7039ee7a7aSBaptiste Daroussin 			}
7139ee7a7aSBaptiste Daroussin 		}
7239ee7a7aSBaptiste Daroussin 		return val;
7339ee7a7aSBaptiste Daroussin 	}
7439ee7a7aSBaptiste Daroussin 
7539ee7a7aSBaptiste Daroussin 	PyErr_SetString(PyExc_SystemError, "unhandled type");
7639ee7a7aSBaptiste Daroussin 	return NULL;
7739ee7a7aSBaptiste Daroussin }
7839ee7a7aSBaptiste Daroussin 
7939ee7a7aSBaptiste Daroussin static PyObject *
80d9f0ce31SBaptiste Daroussin _internal_load_ucl (char *uclstr)
81d9f0ce31SBaptiste Daroussin {
8239ee7a7aSBaptiste Daroussin 	PyObject *ret;
8339ee7a7aSBaptiste Daroussin 	struct ucl_parser *parser = ucl_parser_new (UCL_PARSER_NO_TIME);
8439ee7a7aSBaptiste Daroussin 	bool r = ucl_parser_add_string(parser, uclstr, 0);
85d9f0ce31SBaptiste Daroussin 
8639ee7a7aSBaptiste Daroussin 	if (r) {
8739ee7a7aSBaptiste Daroussin 		if (ucl_parser_get_error (parser)) {
8839ee7a7aSBaptiste Daroussin 			PyErr_SetString(PyExc_ValueError, ucl_parser_get_error(parser));
8939ee7a7aSBaptiste Daroussin 			ucl_parser_free(parser);
9039ee7a7aSBaptiste Daroussin 			ret = NULL;
9139ee7a7aSBaptiste Daroussin 			goto return_with_parser;
9239ee7a7aSBaptiste Daroussin 		} else {
9339ee7a7aSBaptiste Daroussin 			ucl_object_t *uclobj = ucl_parser_get_object(parser);
9439ee7a7aSBaptiste Daroussin 			ret = _iterate_valid_ucl(uclobj);
9539ee7a7aSBaptiste Daroussin 			ucl_object_unref(uclobj);
9639ee7a7aSBaptiste Daroussin 			goto return_with_parser;
9739ee7a7aSBaptiste Daroussin 		}
98d9f0ce31SBaptiste Daroussin 	}
99d9f0ce31SBaptiste Daroussin 	else {
10039ee7a7aSBaptiste Daroussin 		PyErr_SetString(PyExc_ValueError, ucl_parser_get_error (parser));
10139ee7a7aSBaptiste Daroussin 		ret = NULL;
10239ee7a7aSBaptiste Daroussin 		goto return_with_parser;
10339ee7a7aSBaptiste Daroussin 	}
10439ee7a7aSBaptiste Daroussin 
10539ee7a7aSBaptiste Daroussin return_with_parser:
10639ee7a7aSBaptiste Daroussin 	ucl_parser_free(parser);
10739ee7a7aSBaptiste Daroussin 	return ret;
10839ee7a7aSBaptiste Daroussin }
10939ee7a7aSBaptiste Daroussin 
11039ee7a7aSBaptiste Daroussin static PyObject*
111d9f0ce31SBaptiste Daroussin ucl_load (PyObject *self, PyObject *args)
112d9f0ce31SBaptiste Daroussin {
11339ee7a7aSBaptiste Daroussin 	char *uclstr;
114d9f0ce31SBaptiste Daroussin 
11539ee7a7aSBaptiste Daroussin 	if (PyArg_ParseTuple(args, "z", &uclstr)) {
11639ee7a7aSBaptiste Daroussin 		if (!uclstr) {
11739ee7a7aSBaptiste Daroussin 			Py_RETURN_NONE;
11839ee7a7aSBaptiste Daroussin 		}
119d9f0ce31SBaptiste Daroussin 
12039ee7a7aSBaptiste Daroussin 		return _internal_load_ucl(uclstr);
12139ee7a7aSBaptiste Daroussin 	}
122d9f0ce31SBaptiste Daroussin 
123d9f0ce31SBaptiste Daroussin 	return NULL;
124d9f0ce31SBaptiste Daroussin }
125d9f0ce31SBaptiste Daroussin 
126d9f0ce31SBaptiste Daroussin static ucl_object_t *
127d9f0ce31SBaptiste Daroussin _iterate_python (PyObject *obj)
128d9f0ce31SBaptiste Daroussin {
129d9f0ce31SBaptiste Daroussin 	if (obj == Py_None) {
130d9f0ce31SBaptiste Daroussin 		return ucl_object_new();
131d9f0ce31SBaptiste Daroussin 	}
132*273c26a3SBaptiste Daroussin 	else if (PyBool_Check (obj)) {
133*273c26a3SBaptiste Daroussin 		return ucl_object_frombool (obj == Py_True);
134*273c26a3SBaptiste Daroussin 	}
135*273c26a3SBaptiste Daroussin #if PY_MAJOR_VERSION < 3
136*273c26a3SBaptiste Daroussin 	else if (PyInt_Check (obj)) {
137*273c26a3SBaptiste Daroussin 		return ucl_object_fromint (PyInt_AsLong (obj));
138*273c26a3SBaptiste Daroussin 	}
139*273c26a3SBaptiste Daroussin #endif
140*273c26a3SBaptiste Daroussin 	else if (PyLong_Check (obj)) {
141*273c26a3SBaptiste Daroussin 		return ucl_object_fromint (PyLong_AsLong (obj));
142*273c26a3SBaptiste Daroussin 	}
143*273c26a3SBaptiste Daroussin 	else if (PyFloat_Check (obj)) {
144*273c26a3SBaptiste Daroussin 		return ucl_object_fromdouble (PyFloat_AsDouble (obj));
145*273c26a3SBaptiste Daroussin 	}
146*273c26a3SBaptiste Daroussin 	else if (PyUnicode_Check (obj)) {
147*273c26a3SBaptiste Daroussin 		ucl_object_t *ucl_str;
148*273c26a3SBaptiste Daroussin 		PyObject *str = PyUnicode_AsASCIIString(obj);
149*273c26a3SBaptiste Daroussin 		ucl_str = ucl_object_fromstring (PyBytes_AsString (str));
150*273c26a3SBaptiste Daroussin 		Py_DECREF(str);
151*273c26a3SBaptiste Daroussin 		return ucl_str;
152*273c26a3SBaptiste Daroussin 	}
153*273c26a3SBaptiste Daroussin #if PY_MAJOR_VERSION < 3
154*273c26a3SBaptiste Daroussin 	else if (PyString_Check (obj)) {
155*273c26a3SBaptiste Daroussin 		return ucl_object_fromstring (PyString_AsString (obj));
156*273c26a3SBaptiste Daroussin 	}
157*273c26a3SBaptiste Daroussin #endif
158d9f0ce31SBaptiste Daroussin 	else if (PyDict_Check(obj)) {
159d9f0ce31SBaptiste Daroussin 		PyObject *key, *value;
160d9f0ce31SBaptiste Daroussin 		Py_ssize_t pos = 0;
161d9f0ce31SBaptiste Daroussin 		ucl_object_t *top, *elm;
162*273c26a3SBaptiste Daroussin 		char *keystr = NULL;
163d9f0ce31SBaptiste Daroussin 
164d9f0ce31SBaptiste Daroussin 		top = ucl_object_typed_new (UCL_OBJECT);
165d9f0ce31SBaptiste Daroussin 
166d9f0ce31SBaptiste Daroussin 		while (PyDict_Next(obj, &pos, &key, &value)) {
167d9f0ce31SBaptiste Daroussin 			elm = _iterate_python(value);
168*273c26a3SBaptiste Daroussin 
169*273c26a3SBaptiste Daroussin 			if (PyUnicode_Check(key)) {
170*273c26a3SBaptiste Daroussin 				PyObject *keyascii = PyUnicode_AsASCIIString(key);
171*273c26a3SBaptiste Daroussin 				keystr = PyBytes_AsString(keyascii);
172*273c26a3SBaptiste Daroussin 				Py_DECREF(keyascii);
173*273c26a3SBaptiste Daroussin 			}
174*273c26a3SBaptiste Daroussin #if PY_MAJOR_VERSION < 3
175*273c26a3SBaptiste Daroussin 			else if (PyString_Check(key)) {
176*273c26a3SBaptiste Daroussin 				keystr = PyString_AsString(key);
177*273c26a3SBaptiste Daroussin 			}
178*273c26a3SBaptiste Daroussin #endif
179*273c26a3SBaptiste Daroussin 			else {
180*273c26a3SBaptiste Daroussin 				PyErr_SetString(PyExc_TypeError, "Unknown key type");
181*273c26a3SBaptiste Daroussin 				return NULL;
182*273c26a3SBaptiste Daroussin 			}
183*273c26a3SBaptiste Daroussin 
184*273c26a3SBaptiste Daroussin 			ucl_object_insert_key (top, elm, keystr, 0, true);
185d9f0ce31SBaptiste Daroussin 		}
186d9f0ce31SBaptiste Daroussin 
187d9f0ce31SBaptiste Daroussin 		return top;
188d9f0ce31SBaptiste Daroussin 	}
189d9f0ce31SBaptiste Daroussin 	else if (PySequence_Check(obj)) {
190d9f0ce31SBaptiste Daroussin 		PyObject *value;
191d9f0ce31SBaptiste Daroussin 		Py_ssize_t len, pos;
192d9f0ce31SBaptiste Daroussin 		ucl_object_t *top, *elm;
193d9f0ce31SBaptiste Daroussin 
194d9f0ce31SBaptiste Daroussin 		len  = PySequence_Length(obj);
195d9f0ce31SBaptiste Daroussin 		top = ucl_object_typed_new (UCL_ARRAY);
196d9f0ce31SBaptiste Daroussin 
197d9f0ce31SBaptiste Daroussin 		for (pos = 0; pos < len; pos++) {
198d9f0ce31SBaptiste Daroussin 			value = PySequence_GetItem(obj, pos);
199d9f0ce31SBaptiste Daroussin 			elm = _iterate_python(value);
200d9f0ce31SBaptiste Daroussin 			ucl_array_append(top, elm);
201d9f0ce31SBaptiste Daroussin 		}
202d9f0ce31SBaptiste Daroussin 
203d9f0ce31SBaptiste Daroussin 		return top;
204d9f0ce31SBaptiste Daroussin 	}
205d9f0ce31SBaptiste Daroussin 	else {
206d9f0ce31SBaptiste Daroussin 		PyErr_SetString(PyExc_TypeError, "Unhandled object type");
207d9f0ce31SBaptiste Daroussin 		return NULL;
208d9f0ce31SBaptiste Daroussin 	}
209d9f0ce31SBaptiste Daroussin 
21039ee7a7aSBaptiste Daroussin 	return NULL;
21139ee7a7aSBaptiste Daroussin }
21239ee7a7aSBaptiste Daroussin 
21339ee7a7aSBaptiste Daroussin static PyObject *
214d9f0ce31SBaptiste Daroussin ucl_dump (PyObject *self, PyObject *args)
215d9f0ce31SBaptiste Daroussin {
216d9f0ce31SBaptiste Daroussin 	PyObject *obj;
217d9f0ce31SBaptiste Daroussin 	ucl_emitter_t emitter;
218d9f0ce31SBaptiste Daroussin 	ucl_object_t *root = NULL;
219d9f0ce31SBaptiste Daroussin 
220d9f0ce31SBaptiste Daroussin 	emitter = UCL_EMIT_CONFIG;
221d9f0ce31SBaptiste Daroussin 
222d9f0ce31SBaptiste Daroussin 	if (!PyArg_ParseTuple(args, "O|i", &obj, &emitter)) {
223d9f0ce31SBaptiste Daroussin 		PyErr_SetString(PyExc_TypeError, "Unhandled object type");
224d9f0ce31SBaptiste Daroussin 		return NULL;
225d9f0ce31SBaptiste Daroussin 	}
226d9f0ce31SBaptiste Daroussin 
227d9f0ce31SBaptiste Daroussin 	if (emitter >= UCL_EMIT_MAX) {
228d9f0ce31SBaptiste Daroussin 		PyErr_SetString(PyExc_TypeError, "Invalid emitter type");
229d9f0ce31SBaptiste Daroussin 		return NULL;
230d9f0ce31SBaptiste Daroussin 	}
231d9f0ce31SBaptiste Daroussin 
232d9f0ce31SBaptiste Daroussin 	if (obj == Py_None) {
233d9f0ce31SBaptiste Daroussin 		Py_RETURN_NONE;
234d9f0ce31SBaptiste Daroussin 	}
235d9f0ce31SBaptiste Daroussin 
236d9f0ce31SBaptiste Daroussin 	root = _iterate_python(obj);
237d9f0ce31SBaptiste Daroussin 	if (root) {
238d9f0ce31SBaptiste Daroussin 		PyObject *ret;
239d9f0ce31SBaptiste Daroussin 		char *buf;
240d9f0ce31SBaptiste Daroussin 
241d9f0ce31SBaptiste Daroussin 		buf = (char *) ucl_object_emit (root, emitter);
242d9f0ce31SBaptiste Daroussin 		ucl_object_unref (root);
243*273c26a3SBaptiste Daroussin #if PY_MAJOR_VERSION < 3
244d9f0ce31SBaptiste Daroussin 		ret = PyString_FromString (buf);
245*273c26a3SBaptiste Daroussin #else
246*273c26a3SBaptiste Daroussin 		ret = PyUnicode_FromString (buf);
247*273c26a3SBaptiste Daroussin #endif
248d9f0ce31SBaptiste Daroussin 		free(buf);
249d9f0ce31SBaptiste Daroussin 
250d9f0ce31SBaptiste Daroussin 		return ret;
251d9f0ce31SBaptiste Daroussin 	}
252d9f0ce31SBaptiste Daroussin 
253d9f0ce31SBaptiste Daroussin 	return NULL;
254d9f0ce31SBaptiste Daroussin }
255d9f0ce31SBaptiste Daroussin 
256d9f0ce31SBaptiste Daroussin static PyObject *
257d9f0ce31SBaptiste Daroussin ucl_validate (PyObject *self, PyObject *args)
258d9f0ce31SBaptiste Daroussin {
259*273c26a3SBaptiste Daroussin 	PyObject *dataobj, *schemaobj;
260*273c26a3SBaptiste Daroussin 	ucl_object_t *data, *schema;
261*273c26a3SBaptiste Daroussin 	bool r;
262*273c26a3SBaptiste Daroussin 	struct ucl_schema_error err;
263d9f0ce31SBaptiste Daroussin 
264*273c26a3SBaptiste Daroussin 	if (!PyArg_ParseTuple (args, "OO", &schemaobj, &dataobj)) {
265*273c26a3SBaptiste Daroussin 		PyErr_SetString (PyExc_TypeError, "Unhandled object type");
26639ee7a7aSBaptiste Daroussin 		return NULL;
26739ee7a7aSBaptiste Daroussin 	}
26839ee7a7aSBaptiste Daroussin 
269*273c26a3SBaptiste Daroussin 	schema = _iterate_python(schemaobj);
270*273c26a3SBaptiste Daroussin 	if (!schema)
271*273c26a3SBaptiste Daroussin 		return NULL;
272*273c26a3SBaptiste Daroussin 
273*273c26a3SBaptiste Daroussin 	data = _iterate_python(dataobj);
274*273c26a3SBaptiste Daroussin 	if (!data)
275*273c26a3SBaptiste Daroussin 		return NULL;
276*273c26a3SBaptiste Daroussin 
277*273c26a3SBaptiste Daroussin 	// validation
278*273c26a3SBaptiste Daroussin 	r = ucl_object_validate (schema, data, &err);
279*273c26a3SBaptiste Daroussin 	ucl_object_unref (schema);
280*273c26a3SBaptiste Daroussin 	ucl_object_unref (data);
281*273c26a3SBaptiste Daroussin 
282*273c26a3SBaptiste Daroussin 	if (!r) {
283*273c26a3SBaptiste Daroussin 		PyErr_SetString (SchemaError, err.msg);
284*273c26a3SBaptiste Daroussin 		return NULL;
285*273c26a3SBaptiste Daroussin 	}
286*273c26a3SBaptiste Daroussin 
287*273c26a3SBaptiste Daroussin 	Py_RETURN_TRUE;
288*273c26a3SBaptiste Daroussin }
289*273c26a3SBaptiste Daroussin 
29039ee7a7aSBaptiste Daroussin static PyMethodDef uclMethods[] = {
29139ee7a7aSBaptiste Daroussin 	{"load", ucl_load, METH_VARARGS, "Load UCL from stream"},
292d9f0ce31SBaptiste Daroussin 	{"dump", ucl_dump, METH_VARARGS, "Dump UCL to stream"},
29339ee7a7aSBaptiste Daroussin 	{"validate", ucl_validate, METH_VARARGS, "Validate ucl stream against schema"},
29439ee7a7aSBaptiste Daroussin 	{NULL, NULL, 0, NULL}
29539ee7a7aSBaptiste Daroussin };
29639ee7a7aSBaptiste Daroussin 
297d9f0ce31SBaptiste Daroussin static void
298d9f0ce31SBaptiste Daroussin init_macros(PyObject *mod)
299d9f0ce31SBaptiste Daroussin {
300d9f0ce31SBaptiste Daroussin 	PyModule_AddIntMacro(mod, UCL_EMIT_JSON);
301d9f0ce31SBaptiste Daroussin 	PyModule_AddIntMacro(mod, UCL_EMIT_JSON_COMPACT);
302d9f0ce31SBaptiste Daroussin 	PyModule_AddIntMacro(mod, UCL_EMIT_CONFIG);
303d9f0ce31SBaptiste Daroussin 	PyModule_AddIntMacro(mod, UCL_EMIT_YAML);
304d9f0ce31SBaptiste Daroussin 	PyModule_AddIntMacro(mod, UCL_EMIT_MSGPACK);
305*273c26a3SBaptiste Daroussin 
306*273c26a3SBaptiste Daroussin 	SchemaError = PyErr_NewException("ucl.SchemaError", NULL, NULL);
307*273c26a3SBaptiste Daroussin 	Py_INCREF(SchemaError);
308*273c26a3SBaptiste Daroussin 	PyModule_AddObject(mod, "SchemaError", SchemaError);
309d9f0ce31SBaptiste Daroussin }
310d9f0ce31SBaptiste Daroussin 
31139ee7a7aSBaptiste Daroussin #if PY_MAJOR_VERSION >= 3
31239ee7a7aSBaptiste Daroussin static struct PyModuleDef uclmodule = {
31339ee7a7aSBaptiste Daroussin 	PyModuleDef_HEAD_INIT,
31439ee7a7aSBaptiste Daroussin 	"ucl",
31539ee7a7aSBaptiste Daroussin 	NULL,
31639ee7a7aSBaptiste Daroussin 	-1,
31739ee7a7aSBaptiste Daroussin 	uclMethods
31839ee7a7aSBaptiste Daroussin };
31939ee7a7aSBaptiste Daroussin 
32039ee7a7aSBaptiste Daroussin PyMODINIT_FUNC
321d9f0ce31SBaptiste Daroussin PyInit_ucl (void)
322d9f0ce31SBaptiste Daroussin {
323d9f0ce31SBaptiste Daroussin 	PyObject *mod = PyModule_Create (&uclmodule);
324d9f0ce31SBaptiste Daroussin 	init_macros (mod);
325d9f0ce31SBaptiste Daroussin 
326d9f0ce31SBaptiste Daroussin 	return mod;
32739ee7a7aSBaptiste Daroussin }
32839ee7a7aSBaptiste Daroussin #else
329d9f0ce31SBaptiste Daroussin void initucl (void)
330d9f0ce31SBaptiste Daroussin {
331d9f0ce31SBaptiste Daroussin 	PyObject *mod = Py_InitModule ("ucl", uclMethods);
332d9f0ce31SBaptiste Daroussin 	init_macros (mod);
33339ee7a7aSBaptiste Daroussin }
33439ee7a7aSBaptiste Daroussin #endif
335