Bug 552568 - All the argv parameters in Gtk.gir map char*** to int8
authorColin Walters <walters@src.gnome.org>
Mon, 17 Nov 2008 17:01:36 +0000 (17:01 +0000)
committerColin Walters <walters@src.gnome.org>
Mon, 17 Nov 2008 17:01:36 +0000 (17:01 +0000)
svn path=/trunk/; revision=939

ChangeLog
giscanner/ast.py
giscanner/transformer.py
tests/scanner/annotation-1.0-expected.gir
tests/scanner/annotation-1.0-expected.tgir
tests/scanner/annotation.c
tests/scanner/annotation.h

index 314fe27..2d92847 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2008-11-17  Andreas Rottmann  <a.rottmann@gmx.at>
+
+       * giscanner/ast.py: Change string array match type to be in terms
+       of canonicalized type.
+       * giscanner/transformer.py: Add canonicalize_ctype which gives us
+       a version of a c:type without aliases, so we can deep canonicalize
+       char** to utf8*.  Update parse_ctype to use it.
+       * tests/*: Add gtk_init like int*/char*** arg functions for testing.
+
 2008-11-16  Colin Walters  <walters@verbum.org>
 
        * girepository/girepository.c: Ensure we always call init_globals,
index 41587bc..f2d7219 100644 (file)
@@ -129,7 +129,7 @@ type_names['constpointer'] = TYPE_ANY
 # If you add/change these, be sure to update glibast.py too
 default_array_types = {}
 default_array_types['uint8*'] = TYPE_UINT8
-default_array_types['char**'] = TYPE_STRING
+default_array_types['utf8*'] = TYPE_STRING
 
 # These types, when seen by reference, are interpreted as out parameters
 default_out_types = (TYPE_INT, TYPE_UINT, TYPE_LONG, TYPE_ULONG,
index a43cfdc..c60ec62 100644 (file)
@@ -372,23 +372,43 @@ class Transformer(object):
                 "symbol %r of type %s" % (symbol.ident, ctype_name(ctype)))
         return node
 
-    def parse_ctype(self, ctype, is_member=False):
+    def _canonicalize_ctype(self, ctype):
         # First look up the ctype including any pointers;
         # a few type names like 'char*' have their own aliases
         # and we need pointer information for those.
         firstpass = type_name_from_ctype(ctype)
 
+        # If we have a particular alias for this, skip deep
+        # canonicalization to prevent changing
+        # e.g. char* -> int8*
+        if firstpass != ctype:
+            return firstpass
+
+        # We're also done if the type is already a fundamental
+        # known type, or there are no pointers.
+        if ctype in type_names or not firstpass.endswith('*'):
+            return firstpass
+
+        # We have a pointer type.
+        # Strip the end pointer, canonicalize our base type
+        base = firstpass[:-1]
+        canonical_base = self._canonicalize_ctype(base)
+
+        # Append the pointer again
+        canonical = canonical_base + '*'
+
+        return canonical
+
+    def parse_ctype(self, ctype, is_member=False):
+        canonical = self._canonicalize_ctype(ctype)
+
         # Remove all pointers - we require standard calling
         # conventions.  For example, an 'int' is always passed by
         # value (unless it's out or inout).
-        derefed = firstpass.replace('*', '')
-
-        # Canonicalize our type again, this time without the pointer;
-        # this ensures we turn e.g. plain "guint" => "int"
-        derefed_typename = type_name_from_ctype(derefed)
+        derefed_typename = canonical.replace('*', '')
 
         # Preserve "pointerness" of struct/union members
