gobject-introspection r633 - in trunk: giscanner tests/scanner



Author: walters
Date: Mon Sep 29 19:03:35 2008
New Revision: 633
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=633&view=rev

Log:
Some work on arrays


Modified:
   trunk/giscanner/ast.py
   trunk/giscanner/girwriter.py
   trunk/giscanner/glibtransformer.py
   trunk/giscanner/scannerlexer.l
   trunk/giscanner/transformer.py
   trunk/tests/scanner/annotation.c
   trunk/tests/scanner/annotation.h

Modified: trunk/giscanner/ast.py
==============================================================================
--- trunk/giscanner/ast.py	(original)
+++ trunk/giscanner/ast.py	Mon Sep 29 19:03:35 2008
@@ -109,6 +109,13 @@
 type_names['constpointer'] = TYPE_ANY
 
 
+# These types, when seen by reference, are converted into an Array()
+# by default
+default_array_types = {}
+default_array_types['uint8*'] = TYPE_UINT8
+default_array_types['char**'] = TYPE_STRING
+
+
 def type_name_from_ctype(ctype):
     return type_names.get(ctype, ctype)
 
@@ -161,6 +168,39 @@
         self.resolved = False
 
 
+class Array(Type):
+
+    def __init__(self, name, ctype, element_type):
+        Type.__init__(self, name, ctype)
+        self.element_type = element_type
+        self.zeroterminated = True
+        self.length_param_index = -1
+
+    def __repr__(self):
+        return 'Array(%r of %r)' % (self.name, self.element_type, )
+
+
+class List(Type):
+
+    def __init__(self, name, ctype, element_type):
+        Type.__init__(self, name, ctype)
+        self.element_type = element_type
+
+    def __repr__(self):
+        return 'List(%r of %r)' % (self.name, self.element_type, )
+
+
+class Map(Type):
+
+    def __init__(self, name, ctype, key_type, value_type):
+        Type.__init__(self, name, ctype)
+        self.key_type = key_type
+        self.value_type = value_type
+
+    def __repr__(self):
+        return 'Map(%r <%r,%r.)' % (self.name, self.key_type, self.value_type)
+
+
 class Alias(Node):
 
     def __init__(self, name, target, ctype=None):
@@ -315,18 +355,6 @@
             self.name, self.retval, self.parameters)
 
 
-class Sequence(Type):
-    # Subclass, because a Sequence is a kind of Type
-
-    def __init__(self, name, ctype, element_type):
-        Type.__init__(self, name, ctype)
-        self.element_type = element_type
-        self.transfer = False
-
-    def __repr__(self):
-        return 'Sequence(%r of %r)' % (self.name, self.element_type, )
-
-
 class Union(Node):
 
     def __init__(self, name, symbol):

Modified: trunk/giscanner/girwriter.py
==============================================================================
--- trunk/giscanner/girwriter.py	(original)
+++ trunk/giscanner/girwriter.py	Mon Sep 29 19:03:35 2008
@@ -23,7 +23,7 @@
 import os
 
 from .ast import (Callback, Class, Enum, Function, Interface, Member,
-                  Sequence, Struct, Alias, Union)
+                  Array, Struct, Alias, Union)
 from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember,
                       GLibFlags, GLibObject, GLibInterface)
 from .xmlwriter import XMLWriter
@@ -140,6 +140,19 @@
         with self.tagcontext('parameter', attrs):
             self._write_type(parameter.type)
 
+    def _type_to_string(self, ntype):
+        if isinstance(ntype, basestring):
+            return ntype
+        if isinstance(ntype, Array):
+            options = []
+            if not ntype.zeroterminated:
+                options.append('zero-terminated=0')
+            if ntype.length_param_index >= 0:
+                options.append('length=%d' % (ntype.length_param_index, ))
+            return self._type_to_string(ntype.element_type) + \
+                '[%s]' % (','.join(options), )
+        return ntype.name
+
     def _write_type(self, ntype, relation=None):
         if isinstance(ntype, basestring):
             typename = ntype
@@ -147,21 +160,14 @@
         else:
             typename = ntype.name
             type_cname = ntype.ctype
-        attrs = [('name', typename)]
+        attrs = [('name', self._type_to_string(ntype))]
         if relation:
             attrs.append(('relation', relation))
