summaryrefslogtreecommitdiff
path: root/giscanner/giscannermodule.c
diff options
context:
space:
mode:
authorSimon Feltman <sfeltman@src.gnome.org>2014-04-28 20:25:30 -0700
committerColin Walters <walters@verbum.org>2015-09-29 23:16:32 -0400
commitae198873254769bd49207003d25b47d12b096e2f (patch)
tree5c192285bbcb92e400c38307ce72a1f96e1c4270 /giscanner/giscannermodule.c
parentd59b3827d2bb62c1ed4db8030ed9e8e753b7f52d (diff)
downloadgobject-introspection-ae198873254769bd49207003d25b47d12b096e2f.tar.gz
giscanner: Port scanner extension module to work with Python 3
Define portable macros for use between Python 2 and 3. Replace usage of PyString related functions with PyBytes. Update pygi_source_scanner_parse_macros to support both PyBytes and PyUnicode. https://bugzilla.gnome.org/show_bug.cgi?id=679438
Diffstat (limited to 'giscanner/giscannermodule.c')
-rw-r--r--giscanner/giscannermodule.c104
1 files changed, 75 insertions, 29 deletions
diff --git a/giscanner/giscannermodule.c b/giscanner/giscannermodule.c
index f6945da3..845a72f5 100644
--- a/giscanner/giscannermodule.c
+++ b/giscanner/giscannermodule.c
@@ -39,32 +39,38 @@
#include <glib-object.h>
-DL_EXPORT(void) init_giscanner(void);
+#ifndef Py_TYPE
+ #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
+#endif
+
+#if PY_MAJOR_VERSION >= 3
+ #define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
+ #define MOD_ERROR_RETURN NULL
+ #define PyInt_FromLong PyLong_FromLong
+#else
+ #define MOD_INIT(name) DL_EXPORT(void) init##name(void)
+ #define MOD_ERROR_RETURN
+#endif
+
+/* forward declaration */
+MOD_INIT(_giscanner);
#define NEW_CLASS(ctype, name, cname, num_methods) \
static const PyMethodDef _Py##cname##_methods[num_methods]; \
PyTypeObject Py##cname##_Type = { \
- PyObject_HEAD_INIT(NULL) \
- 0, \
+ PyVarObject_HEAD_INIT(NULL, 0) \
"scanner." name, \
- sizeof(ctype), \
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 0, 0, 0, \
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, \
- NULL, 0, 0, 0, \
- 0, \
- 0, 0, \
- 0, \
- 0, 0, NULL, NULL, 0, 0, \
- 0 \
+ sizeof(ctype), \
+ 0 \
}
#define REGISTER_TYPE(d, name, type) \
- type.ob_type = &PyType_Type; \
+ Py_TYPE(&type) = &PyType_Type; \
type.tp_alloc = PyType_GenericAlloc; \
type.tp_new = PyType_GenericNew; \
+ type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; \
if (PyType_Ready (&type)) \
- return; \
+ return MOD_ERROR_RETURN; \
PyDict_SetItemString (d, name, (PyObject *)&type); \
Py_INCREF (&type);
@@ -402,16 +408,34 @@ pygi_source_scanner_parse_macros (PyGISourceScanner *self,
for (i = 0; i < PyList_Size (list); ++i)
{
PyObject *obj;
- char *filename;
+ char *filename = NULL;
obj = PyList_GetItem (list, i);
- filename = PyString_AsString (obj);
+ if (PyUnicode_Check (obj))
+ {
+ PyObject *s = PyUnicode_AsUTF8String (obj);
+ filename = g_strdup (PyBytes_AsString (s));
+ Py_DECREF (s);
+ }
+ else if (PyBytes_Check (obj))
+ {
+ filename = g_strdup (PyBytes_AsString (obj));
+ }
+
+ if (filename == NULL)
+ {
+ PyErr_Format (PyExc_RuntimeError,
+ "Expected string but got %s",
+ (Py_TYPE(obj))->tp_name);
+ g_list_free_full (filenames, g_free);
+ return NULL;
+ }
filenames = g_list_append (filenames, filename);
}
gi_source_scanner_parse_macros (self->scanner, filenames);
- g_list_free (filenames);
+ g_list_free_full (filenames, g_free);
Py_INCREF (Py_None);
return Py_None;
@@ -669,9 +693,9 @@ static int calc_attrs_length(PyObject *attributes, int indent,
if (!s) {
return -1;
}
- value = PyString_AsString(s);
- } else if (PyString_Check(pyvalue)) {
- value = PyString_AsString(pyvalue);
+ value = PyBytes_AsString(s);
+ } else if (PyBytes_Check(pyvalue)) {
+ value = PyBytes_AsString(pyvalue);
} else {
PyErr_SetString(PyExc_TypeError,
"value must be string or unicode");
@@ -756,9 +780,9 @@ pygi_collect_attributes (PyObject *self,
s = PyUnicode_AsUTF8String(pyvalue);
if (!s)
goto out;
- value = PyString_AsString(s);
- } else if (PyString_Check(pyvalue)) {
- value = PyString_AsString(pyvalue);
+ value = PyBytes_AsString(s);
+ } else if (PyBytes_Check(pyvalue)) {
+ value = PyBytes_AsString(pyvalue);
} else {
PyErr_SetString(PyExc_TypeError,
"value must be string or unicode");
@@ -792,25 +816,43 @@ pygi_collect_attributes (PyObject *self,
/* Module */
-static const PyMethodDef pyscanner_functions[] = {
+static PyMethodDef pyscanner_functions[] = {
{ "collect_attributes",
(PyCFunction) pygi_collect_attributes, METH_VARARGS },
{ NULL, NULL, 0, NULL }
};
-DL_EXPORT(void)
-init_giscanner(void)
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef moduledef = {
+ PyModuleDef_HEAD_INIT,
+ NULL, /* m_name */
+ NULL, /* m_doc */
+ 0,
+ pyscanner_functions,
+ NULL
+};
+#endif /* PY_MAJOR_VERSION >= 3 */
+
+
+MOD_INIT(_giscanner)
{
PyObject *m, *d;
gboolean is_uninstalled;
+ const char *module_name;
/* Hack to avoid having to create a fake directory structure; when
* running uninstalled, the module will be in the top builddir,
* with no _giscanner prefix.
*/
is_uninstalled = g_getenv ("UNINSTALLED_INTROSPECTION_SRCDIR") != NULL;
- m = Py_InitModule (is_uninstalled ? "_giscanner" : "giscanner._giscanner",
- (PyMethodDef*)pyscanner_functions);
+ module_name = is_uninstalled ? "_giscanner" : "giscanner._giscanner";
+
+#if PY_MAJOR_VERSION >= 3
+ moduledef.m_name = module_name;
+ m = PyModule_Create (&moduledef);
+#else
+ m = Py_InitModule (module_name, (PyMethodDef*)pyscanner_functions);
+#endif
d = PyModule_GetDict (m);
PyGISourceScanner_Type.tp_init = (initproc)pygi_source_scanner_init;
@@ -822,4 +864,8 @@ init_giscanner(void)
PyGISourceType_Type.tp_getset = (PyGetSetDef*)_PyGISourceType_getsets;
REGISTER_TYPE (d, "SourceType", PyGISourceType_Type);
+
+#if PY_MAJOR_VERSION >= 3
+ return m;
+#endif
}