(root)/
glib-2.79.0/
gobject/
tests/
autoptr.c
       1  /* GLib testing framework examples and tests
       2   * Copyright (C) 2018 Canonical Ltd
       3   * Authors: Marco Trevisan <marco@ubuntu.com>
       4   *
       5   * SPDX-License-Identifier: LicenseRef-old-glib-tests
       6   *
       7   * This work is provided "as is"; redistribution and modification
       8   * in whole or in part, in any medium, physical or electronic is
       9   * permitted without restriction.
      10   *
      11   * This work is distributed in the hope that it will be useful,
      12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
      14   *
      15   * In no event shall the authors or contributors be liable for any
      16   * direct, indirect, incidental, special, exemplary, or consequential
      17   * damages (including, but not limited to, procurement of substitute
      18   * goods or services; loss of use, data, or profits; or business
      19   * interruption) however caused and on any theory of liability, whether
      20   * in contract, strict liability, or tort (including negligence or
      21   * otherwise) arising in any way out of the use of this software, even
      22   * if advised of the possibility of such damage.
      23   */
      24  
      25  #include <glib-object.h>
      26  #include <string.h>
      27  
      28  G_DECLARE_DERIVABLE_TYPE (TestAutoCleanupBase, test_base_auto_cleanup, TEST, BASE_AUTO_CLEANUP, GObject)
      29  
      30  struct _TestAutoCleanupBaseClass {
      31    GObjectClass parent_class;
      32  };
      33  
      34  G_DEFINE_TYPE (TestAutoCleanupBase, test_base_auto_cleanup, G_TYPE_OBJECT)
      35  
      36  static void
      37  test_base_auto_cleanup_class_init (TestAutoCleanupBaseClass *class)
      38  {
      39  }
      40  
      41  static void
      42  test_base_auto_cleanup_init (TestAutoCleanupBase *tac)
      43  {
      44  }
      45  
      46  G_DECLARE_FINAL_TYPE (TestAutoCleanup, test_auto_cleanup, TEST, AUTO_CLEANUP, TestAutoCleanupBase)
      47  
      48  struct _TestAutoCleanup
      49  {
      50    TestAutoCleanupBase parent_instance;
      51  };
      52  
      53  G_DEFINE_TYPE (TestAutoCleanup, test_auto_cleanup, G_TYPE_OBJECT)
      54  
      55  static void
      56  test_auto_cleanup_class_init (TestAutoCleanupClass *class)
      57  {
      58  }
      59  
      60  static void
      61  test_auto_cleanup_init (TestAutoCleanup *tac)
      62  {
      63  }
      64  
      65  static TestAutoCleanup *
      66  test_auto_cleanup_new (void)
      67  {
      68    return g_object_new (test_auto_cleanup_get_type (), NULL);
      69  }
      70  
      71  /* Verify that an object declared with G_DECLARE_FINAL_TYPE provides by default
      72   * autocleanup functions, defined using the ones of the base type (defined with
      73   * G_DECLARE_DERIVABLE_TYPE) and so that it can be used with g_autoptr */
      74  static void
      75  test_autoptr (void)
      76  {
      77    TestAutoCleanup *tac_ptr = test_auto_cleanup_new ();
      78    g_object_add_weak_pointer (G_OBJECT (tac_ptr), (gpointer *) &tac_ptr);
      79  
      80    {
      81      g_autoptr (TestAutoCleanup) tac = tac_ptr;
      82      g_assert_nonnull (tac);
      83    }
      84  #ifdef __GNUC__
      85    g_assert_null (tac_ptr);
      86  #endif
      87  }
      88  
      89  /* Verify that an object declared with G_DECLARE_FINAL_TYPE provides by default
      90   * autocleanup functions, defined using the ones of the base type (defined with
      91   * G_DECLARE_DERIVABLE_TYPE) and that stealing an autopointer works properly */
      92  static void
      93  test_autoptr_steal (void)
      94  {
      95    g_autoptr (TestAutoCleanup) tac1 = test_auto_cleanup_new ();
      96    TestAutoCleanup *tac_ptr = tac1;
      97  
      98    g_object_add_weak_pointer (G_OBJECT (tac_ptr), (gpointer *) &tac_ptr);
      99  
     100    {
     101      g_autoptr (TestAutoCleanup) tac2 = g_steal_pointer (&tac1);
     102      g_assert_nonnull (tac_ptr);
     103      g_assert_null (tac1);
     104      g_assert_true (tac2 == tac_ptr);
     105    }
     106  #ifdef __GNUC__
     107    g_assert_null (tac_ptr);
     108  #endif
     109  }
     110  
     111  /* Verify that an object declared with G_DECLARE_FINAL_TYPE provides by default
     112   * autolist cleanup functions defined using the ones of the parent type
     113   * and so that can be used with g_autolist, and that freeing the list correctly
     114   * unrefs the object too */
     115  static void
     116  test_autolist (void)
     117  {
     118    TestAutoCleanup *tac1 = test_auto_cleanup_new ();
     119    TestAutoCleanup *tac2 = test_auto_cleanup_new ();
     120    g_autoptr (TestAutoCleanup) tac3 = test_auto_cleanup_new ();
     121  
     122    g_object_add_weak_pointer (G_OBJECT (tac1), (gpointer *) &tac1);
     123    g_object_add_weak_pointer (G_OBJECT (tac2), (gpointer *) &tac2);
     124    g_object_add_weak_pointer (G_OBJECT (tac3), (gpointer *) &tac3);
     125  
     126    {
     127      g_autolist (TestAutoCleanup) l = NULL;
     128  
     129      l = g_list_prepend (l, tac1);
     130      l = g_list_prepend (l, tac2);
     131  
     132      /* Squash warnings about dead stores */
     133      (void) l;
     134    }
     135  
     136    /* Only assert if autoptr works */
     137  #ifdef __GNUC__
     138    g_assert_null (tac1);
     139    g_assert_null (tac2);
     140  #endif
     141    g_assert_nonnull (tac3);
     142  
     143    g_clear_object (&tac3);
     144    g_assert_null (tac3);
     145  }
     146  
     147  /* Verify that an object declared with G_DECLARE_FINAL_TYPE provides by default
     148   * autoslist cleanup functions (defined using the ones of the base type declared
     149   * with G_DECLARE_DERIVABLE_TYPE) and so that can be used with g_autoslist, and
     150   * that freeing the slist correctly unrefs the object too */
     151  static void
     152  test_autoslist (void)
     153  {
     154    TestAutoCleanup *tac1 = test_auto_cleanup_new ();
     155    TestAutoCleanup *tac2 = test_auto_cleanup_new ();
     156    g_autoptr (TestAutoCleanup) tac3 = test_auto_cleanup_new ();
     157  
     158    g_object_add_weak_pointer (G_OBJECT (tac1), (gpointer *) &tac1);
     159    g_object_add_weak_pointer (G_OBJECT (tac2), (gpointer *) &tac2);
     160    g_object_add_weak_pointer (G_OBJECT (tac3), (gpointer *) &tac3);
     161  
     162    {
     163      g_autoslist (TestAutoCleanup) l = NULL;
     164  
     165      l = g_slist_prepend (l, tac1);
     166      l = g_slist_prepend (l, tac2);
     167    }
     168  
     169    /* Only assert if autoptr works */
     170  #ifdef __GNUC__
     171    g_assert_null (tac1);
     172    g_assert_null (tac2);
     173  #endif
     174    g_assert_nonnull (tac3);
     175  
     176    g_clear_object (&tac3);
     177    g_assert_null (tac3);
     178  }
     179  
     180  /* Verify that an object declared with G_DECLARE_FINAL_TYPE provides by default
     181   * autoqueue cleanup functions (defined using the ones of the base type declared
     182   * with G_DECLARE_DERIVABLE_TYPE) and so that can be used with g_autoqueue, and
     183   * that freeing the queue correctly unrefs the object too */
     184  static void
     185  test_autoqueue (void)
     186  {
     187    TestAutoCleanup *tac1 = test_auto_cleanup_new ();
     188    TestAutoCleanup *tac2 = test_auto_cleanup_new ();
     189    g_autoptr (TestAutoCleanup) tac3 = test_auto_cleanup_new ();
     190  
     191    g_object_add_weak_pointer (G_OBJECT (tac1), (gpointer *) &tac1);
     192    g_object_add_weak_pointer (G_OBJECT (tac2), (gpointer *) &tac2);
     193    g_object_add_weak_pointer (G_OBJECT (tac3), (gpointer *) &tac3);
     194  
     195    {
     196      g_autoqueue (TestAutoCleanup) q = g_queue_new ();
     197  
     198      g_queue_push_head (q, tac1);
     199      g_queue_push_tail (q, tac2);
     200    }
     201  
     202    /* Only assert if autoptr works */
     203  #ifdef __GNUC__
     204    g_assert_null (tac1);
     205    g_assert_null (tac2);
     206  #endif
     207    g_assert_nonnull (tac3);
     208  
     209    g_clear_object (&tac3);
     210    g_assert_null (tac3);
     211  }
     212  
     213  static void
     214  test_autoclass (void)
     215  {
     216    g_autoptr (TestAutoCleanupBaseClass) base_class_ptr = NULL;
     217    g_autoptr (TestAutoCleanupClass) class_ptr = NULL;
     218  
     219    base_class_ptr = g_type_class_ref (test_base_auto_cleanup_get_type ());
     220    class_ptr = g_type_class_ref (test_auto_cleanup_get_type ());
     221  
     222    g_assert_nonnull (base_class_ptr);
     223    g_assert_nonnull (class_ptr);
     224  }
     225  
     226  int
     227  main (int argc, gchar *argv[])
     228  {
     229    g_test_init (&argc, &argv, NULL);
     230  
     231    g_test_add_func ("/autoptr/autoptr", test_autoptr);
     232    g_test_add_func ("/autoptr/autoptr_steal", test_autoptr_steal);
     233    g_test_add_func ("/autoptr/autolist", test_autolist);
     234    g_test_add_func ("/autoptr/autoslist", test_autoslist);
     235    g_test_add_func ("/autoptr/autoqueue", test_autoqueue);
     236    g_test_add_func ("/autoptr/autoclass", test_autoclass);
     237  
     238    return g_test_run ();
     239  }