-        if isinstance(ntype, Sequence):
-            if ntype.transfer:
-                attrs.append(('transfer-ownership',
-                              str(int(ntype.transfer))))
-            with self.tagcontext('type', attrs):
-                self._write_type(ntype.element_type, relation="element")
-        else:
-            # FIXME: figure out if type references a basic type
-            #        or a boxed/class/interface etc. and skip
-            #        writing the ctype if the latter.
-            if type_cname is not None:
-                attrs.append(('c:type', type_cname))
+        # FIXME: figure out if type references a basic type
+        #        or a boxed/class/interface etc. and skip
+        #        writing the ctype if the latter.
+        if type_cname is not None:
+            attrs.append(('c:type', type_cname))
             self.write_tag('type', attrs)
 
     def _write_enum(self, enum):

Modified: trunk/giscanner/glibtransformer.py
==============================================================================
--- trunk/giscanner/glibtransformer.py	(original)
+++ trunk/giscanner/glibtransformer.py	Mon Sep 29 19:03:35 2008
@@ -25,7 +25,7 @@
 
 from . import cgobject
 from .ast import (Callback, Enum, Function, Member, Namespace, Parameter,
-                  Sequence, Property, Return, Struct, Type, Alias,
+                  Property, Return, Struct, Type, Alias, Array,
                   Union, type_name_from_ctype)
 from .transformer import Names
 from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember, GLibFlags,
@@ -167,6 +167,12 @@
         no_uscore_prefixed = (prefix + '_' + to_underscores(suffix)).lower()
         self._uscore_type_names[no_uscore_prefixed] = node
 
+    def type_is_list(self, ctype):
+        return ctype in ['GList*', 'GSList*']
+
+    def type_is_map(self, ctype):
+        return ctype in ['GHashTable*']
+
     # Helper functions
 
     def _type_from_gtype(self, type_id):
@@ -630,9 +636,9 @@
         return False
 
     def _validate_type(self, ptype):
-        if isinstance(ptype, Sequence):
+        if isinstance(ptype, Array):
             etype = ptype.element_type
-            if isinstance(etype, Sequence):
+            if isinstance(etype, Array):
                 return self._validate_type(etype)
             return self._validate_type_name(etype)
         return self._validate_type_name(ptype.name)

Modified: trunk/giscanner/scannerlexer.l
==============================================================================
--- trunk/giscanner/scannerlexer.l	(original)
+++ trunk/giscanner/scannerlexer.l	Mon Sep 29 19:03:35 2008
@@ -258,13 +258,13 @@
 
           do
             {
-              if (*ptr == '(')
+              if (*ptr == '<')
 		{
 		  pstack++;
 		  if (pstack == 1)
 		    continue;
 		}
-	      else if (*ptr == ')')
+	      else if (*ptr == '>')
 		pstack--;
 		       
               if (pstack == 0)

Modified: trunk/giscanner/transformer.py
==============================================================================
--- trunk/giscanner/transformer.py	(original)
+++ trunk/giscanner/transformer.py	Mon Sep 29 19:03:35 2008
@@ -21,9 +21,10 @@
 import os
 
 from giscanner.ast import (Callback, Enum, Function, Namespace, Member,
-                           Parameter, Return, Sequence, Struct, Field,
+                           Parameter, Return, Array, Struct, Field,
                            Type, Alias, Interface, Class, Node, Union,
-                           type_name_from_ctype, type_names)
+                           List, Map, type_name_from_ctype, type_names,
+                           default_array_types)
 from giscanner.config import DATADIR
 from .glibast import GLibBoxed
 from giscanner.sourcescanner import (
@@ -69,6 +70,9 @@
         self._includes = set()
         self._includepaths = []
 
+        self._list_ctypes = []
+        self._map_ctypes = []
+
     def get_names(self):
         return self._names
 
@@ -302,7 +306,7 @@
                 "symbol %r of type %s" % (symbol.ident, ctype_name(ctype)))
         return node
 
-    def _create_type(self, source_type):
+    def _create_type(self, source_type, options=[]):
         ctype = self._create_source_type(source_type)
         if ctype == 'va_list':
             raise SkipError
@@ -310,13 +314,35 @@
         #        properly instead
         elif ctype == 'FILE*':
             raise SkipError
