[pygobject/gsoc2009: 73/160] Add release support for simply and doubly linked lists



commit 6413be12f7b486c12b3c87887f676533902fd208
Author: Simon van der Linden <svdlinden src gnome org>
Date:   Tue Jul 28 12:49:37 2009 +0200

    Add release support for simply and doubly linked lists

 gi/pygargument.c           |   42 ++++++++++++++++++++++++++++++++++++++++++
 gi/pygiinfo.c              |   23 +++++++++++++++++++----
 tests/test_girepository.py |   32 ++++++++++++++++++++++++++++----
 3 files changed, 89 insertions(+), 8 deletions(-)
---
diff --git a/gi/pygargument.c b/gi/pygargument.c
index 253147e..75749f3 100644
--- a/gi/pygargument.c
+++ b/gi/pygargument.c
@@ -1450,8 +1450,50 @@ pygi_g_argument_release(GArgument *arg, GITypeInfo *type_info, GITransfer transf
             break;
         }
         case GI_TYPE_TAG_INTERFACE:
+            /* TODO */
+            break;
         case GI_TYPE_TAG_GLIST:
         case GI_TYPE_TAG_GSLIST:
+        {
+            GSList *list;
+            GITypeInfo *item_type_info;
+
+            list = arg->v_pointer;
+
+            item_type_info = g_type_info_get_param_type(type_info, 0);
+            g_assert(item_type_info != NULL);
+
+            if ((direction == GI_DIRECTION_IN && transfer != GI_TRANSFER_EVERYTHING)
+                    || (direction == GI_DIRECTION_OUT && transfer == GI_TRANSFER_EVERYTHING)) {
+                GSList *item;
+                GITransfer item_transfer;
+
+                if (direction == GI_DIRECTION_IN) {
+                    item_transfer = GI_TRANSFER_NOTHING;
+                } else {
+                    item_transfer = GI_TRANSFER_EVERYTHING;
+                }
+
+                /* Free the items */
+                for (item = list; item != NULL; item = g_slist_next(item)) {
+                    pygi_g_argument_release((GArgument *)&item->data, item_type_info,
+                        item_transfer, direction);
+                }
+            }
+
+            if ((direction == GI_DIRECTION_IN && transfer == GI_TRANSFER_NOTHING)
+                    || (direction == GI_DIRECTION_OUT && transfer != GI_TRANSFER_NOTHING)) {
+                if (type_tag == GI_TYPE_TAG_GLIST) {
+                    g_list_free((GList *)list);
+                } else {
+                    /* type_tag == GI_TYPE_TAG_GSLIST */
+                    g_slist_free(list);
+                }
+            }
+
+            g_base_info_unref((GIBaseInfo *)item_type_info);
+            break;
+        }
         case GI_TYPE_TAG_GHASH:
         case GI_TYPE_TAG_ERROR:
             /* TODO */
diff --git a/gi/pygiinfo.c b/gi/pygiinfo.c
index f81aceb..8b19ecc 100644
--- a/gi/pygiinfo.c
+++ b/gi/pygiinfo.c
@@ -508,15 +508,16 @@ _wrap_g_function_info_invoke(PyGIBaseInfo *self, PyObject *py_args)
 
         if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT) {
             n_in_args += 1;
-            if (arg_type_tag == GI_TYPE_TAG_ARRAY
-                    && transfer == GI_TRANSFER_CONTAINER) {
-                n_containers += 1;
-            }
         }
         if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT) {
             n_out_args += 1;
         }
 
