diff options
author | Johan Dahlin <johan@gnome.org> | 2008-03-25 21:47:47 +0000 |
---|---|---|
committer | Johan Dahlin <johan@src.gnome.org> | 2008-03-25 21:47:47 +0000 |
commit | a310fd859d42006253d8541f366ca458bdb09493 (patch) | |
tree | 777b485f61419a9c0ea04d002ce32251ed596bc2 | |
parent | 66ab1202b6499e030c32c9d0d3432e0b09bee7db (diff) | |
download | gobject-introspection-a310fd859d42006253d8541f366ca458bdb09493.tar.gz |
Add initial python bindings for the scanner and depend on python 2.5.
2008-03-25 Johan Dahlin <johan@gnome.org>
* configure.ac:
* giscanner:
* giscanner/__init__.py:
* giscanner/giscannermodule.c:
* giscanner/Makefile.am:
Add initial python bindings for the scanner and
depend on python 2.5.
svn path=/trunk/; revision=165
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | configure.ac | 6 | ||||
-rw-r--r-- | giscanner/Makefile.am | 21 | ||||
-rw-r--r-- | giscanner/__init__.py | 1 | ||||
-rw-r--r-- | giscanner/giscannermodule.c | 257 | ||||
-rw-r--r-- | m4/python.m4 | 25 |
6 files changed, 321 insertions, 0 deletions
@@ -1,4 +1,15 @@ 2008-03-25 Johan Dahlin <johan@gnome.org> + + * configure.ac: + * giscanner: + * giscanner/__init__.py: + * giscanner/giscannermodule.c: + * giscanner/Makefile.am: + + Add initial python bindings for the scanner and + depend on python 2.5. + +2008-03-25 Johan Dahlin <johan@gnome.org> * Makefile.am: * configure.ac: diff --git a/configure.ac b/configure.ac index 5ca163df..51d44f85 100644 --- a/configure.ac +++ b/configure.ac @@ -90,6 +90,12 @@ AC_C_CONST AC_FUNC_STRTOD AC_CHECK_FUNCS([memchr strchr strspn strstr strtol strtoull]) +# Python + +AC_MSG_CHECKING([whether Python support is requested]) + +AM_PATH_PYTHON([2.5]) +AM_CHECK_PYTHON_HEADERS AC_CONFIG_FILES([Makefile gidl/Makefile diff --git a/giscanner/Makefile.am b/giscanner/Makefile.am index 30ed3352..4ed31069 100644 --- a/giscanner/Makefile.am +++ b/giscanner/Makefile.am @@ -22,4 +22,25 @@ libgiscanner_la_CFLAGS = $(GOBJECT_CFLAGS) GCOVSOURCES = $(libgiscanner_la_SOURCES) +# Python module +pyexec_LTLIBRARIES = _giscanner.la +pyexec_PYTHON = __init__.py + +_giscanner_la_CFLAGS = \ + $(PYTHON_INCLUDES) \ + $(GOBJECT_CFLAGS) \ + -I$(top_srcdir)/giscanner +_giscanner_la_LIBADD = $(GOBJECT_LIBS) libgiscanner.la +_giscanner_la_LDFLAGS = \ + -module -avoid-version -export-symbols-regex init_giscanner +_giscanner_la_SOURCES = giscannermodule.c + +BUILT_SOURCES += _giscanner.so +CLEANFILES += _giscanner.so + +# Yuck, ugly but... +_giscanner.so: _giscanner.la + ln -sf .libs/_giscanner.so . + + include $(top_srcdir)/gcov.mak diff --git a/giscanner/__init__.py b/giscanner/__init__.py new file mode 100644 index 00000000..aff773a7 --- /dev/null +++ b/giscanner/__init__.py @@ -0,0 +1 @@ +from _giscanner import * diff --git a/giscanner/giscannermodule.c b/giscanner/giscannermodule.c new file mode 100644 index 00000000..b9245f22 --- /dev/null +++ b/giscanner/giscannermodule.c @@ -0,0 +1,257 @@ +/* GObject introspection: scanner + * + * Copyright (C) 2008 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include "sourcescanner.h" +#include <Python.h> + +#define NEW_CLASS(ctype, name, cname) \ +static PyMethodDef _Py##cname##_methods[]; \ +PyTypeObject Py##cname##_Type = { \ + PyObject_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 \ +} + +#define REGISTER_TYPE(d, name, type) \ + type.ob_type = &PyType_Type; \ + type.tp_alloc = PyType_GenericAlloc; \ + type.tp_new = PyType_GenericNew; \ + if (PyType_Ready (&type)) \ + return; \ + PyDict_SetItemString (d, name, (PyObject *)&type); \ + Py_INCREF (&type); + +typedef struct { + PyObject_HEAD + GISourceType *type; +} PyGISourceType; + +typedef struct { + PyObject_HEAD + GISourceSymbol *symbol; +} PyGISourceSymbol; + +typedef struct { + PyObject_HEAD + GISourceScanner *scanner; +} PyGISourceScanner; + +NEW_CLASS(PyGISourceSymbol, "SourceSymbol", GISourceSymbol); +NEW_CLASS(PyGISourceType, "SourceType", GISourceType); +NEW_CLASS(PyGISourceScanner, "SourceScanner", GISourceScanner); + + +/* Symbol */ + +static PyObject * +symbol_get_type(PyGISourceSymbol *self, + void *context) +{ + return PyInt_FromLong(self->symbol->type); +} + +static PyObject * +symbol_get_ident(PyGISourceSymbol *self, + void *context) +{ + return PyString_FromString(self->symbol->ident); +} + +static PyObject * +symbol_get_base_type(PyGISourceSymbol *self, + void *context) +{ + PyGISourceType *item; + item = (PyGISourceType *)PyObject_GC_New(PyGISourceType, + &PyGISourceType_Type); + item->type = self->symbol->base_type; + return (PyObject*)item; +} + +static PyGetSetDef _PyGISourceSymbol_getsets[] = { + { "type", (getter)symbol_get_type, NULL, NULL}, + { "ident", (getter)symbol_get_ident, NULL, NULL}, + { "base_type", (getter)symbol_get_base_type, NULL, NULL}, + { 0 } +}; + + + +/* Type */ + +static PyObject * +type_get_type(PyGISourceType *self, + void *context) +{ + return PyInt_FromLong(self->type->type); +} + +static PyObject * +type_get_name(PyGISourceType *self, + void *context) +{ + if (!self->type->name) + { + Py_INCREF(Py_None); + return Py_None; + } + + return PyString_FromString(self->type->name); +} + +static PyGetSetDef _PyGISourceType_getsets[] = { + { "type", (getter)type_get_type, NULL, NULL}, + { "name", (getter)type_get_name, NULL, NULL}, + { 0 } +}; + + + +/* Scanner */ + +static int +pygi_source_scanner_init (PyGISourceScanner *self, + PyObject *args, + PyObject *kwargs) +{ + if (!PyArg_ParseTuple (args, ":SourceScanner.__init__")) + return -1; + + self->scanner = gi_source_scanner_new (); + + return 0; +} + +static PyObject * +pygi_source_scanner_parse_file (PyGISourceScanner *self, + PyObject *args) +{ + char *filename; + FILE *fp; + + if (!PyArg_ParseTuple (args, "s:SourceScanner.__init__", &filename)) + return NULL; + + fp = fopen (filename, "r"); + if (!fp) + { + PyErr_SetFromErrnoWithFilename (PyExc_OSError, filename); + return NULL; + } + + self->scanner->filenames = + g_list_append (self->scanner->filenames, g_strdup (filename)); + self->scanner->current_filename = self->scanner->filenames->data; + + if (!gi_source_scanner_parse_file (self->scanner, fp)) + { + g_print ("Something went wrong..\n"); + return NULL; + } + + fclose (fp); + + Py_INCREF (Py_None); + return Py_None; +} + +static PyObject * +pygi_source_scanner_set_macro_scan (PyGISourceScanner *self, + PyObject *args) +{ + int macro_scan; + + if (!PyArg_ParseTuple (args, "b:SourceScanner.set_macro_scan", ¯o_scan)) + return NULL; + + gi_source_scanner_set_macro_scan (self->scanner, macro_scan); + + Py_INCREF (Py_None); + return Py_None; +} + +static PyObject * +pygi_source_scanner_get_symbols (PyGISourceScanner *self) +{ + GSList *l, *symbols; + PyObject *list; + int i = 0; + + symbols = gi_source_scanner_get_symbols (self->scanner); + list = PyList_New (g_slist_length (symbols)); + + for (l = symbols; l; l = l->next) + { + PyGISourceSymbol *item; + item = (PyGISourceSymbol *)PyObject_GC_New(PyGISourceSymbol, + &PyGISourceSymbol_Type); + item->symbol = l->data; + PyList_SetItem(list, i++, (PyObject*)item); + } + + return list; +} + +static PyMethodDef _PyGISourceScanner_methods[] = { + { "get_symbols", (PyCFunction) pygi_source_scanner_get_symbols, METH_NOARGS }, + { "parse_file", (PyCFunction) pygi_source_scanner_parse_file, METH_VARARGS }, + { "set_macro_scan", (PyCFunction) pygi_source_scanner_set_macro_scan, METH_VARARGS }, + { NULL, NULL, 0 } +}; + + +/* Module */ + +PyMethodDef pyscanner_functions[] = { + { NULL, NULL, 0, NULL } +}; + +DL_EXPORT(void) +init_giscanner(void) +{ + PyObject *m, *d; + + m = Py_InitModule ("giscanner._giscanner", pyscanner_functions); + d = PyModule_GetDict (m); + + PyGISourceScanner_Type.tp_init = (initproc)pygi_source_scanner_init; + PyGISourceScanner_Type.tp_methods = _PyGISourceScanner_methods; + REGISTER_TYPE (d, "SourceScanner", PyGISourceScanner_Type); + + PyGISourceSymbol_Type.tp_getset = _PyGISourceSymbol_getsets; + REGISTER_TYPE (d, "SourceSymbol", PyGISourceSymbol_Type); + + PyGISourceType_Type.tp_getset = _PyGISourceType_getsets; + REGISTER_TYPE (d, "SourceType", PyGISourceType_Type); +} diff --git a/m4/python.m4 b/m4/python.m4 new file mode 100644 index 00000000..aff55371 --- /dev/null +++ b/m4/python.m4 @@ -0,0 +1,25 @@ +## this one is commonly used with AM_PATH_PYTHONDIR ... +dnl a macro to check for ability to create python extensions +dnl AM_CHECK_PYTHON_HEADERS([ACTION-IF-POSSIBLE], [ACTION-IF-NOT-POSSIBLE]) +dnl function also defines PYTHON_INCLUDES +AC_DEFUN([AM_CHECK_PYTHON_HEADERS], +[AC_REQUIRE([AM_PATH_PYTHON]) +AC_MSG_CHECKING(for headers required to compile python extensions) +dnl deduce PYTHON_INCLUDES +py_prefix=`$PYTHON -c "import sys; print sys.prefix"` +py_exec_prefix=`$PYTHON -c "import sys; print sys.exec_prefix"` +PYTHON_INCLUDES="-I${py_prefix}/include/python${PYTHON_VERSION}" +if test "$py_prefix" != "$py_exec_prefix"; then + PYTHON_INCLUDES="$PYTHON_INCLUDES -I${py_exec_prefix}/include/python${PYTHON_VERSION}" +fi +AC_SUBST(PYTHON_INCLUDES) +dnl check if the headers exist: +save_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES" +AC_TRY_CPP([#include <Python.h>],dnl +[AC_MSG_RESULT(found) +$1],dnl +[AC_MSG_RESULT(not found) +$2]) +CPPFLAGS="$save_CPPFLAGS" +]) |