2005-01-03 [colin] 0.9.13cvs25.4

* src/common/utils.c
	* src/common/utils.h
	* src/gtk/prefswindow.c
		Move auto pointer stuff to utils.c
		Patch by Alfons again :)
This commit is contained in:
Colin Leroy 2005-01-03 18:03:20 +00:00
parent 3d0e2ea4b3
commit bc4055664b
6 changed files with 189 additions and 68 deletions

View file

@ -1,3 +1,11 @@
2005-01-03 [colin] 0.9.13cvs25.4
* src/common/utils.c
* src/common/utils.h
* src/gtk/prefswindow.c
Move auto pointer stuff to utils.c
Patch by Alfons again :)
2005-01-03 [colin] 0.9.13cvs25.3
* src/compose.c

View file

@ -303,3 +303,4 @@
( cvs diff -u -r 1.56.2.30 -r 1.56.2.31 src/pop.c; cvs diff -u -r 1.17.2.12 -r 1.17.2.13 src/pop.h; ) > 0.9.13cvs25.1.patchset
( cvs diff -u -r 1.115.2.25 -r 1.115.2.26 src/main.c; cvs diff -u -r 1.100.2.9 -r 1.100.2.10 AUTHORS; ) > 0.9.13cvs25.2.patchset
( cvs diff -u -r 1.382.2.81 -r 1.382.2.82 src/compose.c; cvs diff -u -r 1.10.2.8 -r 1.10.2.9 src/prefs_gtk.c; cvs diff -u -r 1.12.2.4 -r 1.12.2.5 src/prefs_template.c; cvs diff -u -r 1.96.2.37 -r 1.96.2.38 src/textview.c; ) > 0.9.13cvs25.3.patchset
( cvs diff -u -r 1.36.2.18 -r 1.36.2.19 src/common/utils.c; cvs diff -u -r 1.20.2.12 -r 1.20.2.13 src/common/utils.h; cvs diff -u -r 1.12.2.13 -r 1.12.2.14 src/gtk/prefswindow.c; ) > 0.9.13cvs25.4.patchset

View file

@ -13,7 +13,7 @@ INTERFACE_AGE=0
BINARY_AGE=0
EXTRA_VERSION=25
EXTRA_RELEASE=
EXTRA_GTK2_VERSION=.3
EXTRA_GTK2_VERSION=.4
if test \( $EXTRA_VERSION -eq 0 \) -o \( "x$EXTRA_RELEASE" != "x" \); then
VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION}${EXTRA_RELEASE}${EXTRA_GTK2_VERSION}

View file

@ -3731,3 +3731,168 @@ void get_hex_str(gchar *out, guchar ch)
INT_TO_HEX(hex, ch & 0x0f);
*out++ = hex;
}
#undef REF_DEBUG
#ifndef REF_DEBUG
#define G_PRINT_REF 1 == 1 ? (void) 0 : (void)
#else
#define G_PRINT_REF g_print
#endif
/*!
*\brief Register ref counted pointer. It is based on GBoxed, so should
* work with anything that uses the GType system. The semantics
* are similar to a C++ auto pointer, with the exception that
* C doesn't have automatic closure (calling destructors) when
* exiting a block scope.
* Use the \ref G_TYPE_AUTO_POINTER macro instead of calling this
* function directly.
*
*\return GType A GType type.
*/
GType g_auto_pointer_register(void)
{
static GType auto_pointer_type;
if (!auto_pointer_type)
auto_pointer_type =
g_boxed_type_register_static
("G_TYPE_AUTO_POINTER",
(GBoxedCopyFunc) g_auto_pointer_copy,
(GBoxedFreeFunc) g_auto_pointer_free);
return auto_pointer_type;
}
/*!
*\brief Structure with g_new() allocated pointer guarded by the
* auto pointer
*/
typedef struct AutoPointerRef {
void (*free) (gpointer);
gpointer pointer;
glong cnt;
} AutoPointerRef;
/*!
*\brief The auto pointer opaque structure that references the
* pointer guard block.
*/
typedef struct AutoPointer {
AutoPointerRef *ref;
gpointer ptr; /*!< access to protected pointer */
} AutoPointer;
/*!
*\brief Creates an auto pointer for a g_new()ed pointer. Example:
*
*\code
*
* ... tell gtk_list_store it should use a G_TYPE_AUTO_POINTER
* ... when assigning, copying and freeing storage elements
*
* gtk_list_store_new(N_S_COLUMNS,
* G_TYPE_AUTO_POINTER,
* -1);
*
*
* Template *precious_data = g_new0(Template, 1);
* g_pointer protect = g_auto_pointer_new(precious_data);
*
* gtk_list_store_set(container, &iter,
* S_DATA, protect,
* -1);
*
* ... the gtk_list_store has copied the pointer and
* ... incremented its reference count, we should free
* ... the auto pointer (in C++ a destructor would do
* ... this for us when leaving block scope)
*
* g_auto_pointer_free(protect);
*
* ... gtk_list_store_set() now manages the data. When
* ... *explicitly* requesting a pointer from the list
* ... store, don't forget you get a copy that should be
* ... freed with g_auto_pointer_free() eventually.
*
*\endcode
*
*\param pointer Pointer to be guarded.
*
*\return GAuto * Pointer that should be used in containers with
* GType support.
*/
GAuto *g_auto_pointer_new(gpointer p)
{
AutoPointerRef *ref = g_new0(AutoPointerRef, 1);
AutoPointer *ptr = g_new0(AutoPointer, 1);
ref->pointer = p;
ref->free = g_free;
ref->cnt = 1;
ptr->ref = ref;
ptr->ptr = p;
G_PRINT_REF ("XXXX ALLOC(%lx)\n", p);
return ptr;
}
/*!
*\brief Allocate an autopointer using the passed \a free function to
* free the guarded pointer
*/
GAuto *g_auto_pointer_new_with_free(gpointer p, GFreeFunc free_)
{
AutoPointer *aptr = g_auto_pointer_new(p);
aptr->ref->free = free_;
return aptr;
}
gpointer g_auto_pointer_get_ptr(GAuto *auto_ptr)
{
return ((AutoPointer *) auto_ptr)->ptr;
}
/*!
*\brief Copies an auto pointer by. It's mostly not necessary
* to call this function directly, unless you copy/assign
* the guarded pointer.
*
*\param auto_ptr Auto pointer returned by previous call to
* g_auto_pointer_new_XXX()
*
*\return gpointer An auto pointer
*/
GAuto *g_auto_pointer_copy(GAuto *auto_ptr)
{
AutoPointer *ptr = auto_ptr;
AutoPointerRef *ref = ptr->ref;
AutoPointer *newp = g_new0(AutoPointer, 1);
newp->ref = ref;
newp->ptr = ref->pointer;
++(ref->cnt);
G_PRINT_REF ("XXXX COPY(%lx) -- REF (%d)\n", ref->pointer, ref->cnt);
return newp;
}
/*!
*\brief Free an auto pointer
*/
void g_auto_pointer_free(GAuto *auto_ptr)
{
AutoPointer *ptr = auto_ptr;
AutoPointerRef *ref = ptr->ref;
if (--(ref->cnt) == 0) {
G_PRINT_REF ("XXXX FREE(%lx) -- REF (%d)\n", ref->pointer, ref->cnt);
ref->free(ref->pointer);
g_free(ref);
} else
G_PRINT_REF ("XXXX DEREF(%lx) -- REF (%d)\n", ref->pointer, ref->cnt);
g_free(ptr);
}

