[glib] Add g_autofree
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] Add g_autofree
- Date: Mon, 23 Feb 2015 03:19:17 +0000 (UTC)
commit d0105f1c0845c1244c8419d0bb24c6f64ac9015f
Author: Colin Walters <walters verbum org>
Date: Sun Feb 15 08:58:44 2015 -0500
Add g_autofree
The g_autoptr() being associated with the type name works out really
well for things like GHashTable. However, it's a bit more awkward to
associate with "gchar". Also because one can't use "char".
Similarly, there are a lot of other "bare primitive array" types that
one might reasonably use.
This patch does not remove the autoptr for "gchar", even though I
think it's rather awkward and strange.
Also while we're here, add a test case for the cleanup bits.
https://bugzilla.gnome.org/show_bug.cgi?id=744747
glib/docs.c | 34 ++++++++++++++++++++++++++++++++++
glib/glib-autocleanups.h | 8 ++++++++
glib/gmacros.h | 1 +
glib/tests/Makefile.am | 6 ++++++
glib/tests/autoptr.c | 37 +++++++++++++++++++++++++++++++++++++
5 files changed, 86 insertions(+), 0 deletions(-)
---
diff --git a/glib/docs.c b/glib/docs.c
index f7a0bf2..9169d85 100644
--- a/glib/docs.c
+++ b/glib/docs.c
@@ -2423,6 +2423,40 @@
*/
/**
+ * g_autofree:
+ *
+ * Macro to add an attribute to pointer variable to ensure automatic
+ * cleanup using g_free().
+ *
+ * This macro differs from g_autoptr() in that it is an attribute supplied
+ * before the type name, rather than wrapping the type definition. Instead
+ * of using a type-specific lookup, this macro always calls g_free() directly.
+ *
+ * This means it's useful for any type that is returned from
+ * g_malloc().
+ *
+ * Otherwise, this macro has similar constraints as g_autoptr() - only
+ * supported on GCC and clang, the variable must be initialized, etc.
+ *
+ * |[
+ * gboolean
+ * operate_on_malloc_buf (void)
+ * {
+ * g_autofree guint8* membuf = NULL;
+ *
+ * membuf = g_malloc (8192);
+ *
+ * /* Some computation on membuf */
+ *
+ * /* membuf will be automatically freed here */
+ * return TRUE;
+ * }
+ * ]|
+ *
+ * Since: 2.44
+ */
+
+/**
* G_DEFINE_AUTOPTR_CLEANUP_FUNC:
* @TypeName: a type name to define a g_autoptr() cleanup function for
* @func: the cleanup function
diff --git a/glib/glib-autocleanups.h b/glib/glib-autocleanups.h
index 902e952..80d7b2b 100644
--- a/glib/glib-autocleanups.h
+++ b/glib/glib-autocleanups.h
@@ -21,6 +21,14 @@
#error "Only <glib.h> can be included directly."
#endif
+static inline void
+g_autoptr_cleanup_generic_gfree (void *p)
+{
+ void **pp = (void**)p;
+ if (*pp)
+ g_free (*pp);
+}
+
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GAsyncQueue, g_async_queue_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GBookmarkFile, g_bookmark_file_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GBytes, g_bytes_unref)
diff --git a/glib/gmacros.h b/glib/gmacros.h
index 62b61cb..b34cc77 100644
--- a/glib/gmacros.h
+++ b/glib/gmacros.h
@@ -402,6 +402,7 @@
G_GNUC_END_IGNORE_DEPRECATIONS
#define g_autoptr(TypeName) _GLIB_CLEANUP(_GLIB_AUTOPTR_FUNC_NAME(TypeName)) _GLIB_AUTOPTR_TYPENAME(TypeName)
#define g_auto(TypeName) _GLIB_CLEANUP(_GLIB_AUTO_FUNC_NAME(TypeName)) TypeName
+#define g_autofree _GLIB_CLEANUP(g_autoptr_cleanup_generic_gfree)
#else /* not GNU C */
/* this (dummy) macro is private */
diff --git a/glib/tests/Makefile.am b/glib/tests/Makefile.am
index 445040a..bdcd0cb 100644
--- a/glib/tests/Makefile.am
+++ b/glib/tests/Makefile.am
@@ -200,6 +200,12 @@ check-am: gtester-xmllint-check
private_LDFLAGS = @G_THREAD_LIBS@
endif
+if HAVE_GCC
+test_programs += \
+ autoptr \
+ $(NULL)
+endif
+
# -----------------------------------------------------------------------------
if HAVE_EVENTFD
diff --git a/glib/tests/autoptr.c b/glib/tests/autoptr.c
new file mode 100644
index 0000000..b2db335
--- /dev/null
+++ b/glib/tests/autoptr.c
@@ -0,0 +1,37 @@
+#include <glib.h>
+
+static void
+test_autofree (void)
+{
+ g_autofree char *p = NULL;
+ g_autofree char *p2 = NULL;
+ g_autofree char *alwaysnull = NULL;
+
+ p = g_malloc (10);
+ p2 = g_malloc (42);
+
+ if (TRUE)
+ {
+ g_autofree guint8 *buf = g_malloc (128);
+ g_autofree char *alwaysnull_again = NULL;
+
+ buf[0] = 1;
+ }
+
+ if (TRUE)
+ {
+ g_autofree guint8 *buf2 = g_malloc (256);
+
+ buf2[255] = 42;
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add_func ("/autoptr/autofree", test_autofree);
+
+ return g_test_run ();
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]