[glib] goption: Add boxed type for GOptionGroup



commit 43df97ab86187a56495c8c00abb6130b7e379c8c
Author: Bastien Nocera <hadess hadess net>
Date:   Thu Jan 22 14:44:47 2015 +0100

    goption: Add boxed type for GOptionGroup
    
    This would allow bindings to use _get_option_group() functions, which
    would then allow them to use GOption parsing.
    
    This also adds introspection annotations to
    g_option_context_add_group(), g_option_context_set_main_group() and
    g_option_context_get_main_group().
    
    https://bugzilla.gnome.org/show_bug.cgi?id=743349

 glib/goption.c       |   85 +++++++++++++++++++++++++++++++++++++-------------
 glib/goption.h       |    6 +++-
 gobject/gboxed.c     |    2 +
 gobject/glib-types.h |   11 ++++++
 4 files changed, 81 insertions(+), 23 deletions(-)
---
diff --git a/glib/goption.c b/glib/goption.c
index 10bbafd..7d59eee 100644
--- a/glib/goption.c
+++ b/glib/goption.c
@@ -267,6 +267,8 @@ struct _GOptionGroup
   gchar           *description;
   gchar           *help_description;
 
+  gint             ref_count;
+
   GDestroyNotify   destroy_notify;
   gpointer         user_data;
 