+        if ctype in self._list_ctypes:
+            if len(options) > 0:
+                contained_type = options[0]
+            else:
+                contained_type = None
+            return List(ctype.replace('*', ''),
+                        ctype,
+                        contained_type)
+        if ctype in self._list_ctypes:
+            if len(options) > 0:
+                key_type = options[0]
+                value_type = options[1]
+            else:
+                key_type = None
+                value_type = None
+            return Map(ctype.replace('*', ''),
+                       ctype,
+                       key_type, value_type)
+        if ctype in default_array_types:
+            derefed = ctype[:-1] # strip the *
+            return Array(None, ctype,
+                         type_name_from_ctype(derefed))
         type_name = type_name_from_ctype(ctype)
         type_name = type_name.replace('*', '')
         resolved_type_name = self.resolve_type_name(type_name)
         return Type(resolved_type_name, ctype)
 
     def _create_parameter(self, symbol, options):
-        ptype = self._create_type(symbol.base_type)
+        ptype = self._create_type(symbol.base_type, options)
         param = Parameter(symbol.ident, ptype)
         for option in options:
             if option in ['in-out', 'inout']:
@@ -325,12 +351,12 @@
                 param.direction = 'in'
             elif option == 'out':
                 param.direction = 'out'
-            elif option == 'callee-owns':
+            elif option == 'transfer':
                 param.transfer = True
             elif option == 'allow-none':
                 param.allow_none = True
             else:
-                print 'Unhandled parameter annotation option: %s' % (
+                print 'Unhandled parameter annotation option: %r' % (
                     option, )
         return param
 
@@ -343,17 +369,6 @@
         for option in options:
             if option == 'caller-owns':
                 return_.transfer = True
-            elif option.startswith('seq '):
-                value, element_options = option[3:].split(None, 2)
-                c_element_type = self._parse_type_annotation(value)
-                element_type = c_element_type.replace('*', '')
-                element_type = self.resolve_type_name(element_type,
-                                                      c_element_type)
-                seq = Sequence(rtype.name,
-                               type_name_from_ctype(rtype.name),
-                               element_type)
-                seq.transfer = True
-                return_.type = seq
             else:
                 print 'Unhandled parameter annotation option: %s' % (
                     option, )
@@ -423,12 +438,6 @@
             name = self.strip_namespace_object(symbol.ident)
         return Callback(name, retval, list(parameters), symbol.ident)
 
-    def _parse_type_annotation(self, annotation):
-        if (annotation[0] == "[" and
-            annotation[-1] == "]"):
-            return Sequence(self._parse_type_annotation(annotation[1:-1]))
-        return annotation
-
     def _typepair_to_str(self, item):
         nsname, item = item
         if nsname is None:
@@ -497,7 +506,7 @@
             return None
 
     def resolve_param_type_full(self, ptype, names):
-        if isinstance(ptype, Sequence):
+        if isinstance(ptype, Array):
             ptype.element_type = \
                 self.resolve_param_type_full(ptype.element_type, names)
         elif isinstance(ptype, Node):

Modified: trunk/tests/scanner/annotation.c
==============================================================================
--- trunk/tests/scanner/annotation.c	(original)
+++ trunk/tests/scanner/annotation.c	Mon Sep 29 19:03:35 2008
@@ -32,7 +32,7 @@
  *
  * This is a test for out arguments
  *
- * @outarg: (out): This is an argument test
+ * @outarg: <out>: This is an argument test
  * Return value: an int
  */
 gint
@@ -47,7 +47,7 @@
  *
  * This is a test for out arguments
  *
- * @outarg: (in): This is an argument test
+ * @outarg: <in>: This is an argument test
  * Return value: an int
  */
 gint
@@ -63,7 +63,7 @@
  *
  * This is a test for out arguments
  *
- * @inoutarg: (inout): This is an argument test
+ * @inoutarg: <out>: This is an argument test
  * Return value: an int
  */
 gint
@@ -78,7 +78,7 @@
  *
  * This is a second test for out arguments
  *
- * @inoutarg: (in) (out): This is an argument test
+ * @inoutarg: <inout>: This is an argument test
  * Return value: an int
  */
 gint
@@ -94,7 +94,7 @@
  *
  * This is a 3th test for out arguments
  *
- * @inoutarg: (in-out) (allow-none): This is an argument test
+ * @inoutarg: <inout,allow-none>: This is an argument test
  * Return value: an int
  */
 gint
@@ -109,11 +109,11 @@
  *
  * This is a test for out arguments
  *
- * @toown: (callee-owns): a #GObject
+ * @toown: <out,transfer>: a #GObject
  * Return value: an int
  */
 gint
-annotation_object_calleeowns (AnnotationObject *object, GObject *toown)
+annotation_object_calleeowns (AnnotationObject *object, GObject **toown)
 {
 	return 1;
 }
@@ -125,14 +125,14 @@
  *
  * This is a test for out arguments
  *
- * @toown1: (callee-owns): a #GObject
- * @toown2: (callee-owns): a #GObject
+ * @toown1: <out,transfer>: a #GObject
+ * @toown2: <out,transfer>: a #GObject
  * Return value: an int
  */
 gint
 annotation_object_calleesowns (AnnotationObject *object,
-			       GObject *toown1,
-			       GObject *toown2)
+			       GObject **toown1,
+			       GObject **toown2)
 {
 	return 1;
 }
