gobject-introspection r224 - in trunk: . giscanner tools



Author: johan
Date: Fri Apr 25 00:17:15 2008
New Revision: 224
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=224&view=rev

Log:
2008-04-24  Johan Dahlin  <jdahlin async com br>

    * giscanner/gidlwriter.py:
    * giscanner/girwriter.py:
    * giscanner/giscannermodule.c (directive_get_name),
    (directive_get_value), (directive_get_options),
    (symbol_get_directives), (symbol_set_directives),
    (pygi_source_scanner_parse_file),
    (pygi_source_scanner_lex_filename),
    (pygi_source_scanner_get_directives), (init_giscanner):
    * giscanner/sourcescanner.c (gi_source_scanner_get_directives):
    * giscanner/sourcescanner.h:
    * giscanner/sourcescanner.py:
    * giscanner/treebuilder.py:
    * tools/g-ir-scanner:
    Add support for source/header annotations.



Modified:
   trunk/ChangeLog
   trunk/giscanner/gidlwriter.py
   trunk/giscanner/girwriter.py
   trunk/giscanner/giscannermodule.c
   trunk/giscanner/sourcescanner.c
   trunk/giscanner/sourcescanner.h
   trunk/giscanner/sourcescanner.py
   trunk/giscanner/treebuilder.py
   trunk/tools/g-ir-scanner

Modified: trunk/giscanner/gidlwriter.py
==============================================================================
--- trunk/giscanner/gidlwriter.py	(original)
+++ trunk/giscanner/gidlwriter.py	Fri Apr 25 00:17:15 2008
@@ -50,7 +50,10 @@
     def _write_return_type(self, return_):
         if not return_:
             return
-        self.write_tag('return-type', [('type', return_.type)])
+        attrs = [('type', return_.type)]
+        if return_.transfer != 'none':
+            attrs.append(('transfer', return_.transfer))
+        self.write_tag('return-type', attrs)
 
     def _write_parameters(self, parameters):
         if not parameters:
@@ -60,8 +63,13 @@
                 self._write_parameter(parameter)
 
     def _write_parameter(self, parameter):
-        self.write_tag('parameter', [('name', parameter.name),
-                                     ('type', parameter.type)])
+        attrs = [('name', parameter.name),
+                 ('type', parameter.type)]
+        if parameter.direction != 'in':
+            attrs.append(('direction', parameter.direction))
+        if parameter.transfer != 'none':
+            attrs.append(('transfer', parameter.transfer))
+        self.write_tag('parameter', attrs)
 
     def _write_enum(self, enum):
         attrs = [('name', enum.name)]

Modified: trunk/giscanner/girwriter.py
==============================================================================
--- trunk/giscanner/girwriter.py	(original)
+++ trunk/giscanner/girwriter.py	Fri Apr 25 00:17:15 2008
@@ -58,7 +58,10 @@
             return
         with self.tagcontext('return-values'):
             with self.tagcontext('return-value'):
-                self.write_tag('type', [('name', return_.type)])
+                attrs = [('name', return_.type)]
+                if return_.transfer != 'none':
+                    attrs.append(('transfer', return_.transfer))
+                self.write_tag('type', attrs)
 
     def _write_parameters(self, parameters):
         if not parameters:
@@ -69,6 +72,10 @@
 
     def _write_parameter(self, parameter):
         attrs = [('name', parameter.name)]
+        if parameter.direction != 'in':
+            attrs.append(('direction', parameter.direction))
+        if parameter.transfer != 'none':
+            attrs.append(('transfer', parameter.transfer))
         with self.tagcontext('parameters', attrs):
             self.write_tag('type', [('name', parameter.type)])
 

Modified: trunk/giscanner/giscannermodule.c
==============================================================================
--- trunk/giscanner/giscannermodule.c	(original)
+++ trunk/giscanner/giscannermodule.c	Fri Apr 25 00:17:15 2008
@@ -54,12 +54,18 @@
 
 typedef struct {
   PyObject_HEAD
+  GISourceDirective *directive;
+} PyGISourceDirective;
+
+typedef struct {
+  PyObject_HEAD
   GISourceType *type;
 } PyGISourceType;
 
 typedef struct {
   PyObject_HEAD
   GISourceSymbol *symbol;
+  PyObject *directives;
 } PyGISourceSymbol;
 
 typedef struct {
@@ -67,11 +73,59 @@
   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 *
+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, *symbols;
+  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++, (PyObject*)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 *
@@ -119,6 +173,26 @@
   return PyString_FromString (self->symbol->const_string);
 }
 