@@ -382,10 +384,10 @@ void g_option_context_free (GOptionContext *context)
 {
   g_return_if_fail (context != NULL);
 
-  g_list_free_full (context->groups, (GDestroyNotify) g_option_group_free);
+  g_list_free_full (context->groups, (GDestroyNotify) g_option_group_unref);
 
   if (context->main_group)
-    g_option_group_free (context->main_group);
+    g_option_group_unref (context->main_group);
 
   free_changes_list (context, FALSE);
   free_pending_nulls (context, FALSE);
@@ -549,13 +551,11 @@ g_option_context_get_strict_posix (GOptionContext *context)
 /**
  * g_option_context_add_group:
  * @context: a #GOptionContext
- * @group: the group to add
+ * @group: (transfer full): the group to add
  *
  * Adds a #GOptionGroup to the @context, so that parsing with @context
- * will recognize the options in the group. Note that the group will
- * be freed together with the context when g_option_context_free() is
- * called, so you must not free the group yourself after adding it
- * to a context.
+ * will recognize the options in the group. Note that this will take
+ * ownership of the @group and thus the @group should not be freed.
  *
  * Since: 2.6
  **/
@@ -587,7 +587,7 @@ g_option_context_add_group (GOptionContext *context,
 /**
  * g_option_context_set_main_group:
  * @context: a #GOptionContext
- * @group: the group to set as main group
+ * @group: (transfer full): the group to set as main group
  *
  * Sets a #GOptionGroup as main group of the @context.
  * This has the same effect as calling g_option_context_add_group(),
@@ -619,9 +619,9 @@ g_option_context_set_main_group (GOptionContext *context,
  *
  * Returns a pointer to the main group of @context.
  *
- * Returns: the main group of @context, or %NULL if @context doesn't
- *  have a main group. Note that group belongs to @context and should
- *  not be modified or freed.
+ * Returns: (transfer none): the main group of @context, or %NULL if
+ *  @context doesn't have a main group. Note that group belongs to
+ *  @context and should not be modified or freed.
  *
  * Since: 2.6
  **/
@@ -2232,7 +2232,7 @@ g_option_context_parse (GOptionContext   *context,
  * Creates a new #GOptionGroup.
  *
  * Returns: a newly created option group. It should be added
- *   to a #GOptionContext or freed with g_option_group_free().
+ *   to a #GOptionContext or freed with g_option_group_unref().
  *
  * Since: 2.6
  **/
@@ -2247,6 +2247,7 @@ g_option_group_new (const gchar    *name,
   GOptionGroup *group;
 
   group = g_new0 (GOptionGroup, 1);
+  group->ref_count = 1;
   group->name = g_strdup (name);
   group->description = g_strdup (description);
   group->help_description = g_strdup (help_description);
@@ -2265,28 +2266,68 @@ g_option_group_new (const gchar    *name,
  * which have been added to a #GOptionContext.
  *
  * Since: 2.6
+ *
+ * Deprecated: 2.44: Use g_option_group_unref() instead.
  */
 void
 g_option_group_free (GOptionGroup *group)
 {
+  g_option_group_unref (group);
+}
+
+/**
+ * g_option_group_ref:
+ * @group: a #GOptionGroup
+ *
+ * Increments the reference count of @group by one.
+ *
+ * Returns: a #GoptionGroup
+ *
+ * Since: 2.44
+ */
+GOptionGroup *
+g_option_group_ref (GOptionGroup *group)
+{
+  g_return_val_if_fail (group != NULL, NULL);
+
+  group->ref_count++;
+
+  return group;
+}
+
+/**
+ * g_option_group_unref:
+ * @group: a #GOptionGroup
+ *
+ * Decrements the reference count of @group by one.
+ * If the reference count drops to 0, the @group will be freed.
+ * and all memory allocated by the @group is released.
+ *
+ * Since: 2.44
+ */
+void
+g_option_group_unref (GOptionGroup *group)
+{
   g_return_if_fail (group != NULL);
 
-  g_free (group->name);
-  g_free (group->description);
-  g_free (group->help_description);
+  if (--group->ref_count == 0)
+    {
+      g_free (group->name);
+      g_free (group->description);
+      g_free (group->help_description);
 
-  g_free (group->entries);
+      g_free (group->entries);
 
-  if (group->destroy_notify)
-    (* group->destroy_notify) (group->user_data);
+      if (group->destroy_notify)
+        (* group->destroy_notify) (group->user_data);
 
-  if (group->translate_notify)
-    (* group->translate_notify) (group->translate_data);
+      if (group->translate_notify)
+        (* group->translate_notify) (group->translate_data);
 
-  g_free (group);
+      g_free (group);
+    }
 }
 
-
 /**
  * g_option_group_add_entries:
  * @group: a #GOptionGroup
diff --git a/glib/goption.h b/glib/goption.h
index 205a484..8f3a92c 100644
--- a/glib/goption.h
+++ b/glib/goption.h
@@ -364,8 +364,12 @@ void             g_option_group_set_parse_hooks        (GOptionGroup       *group,
 GLIB_AVAILABLE_IN_ALL
 void         g_option_group_set_error_hook         (GOptionGroup       *group,
                                                     GOptionErrorFunc    error_func);
-GLIB_AVAILABLE_IN_ALL
+GLIB_DEPRECATED_IN_2_44
 void          g_option_group_free                   (GOptionGroup       *group);
+GLIB_AVAILABLE_IN_2_44
+GOptionGroup *g_option_group_ref                    (GOptionGroup       *group);
+GLIB_AVAILABLE_IN_2_44
+void          g_option_group_unref                  (GOptionGroup       *group);
 GLIB_AVAILABLE_IN_ALL
 void          g_option_group_add_entries            (GOptionGroup       *group,
                                                     const GOptionEntry *entries);
diff --git a/gobject/gboxed.c b/gobject/gboxed.c
index ca7f66c..54f658e 100644
--- a/gobject/gboxed.c
+++ b/gobject/gboxed.c
@@ -165,6 +165,8 @@ G_DEFINE_BOXED_TYPE (GMarkupParseContext, g_markup_parse_context, g_markup_parse
 G_DEFINE_BOXED_TYPE (GThread, g_thread, g_thread_ref, g_thread_unref)
 G_DEFINE_BOXED_TYPE (GChecksum, g_checksum, g_checksum_copy, g_checksum_free)
 
+G_DEFINE_BOXED_TYPE (GOptionGroup, g_option_group, g_option_group_ref, g_option_group_unref)
+
 /* This one can't use G_DEFINE_BOXED_TYPE (GStrv, g_strv, g_strdupv, g_strfreev) */
 GType
 g_strv_get_type (void)
diff --git a/gobject/glib-types.h b/gobject/glib-types.h
index e9f6472..ac222b8 100644
--- a/gobject/glib-types.h
+++ b/gobject/glib-types.h
@@ -288,6 +288,15 @@ typedef gsize GType;
  */
 #define G_TYPE_CHECKSUM (g_checksum_get_type ())
 
+/**
+ * G_TYPE_OPTION_GROUP:
+ *
+ * The #GType for a boxed type holding a #GOptionGroup.
+ *
+ * Since: 2.44
+ */
+#define G_TYPE_OPTION_GROUP (g_option_group_get_type ())
+
 GLIB_AVAILABLE_IN_ALL
 GType   g_date_get_type            (void) G_GNUC_CONST;
 GLIB_AVAILABLE_IN_ALL
@@ -342,6 +351,8 @@ GLIB_AVAILABLE_IN_2_36
 GType   g_markup_parse_context_get_type (void) G_GNUC_CONST;
 GLIB_AVAILABLE_IN_2_40
 GType   g_mapped_file_get_type (void) G_GNUC_CONST;
+GLIB_AVAILABLE_IN_2_44
+GType   g_option_group_get_type    (void) G_GNUC_CONST;
 
 GLIB_DEPRECATED_FOR('G_TYPE_VARIANT')
 GType   g_variant_get_gtype        (void) G_GNUC_CONST;


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