-        if (is_member and firstpass.endswith('*') and
+        if (is_member and canonical.endswith('*') and
             derefed_typename in BASIC_GIR_TYPES):
             return 'any'
         else:
@@ -403,8 +423,10 @@ class Transformer(object):
         elif ctype == 'FILE*':
             raise SkipError
 
+        canonical_ctype = self._canonicalize_ctype(ctype)
+
         # Now check for a list/map/array type
-        if ctype in self._list_ctypes:
+        if canonical_ctype in self._list_ctypes:
             param = options.get('element-type')
             if param:
                 contained_type = self.parse_ctype(param[0])
@@ -414,7 +436,7 @@ class Transformer(object):
             rettype = List(derefed_name,
                            ctype,
                            contained_type)
-        elif ctype in self._map_ctypes:
+        elif canonical_ctype in self._map_ctypes:
             param = options.get('element-type')
             if param:
                 key_type = self.parse_ctype(param[0])
@@ -426,9 +448,12 @@ class Transformer(object):
             rettype = Map(derefed_name,
                           ctype,
                           key_type, value_type)
-        elif ((is_param and ctype in default_array_types)
+        elif ((is_param and canonical_ctype in default_array_types)
               or ('array' in options)):
-            derefed_name = ctype[:-1] if ctype[-1] == '*' else ctype
+            if canonical_ctype[-1] == '*':
+                derefed_name = canonical_ctype[:-1]
+            else:
+                derefed_name = canonical_ctype
             rettype = Array(ctype,
                             self.parse_ctype(derefed_name))
             array_opts = dict([opt.split('=')
index 33fb370..5f8102e 100644 (file)
           </parameter>
         </parameters>
       </method>
+      <method name="parse_args" c:identifier="annotation_object_parse_args">
+        <return-value transfer-ownership="none">
+          <type name="none" c:type="void"/>
+        </return-value>
+        <parameters>
+          <parameter name="argc" direction="inout" transfer-ownership="full">
+            <type name="int" c:type="int*"/>
+          </parameter>
+          <parameter name="argv" direction="inout" transfer-ownership="none">
+            <array length="1" c:type="char***">
+              <type name="utf8"/>
+            </array>
+          </parameter>
+        </parameters>
+      </method>
       <method name="do_not_use"
               c:identifier="annotation_object_do_not_use"
               deprecated="Use annotation_object_create_object() instead."
         <type name="GObject.ObjectClass" c:type="GObjectClass"/>
       </field>
     </record>
+    <function name="init" c:identifier="annotation_init">
+      <return-value transfer-ownership="none">
+        <type name="none" c:type="void"/>
+      </return-value>
+      <parameters>
+        <parameter name="argc" direction="inout" transfer-ownership="full">
+          <type name="int" c:type="int*"/>
+        </parameter>
+        <parameter name="argv" direction="inout" transfer-ownership="none">
+          <array length="0" c:type="char***">
+            <type name="utf8"/>
+          </array>
+        </parameter>
+      </parameters>
+    </function>
   </namespace>
 </repository>
index 9a50dd9..4728f8d 100644 (file)
           </parameter>
         </parameters>
       </method>
+      <method name="parse_args" c:identifier="annotation_object_parse_args">
+        <return-value transfer-ownership="none">
+          <type name="none"/>
+        </return-value>
+        <parameters>
+          <parameter name="argc" transfer-ownership="full" direction="inout">
+            <type name="int"/>
+          </parameter>
+          <parameter name="argv" transfer-ownership="none" direction="inout">
+            <array length="1" zero-terminated="1">
+              <type name="utf8"/>
+            </array>
+          </parameter>
+        </parameters>
+      </method>
       <method name="do_not_use" c:identifier="annotation_object_do_not_use" deprecated="1">
         <return-value transfer-ownership="full">
           <type name="GObject.Object"/>
         <type name="GObject.ObjectClass"/>
       </field>
     </record>
+    <function name="init" c:identifier="annotation_init">
+      <return-value transfer-ownership="none">
+        <type name="none"/>
+      </return-value>
+      <parameters>
+        <parameter name="argc" transfer-ownership="full" direction="inout">
+          <type name="int"/>
+        </parameter>
+        <parameter name="argv" transfer-ownership="none" direction="inout">
+          <array length="0" zero-terminated="1">
+            <type name="utf8"/>
+          </array>
+        </parameter>
+      </parameters>
+    </function>
   </namespace>
 </repository>
index e4c44e1..3a67a01 100644 (file)
@@ -257,6 +257,22 @@ annotation_object_compute_sum_nz(AnnotationObject *object,
 
 }
 
+/**
+ * annotation_object_parse_args:
+ * @object: a #AnnotationObject
+ * @argc: (inout): Length of the argument vector
+ * @argv: (inout) (array length=argc zero-terminated=1): Argument vector
+ *
+ * Test taking a zero-terminated array with length parameter
+ **/
+void
+annotation_object_parse_args(AnnotationObject *object,
+                             int              *argc,
+                             char           ***argv)
+{
+
+}
+
 /**
  * annotation_object_allow_none:
  * @object: a #GObject
@@ -293,4 +309,16 @@ annotation_object_do_not_use (AnnotationObject *object)
   return NULL;
 }
 
+/**
+ * annotation_init:
+ * @argc: (inout): The number of args. 
+ * @argv: (inout) (array length=argc zero-terminated=1): The arguments.
+ **/
+void
+annotation_init (int *argc, char ***argv)
+{
+
+}
+
+
 static char backslash_parsing_tester_2 = '\\';
index 23a5c6b..116b881 100644 (file)
@@ -69,8 +69,13 @@ void     annotation_object_compute_sum_n(AnnotationObject *object,
 void     annotation_object_compute_sum_nz(AnnotationObject *object,
                                           int             *nums,
                                           int              n_nums);
+void     annotation_object_parse_args   (AnnotationObject *object,
+                                         int              *argc,
+                                         char           ***argv);
 
 GObject* annotation_object_do_not_use   (AnnotationObject *object);
 
 
+void     annotation_init (int *argc, char ***argv);
+
 #endif /* __ANNOTATION_OBJECT_H__ */