View file

@ -25,6 +25,7 @@
#endif
#include <glib.h>
#include <glib-object.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@ -477,6 +478,18 @@ GNode *g_node_map(GNode *node, GNodeMapFunc func, gpointer data);
gboolean get_hex_value(guchar *out, gchar c1, gchar c2);
void get_hex_str(gchar *out, guchar ch);
/* auto pointer for containers that support GType system */
#define G_TYPE_AUTO_POINTER g_auto_pointer_register()
typedef struct AutoPointer GAuto;
GType g_auto_pointer_register (void);
GAuto *g_auto_pointer_new (gpointer pointer);
GAuto *g_auto_pointer_new_with_free (gpointer p,
GFreeFunc free);
gpointer g_auto_pointer_get_ptr (GAuto *auto_ptr);
GAuto *g_auto_pointer_copy (GAuto *auto_ptr);
void g_auto_pointer_free (GAuto *auto_ptr);
#ifdef __cplusplus
}
#endif

View file

@ -72,21 +72,6 @@ struct _PrefsTreeNode
gfloat treeweight; /* GTK2: not used */
};
static GType G_TYPE_AUTO_POINTER;
typedef struct AutoPointerRef {
gpointer pointer;
glong cnt;
} AutoPointerRef;
typedef struct AutoPointer {
AutoPointerRef *ref;
} AutoPointer;
static gpointer g_auto_pointer_new (gpointer pointer);
static gpointer g_auto_pointer_copy (gpointer p);
static void g_auto_pointer_free (gpointer p);
static GtkTreeStore *prefswindow_create_data_store (void);
static GtkWidget *prefswindow_tree_view_create (PrefsWindow* prefswindow);
static void prefs_filtering_create_tree_view_columns (GtkWidget *tree_view);
@ -272,7 +257,7 @@ static void prefswindow_build_tree(GtkWidget *tree_view, GSList *prefs_pages)
PREFS_PAGE_DATA, &prefs_node,
-1);
} else {
gpointer autoptr;
GAuto *autoptr;
/* create a new top level */
gtk_tree_store_append(store, &child, i == 0 ? NULL : &node);
@ -425,59 +410,8 @@ void prefswindow_open(const gchar *title, GSList *prefs_pages, gpointer data)
prefswindow_open_full(title, prefs_pages, data, NULL);
}
/* NOTE: auto pointer could be made more generic, but this works
* fine for now. */
static gpointer g_auto_pointer_new(gpointer p)
{
AutoPointerRef *ref = g_new0(AutoPointerRef, 1);
AutoPointer *ptr = g_new0(AutoPointer, 1);
ref->pointer = p;
ref->cnt = 1;
ptr->ref = ref;
return ptr;
}
static gpointer g_auto_pointer_copy(gpointer p)
{
AutoPointer *ptr = p;
AutoPointerRef *ref = ptr->ref;
AutoPointer *newp = g_new0(AutoPointer, 1);
newp->ref = ref;
++(ref->cnt);
return newp;
}
static void g_auto_pointer_free(gpointer p)
{
AutoPointer *ptr = p;
AutoPointerRef *ref = ptr->ref;
if (--(ref->cnt) == 0) {
g_free(ref->pointer);
g_free(ref);
}
g_free(ptr);
}
static void prefswindow_static_init(void)
{
if (!G_TYPE_AUTO_POINTER)
G_TYPE_AUTO_POINTER =
g_boxed_type_register_static("G_TYPE_AUTO_POINTER",
g_auto_pointer_copy,
g_auto_pointer_free);
}
static GtkTreeStore *prefswindow_create_data_store(void)
{
/* should always be called before using auto pointer type */
prefswindow_static_init();
return gtk_tree_store_new(N_PREFS_PAGE_COLUMNS,
G_TYPE_STRING,
G_TYPE_POINTER,