+        if ((direction == GI_DIRECTION_INOUT && transfer != GI_TRANSFER_EVERYTHING)
+                || (direction == GI_DIRECTION_IN && transfer == GI_TRANSFER_CONTAINER)) {
+            n_containers += 1;
+        }
+
         if (arg_type_tag == GI_TYPE_TAG_ARRAY) {
             gint length_arg_pos;
 
@@ -778,6 +779,18 @@ _wrap_g_function_info_invoke(PyGIBaseInfo *self, PyObject *py_args)
                             containers[containers_pos].v_string = args[i]->v_pointer;
                         case GI_TYPE_TAG_ARRAY:
                             containers[containers_pos].v_pointer = g_array_copy(args[i]->v_pointer);
+                        case GI_TYPE_TAG_INTERFACE:
+                            /* TODO */
+                            break;
+                        case GI_TYPE_TAG_GLIST:
+                            containers[containers_pos].v_pointer = g_list_copy(args[i]->v_pointer);
+                            break;
+                        case GI_TYPE_TAG_GSLIST:
+                            containers[containers_pos].v_pointer = g_slist_copy(args[i]->v_pointer);
+                            break;
+                        case GI_TYPE_TAG_GHASH:
+                            /* TODO */
+                            break;
                         default:
                             break;
                     }
@@ -805,6 +818,7 @@ _wrap_g_function_info_invoke(PyGIBaseInfo *self, PyObject *py_args)
         }
 
         g_assert(py_args_pos == n_py_args);
+        g_assert(containers_pos == n_containers);
     }
 
     /* Invoke the callable. */
@@ -988,6 +1002,7 @@ _wrap_g_function_info_invoke(PyGIBaseInfo *self, PyObject *py_args)
         }
 
         g_assert(n_return_values <= 1 || return_values_pos == n_return_values);
+        g_assert(containers_pos == n_containers);
     }
 
 return_:
diff --git a/tests/test_girepository.py b/tests/test_girepository.py
index b5ca881..59f4b6f 100644
--- a/tests/test_girepository.py
+++ b/tests/test_girepository.py
@@ -412,10 +412,16 @@ class TestGIEverything(unittest.TestCase):
 # Interface
 # GList
 
-    def testGListReturn(self):
+    def testGListNothingReturn(self):
         self.assertEqual(list(test_sequence), Everything.test_glist_nothing_return())
 
-    def testGListIn(self):
+    def testGListContainerReturn(self):
+        self.assertEqual(list(test_sequence), Everything.test_glist_container_return())
+
+    def testGListEverythingReturn(self):
+        self.assertEqual(list(test_sequence), Everything.test_glist_everything_return())
+
+    def testGListNothingIn(self):
         Everything.test_glist_nothing_in(test_sequence)
 
         # Test as string, which implements the sequence protocol too.
@@ -425,13 +431,25 @@ class TestGIEverything(unittest.TestCase):
         self.assertRaises(TypeError, Everything.test_glist_nothing_in, 1)
         self.assertRaises(TypeError, Everything.test_glist_nothing_in, (1, 2, 3))
 
+    def testGListContainerIn(self):
+        Everything.test_glist_container_in(test_sequence)
+
+    def testGListEverythingIn(self):
+        Everything.test_glist_everything_in(test_sequence)
+
 
 # GSList
 
-    def testGSListReturn(self):
+    def testGSListNothingReturn(self):
         self.assertEqual(list(test_sequence), Everything.test_gslist_nothing_return())
 
-    def testGSListIn(self):
+    def testGSListContainerReturn(self):
+        self.assertEqual(list(test_sequence), Everything.test_gslist_container_return())
+
+    def testGSListEverythingReturn(self):
+        self.assertEqual(list(test_sequence), Everything.test_gslist_everything_return())
+
+    def testGSListNothingIn(self):
         Everything.test_gslist_nothing_in(test_sequence)
 
         # Test as string, which implements the sequence protocol too.
@@ -441,6 +459,12 @@ class TestGIEverything(unittest.TestCase):
         self.assertRaises(TypeError, Everything.test_gslist_nothing_in, 1)
         self.assertRaises(TypeError, Everything.test_gslist_nothing_in, (1, 2, 3))
 
+    def testGSListContainerIn(self):
+        Everything.test_gslist_container_in(test_sequence)
+
+    def testGSListEverythingIn(self):
+        Everything.test_gslist_everything_in(test_sequence)
+
 
 # GHashTable
 



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