+static PyObject *
+symbol_get_directives (PyGISourceSymbol *self,
+		       void             *context)
+{
+  if (!self->directives)
+    self->directives = Py_BuildValue("[]");
+  Py_INCREF (self->directives);
+  return self->directives;
+}
+
+static int
+symbol_set_directives (PyGISourceSymbol *self,
+		       PyObject         *value,
+		       void             *context)
+{
+  self->directives = value;
+  Py_INCREF(value);
+  return 0;
+}
+
 static const PyGetSetDef _PyGISourceSymbol_getsets[] = {
   /* int ref_count; */
   { "type", (getter)symbol_get_type, NULL, NULL},
@@ -128,7 +202,7 @@
   /* gboolean const_int_set; */
   { "const_int", (getter)symbol_get_const_int, NULL, NULL},  
   { "const_string", (getter)symbol_get_const_string, NULL, NULL},  
-  /* GSList *directives; */
+  { "directives", (getter)symbol_get_directives, symbol_set_directives, NULL},  
   { 0 }
 };
 
@@ -251,7 +325,7 @@
   char *filename;
   FILE *fp;
   
-  if (!PyArg_ParseTuple (args, "is:SourceScanner.__init__", &fd, &filename))
+  if (!PyArg_ParseTuple (args, "is:SourceScanner.parse_file", &fd, &filename))
     return NULL;
 
   fp = fdopen (fd, "r");
@@ -267,9 +341,31 @@
 
   if (!gi_source_scanner_parse_file (self->scanner, fp))
     {
-      g_print ("Something went wrong..\n");
+      g_print ("Something went wrong during parsing.\n");
+      return NULL;
+    }
+
+  Py_INCREF (Py_None);
+  return Py_None;
+}
+
+static PyObject *
+pygi_source_scanner_lex_filename (PyGISourceScanner *self,
+				  PyObject          *args)
+{
+  char *filename;
+  
+  if (!PyArg_ParseTuple (args, "s:SourceScanner.lex_filename", &filename))
+    return NULL;
+
+  if (!gi_source_scanner_lex_filename (self->scanner, filename))
+    {
+      g_print ("Something went wrong during lexing.\n");
       return NULL;
     }
+  self->scanner->filenames =
+    g_list_append (self->scanner->filenames, g_strdup (filename));
+  self->scanner->current_filename = g_strdup (filename);
 
   Py_INCREF (Py_None);
   return Py_None;
@@ -314,9 +410,40 @@
   return list;
 }
 
+static PyObject *
+pygi_source_scanner_get_directives (PyGISourceScanner *self,
+				    PyObject          *args)
+{
+  GSList *l, *directives;
+  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));
+  
+  for (l = directives; l; l = l->next)
+    {
+      PyGISourceDirective *item;
+      item = (PyGISourceDirective *)PyObject_New (PyGISourceDirective,
+						  &PyGISourceDirective_Type);
+      item->directive = l->data;
+      PyList_SetItem (list, i++, (PyObject*)item);
+      Py_INCREF (item);
+    }
+
+  Py_INCREF (list);
+  return list;
+}
+
 static const PyMethodDef _PyGISourceScanner_methods[] = {
+  { "get_directives", (PyCFunction) pygi_source_scanner_get_directives, METH_VARARGS },
   { "get_symbols", (PyCFunction) pygi_source_scanner_get_symbols, METH_NOARGS },
   { "parse_file", (PyCFunction) pygi_source_scanner_parse_file, METH_VARARGS },
+  { "lex_filename", (PyCFunction) pygi_source_scanner_lex_filename, METH_VARARGS },
   { "set_macro_scan", (PyCFunction) pygi_source_scanner_set_macro_scan, METH_VARARGS },
   { NULL, NULL, 0 }
 };
@@ -337,6 +464,9 @@
 		       (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);

Modified: trunk/giscanner/sourcescanner.c
==============================================================================
--- trunk/giscanner/sourcescanner.c	(original)
+++ trunk/giscanner/sourcescanner.c	Fri Apr 25 00:17:15 2008
@@ -287,3 +287,10 @@
 {
   return g_slist_reverse (scanner->symbols);
 }
