Add initial python bindings for the scanner and depend on python 2.5.
[platform/upstream/gobject-introspection.git] / giscanner / giscannermodule.c
1 /* GObject introspection: scanner
2  *
3  * Copyright (C) 2008
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #  include "config.h"
24 #endif
25 #include "sourcescanner.h"
26 #include <Python.h>
27
28 #define NEW_CLASS(ctype, name, cname)         \
29 static PyMethodDef _Py##cname##_methods[];    \
30 PyTypeObject Py##cname##_Type = {             \
31     PyObject_HEAD_INIT(NULL)                  \
32     0,                                        \
33     "scanner." name,                          \
34     sizeof(ctype),                    \
35     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,             \
36     0, 0, 0, 0, 0, 0,                         \
37     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, \
38     NULL, 0, 0, 0,                            \
39     0,        \
40     0, 0,                                     \
41     0,                                        \
42     0, 0, NULL, NULL, 0, 0,                   \
43     0             \
44 }
45
46 #define REGISTER_TYPE(d, name, type)          \
47     type.ob_type = &PyType_Type;              \
48     type.tp_alloc = PyType_GenericAlloc;      \
49     type.tp_new = PyType_GenericNew;          \
50     if (PyType_Ready (&type))                 \
51         return;                               \
52     PyDict_SetItemString (d, name, (PyObject *)&type); \
53     Py_INCREF (&type);
54
55 typedef struct {
56   PyObject_HEAD
57   GISourceType *type;
58 } PyGISourceType;
59
60 typedef struct {
61   PyObject_HEAD
62   GISourceSymbol *symbol;
63 } PyGISourceSymbol;
64
65 typedef struct {
66   PyObject_HEAD
67   GISourceScanner *scanner;
68 } PyGISourceScanner;
69
70 NEW_CLASS(PyGISourceSymbol, "SourceSymbol", GISourceSymbol);
71 NEW_CLASS(PyGISourceType, "SourceType", GISourceType);
72 NEW_CLASS(PyGISourceScanner, "SourceScanner", GISourceScanner);
73
74
75 /* Symbol */
76
77 static PyObject *
78 symbol_get_type(PyGISourceSymbol *self,
79                 void             *context)
80 {
81   return PyInt_FromLong(self->symbol->type);
82 }
83
84 static PyObject *
85 symbol_get_ident(PyGISourceSymbol *self,
86                   void            *context)
87 {
88   return PyString_FromString(self->symbol->ident);
89 }
90
91 static PyObject *
92 symbol_get_base_type(PyGISourceSymbol *self,
93                      void             *context)
94 {
95   PyGISourceType *item;
96   item = (PyGISourceType *)PyObject_GC_New(PyGISourceType,
97                                            &PyGISourceType_Type);
98   item->type = self->symbol->base_type;
99   return (PyObject*)item;
100 }
101
102 static PyGetSetDef _PyGISourceSymbol_getsets[] = {
103   { "type", (getter)symbol_get_type, NULL, NULL},
104   { "ident", (getter)symbol_get_ident, NULL, NULL},
105   { "base_type", (getter)symbol_get_base_type, NULL, NULL},
106   { 0 }
107 };
108
109
110
111 /* Type */
112
113 static PyObject *
114 type_get_type(PyGISourceType *self,
115               void           *context)
116 {
117   return PyInt_FromLong(self->type->type);
118 }
119
120 static PyObject *
121 type_get_name(PyGISourceType *self,
122               void           *context)
123 {
124   if (!self->type->name)
125     {
126       Py_INCREF(Py_None);
127       return Py_None;
128     }
129     
130   return PyString_FromString(self->type->name);
131 }
132
133 static PyGetSetDef _PyGISourceType_getsets[] = {
134   { "type", (getter)type_get_type, NULL, NULL},
135   { "name", (getter)type_get_name, NULL, NULL},
136   { 0 }
137 };
138
139
140
141 /* Scanner */
142
143 static int
144 pygi_source_scanner_init (PyGISourceScanner *self,
145                           PyObject          *args,
146                           PyObject          *kwargs)
147 {
148   if (!PyArg_ParseTuple (args, ":SourceScanner.__init__"))
149     return -1;
150
151   self->scanner = gi_source_scanner_new ();
152
153   return 0;
154 }
155
156 static PyObject *
157 pygi_source_scanner_parse_file (PyGISourceScanner *self,
158                                 PyObject          *args)
159 {
160   char *filename;
161   FILE *fp;
162   
163   if (!PyArg_ParseTuple (args, "s:SourceScanner.__init__", &filename))
164     return NULL;
165
166   fp = fopen (filename, "r");
167   if (!fp)
168     {
169       PyErr_SetFromErrnoWithFilename (PyExc_OSError, filename);
170       return NULL;
171     }
172
173   self->scanner->filenames =
174     g_list_append (self->scanner->filenames, g_strdup (filename));
175   self->scanner->current_filename = self->scanner->filenames->data;
176   
177   if (!gi_source_scanner_parse_file (self->scanner, fp))
178     {
179       g_print ("Something went wrong..\n");
180       return NULL;
181     }
182
183   fclose (fp);
184
185   Py_INCREF (Py_None);
186   return Py_None;
187 }
188
189 static PyObject *
190 pygi_source_scanner_set_macro_scan (PyGISourceScanner *self,
191                                     PyObject          *args)
192 {
193   int macro_scan;
194   
195   if (!PyArg_ParseTuple (args, "b:SourceScanner.set_macro_scan", &macro_scan))
196     return NULL;
197
198   gi_source_scanner_set_macro_scan (self->scanner, macro_scan);
199
200   Py_INCREF (Py_None);
201   return Py_None;
202 }
203
204 static PyObject *
205 pygi_source_scanner_get_symbols (PyGISourceScanner *self)
206 {
207   GSList *l, *symbols;
208   PyObject *list;
209   int i = 0;
210   
211   symbols = gi_source_scanner_get_symbols (self->scanner);
212   list = PyList_New (g_slist_length (symbols));
213   
214   for (l = symbols; l; l = l->next)
215     {
216       PyGISourceSymbol *item;
217       item = (PyGISourceSymbol *)PyObject_GC_New(PyGISourceSymbol,
218                                                  &PyGISourceSymbol_Type);
219       item->symbol = l->data;
220       PyList_SetItem(list, i++, (PyObject*)item);
221     }
222   
223   return list;
224 }
225
226 static PyMethodDef _PyGISourceScanner_methods[] = {
227   { "get_symbols", (PyCFunction) pygi_source_scanner_get_symbols, METH_NOARGS },
228   { "parse_file", (PyCFunction) pygi_source_scanner_parse_file, METH_VARARGS },
229   { "set_macro_scan", (PyCFunction) pygi_source_scanner_set_macro_scan, METH_VARARGS },
230   { NULL, NULL, 0 }
231 };
232
233
234 /* Module */
235
236 PyMethodDef pyscanner_functions[] = {
237   { NULL, NULL, 0, NULL }
238 };
239
240 DL_EXPORT(void)
241 init_giscanner(void)
242 {
243     PyObject *m, *d;
244
245     m = Py_InitModule ("giscanner._giscanner", pyscanner_functions);
246     d = PyModule_GetDict (m);
247
248     PyGISourceScanner_Type.tp_init = (initproc)pygi_source_scanner_init;
249     PyGISourceScanner_Type.tp_methods = _PyGISourceScanner_methods;
250     REGISTER_TYPE (d, "SourceScanner", PyGISourceScanner_Type);
251
252     PyGISourceSymbol_Type.tp_getset = _PyGISourceSymbol_getsets;
253     REGISTER_TYPE (d, "SourceSymbol", PyGISourceSymbol_Type);
254
255     PyGISourceType_Type.tp_getset = _PyGISourceType_getsets;
256     REGISTER_TYPE (d, "SourceType", PyGISourceType_Type);
257 }