[SYMBOL_LINES] Support for line numbers on Symbols
[gnome.gobject-introspection] / giscanner / giscannermodule.c
index df1ba09..2d2e073 100644 (file)
@@ -22,8 +22,9 @@
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
 #endif
-#include "sourcescanner.h"
 #include <Python.h>
+#include "sourcescanner.h"
+#include "grealpath.h"
 
 #ifdef _WIN32
 #include <fcntl.h>
@@ -62,11 +63,6 @@ PyTypeObject Py##cname##_Type = {             \
     PyDict_SetItemString (d, name, (PyObject *)&type); \
     Py_INCREF (&type);
 
-typedef struct {
-  PyObject_HEAD
-  GISourceDirective *directive;
-} PyGISourceDirective;
-
 typedef struct {
   PyObject_HEAD
   GISourceType *type;
@@ -77,7 +73,6 @@ static PyObject * pygi_source_type_new (GISourceType *type);
 typedef struct {
   PyObject_HEAD
   GISourceSymbol *symbol;
-  PyObject *directives;
 } PyGISourceSymbol;
 
 typedef struct {
@@ -85,76 +80,11 @@ typedef struct {
   GISourceScanner *scanner;
 } PyGISourceScanner;
 
-NEW_CLASS (PyGISourceDirective, "SourceDirective", GISourceDirective);
 NEW_CLASS (PyGISourceSymbol, "SourceSymbol", GISourceSymbol);
 NEW_CLASS (PyGISourceType, "SourceType", GISourceType);
 NEW_CLASS (PyGISourceScanner, "SourceScanner", GISourceScanner);
 
 
-/* Directive */
-
-static PyObject *
-pygi_source_directive_new (GISourceDirective *directive)
-{
-  PyGISourceDirective *self;
-
-  if (directive == NULL)
-    {
-      Py_INCREF (Py_None);
-      return Py_None;
-    }
-    
-  self = (PyGISourceDirective *)PyObject_New (PyGISourceDirective,
-                                             &PyGISourceDirective_Type);
-  self->directive = directive;
-  return (PyObject*)self;
-}
-
-static PyObject *
-directive_get_name (PyGISourceDirective *self,
-                   void                *context)
-{
-  return PyString_FromString (self->directive->name);
-}
-
-static PyObject *
-directive_get_value (PyGISourceDirective *self,
-                    void                *context)
-{
-  return PyString_FromString (self->directive->value);
-}
-
-static PyObject *
-directive_get_options (PyGISourceDirective *self,
-                      void                *context)
-{
-  GSList *l;
-  PyObject *list;
-  int i = 0;
-
-  if (!self->directive)
-    return Py_BuildValue("[]");
-  
-  list = PyList_New (g_slist_length (self->directive->options));
-  
-  for (l = self->directive->options; l; l = l->next)
-    {
-      PyObject *item = PyString_FromString (l->data);
-      PyList_SetItem (list, i++, item);
-      Py_INCREF (item);
-    }
-
-  Py_INCREF (list);
-  return list;
-}
-
-static const PyGetSetDef _PyGISourceDirective_getsets[] = {
-  { "name", (getter)directive_get_name, NULL, NULL},
-  { "value", (getter)directive_get_value, NULL, NULL},
-  { "options", (getter)directive_get_options, NULL, NULL},
-  { 0 }
-};
-
 /* Symbol */
 
 static PyObject *
@@ -181,6 +111,13 @@ symbol_get_type (PyGISourceSymbol *self,
   return PyInt_FromLong (self->symbol->type);
 }
 
+static PyObject *
+symbol_get_line (PyGISourceSymbol *self,
+                void             *context)
+{
+  return PyInt_FromLong (self->symbol->line);
+}
+
 static PyObject *
 symbol_get_ident (PyGISourceSymbol *self,
                  void            *context)
@@ -206,9 +143,26 @@ static PyObject *
 symbol_get_const_int (PyGISourceSymbol *self,
                      void             *context)
 {
+  if (!self->symbol->const_int_set)
+    {
+      Py_INCREF(Py_None);
+      return Py_None;
+    }
   return PyInt_FromLong (self->symbol->const_int);
 }
 
+static PyObject *
+symbol_get_const_double (PyGISourceSymbol *self,
+                         void             *context)
+{
+  if (!self->symbol->const_double_set)
+    {
+      Py_INCREF(Py_None);
+      return Py_None;
+    }
+  return PyFloat_FromDouble (self->symbol->const_double);
+}
+
 static PyObject *
 symbol_get_const_string (PyGISourceSymbol *self,
                         void             *context)
@@ -223,23 +177,16 @@ symbol_get_const_string (PyGISourceSymbol *self,
 }
 
 static PyObject *
-symbol_get_directives (PyGISourceSymbol *self,
-                      void             *context)
+symbol_get_source_filename (PyGISourceSymbol *self,
+                            void             *context)
 {
-  if (!self->directives)
-    self->directives = Py_BuildValue("[]");
-  Py_INCREF (self->directives);
-  return self->directives;
-}
+  if (!self->symbol->source_filename)
+    {
+      Py_INCREF(Py_None);
+      return Py_None;
+    }
 
-static int
-symbol_set_directives (PyGISourceSymbol *self,
-                      PyObject         *value,
-                      void             *context)
-{
-  self->directives = value;
-  Py_INCREF(value);
-  return 0;
+  return PyString_FromString (self->symbol->source_filename);
 }
 
 static const PyGetSetDef _PyGISourceSymbol_getsets[] = {
@@ -249,10 +196,12 @@ static const PyGetSetDef _PyGISourceSymbol_getsets[] = {
   { "ident", (getter)symbol_get_ident, NULL, NULL},
   { "base_type", (getter)symbol_get_base_type, NULL, NULL},
   /* gboolean const_int_set; */
-  { "const_int", (getter)symbol_get_const_int, NULL, NULL},  
-  { "const_string", (getter)symbol_get_const_string, NULL, NULL},  
-  { "directives", (getter)symbol_get_directives,
-    (setter)symbol_set_directives, NULL},  
+  { "const_int", (getter)symbol_get_const_int, NULL, NULL},
+  /* gboolean const_double_set; */
+  { "const_double", (getter)symbol_get_const_double, NULL, NULL},
+  { "const_string", (getter)symbol_get_const_string, NULL, NULL},
+  { "source_filename", (getter)symbol_get_source_filename, NULL, NULL},
+  { "line", (getter)symbol_get_line, NULL, NULL},
   { 0 }
 };
 
@@ -349,6 +298,13 @@ type_get_child_list (PyGISourceType *self,
   return list;
 }
 
+static PyObject *
+type_get_is_bitfield (PyGISourceType *self,
+                            void           *context)
+{
+  return PyInt_FromLong (self->type->is_bitfield);
+}
+
 static const PyGetSetDef _PyGISourceType_getsets[] = {
   { "type", (getter)type_get_type, NULL, NULL},
   { "storage_class_specifier", (getter)type_get_storage_class_specifier, NULL, NULL},
@@ -357,6 +313,7 @@ static const PyGetSetDef _PyGISourceType_getsets[] = {
   { "name", (getter)type_get_name, NULL, NULL},
   { "base_type", (getter)type_get_base_type, NULL, NULL},
   { "child_list", (getter)type_get_child_list, NULL, NULL},
+  { "is_bitfield", (getter)type_get_is_bitfield, NULL, NULL},
   { 0 }
 };
 
@@ -387,7 +344,7 @@ pygi_source_scanner_append_filename (PyGISourceScanner *self,
     return NULL;
 
   self->scanner->filenames = g_list_append (self->scanner->filenames,
-                                           g_strdup (filename));
+                                           g_realpath (filename));
   
   Py_INCREF (Py_None);
   return Py_None;
@@ -555,23 +512,18 @@ pygi_source_scanner_get_symbols (PyGISourceScanner *self)
 }
 
 static PyObject *
-pygi_source_scanner_get_directives (PyGISourceScanner *self,
-                                   PyObject          *args)
+pygi_source_scanner_get_comments (PyGISourceScanner *self)
 {
-  GSList *l, *directives;
+  GSList *l, *comments;
   PyObject *list;
   int i = 0;
-  char *name;
   
-  if (!PyArg_ParseTuple (args, "s:SourceScanner.get_directives", &name))
-    return NULL;
-  
-  directives = gi_source_scanner_get_directives (self->scanner, name);
-  list = PyList_New (g_slist_length (directives));
+  comments = gi_source_scanner_get_comments (self->scanner);
+  list = PyList_New (g_slist_length (comments));
   
-  for (l = directives; l; l = l->next)
+  for (l = comments; l; l = l->next)
     {
-      PyObject *item = pygi_source_directive_new (l->data);
+      PyObject *item = PyString_FromString (l->data);
       PyList_SetItem (list, i++, item);
       Py_INCREF (item);
     }
@@ -581,7 +533,7 @@ pygi_source_scanner_get_directives (PyGISourceScanner *self,
 }
 
 static const PyMethodDef _PyGISourceScanner_methods[] = {
-  { "get_directives", (PyCFunction) pygi_source_scanner_get_directives, METH_VARARGS },
+  { "get_comments", (PyCFunction) pygi_source_scanner_get_comments, METH_NOARGS },
   { "get_symbols", (PyCFunction) pygi_source_scanner_get_symbols, METH_NOARGS },
   { "append_filename", (PyCFunction) pygi_source_scanner_append_filename, METH_VARARGS },
   { "parse_file", (PyCFunction) pygi_source_scanner_parse_file, METH_VARARGS },
@@ -611,7 +563,8 @@ static int calc_attrs_length(PyObject *attributes, int indent,
       if (PyTuple_GetItem(tuple, 1) == Py_None)
        continue;
 
-      g_assert(PyArg_ParseTuple(tuple, "ss", &attr, &value));
+      if (!PyArg_ParseTuple(tuple, "ss", &attr, &value))
+        return -1;
       
       escaped = g_markup_escape_text (value, -1);
       attr_length += 2 + strlen(attr) + strlen(escaped) + 2;
@@ -621,6 +574,9 @@ static int calc_attrs_length(PyObject *attributes, int indent,
   return attr_length + indent + self_indent;
 }
 
+/* Hall of shame, wasted time debugging the code below
+ * 20min - Johan 2009-02-19
+ */
 static PyObject *
 pygi_collect_attributes (PyObject *self,
                         PyObject *args)
@@ -631,9 +587,10 @@ pygi_collect_attributes (PyObject *self,
   char *indent_char;
   gboolean first;
   GString *attr_value;
+  int len;
   
-  if (!PyArg_ParseTuple(args, "sOisi",
-                       &tag_name, &attributes,
+  if (!PyArg_ParseTuple(args, "sO!isi",
+                       &tag_name, &PyList_Type, &attributes,
                        &self_indent, &indent_char,
                        &indent))
     return NULL;
@@ -641,26 +598,44 @@ pygi_collect_attributes (PyObject *self,
   if (attributes == Py_None || !PyList_Size(attributes))
     return PyString_FromString("");
 
-  if (calc_attrs_length(attributes, indent, self_indent) > 79)
+  len = calc_attrs_length(attributes, indent, self_indent);
+  if (len < 0)
+    return NULL;
+  if (len > 79)
     indent_len = self_indent + strlen(tag_name) + 1;
   else
     indent_len = 0;
 
   first = TRUE;
   attr_value = g_string_new ("");
-
+  
   for (i = 0; i < PyList_Size (attributes); ++i)
     {
       PyObject *tuple;
       char *attr, *value, *escaped;
       
       tuple = PyList_GetItem (attributes, i);
-      g_assert(tuple != NULL);
-      g_assert(PyTuple_Size(tuple) == 2);
+      
+      if (!PyTuple_Check (tuple)) 
+        {
+          PyErr_SetString(PyExc_TypeError,
+                          "attribute item must be a tuple");
+          return NULL;
+        }
+      
+      if (!PyTuple_Size (tuple) == 2)
+        {
+          PyErr_SetString(PyExc_IndexError,
+                          "attribute item must be a tuple of length 2");
+          return NULL;
+        }
+      
       if (PyTuple_GetItem(tuple, 1) == Py_None)
        continue;
 
-      g_assert(PyArg_ParseTuple(tuple, "ss", &attr, &value));
+      /* this leaks, but we exit after, so */
+      if (!PyArg_ParseTuple(tuple, "ss", &attr, &value))
+        return NULL;
 
       if (indent_len && !first)
        {
@@ -699,9 +674,6 @@ init_giscanner(void)
                       (PyMethodDef*)pyscanner_functions);
     d = PyModule_GetDict (m);
 
-    PyGISourceDirective_Type.tp_getset = (PyGetSetDef*)_PyGISourceDirective_getsets;
-    REGISTER_TYPE (d, "SourceDirective", PyGISourceDirective_Type);
-
     PyGISourceScanner_Type.tp_init = (initproc)pygi_source_scanner_init;
     PyGISourceScanner_Type.tp_methods = (PyMethodDef*)_PyGISourceScanner_methods;
     REGISTER_TYPE (d, "SourceScanner", PyGISourceScanner_Type);