+
+GSList *
+gi_source_scanner_get_directives(GISourceScanner  *scanner,
+				 const gchar      *name)
+{
+  return g_hash_table_lookup (scanner->directives_map, name);
+}

Modified: trunk/giscanner/sourcescanner.h
==============================================================================
--- trunk/giscanner/sourcescanner.h	(original)
+++ trunk/giscanner/sourcescanner.h	Fri Apr 25 00:17:15 2008
@@ -143,6 +143,8 @@
 void                gi_source_scanner_set_macro_scan   (GISourceScanner  *scanner,
 							gboolean          macro_scan);
 GSList *            gi_source_scanner_get_symbols      (GISourceScanner  *scanner);
+GSList *            gi_source_scanner_get_directives   (GISourceScanner  *scanner,
+							const gchar      *name);
 void                gi_source_scanner_free             (GISourceScanner  *scanner);
 
 GISourceSymbol *    gi_source_symbol_new               (GISourceSymbolType  type);

Modified: trunk/giscanner/sourcescanner.py
==============================================================================
--- trunk/giscanner/sourcescanner.py	(original)
+++ trunk/giscanner/sourcescanner.py	Fri Apr 25 00:17:15 2008
@@ -3,6 +3,31 @@
 
 import giscanner
 
+
+class SourceSymbol(object):
+    def __init__(self, symbol, directives):
+        self._symbol = symbol
+        self._directives = directives
+
+    def directives(self):
+        mapping = {}
+        for directive in self._directives:
+            mapping[directive.name] = directive.options
+        return mapping
+
+    @property
+    def ident(self):
+        return self._symbol.ident
+
+    @property
+    def type(self):
+        return self._symbol.type
+
+    @property
+    def base_type(self):
+        return self._symbol.base_type
+
+
 class SourceScanner(object):
     def __init__(self):
         self._scanner = giscanner.SourceScanner()
@@ -20,9 +45,18 @@
                 if not opt in self._cpp_options:
                     self._cpp_options.append(opt)
 
-    def parse_file(self, filename):
-        self._parse_one(filename)
-        self._filenames.append(filename)
+    def parse_files(self, filenames):
+        headers = []
+        for filename in filenames:
+            if filename.endswith('.c'):
+                filename = os.path.abspath(filename)
+                self._scanner.lex_filename(filename)
+            else:
+                headers.append(filename)
+
+        for filename in headers:
+            self._parse_one(filename)
+            self._filenames.append(filename)
 
     def parse_macros(self):
         self._scanner.set_macro_scan(True)
@@ -32,7 +66,8 @@
 
     def get_symbols(self):
         for symbol in self._scanner.get_symbols():
-            yield symbol
+            yield SourceSymbol(
+                symbol, self._scanner.get_directives(symbol.ident))
 
     def dump(self):
         print '-'*30
@@ -42,10 +77,6 @@
     # Private
 
     def _parse_one(self, filename):
-        if filename.endswith('.c'):
-            # FIXME lex only
-            return
-
         filename = os.path.abspath(filename)
         proc = self._preprocess(filename)
         fd = proc.stdout.fileno()

Modified: trunk/giscanner/treebuilder.py
==============================================================================
--- trunk/giscanner/treebuilder.py	(original)
+++ trunk/giscanner/treebuilder.py	Fri Apr 25 00:17:15 2008
@@ -2,12 +2,13 @@
 
 
 class Node(object):
-    pass
+    def __init__(self, name=None):
+        self.name = name
 
 
 class Function(Node):
     def __init__(self, name, retval, parameters, symbol):
-        self.name = name
+        Node.__init__(self, name)
         self.retval = retval
         self.parameters = parameters
         self.symbol = symbol
@@ -19,8 +20,10 @@
 
 class Parameter(Node):
     def __init__(self, name, type):
-        self.name = name
+        Node.__init__(self, name)
         self.type = type
+        self.direction = 'in'
+        self.transfer = 'none'
 
     def __repr__(self):
         return 'Parameter(%r, %r)' % (self.name, self.type)
@@ -28,7 +31,7 @@
 
 class Enum(Node):
     def __init__(self, name, members):
-        self.name = name
+        Node.__init__(self, name)
         self.members = members
 
     def __repr__(self):
