[gobject-introspection: 1/2] Perform array to pointer adjustment in function parameters.



commit 781d94977f2c9310b15ce69952ea4a06915cd678
Author: Tomasz Miąsko <tomasz miasko gmail com>
Date:   Fri Feb 9 00:00:00 2018 +0000

    Perform array to pointer adjustment in function parameters.
    
    A declaration of a parameter as "array of type" shall be adjusted to
    "qualified pointer to type". This change performs this adjustment.
    
    For example, this makes parameters of following functions equivalent:
    
    ```
    void f1(const char s[]);
    void f2(const char s[10]);
    void f3(const char *s);
    ```
    
    Fixes issue #189.

 giscanner/transformer.py               | 31 +++++++++++++++++++------------
 tests/scanner/Regress-1.0-expected.gir |  2 +-
 2 files changed, 20 insertions(+), 13 deletions(-)
---
diff --git a/giscanner/transformer.py b/giscanner/transformer.py
index 50018cd2..d9651f1a 100644
--- a/giscanner/transformer.py
+++ b/giscanner/transformer.py
@@ -456,7 +456,7 @@ raise ValueError."""
         func.add_symbol_reference(symbol)
         return func
 
-    def _create_source_type(self, source_type):
+    def _create_source_type(self, source_type, is_parameter=False):
         assert source_type is not None
         if source_type.type == CTYPE_VOID:
             value = 'void'
@@ -464,15 +464,19 @@ raise ValueError."""
             value = source_type.name
         elif source_type.type == CTYPE_TYPEDEF:
             value = source_type.name
+        elif (source_type.type == CTYPE_POINTER or
+                # Array to pointer adjustment as per 6.7.6.3.
+                # This is performed only on the outermost array,
+                # so we don't forward is_parameter.
+                (source_type.type == CTYPE_ARRAY and is_parameter)):
+            value = self._create_source_type(source_type.base_type) + '*'
         elif source_type.type == CTYPE_ARRAY:
             return self._create_source_type(source_type.base_type)
-        elif source_type.type == CTYPE_POINTER:
-            value = self._create_source_type(source_type.base_type) + '*'
         else:
             value = 'gpointer'
         return value
 
-    def _create_complete_source_type(self, source_type):
+    def _create_complete_source_type(self, source_type, is_parameter=False):
         assert source_type is not None
 
         const = (source_type.type_qualifier & TYPE_QUALIFIER_CONST)
@@ -492,16 +496,21 @@ raise ValueError."""
                 value = 'const ' + value
             if volatile:
                 value = 'volatile ' + value
-        elif source_type.type == CTYPE_ARRAY:
-            return self._create_complete_source_type(source_type.base_type)
-        elif source_type.type == CTYPE_POINTER:
+            return value
+        elif (source_type.type == CTYPE_POINTER or
+                # Array to pointer adjustment as per 6.7.6.3.
+                # This is performed only on the outermost array,
+                # so we don't forward is_parameter.
+                (source_type.type == CTYPE_ARRAY and is_parameter)):
             value = self._create_complete_source_type(source_type.base_type) + '*'
             # TODO: handle pointer to function as a special case?
             if const:
                 value += ' const'
             if volatile:
                 value += ' volatile'
-
+            return value
+        elif source_type.type == CTYPE_ARRAY:
+            return self._create_complete_source_type(source_type.base_type)
         else:
             if const:
                 value = 'gconstpointer'
@@ -511,8 +520,6 @@ raise ValueError."""
                 value = 'volatile ' + value
             return value
 
-        return value
-
     def _create_parameters(self, symbol, base_type):
         for i, child in enumerate(base_type.child_list):
             yield self._create_parameter(symbol, i, child)
@@ -652,8 +659,8 @@ raise ValueError."""
         return canonical
 
     def _create_type_from_base(self, source_type, is_parameter=False, is_return=False):
-        ctype = self._create_source_type(source_type)
-        complete_ctype = self._create_complete_source_type(source_type)
+        ctype = self._create_source_type(source_type, is_parameter=is_parameter)
+        complete_ctype = self._create_complete_source_type(source_type, is_parameter=is_parameter)
         const = ((source_type.type == CTYPE_POINTER) and
                  (source_type.base_type.type_qualifier & TYPE_QUALIFIER_CONST))
         return self.create_type_from_ctype_string(ctype, is_const=const,
diff --git a/tests/scanner/Regress-1.0-expected.gir b/tests/scanner/Regress-1.0-expected.gir
index cd47fcb5..5fadc9aa 100644
--- a/tests/scanner/Regress-1.0-expected.gir
+++ b/tests/scanner/Regress-1.0-expected.gir
@@ -4528,7 +4528,7 @@ detection, and fixing it via annotations.</doc>
           <type name="guint" c:type="guint"/>
         </parameter>
         <parameter name="properties" transfer-ownership="none">
-          <array length="0" zero-terminated="0" c:type="gchar*">
+          <array length="0" zero-terminated="0" c:type="gchar**">
             <type name="utf8"/>
           </array>
         </parameter>


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