Mark structures as const, wrap SourceType.const_string.
[gnome.gobject-introspection] / giscanner / giscannermodule.c
1 /* GObject introspection: scanner
2  *
3  * Copyright (C) 2008  Johan Dahlin <johan@gnome.org>
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 const 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_New (PyGISourceType,
97                                          &PyGISourceType_Type);
98   item->type = self->symbol->base_type;
99   return (PyObject*)item;
100 }
101
102 static PyObject *
103 symbol_get_const_int (PyGISourceSymbol *self,
104                       void             *context)
105 {
106   return PyInt_FromLong (self->symbol->const_int);
107 }
108
109 static PyObject *
110 symbol_get_const_string (PyGISourceSymbol *self,
111                          void             *context)
112 {
113   if (!self->symbol->const_string)
114     {
115       Py_INCREF(Py_None);
116       return Py_None;
117     }
118     
119   return PyString_FromString (self->symbol->const_string);
120 }
121
122 static const PyGetSetDef _PyGISourceSymbol_getsets[] = {
123   /* int ref_count; */
124   { "type", (getter)symbol_get_type, NULL, NULL},
125   /* int id; */
126   { "ident", (getter)symbol_get_ident, NULL, NULL},
127   { "base_type", (getter)symbol_get_base_type, NULL, NULL},
128   /* gboolean const_int_set; */
129   { "const_int", (getter)symbol_get_const_int, NULL, NULL},  
130   { "const_string", (getter)symbol_get_const_string, NULL, NULL},  
131   /* GSList *directives; */
132   { 0 }
133 };
134
135
136
137 /* Type */
138
139 static PyObject *
140 type_get_type (PyGISourceType *self,
141                void           *context)
142 {
143   return PyInt_FromLong (self->type->type);
144 }
145
146 static PyObject *
147 type_get_storage_class_specifier (PyGISourceType *self,
148                                   void           *context)
149 {
150   return PyInt_FromLong (self->type->storage_class_specifier);
151 }
152
153 static PyObject *
154 type_get_type_qualifier (PyGISourceType *self,
155                          void           *context)
156 {
157   return PyInt_FromLong (self->type->type_qualifier);
158 }
159
160 static PyObject *
161 type_get_function_specifier (PyGISourceType *self,
162                              void           *context)
163 {
164   return PyInt_FromLong (self->type->function_specifier);
165 }
166
167 static PyObject *
168 type_get_name (PyGISourceType *self,
169                void           *context)
170 {
171   if (!self->type->name)
172     {
173       Py_INCREF (Py_None);
174       return Py_None;
175     }
176     
177   return PyString_FromString (self->type->name);
178 }
179
180 static PyObject *
181 type_get_base_type (PyGISourceType *self,
182                     void           *context)
183 {
184   PyGISourceType *item;
185   item = (PyGISourceType *)PyObject_New (PyGISourceType,
186                                          &PyGISourceType_Type);
187   item->type = self->type->base_type;
188   return (PyObject*)item;
189 }
190
191 static PyObject *
192 type_get_child_list (PyGISourceType *self,
193                      void           *context)
194 {
195   GList *l, *symbols;
196   PyObject *list;
197   int i = 0;
198
199   if (!self->type)
200     return Py_BuildValue("[]");
201   
202   list = PyList_New (g_list_length (self->type->child_list));
203   
204   for (l = self->type->child_list; l; l = l->next)
205     {
206       PyGISourceSymbol *item;
207       item = (PyGISourceSymbol *)PyObject_New (PyGISourceSymbol,
208                                                &PyGISourceSymbol_Type);
209       item->symbol = l->data;
210       PyList_SetItem (list, i++, (PyObject*)item);
211       Py_INCREF (item);
212     }
213
214   Py_INCREF (list);
215   return list;
216 }
217
218 static const PyGetSetDef _PyGISourceType_getsets[] = {
219   { "type", (getter)type_get_type, NULL, NULL},
220   { "storage_class_specifier", (getter)type_get_storage_class_specifier, NULL, NULL},
221   { "type_qualifier", (getter)type_get_type_qualifier, NULL, NULL},
222   { "function_specifier", (getter)type_get_function_specifier, NULL, NULL},
223   { "name", (getter)type_get_name, NULL, NULL},
224   { "base_type", (getter)type_get_base_type, NULL, NULL},
225   { "child_list", (getter)type_get_child_list, NULL, NULL},
226   { 0 }
227 };
228
229
230
231 /* Scanner */
232
233 static int
234 pygi_source_scanner_init (PyGISourceScanner *self,
235                           PyObject          *args,
236                           PyObject          *kwargs)
237 {
238   if (!PyArg_ParseTuple (args, ":SourceScanner.__init__"))
239     return -1;
240
241   self->scanner = gi_source_scanner_new ();
242
243   return 0;
244 }
245
246 static PyObject *
247 pygi_source_scanner_parse_file (PyGISourceScanner *self,
248                                 PyObject          *args)
249 {
250   int fd;
251   char *filename;
252   FILE *fp;
253   
254   if (!PyArg_ParseTuple (args, "is:SourceScanner.__init__", &fd, &filename))
255     return NULL;
256
257   fp = fdopen (fd, "r");
258   if (!fp)
259     {
260       PyErr_SetFromErrnoWithFilename (PyExc_OSError, filename);
261       return NULL;
262     }
263
264   self->scanner->filenames =
265     g_list_append (self->scanner->filenames, g_strdup (filename));
266   self->scanner->current_filename = g_strdup (filename);
267
268   if (!gi_source_scanner_parse_file (self->scanner, fp))
269     {
270       g_print ("Something went wrong..\n");
271       return NULL;
272     }
273
274   Py_INCREF (Py_None);
275   return Py_None;
276 }
277
278 static PyObject *
279 pygi_source_scanner_set_macro_scan (PyGISourceScanner *self,
280                                     PyObject          *args)
281 {
282   int macro_scan;
283   
284   if (!PyArg_ParseTuple (args, "b:SourceScanner.set_macro_scan", &macro_scan))
285     return NULL;
286
287   gi_source_scanner_set_macro_scan (self->scanner, macro_scan);
288
289   Py_INCREF (Py_None);
290   return Py_None;
291 }
292
293 static PyObject *
294 pygi_source_scanner_get_symbols (PyGISourceScanner *self)
295 {
296   GSList *l, *symbols;
297   PyObject *list;
298   int i = 0;
299   
300   symbols = gi_source_scanner_get_symbols (self->scanner);
301   list = PyList_New (g_slist_length (symbols));
302   
303   for (l = symbols; l; l = l->next)
304     {
305       PyGISourceSymbol *item;
306       item = (PyGISourceSymbol *)PyObject_New (PyGISourceSymbol,
307                                                &PyGISourceSymbol_Type);
308       item->symbol = l->data;
309       PyList_SetItem (list, i++, (PyObject*)item);
310       Py_INCREF (item);
311     }
312
313   Py_INCREF (list);
314   return list;
315 }
316
317 static const PyMethodDef _PyGISourceScanner_methods[] = {
318   { "get_symbols", (PyCFunction) pygi_source_scanner_get_symbols, METH_NOARGS },
319   { "parse_file", (PyCFunction) pygi_source_scanner_parse_file, METH_VARARGS },
320   { "set_macro_scan", (PyCFunction) pygi_source_scanner_set_macro_scan, METH_VARARGS },
321   { NULL, NULL, 0 }
322 };
323
324
325 /* Module */
326
327 static const PyMethodDef pyscanner_functions[] = {
328   { NULL, NULL, 0, NULL }
329 };
330
331 DL_EXPORT(void)
332 init_giscanner(void)
333 {
334     PyObject *m, *d;
335
336     m = Py_InitModule ("giscanner._giscanner",
337                        (PyMethodDef*)pyscanner_functions);
338     d = PyModule_GetDict (m);
339
340     PyGISourceScanner_Type.tp_init = (initproc)pygi_source_scanner_init;
341     PyGISourceScanner_Type.tp_methods = (PyMethodDef*)_PyGISourceScanner_methods;
342     REGISTER_TYPE (d, "SourceScanner", PyGISourceScanner_Type);
343
344     PyGISourceSymbol_Type.tp_getset = (PyGetSetDef*)_PyGISourceSymbol_getsets;
345     REGISTER_TYPE (d, "SourceSymbol", PyGISourceSymbol_Type);
346
347     PyGISourceType_Type.tp_getset = (PyGetSetDef*)_PyGISourceType_getsets;
348     REGISTER_TYPE (d, "SourceType", PyGISourceType_Type);
349 }