@@ -37,7 +40,7 @@
 
 class Member(Node):
     def __init__(self, name, value):
-        self.name = name
+        Node.__init__(self, name)
         self.value = value
 
     def __repr__(self):
@@ -45,16 +48,15 @@
 
 
 class Struct(Node):
-    def __init__(self, name):
-        self.name = name
-
     def __repr__(self):
         return 'Struct(%r)' % (self.name,)
 
 
 class Return(Node):
     def __init__(self, type):
+        Node.__init__(self)
         self.type = type
+        self.transfer = 'none'
 
     def __repr__(self):
         return 'Return(%r)' % (self.type,)
@@ -62,7 +64,7 @@
 
 class Class(Node):
     def __init__(self, name, parent):
-        self.name = name
+        Node.__init__(self, name)
         self.parent = parent
         self.methods = []
         self.constructors = []
@@ -76,7 +78,7 @@
 
 class Interface(Node):
     def __init__(self, name):
-        self.name = name
+        Node.__init__(self, name)
         self.methods = []
         self.properties = []
 
@@ -88,7 +90,7 @@
 
 class Constant(Node):
     def __init__(self, name, type, value):
-        self.name = name
+        Node.__init__(self, name)
         self.type = type
         self.value = value
 
@@ -99,7 +101,7 @@
 
 class Property(Node):
     def __init__(self, name, type):
-        self.name = name
+        Node.__init__(self, name)
         self.type = type
 
     def __repr__(self):
@@ -110,7 +112,7 @@
 
 class Callback(Node):
     def __init__(self, name, retval, parameters):
-        self.name = name
+        Node.__init__(self, name)
         self.retval = retval
         self.parameters = parameters
 
@@ -166,9 +168,11 @@
         return Enum(symbol.ident, members)
 
     def _create_function(self, symbol):
-        parameters = self._create_parameters(symbol.base_type)
-        retval = Return(self._create_source_type(symbol.base_type.base_type))
-        return Function(symbol.ident, retval, list(parameters), symbol.ident)
+        directives = symbol.directives()
+        parameters = list(self._create_parameters(symbol.base_type, directives))
+        return_ = self._create_return(symbol.base_type.base_type,
+                                      directives.get('return', []))
+        return Function(symbol.ident, return_, parameters, symbol.ident)
 
     def _create_source_type(self, source_type):
         if source_type.type == giscanner.CTYPE_VOID:
@@ -184,13 +188,39 @@
             value = '???'
         return value
 
-    def _create_parameters(self, base_type):
+    def _create_parameters(self, base_type, options=None):
+        if not options:
+            options = {}
         for child in base_type.child_list:
-            yield self._create_parameter(child)
+            yield self._create_parameter(
+                child, options.get(child.ident, []))
 
-    def _create_parameter(self, symbol):
-        return Parameter(symbol.ident,
-                         self._create_source_type(symbol.base_type))
+    def _create_parameter(self, symbol, options):
+        param = Parameter(symbol.ident,
+                          self._create_source_type(symbol.base_type))
+        for option in options:
+            if option in ['in-out', 'inout']:
+                param.direction = 'inout'
+            elif option == 'in':
+                param.direction = 'in'
+            elif option == 'out':
+                param.direction = 'out'
+            elif option == 'callee-owns':
+                param.transfer = 'full'
+            else:
+                print 'Unhandled parameter annotation option: %s' % (
+                    option,)
+        return param
+
+    def _create_return(self, symbol, options):
+        return_ = Return(self._create_source_type(symbol))
+        for option in options:
+            if option == 'caller-owns':
+                return_.transfer = 'full'
+            else:
+                print 'Unhandled parameter annotation option: %s' % (
+                    option,)
+        return return_
 
     def _create_struct(self, symbol):
         return Struct(symbol.ident)

Modified: trunk/tools/g-ir-scanner
==============================================================================
--- trunk/tools/g-ir-scanner	(original)
+++ trunk/tools/g-ir-scanner	Fri Apr 25 00:17:15 2008
@@ -70,8 +70,7 @@
             arg.endswith('.h')):
             filenames.append(arg)
 
-    for filename in filenames:
-        ss.parse_file(filename)
+    ss.parse_files(filenames)
     ss.parse_macros()
 
     builder = GObjectTreeBuilder(options.namespace)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]