1 /* GObject introspection: scanner
3 * Copyright (C) 2008 Johan Dahlin <johan@gnome.org>
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.
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.
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.
25 #include "sourcescanner.h"
31 #define WIN32_LEAN_AND_MEAN
36 #define NEW_CLASS(ctype, name, cname) \
37 static const PyMethodDef _Py##cname##_methods[]; \
38 PyTypeObject Py##cname##_Type = { \
39 PyObject_HEAD_INIT(NULL) \
43 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
45 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, \
50 0, 0, NULL, NULL, 0, 0, \
54 #define REGISTER_TYPE(d, name, type) \
55 type.ob_type = &PyType_Type; \
56 type.tp_alloc = PyType_GenericAlloc; \
57 type.tp_new = PyType_GenericNew; \
58 if (PyType_Ready (&type)) \
60 PyDict_SetItemString (d, name, (PyObject *)&type); \
65 GISourceDirective *directive;
66 } PyGISourceDirective;
73 static PyObject * pygi_source_type_new (GISourceType *type);
77 GISourceSymbol *symbol;
83 GISourceScanner *scanner;
86 NEW_CLASS (PyGISourceDirective, "SourceDirective", GISourceDirective);
87 NEW_CLASS (PyGISourceSymbol, "SourceSymbol", GISourceSymbol);
88 NEW_CLASS (PyGISourceType, "SourceType", GISourceType);
89 NEW_CLASS (PyGISourceScanner, "SourceScanner", GISourceScanner);
95 pygi_source_directive_new (GISourceDirective *directive)
97 PyGISourceDirective *self;
99 if (directive == NULL)
105 self = (PyGISourceDirective *)PyObject_New (PyGISourceDirective,
106 &PyGISourceDirective_Type);
107 self->directive = directive;
108 return (PyObject*)self;
112 directive_get_name (PyGISourceDirective *self,
115 return PyString_FromString (self->directive->name);
119 directive_get_value (PyGISourceDirective *self,
122 return PyString_FromString (self->directive->value);
126 directive_get_options (PyGISourceDirective *self,
133 if (!self->directive)
134 return Py_BuildValue("[]");
136 list = PyList_New (g_slist_length (self->directive->options));
138 for (l = self->directive->options; l; l = l->next)
140 PyObject *item = PyString_FromString (l->data);
141 PyList_SetItem (list, i++, item);
149 static const PyGetSetDef _PyGISourceDirective_getsets[] = {
150 { "name", (getter)directive_get_name, NULL, NULL},
151 { "value", (getter)directive_get_value, NULL, NULL},
152 { "options", (getter)directive_get_options, NULL, NULL},
159 pygi_source_symbol_new (GISourceSymbol *symbol)
161 PyGISourceSymbol *self;
169 self = (PyGISourceSymbol *)PyObject_New (PyGISourceSymbol,
170 &PyGISourceSymbol_Type);
171 self->symbol = symbol;
172 return (PyObject*)self;
176 symbol_get_type (PyGISourceSymbol *self,
179 return PyInt_FromLong (self->symbol->type);
183 symbol_get_ident (PyGISourceSymbol *self,
187 if (!self->symbol->ident)
193 return PyString_FromString (self->symbol->ident);
197 symbol_get_base_type (PyGISourceSymbol *self,
200 return pygi_source_type_new (self->symbol->base_type);
204 symbol_get_const_int (PyGISourceSymbol *self,
207 return PyInt_FromLong (self->symbol->const_int);
211 symbol_get_const_string (PyGISourceSymbol *self,
214 if (!self->symbol->const_string)
220 return PyString_FromString (self->symbol->const_string);
224 symbol_get_directives (PyGISourceSymbol *self,
227 if (!self->directives)
228 self->directives = Py_BuildValue("[]");
229 Py_INCREF (self->directives);
230 return self->directives;
234 symbol_set_directives (PyGISourceSymbol *self,
238 self->directives = value;
243 static const PyGetSetDef _PyGISourceSymbol_getsets[] = {
245 { "type", (getter)symbol_get_type, NULL, NULL},
247 { "ident", (getter)symbol_get_ident, NULL, NULL},
248 { "base_type", (getter)symbol_get_base_type, NULL, NULL},
249 /* gboolean const_int_set; */
250 { "const_int", (getter)symbol_get_const_int, NULL, NULL},
251 { "const_string", (getter)symbol_get_const_string, NULL, NULL},
252 { "directives", (getter)symbol_get_directives,
253 (setter)symbol_set_directives, NULL},
262 pygi_source_type_new (GISourceType *type)
264 PyGISourceType *self;
272 self = (PyGISourceType *)PyObject_New (PyGISourceType,
273 &PyGISourceType_Type);
275 return (PyObject*)self;
279 type_get_type (PyGISourceType *self,
282 return PyInt_FromLong (self->type->type);
286 type_get_storage_class_specifier (PyGISourceType *self,
289 return PyInt_FromLong (self->type->storage_class_specifier);
293 type_get_type_qualifier (PyGISourceType *self,
296 return PyInt_FromLong (self->type->type_qualifier);
300 type_get_function_specifier (PyGISourceType *self,
303 return PyInt_FromLong (self->type->function_specifier);
307 type_get_name (PyGISourceType *self,
310 if (!self->type->name)
316 return PyString_FromString (self->type->name);
320 type_get_base_type (PyGISourceType *self,
323 return pygi_source_type_new (self->type->base_type);
327 type_get_child_list (PyGISourceType *self,
335 return Py_BuildValue("[]");
337 list = PyList_New (g_list_length (self->type->child_list));
339 for (l = self->type->child_list; l; l = l->next)
341 PyObject *item = pygi_source_symbol_new (l->data);
342 PyList_SetItem (list, i++, item);
350 static const PyGetSetDef _PyGISourceType_getsets[] = {
351 { "type", (getter)type_get_type, NULL, NULL},
352 { "storage_class_specifier", (getter)type_get_storage_class_specifier, NULL, NULL},
353 { "type_qualifier", (getter)type_get_type_qualifier, NULL, NULL},
354 { "function_specifier", (getter)type_get_function_specifier, NULL, NULL},
355 { "name", (getter)type_get_name, NULL, NULL},
356 { "base_type", (getter)type_get_base_type, NULL, NULL},
357 { "child_list", (getter)type_get_child_list, NULL, NULL},
366 pygi_source_scanner_init (PyGISourceScanner *self,
370 if (!PyArg_ParseTuple (args, ":SourceScanner.__init__"))
373 self->scanner = gi_source_scanner_new ();
379 pygi_source_scanner_append_filename (PyGISourceScanner *self,
384 if (!PyArg_ParseTuple (args, "s:SourceScanner.append_filename", &filename))
387 self->scanner->filenames = g_list_append (self->scanner->filenames,
388 g_strdup (filename));
395 pygi_source_scanner_parse_macros (PyGISourceScanner *self,
402 list = PyTuple_GET_ITEM (args, 0);
404 if (!PyList_Check (list))
406 PyErr_SetString (PyExc_RuntimeError, "parse macro takes a list of filenames");
411 for (i = 0; i < PyList_Size (list); ++i)
416 obj = PyList_GetItem (list, i);
417 filename = PyString_AsString (obj);
419 filenames = g_list_append (filenames, filename);
422 gi_source_scanner_parse_macros (self->scanner, filenames);
423 g_list_free (filenames);
430 pygi_source_scanner_parse_file (PyGISourceScanner *self,
436 if (!PyArg_ParseTuple (args, "i:SourceScanner.parse_file", &fd))
440 /* The file descriptor passed to us is from the C library Python
441 * uses. That is msvcr71.dll at least for Python 2.5. This code, at
442 * least if compiled with mingw, uses msvcrt.dll, so we cannot use
443 * the file descriptor directly. So perform appropriate magic.
447 int (*p__get_osfhandle) (int);
450 msvcr71 = GetModuleHandle ("msvcr71.dll");
453 g_print ("No msvcr71.dll loaded.\n");
457 p__get_osfhandle = GetProcAddress (msvcr71, "_get_osfhandle");
458 if (!p__get_osfhandle)
460 g_print ("No _get_osfhandle found in msvcr71.dll.\n");
464 handle = p__get_osfhandle (fd);
465 if (!p__get_osfhandle)
467 g_print ("Could not get OS handle from msvcr71 fd.\n");
471 fd = _open_osfhandle (handle, _O_RDONLY);
474 g_print ("Could not open C fd from OS handle.\n");
480 fp = fdopen (fd, "r");
483 PyErr_SetFromErrno (PyExc_OSError);
487 if (!gi_source_scanner_parse_file (self->scanner, fp))
489 g_print ("Something went wrong during parsing.\n");
498 pygi_source_scanner_lex_filename (PyGISourceScanner *self,
503 if (!PyArg_ParseTuple (args, "s:SourceScanner.lex_filename", &filename))
506 if (!gi_source_scanner_lex_filename (self->scanner, filename))
508 g_print ("Something went wrong during lexing.\n");
511 self->scanner->filenames =
512 g_list_append (self->scanner->filenames, g_strdup (filename));
513 self->scanner->current_filename = g_strdup (filename);
520 pygi_source_scanner_set_macro_scan (PyGISourceScanner *self,
525 if (!PyArg_ParseTuple (args, "b:SourceScanner.set_macro_scan", ¯o_scan))
528 gi_source_scanner_set_macro_scan (self->scanner, macro_scan);
535 pygi_source_scanner_get_symbols (PyGISourceScanner *self)
541 symbols = gi_source_scanner_get_symbols (self->scanner);
542 list = PyList_New (g_slist_length (symbols));
544 for (l = symbols; l; l = l->next)
546 PyObject *item = pygi_source_symbol_new (l->data);
547 PyList_SetItem (list, i++, item);
556 pygi_source_scanner_get_directives (PyGISourceScanner *self,
559 GSList *l, *directives;
564 if (!PyArg_ParseTuple (args, "s:SourceScanner.get_directives", &name))
567 directives = gi_source_scanner_get_directives (self->scanner, name);
568 list = PyList_New (g_slist_length (directives));
570 for (l = directives; l; l = l->next)
572 PyObject *item = pygi_source_directive_new (l->data);
573 PyList_SetItem (list, i++, item);
581 static const PyMethodDef _PyGISourceScanner_methods[] = {
582 { "get_directives", (PyCFunction) pygi_source_scanner_get_directives, METH_VARARGS },
583 { "get_symbols", (PyCFunction) pygi_source_scanner_get_symbols, METH_NOARGS },
584 { "append_filename", (PyCFunction) pygi_source_scanner_append_filename, METH_VARARGS },
585 { "parse_file", (PyCFunction) pygi_source_scanner_parse_file, METH_VARARGS },
586 { "parse_macros", (PyCFunction) pygi_source_scanner_parse_macros, METH_VARARGS },
587 { "lex_filename", (PyCFunction) pygi_source_scanner_lex_filename, METH_VARARGS },
588 { "set_macro_scan", (PyCFunction) pygi_source_scanner_set_macro_scan, METH_VARARGS },
595 static const PyMethodDef pyscanner_functions[] = {
596 { NULL, NULL, 0, NULL }
604 m = Py_InitModule ("giscanner._giscanner",
605 (PyMethodDef*)pyscanner_functions);
606 d = PyModule_GetDict (m);
608 PyGISourceDirective_Type.tp_getset = (PyGetSetDef*)_PyGISourceDirective_getsets;
609 REGISTER_TYPE (d, "SourceDirective", PyGISourceDirective_Type);
611 PyGISourceScanner_Type.tp_init = (initproc)pygi_source_scanner_init;
612 PyGISourceScanner_Type.tp_methods = (PyMethodDef*)_PyGISourceScanner_methods;
613 REGISTER_TYPE (d, "SourceScanner", PyGISourceScanner_Type);
615 PyGISourceSymbol_Type.tp_getset = (PyGetSetDef*)_PyGISourceSymbol_getsets;
616 REGISTER_TYPE (d, "SourceSymbol", PyGISourceSymbol_Type);
618 PyGISourceType_Type.tp_getset = (PyGetSetDef*)_PyGISourceType_getsets;
619 REGISTER_TYPE (d, "SourceType", PyGISourceType_Type);