diff options
author | Akira TAGOH <akira@tagoh.org> | 2006-09-04 11:33:05 +0000 |
---|---|---|
committer | Akira TAGOH <akira@tagoh.org> | 2006-09-04 11:33:05 +0000 |
commit | bb8ae6d506fd5cc8bde650f9d844b8607d6894c3 (patch) | |
tree | 1373d3722487d9347ebcd2c31c5a02138c3cf63f | |
parent | fe86d53f31d34426589c3af57db6611cb4539aed (diff) |
* hieroglyph/hglist.c (_hg_list_iter_real_set_data): new function.
(hg_list_init): new function.
(hg_list_finalize): new function.
(hg_list_first): new function.
(hg_list_last): new function.
(hg_list_iter_new): use own memory pool to avoid an allocation failure,
because it's quite likely so that it's used under set_flags where could
be invoked during GC.
(hg_list_iter_get_data): renamed.
(hg_list_iter_set_data): new function.
(hg_list_iter_set_object): new function.
(hg_list_iter_delete_link): new function.
(hg_list_find_iter): new function.
(hg_list_find_iter_custom): new function.
* hieroglyph/vm.c (_hg_vm_eval_file): allow NULL to not want to get
an error result.
* src/hgspy.c (_hgspy_quit_cb): try to shutdown VM.
* hieroglyph/hgallocator-bfit.c (_hg_allocator_bfit_remove_block):
-rw-r--r-- | ChangeLog | 22 | ||||
-rw-r--r-- | hieroglyph/hglist.c | 194 | ||||
-rw-r--r-- | hieroglyph/hglist.h | 30 | ||||
-rw-r--r-- | hieroglyph/hgtypes.h | 9 | ||||
-rw-r--r-- | hieroglyph/version.h.in | 2 | ||||
-rw-r--r-- | hieroglyph/vm.c | 11 | ||||
-rw-r--r-- | src/hgspy.c | 4 | ||||
-rw-r--r-- | tests/hglist.c | 8 |
8 files changed, 231 insertions, 49 deletions
@@ -1,5 +1,27 @@ 2006-09-04 Akira TAGOH <at@gclab.org> + * hieroglyph/hglist.c (_hg_list_iter_real_set_data): new function. + (hg_list_init): new function. + (hg_list_finalize): new function. + (hg_list_first): new function. + (hg_list_last): new function. + (hg_list_iter_new): use own memory pool to avoid an allocation failure, + because it's quite likely so that it's used under set_flags where could + be invoked during GC. + (hg_list_iter_get_data): renamed. + (hg_list_iter_set_data): new function. + (hg_list_iter_set_object): new function. + (hg_list_iter_delete_link): new function. + (hg_list_find_iter): new function. + (hg_list_find_iter_custom): new function. + + * hieroglyph/vm.c (_hg_vm_eval_file): allow NULL to not want to get + an error result. + + * src/hgspy.c (_hgspy_quit_cb): try to shutdown VM. + + * hieroglyph/hgallocator-bfit.c (_hg_allocator_bfit_remove_block): + * hieroglyph/operator.c (_hg_operator_real_set_flags): fixed outdated function call. diff --git a/hieroglyph/hglist.c b/hieroglyph/hglist.c index d8e1635..868ea31 100644 --- a/hieroglyph/hglist.c +++ b/hieroglyph/hglist.c @@ -27,6 +27,7 @@ #include "hglist.h" #include "hgmem.h" +#include "hgallocator-bfit.h" enum { @@ -35,6 +36,13 @@ enum { HG_LIST_MASK_OBJECT_NODE = 1 << 2, }; +struct _HieroGlyphList { + HgObject object; + HgList *prev; + HgList *next; + gpointer data; +}; + struct _HieroGlyphListIter { HgObject object; HgList *top; @@ -97,6 +105,9 @@ static HgObjectVTable __hg_list_iter_vtable = { .copy = NULL, .to_string = NULL, }; +static HgAllocator *__hg_list_allocator = NULL; +static HgMemPool *__hg_list_pool = NULL; +static gboolean __hg_list_initialized = FALSE; /* * Private Functions @@ -223,7 +234,7 @@ _hg_list_get_last_node(HgList *list) /* assume that the initial position may be the top node */ while (tmp) { - if (HG_LIST_IS_UNUSED ((HgObject *)tmp)) { + if (HG_LIST_IS_UNUSED (tmp)) { /* validate node */ if (hg_list_next(tmp) != NULL || hg_list_previous(tmp) != NULL) { @@ -234,7 +245,7 @@ _hg_list_get_last_node(HgList *list) return tmp; } } else { - if (HG_LIST_IS_LAST_NODE ((HgObject *)tmp)) { + if (HG_LIST_IS_LAST_NODE (tmp)) { return tmp; } } @@ -267,7 +278,7 @@ _hg_list_get_top_node(HgList *list) return retval; } -HgList * +static HgList * _hg_list_real_append(HgList *list, gpointer data, gboolean is_object) @@ -278,7 +289,7 @@ _hg_list_real_append(HgList *list, g_return_val_if_fail (list != NULL, NULL); if ((last = _hg_list_get_last_node(list)) != NULL) { - if (!HG_LIST_IS_UNUSED ((HgObject *)last)) { + if (!HG_LIST_IS_UNUSED (last)) { hg_mem_get_object__inline(last, obj); if (obj == NULL) { g_warning("[BUG] Invalid object %p is given to append a list.", @@ -307,7 +318,7 @@ _hg_list_real_append(HgList *list, return list; } -HgList * +static HgList * _hg_list_real_prepend(HgList *list, gpointer data, gboolean is_object) @@ -318,7 +329,7 @@ _hg_list_real_prepend(HgList *list, g_return_val_if_fail (list != NULL, NULL); if ((top = _hg_list_get_top_node(list)) != NULL) { - if (!HG_LIST_IS_UNUSED ((HgObject *)top)) { + if (!HG_LIST_IS_UNUSED (top)) { hg_mem_get_object__inline(top, obj); if (obj == NULL) { g_warning("[BUG] Invalid object %p is given to prepend a list.", @@ -345,9 +356,44 @@ _hg_list_real_prepend(HgList *list, return list; } +static void +_hg_list_iter_real_set_data(HgListIter iter, + gpointer data, + gboolean is_object) +{ + g_return_if_fail (iter != NULL); + + iter->current->data = data; + HG_LIST_SET_OBJECT_NODE (iter->current, is_object); +} + /* * Public Functions */ +void +hg_list_init(void) +{ + if (!__hg_list_initialized) { + hg_mem_init(); + __hg_list_allocator = hg_allocator_new(hg_allocator_bfit_get_vtable()); + __hg_list_pool = hg_mem_pool_new(__hg_list_allocator, + "HgList Pool", + 128, TRUE); + hg_mem_pool_use_garbage_collection(__hg_list_pool, FALSE); + __hg_list_initialized = TRUE; + } +} + +void +hg_list_finalize(void) +{ + if (__hg_list_initialized) { + hg_mem_pool_destroy(__hg_list_pool); + hg_allocator_destroy(__hg_list_allocator); + __hg_list_initialized = FALSE; + } +} + HgList * hg_list_new(HgMemPool *pool) { @@ -427,12 +473,14 @@ hg_list_remove(HgList *list, g_return_val_if_fail (list != NULL, NULL); do { - if (HG_LIST_IS_LAST_NODE (l)) { - top = hg_list_next(l); - } else { - prev = hg_list_previous(l); - if (prev && HG_LIST_IS_LAST_NODE (prev)) { - top = l; + if (top == NULL) { + if (HG_LIST_IS_LAST_NODE (l)) { + top = hg_list_next(l); + } else { + prev = hg_list_previous(l); + if (prev && HG_LIST_IS_LAST_NODE (prev)) { + top = l; + } } } if (l->data == data) { @@ -467,28 +515,36 @@ hg_list_remove(HgList *list, return top; } +HgList * +hg_list_first(HgList *list) +{ + return _hg_list_get_top_node(list); +} + +HgList * +hg_list_last(HgList *list) +{ + return _hg_list_get_last_node(list); +} + +/* iterators */ HgListIter hg_list_iter_new(HgList *list) { - HgMemObject *obj; HgListIter iter; g_return_val_if_fail (list != NULL, NULL); g_return_val_if_fail (hg_list_previous(list) != NULL, NULL); g_return_val_if_fail (HG_LIST_IS_LAST_NODE (hg_list_previous(list)), NULL); - hg_mem_get_object__inline(list, obj); - if (obj == NULL) { - g_warning("[BUG] Invalid object %p is given to create an iter for HgList.", - list); - return NULL; - } - iter = hg_mem_alloc_with_flags(obj->pool, sizeof (struct _HieroGlyphListIter), + if (!__hg_list_initialized) + hg_list_init(); + iter = hg_mem_alloc_with_flags(__hg_list_pool, sizeof (struct _HieroGlyphListIter), HG_FL_RESTORABLE | HG_FL_COMPLEX | HG_FL_HGOBJECT); if (iter == NULL) return NULL; HG_OBJECT_INIT_STATE (&iter->object); - HG_OBJECT_SET_STATE (&iter->object, hg_mem_pool_get_default_access_mode(obj->pool)); + HG_OBJECT_SET_STATE (&iter->object, hg_mem_pool_get_default_access_mode(__hg_list_pool)); hg_object_set_vtable(&iter->object, &__hg_list_iter_vtable); iter->top = list; @@ -529,13 +585,99 @@ hg_list_get_iter_next(HgList *list, } gpointer -hg_list_get_iter_data(HgList *list, - HgListIter iter) +hg_list_iter_get_data(HgListIter iter) { - g_return_val_if_fail (list != NULL, NULL); g_return_val_if_fail (iter != NULL, NULL); - g_return_val_if_fail (iter->top == list, NULL); - g_return_val_if_fail (iter->last == hg_list_previous(list), NULL); return iter->current->data; } + +void +hg_list_iter_set_data(HgListIter iter, + gpointer data) +{ + _hg_list_iter_real_set_data(iter, data, FALSE); +} + +void +hg_list_iter_set_object(HgListIter iter, + HgObject *hobject) +{ + _hg_list_iter_real_set_data(iter, hobject, TRUE); +} + +HgList * +hg_list_iter_delete_link(HgListIter iter) +{ + HgList *list, *next, *prev; + + g_return_val_if_fail (iter != NULL, NULL); + + prev = hg_list_previous(iter->current); + next = hg_list_next(iter->current); + hg_list_next(prev) = next; + hg_list_previous(next) = prev; + + if (HG_LIST_IS_LAST_NODE (iter->current)) { + HG_LIST_SET_LAST_NODE (iter->current, FALSE); + HG_LIST_SET_LAST_NODE (prev, TRUE); + HG_LIST_SET_UNUSED (iter->current, TRUE); + } + hg_list_next(iter->current) = NULL; + hg_list_previous(iter->current) = NULL; + if (iter->current == next) + iter->top = NULL; + else if (iter->current == iter->top) + iter->top = next; + list = iter->top; + iter->current = prev; + + return list; +} + +HgListIter +hg_list_find_iter(HgList *list, + gconstpointer data) +{ + gpointer p; + HgListIter iter; + + g_return_val_if_fail (list != NULL, NULL); + + iter = hg_list_iter_new(list); + while (iter) { + p = hg_list_iter_get_data(iter); + if (p == data) + return iter; + if (!hg_list_get_iter_next(list, iter)) + break; + } + if (iter) + hg_list_iter_free(iter); + + return NULL; +} + +HgListIter +hg_list_find_iter_custom(HgList *list, + gconstpointer data, + HgCompareFunc func) +{ + gpointer p; + HgListIter iter; + + g_return_val_if_fail (list != NULL, NULL); + + iter = hg_list_iter_new(list); + while (iter) { + p = hg_list_iter_get_data(iter); + if (func(p, data)) + return iter; + if (!hg_list_get_iter_next(list, iter)) + break; + } + if (iter) + hg_list_iter_free(iter); + + return NULL; +} diff --git a/hieroglyph/hglist.h b/hieroglyph/hglist.h index a2f9e0a..4d28d4a 100644 --- a/hieroglyph/hglist.h +++ b/hieroglyph/hglist.h @@ -29,6 +29,9 @@ G_BEGIN_DECLS +void hg_list_init (void); +void hg_list_finalize(void); + HgList *hg_list_new (HgMemPool *pool); HgList *hg_list_append (HgList *list, gpointer data); @@ -41,14 +44,27 @@ HgList *hg_list_prepend_object(HgList *list, guint hg_list_length (HgList *list); HgList *hg_list_remove (HgList *list, gpointer data); +HgList *hg_list_first (HgList *list); +HgList *hg_list_last (HgList *list); + +#define hg_list_iter_free hg_mem_free -HgListIter hg_list_iter_new (HgList *list); -gboolean hg_list_get_iter_first(HgList *list, - HgListIter iter); -gboolean hg_list_get_iter_next (HgList *list, - HgListIter iter); -gpointer hg_list_get_iter_data (HgList *list, - HgListIter iter); +HgListIter hg_list_iter_new (HgList *list); +gboolean hg_list_get_iter_first (HgList *list, + HgListIter iter); +gboolean hg_list_get_iter_next (HgList *list, + HgListIter iter); +HgListIter hg_list_find_iter (HgList *list, + gconstpointer data); +HgListIter hg_list_find_iter_custom(HgList *list, + gconstpointer data, + HgCompareFunc func); +gpointer hg_list_iter_get_data (HgListIter iter); +void hg_list_iter_set_data (HgListIter iter, + gpointer data); +void hg_list_iter_set_object (HgListIter iter, + HgObject *hobject); +HgList *hg_list_iter_delete_link(HgListIter iter); G_END_DECLS diff --git a/hieroglyph/hgtypes.h b/hieroglyph/hgtypes.h index 8fb49ed..03ab3c4 100644 --- a/hieroglyph/hgtypes.h +++ b/hieroglyph/hgtypes.h @@ -82,6 +82,8 @@ typedef struct _HieroGlyphMatrix HgMatrix; typedef struct _HieroGlyphDeviceVTable HgDeviceVTable; typedef struct _HieroGlyphDevice HgDevice; +typedef gboolean (*HgCompareFunc) (gconstpointer a, + gconstpointer b); typedef gboolean (*HgTraverseFunc) (gpointer key, gpointer val, gpointer data); @@ -353,13 +355,6 @@ struct _HieroGlyphFileObjectCallback { gint (* get_error_code) (gpointer user_data); }; -struct _HieroGlyphList { - HgObject object; - HgList *prev; - HgList *next; - gpointer data; -}; - struct _HieroGlyphColor { gboolean is_rgb; union { diff --git a/hieroglyph/version.h.in b/hieroglyph/version.h.in index ed7f7f5..b8c0c06 100644 --- a/hieroglyph/version.h.in +++ b/hieroglyph/version.h.in @@ -29,7 +29,7 @@ G_BEGIN_DECLS #define HIEROGLYPH_VERSION "@VERSION@" -#define HIEROGLYPH_UUID "1419cd8a-a1ef-4993-ab8f-85e6f1f895f9" +#define HIEROGLYPH_UUID "3caed44e-0bc1-47c4-9a96-7e5625d6b0a7" const char *__hg_rcsid G_GNUC_UNUSED = "$Rev$"; diff --git a/hieroglyph/vm.c b/hieroglyph/vm.c index 83c9d57..dde1923 100644 --- a/hieroglyph/vm.c +++ b/hieroglyph/vm.c @@ -36,6 +36,7 @@ #include "hgdict.h" #include "hgfile.h" #include "hglineedit.h" +#include "hglist.h" #include "hgplugins.h" #include "hgstack.h" #include "hgstring.h" @@ -272,10 +273,12 @@ _hg_vm_eval_file(HgVM *vm, hg_vm_main(vm); hg_mem_free(node); hg_mem_free(file); - if (hg_vm_has_error(vm)) - *error = TRUE; - else + if (hg_vm_has_error(vm)) { + if (error) + *error = TRUE; + } else { retval = TRUE; + } } break; } @@ -338,6 +341,7 @@ hg_vm_init(void) if (!__hg_vm_is_initialized) { hg_mem_init(); hg_file_init(); + hg_list_init(); __hg_vm_allocator = hg_allocator_new(hg_allocator_bfit_get_vtable()); __hg_vm_mem_pool = hg_mem_pool_new(__hg_vm_allocator, @@ -357,6 +361,7 @@ hg_vm_finalize(void) hg_mem_pool_destroy(__hg_vm_mem_pool); hg_allocator_destroy(__hg_vm_allocator); + hg_list_finalize(); hg_file_finalize(); hg_mem_finalize(); diff --git a/src/hgspy.c b/src/hgspy.c index 298e089..5bc5be5 100644 --- a/src/hgspy.c +++ b/src/hgspy.c @@ -387,8 +387,10 @@ _hgspy_quit_cb(GtkWidget *widget, if (spy->vm) { retval = _hgspy_ask_dialog(spy, N_("Hieroglyph VM is still running.\nAre you sure that you really want to quit?")); + if (retval) + hg_vm_shutdown(spy->vm, 0); } else { - retval = FALSE; + retval = TRUE; } if (retval) { gtk_widget_unrealize(spy->window); diff --git a/tests/hglist.c b/tests/hglist.c index a3c76ac..dd93900 100644 --- a/tests/hglist.c +++ b/tests/hglist.c @@ -38,9 +38,9 @@ main(void) } for (i = 0; ; i++) { - if (tc1[i] != GPOINTER_TO_INT (hg_list_get_iter_data(list, iter))) { + if (tc1[i] != GPOINTER_TO_INT (hg_list_iter_get_data(iter))) { g_print("Failed to compare: expected %d, but actually %d", - tc1[i], GPOINTER_TO_INT (hg_list_get_iter_data(list, iter))); + tc1[i], GPOINTER_TO_INT (hg_list_iter_get_data(iter))); return 1; } if (!hg_list_get_iter_next(list, iter)) @@ -53,9 +53,9 @@ main(void) list = hg_list_remove(list, GINT_TO_POINTER (2)); hg_list_get_iter_first(list, iter); for (i = 0; ; i++) { - if (tc2[i] != GPOINTER_TO_INT (hg_list_get_iter_data(list, iter))) { + if (tc2[i] != GPOINTER_TO_INT (hg_list_iter_get_data(iter))) { g_print("Failed to compare: expected %d, but actually %d", - tc2[i], GPOINTER_TO_INT (hg_list_get_iter_data(list, iter))); + tc2[i], GPOINTER_TO_INT (hg_list_iter_get_data(iter))); return 1; } if (!hg_list_get_iter_next(list, iter)) |