@@ -142,16 +142,17 @@
  * annotation_object_get_strings:
  * @object: a #GObject
  *
- * This is a test for returning a list of strings
+ * This is a test for returning a list of strings, where
+ * each string needs to be freed.
  *
- * Return value: (seq char* (callee-owns)) (caller-owns): list of strings
+ * Return value: <char*,transfer>: list of strings
  */
 GList*
 annotation_object_get_strings (AnnotationObject *object)
 {
   GList *list = NULL;
-  list = g_list_prepend (list, "annotation");
-  list = g_list_prepend (list, "bar");
+  list = g_list_prepend (list, g_strdup ("annotation"));
+  list = g_list_prepend (list, g_strdup ("bar"));
   return list;
 }
 
@@ -174,8 +175,7 @@
  * The list itself should be freed, but not the internal objects,
  * intentionally similar example to gtk_container_get_children
  *
- * Return value: (seq AnnotationObject* (callee-owns)) (caller-owns): a list
- *               of strings
+ * Return value: <AnnotationObject*>: list of objects
  */
 GSList*
 annotation_object_get_objects (AnnotationObject *object)
@@ -191,21 +191,51 @@
  *
  * Test returning a caller-owned object
  *
- * Return value: (caller-owns): The object
+ * Return value: <transfer>: The object
  **/
-GObject*
+GObject* 
 annotation_object_create_object (AnnotationObject *object)
 {
 	return g_object_ref (object);
 }
 
 /**
+ * annotation_object_compute_sum:
+ * @object: a #GObject
+ * @nums: <array>: Sequence of numbers
+ *
+ * Test taking a zero-terminated array
+ **/
+void
+annotation_object_compute_sum  (AnnotationObject *object,
+				int              *nums)
+{
+
+}
+
+/**
+ * annotation_object_compute_sum_n:
+ * @object: a #GObject
+ * @nums: <array,length=2>: Sequence of numbers
+ * @nums: Length of number array
+ *
+ * Test taking an array with length parameter
+ **/
+void     
+annotation_object_compute_sum_n(AnnotationObject *object,
+				int              *nums,
+				int               n_nums)
+{
+
+}
+
+/**
  * annotation_object_allow_none: 
  * @object: a #GObject
- * @allow_none: (allow-none): 
+ * @somearg: <allow-none>: 
  **/
 GObject*
-annotation_object_allow_none (AnnotationObject *object, gchar *allow_none)
+annotation_object_allow_none (AnnotationObject *object, gchar *somearg)
 {
 }
 

Modified: trunk/tests/scanner/annotation.h
==============================================================================
--- trunk/tests/scanner/annotation.h	(original)
+++ trunk/tests/scanner/annotation.h	Mon Sep 29 19:03:35 2008
@@ -31,13 +31,20 @@
 gint     annotation_object_in           (AnnotationObject *object,
 					 int              *inarg);
 gint     annotation_object_calleeowns   (AnnotationObject *object,
-					 GObject          *toown);
+					 GObject          **toown);
 gint     annotation_object_calleesowns  (AnnotationObject *object,
-					 GObject          *toown1,
-					 GObject          *toown2);
+					 GObject          **toown1,
+					 GObject          **toown2);
 GList*   annotation_object_get_strings  (AnnotationObject *object);
 GSList*  annotation_object_get_objects  (AnnotationObject *object);
 
+void     annotation_object_compute_sum  (AnnotationObject *object,
+					 int              *nums);
+
+void     annotation_object_compute_sum_n(AnnotationObject *object,
+					 int              *nums,
+					 int               n_nums);
+
 GObject* annotation_object_do_not_use   (AnnotationObject *object);
 
 



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