diff --git a/ChangeLog b/ChangeLog index d505f91ea..ec388775d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +Fri Jan 22 11:58:13 EST 1999 Jeff Garzik + + * Makefile.am: + Add gqueue.c + + * glib.h: + Add GQueue struct and prototypes. + Remove g_stack_free macro. + + * gqueue.c + New file. Implementation of a queue ADT. + + * gstack.c: + Rename _g_stack_free back to g_stack_free. + + * tests/Makefile.am, tests/stack-test.c: + New test for GStack objects. + Fri Jan 22 02:06:10 EST 1999 Jeff Garzik * gstack.c: diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index d505f91ea..ec388775d 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,21 @@ +Fri Jan 22 11:58:13 EST 1999 Jeff Garzik + + * Makefile.am: + Add gqueue.c + + * glib.h: + Add GQueue struct and prototypes. + Remove g_stack_free macro. + + * gqueue.c + New file. Implementation of a queue ADT. + + * gstack.c: + Rename _g_stack_free back to g_stack_free. + + * tests/Makefile.am, tests/stack-test.c: + New test for GStack objects. + Fri Jan 22 02:06:10 EST 1999 Jeff Garzik * gstack.c: diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index d505f91ea..ec388775d 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,21 @@ +Fri Jan 22 11:58:13 EST 1999 Jeff Garzik + + * Makefile.am: + Add gqueue.c + + * glib.h: + Add GQueue struct and prototypes. + Remove g_stack_free macro. + + * gqueue.c + New file. Implementation of a queue ADT. + + * gstack.c: + Rename _g_stack_free back to g_stack_free. + + * tests/Makefile.am, tests/stack-test.c: + New test for GStack objects. + Fri Jan 22 02:06:10 EST 1999 Jeff Garzik * gstack.c: diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index d505f91ea..ec388775d 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,3 +1,21 @@ +Fri Jan 22 11:58:13 EST 1999 Jeff Garzik + + * Makefile.am: + Add gqueue.c + + * glib.h: + Add GQueue struct and prototypes. + Remove g_stack_free macro. + + * gqueue.c + New file. Implementation of a queue ADT. + + * gstack.c: + Rename _g_stack_free back to g_stack_free. + + * tests/Makefile.am, tests/stack-test.c: + New test for GStack objects. + Fri Jan 22 02:06:10 EST 1999 Jeff Garzik * gstack.c: diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index d505f91ea..ec388775d 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,21 @@ +Fri Jan 22 11:58:13 EST 1999 Jeff Garzik + + * Makefile.am: + Add gqueue.c + + * glib.h: + Add GQueue struct and prototypes. + Remove g_stack_free macro. + + * gqueue.c + New file. Implementation of a queue ADT. + + * gstack.c: + Rename _g_stack_free back to g_stack_free. + + * tests/Makefile.am, tests/stack-test.c: + New test for GStack objects. + Fri Jan 22 02:06:10 EST 1999 Jeff Garzik * gstack.c: diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index d505f91ea..ec388775d 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,21 @@ +Fri Jan 22 11:58:13 EST 1999 Jeff Garzik + + * Makefile.am: + Add gqueue.c + + * glib.h: + Add GQueue struct and prototypes. + Remove g_stack_free macro. + + * gqueue.c + New file. Implementation of a queue ADT. + + * gstack.c: + Rename _g_stack_free back to g_stack_free. + + * tests/Makefile.am, tests/stack-test.c: + New test for GStack objects. + Fri Jan 22 02:06:10 EST 1999 Jeff Garzik * gstack.c: diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index d505f91ea..ec388775d 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,21 @@ +Fri Jan 22 11:58:13 EST 1999 Jeff Garzik + + * Makefile.am: + Add gqueue.c + + * glib.h: + Add GQueue struct and prototypes. + Remove g_stack_free macro. + + * gqueue.c + New file. Implementation of a queue ADT. + + * gstack.c: + Rename _g_stack_free back to g_stack_free. + + * tests/Makefile.am, tests/stack-test.c: + New test for GStack objects. + Fri Jan 22 02:06:10 EST 1999 Jeff Garzik * gstack.c: diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index d505f91ea..ec388775d 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,21 @@ +Fri Jan 22 11:58:13 EST 1999 Jeff Garzik + + * Makefile.am: + Add gqueue.c + + * glib.h: + Add GQueue struct and prototypes. + Remove g_stack_free macro. + + * gqueue.c + New file. Implementation of a queue ADT. + + * gstack.c: + Rename _g_stack_free back to g_stack_free. + + * tests/Makefile.am, tests/stack-test.c: + New test for GStack objects. + Fri Jan 22 02:06:10 EST 1999 Jeff Garzik * gstack.c: diff --git a/Makefile.am b/Makefile.am index ea004095c..4a9f01617 100644 --- a/Makefile.am +++ b/Makefile.am @@ -44,9 +44,11 @@ libglib_la_SOURCES = \ gmutex.c \ gnode.c \ gprimes.c \ + gqueue.c \ grel.c \ gscanner.c \ gslist.c \ + gstack.c \ gstrfuncs.c \ gstring.c \ gtimer.c \ diff --git a/glib.h b/glib.h index 64729ff31..f81eaded9 100644 --- a/glib.h +++ b/glib.h @@ -677,6 +677,7 @@ typedef struct _GList GList; typedef struct _GMemChunk GMemChunk; typedef struct _GNode GNode; typedef struct _GPtrArray GPtrArray; +typedef struct _GQueue GQueue; typedef struct _GRelation GRelation; typedef struct _GScanner GScanner; typedef struct _GScannerConfig GScannerConfig; @@ -803,6 +804,13 @@ struct _GStack GList *list; }; +struct _GQueue +{ + GList *list; + GList *list_end; + guint list_size; +}; + struct _GString { gchar *str; @@ -942,31 +950,42 @@ gpointer g_slist_nth_data (GSList *list, /* Stacks */ GStack * g_stack_new (void); -#ifndef G_STACK_MACROIZE void g_stack_free (GStack *stack); -void g_stack_push (GStack *stack, gpointer data); -#endif +void _g_stack_push (GStack *stack, gpointer data); gpointer g_stack_pop (GStack *stack); #if G_STACK_MACROIZE -#define g_stack_free(stack) G_STMT_START { \ - if ((GStack *)(stack)) { \ - if ((GStack *)(stack)->list) \ - g_list_free ((GStack *)(stack)->list); \ - g_free (stack); \ - } \ - } G_STMT_END - -#define g_stack_push(stack) G_STMT_START { \ - if ((GStack *)(stack)) \ - (GStack *)(stack)->list = \ - g_list_prepend ((GStack *)(stack)->list, data); \ - } G_STMT_END - +# define g_stack_push(stack) G_STMT_START { \ + if ((GStack *)(stack)) \ + ((GStack *)(stack))->list = \ + g_list_prepend (((GStack *)(stack))->list, data); \ + } G_STMT_END +#else +# define g_stack_push _g_stack_push #endif +/* Queues + */ + +GQueue * g_queue_new (void); +void g_queue_free (GQueue *q); +guint g_queue_get_size (GQueue *q); +void g_queue_push_front (GQueue *q, gpointer data); +void g_queue_push_back (GQueue *q, gpointer data); +gpointer g_queue_pop_front (GQueue *q); +gpointer g_queue_pop_back (GQueue *q); + +#define q_queue_push q_queue_push_back +#define q_queue_pop q_queue_pop_front + + + + + + + /* Hash tables */ GHashTable* g_hash_table_new (GHashFunc hash_func, diff --git a/glib/Makefile.am b/glib/Makefile.am index ea004095c..4a9f01617 100644 --- a/glib/Makefile.am +++ b/glib/Makefile.am @@ -44,9 +44,11 @@ libglib_la_SOURCES = \ gmutex.c \ gnode.c \ gprimes.c \ + gqueue.c \ grel.c \ gscanner.c \ gslist.c \ + gstack.c \ gstrfuncs.c \ gstring.c \ gtimer.c \ diff --git a/glib/glib.h b/glib/glib.h index 64729ff31..f81eaded9 100644 --- a/glib/glib.h +++ b/glib/glib.h @@ -677,6 +677,7 @@ typedef struct _GList GList; typedef struct _GMemChunk GMemChunk; typedef struct _GNode GNode; typedef struct _GPtrArray GPtrArray; +typedef struct _GQueue GQueue; typedef struct _GRelation GRelation; typedef struct _GScanner GScanner; typedef struct _GScannerConfig GScannerConfig; @@ -803,6 +804,13 @@ struct _GStack GList *list; }; +struct _GQueue +{ + GList *list; + GList *list_end; + guint list_size; +}; + struct _GString { gchar *str; @@ -942,31 +950,42 @@ gpointer g_slist_nth_data (GSList *list, /* Stacks */ GStack * g_stack_new (void); -#ifndef G_STACK_MACROIZE void g_stack_free (GStack *stack); -void g_stack_push (GStack *stack, gpointer data); -#endif +void _g_stack_push (GStack *stack, gpointer data); gpointer g_stack_pop (GStack *stack); #if G_STACK_MACROIZE -#define g_stack_free(stack) G_STMT_START { \ - if ((GStack *)(stack)) { \ - if ((GStack *)(stack)->list) \ - g_list_free ((GStack *)(stack)->list); \ - g_free (stack); \ - } \ - } G_STMT_END - -#define g_stack_push(stack) G_STMT_START { \ - if ((GStack *)(stack)) \ - (GStack *)(stack)->list = \ - g_list_prepend ((GStack *)(stack)->list, data); \ - } G_STMT_END - +# define g_stack_push(stack) G_STMT_START { \ + if ((GStack *)(stack)) \ + ((GStack *)(stack))->list = \ + g_list_prepend (((GStack *)(stack))->list, data); \ + } G_STMT_END +#else +# define g_stack_push _g_stack_push #endif +/* Queues + */ + +GQueue * g_queue_new (void); +void g_queue_free (GQueue *q); +guint g_queue_get_size (GQueue *q); +void g_queue_push_front (GQueue *q, gpointer data); +void g_queue_push_back (GQueue *q, gpointer data); +gpointer g_queue_pop_front (GQueue *q); +gpointer g_queue_pop_back (GQueue *q); + +#define q_queue_push q_queue_push_back +#define q_queue_pop q_queue_pop_front + + + + + + + /* Hash tables */ GHashTable* g_hash_table_new (GHashFunc hash_func, diff --git a/glib/gqueue.c b/glib/gqueue.c new file mode 100644 index 000000000..85e9b54b7 --- /dev/null +++ b/glib/gqueue.c @@ -0,0 +1,144 @@ +/* +* GQueue, opaque ADT with interface: + + q = g_queue_new (); + count = g_queue_size (q); + + q_queue_push_front (q, data); + q_queue_push_back (q, data); + data = q_queue_pop_front (q); + data = q_queue_pop_back (q); + #define q_queue_push q_queue_push_back + #define q_queue_pop q_queue_pop_front + + list = g_queue_get_list (q); + #define g_queue_get_front g_queue_get_list + list_end = g_queue_get_back (q); +*/ + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + + + +GQueue * +g_queue_new (void) +{ + GQueue *q = g_new (GQueue, 1); + + q->list = q->list_end = NULL; + q->list_size = 0; + + return q; +} + + +void +g_queue_free (GQueue *q) +{ + if (q) { + if (q->list) + g_list_free (q->list); + g_free (q); + } +} + + +guint +g_queue_get_size (GQueue *q) +{ + return (q == NULL) ? 0 : q->list_size; +} + + +void +g_queue_push_front (GQueue *q, gpointer data) +{ + if (q) { + q->list = g_list_prepend (q->list, data); + + if (q->list_end == NULL) + q->list_end = q->list; + + q->list_size++; + } +} + + +void +g_queue_push_back (GQueue *q, gpointer data) +{ + if (q) { + q->list_end = g_list_append (q->list_end, data); + + if (! q->list) + q->list = q->list_end; + else + q->list_end = q->list_end->next; + + q->list_size++; + } +} + + +gpointer +g_queue_pop_front (GQueue *q) +{ + gpointer data = NULL; + + if ((q) && (q->list)) { + GList *node; + + node = q->list; + data = node->data; + + if (! node->next) { + q->list = q->list_end = NULL; + q->list_size = 0; + } + else { + q->list = node->next; + q->list->prev = NULL; + q->list_size--; + } + + g_list_free_1 (node); + } + + return data; +} + + +gpointer +g_queue_pop_back (GQueue *q) +{ + gpointer data = NULL; + + if ((q) && (q->list)) { + GList *node; + + node = q->list_end; + data = node->data; + + if (! node->prev) { + q->list = q->list_end = NULL; + q->list_size = 0; + } + else { + q->list_end = node->prev; + q->list_end->next = NULL; + q->list_size--; + } + + g_list_free_1 (node); + } + + return data; +} + + diff --git a/gqueue.c b/gqueue.c new file mode 100644 index 000000000..85e9b54b7 --- /dev/null +++ b/gqueue.c @@ -0,0 +1,144 @@ +/* +* GQueue, opaque ADT with interface: + + q = g_queue_new (); + count = g_queue_size (q); + + q_queue_push_front (q, data); + q_queue_push_back (q, data); + data = q_queue_pop_front (q); + data = q_queue_pop_back (q); + #define q_queue_push q_queue_push_back + #define q_queue_pop q_queue_pop_front + + list = g_queue_get_list (q); + #define g_queue_get_front g_queue_get_list + list_end = g_queue_get_back (q); +*/ + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + + + + +GQueue * +g_queue_new (void) +{ + GQueue *q = g_new (GQueue, 1); + + q->list = q->list_end = NULL; + q->list_size = 0; + + return q; +} + + +void +g_queue_free (GQueue *q) +{ + if (q) { + if (q->list) + g_list_free (q->list); + g_free (q); + } +} + + +guint +g_queue_get_size (GQueue *q) +{ + return (q == NULL) ? 0 : q->list_size; +} + + +void +g_queue_push_front (GQueue *q, gpointer data) +{ + if (q) { + q->list = g_list_prepend (q->list, data); + + if (q->list_end == NULL) + q->list_end = q->list; + + q->list_size++; + } +} + + +void +g_queue_push_back (GQueue *q, gpointer data) +{ + if (q) { + q->list_end = g_list_append (q->list_end, data); + + if (! q->list) + q->list = q->list_end; + else + q->list_end = q->list_end->next; + + q->list_size++; + } +} + + +gpointer +g_queue_pop_front (GQueue *q) +{ + gpointer data = NULL; + + if ((q) && (q->list)) { + GList *node; + + node = q->list; + data = node->data; + + if (! node->next) { + q->list = q->list_end = NULL; + q->list_size = 0; + } + else { + q->list = node->next; + q->list->prev = NULL; + q->list_size--; + } + + g_list_free_1 (node); + } + + return data; +} + + +gpointer +g_queue_pop_back (GQueue *q) +{ + gpointer data = NULL; + + if ((q) && (q->list)) { + GList *node; + + node = q->list_end; + data = node->data; + + if (! node->prev) { + q->list = q->list_end = NULL; + q->list_size = 0; + } + else { + q->list_end = node->prev; + q->list_end->next = NULL; + q->list_size--; + } + + g_list_free_1 (node); + } + + return data; +} + + diff --git a/gstack.c b/gstack.c index e7ad9917c..5d14e3ffb 100644 --- a/gstack.c +++ b/gstack.c @@ -30,9 +30,6 @@ g_stack_new (void) } -#ifndef G_STACK_MACROIZE - - void g_stack_free (GStack *stack) { @@ -46,14 +43,12 @@ g_stack_free (GStack *stack) void -g_stack_push (GStack *stack, gpointer data) +_g_stack_push (GStack *stack, gpointer data) { if (stack) stack->list = g_list_prepend (stack->list, data); } -#endif /* G_STACK_MACROIZE */ - gpointer g_stack_pop (GStack *stack) diff --git a/tests/.cvsignore b/tests/.cvsignore index f6d398f4d..4bc9866c1 100644 --- a/tests/.cvsignore +++ b/tests/.cvsignore @@ -33,3 +33,4 @@ tree-test dirname-test type-test strfunc-test +stack-test diff --git a/tests/Makefile.am b/tests/Makefile.am index 1734038ad..3782f8f0a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -9,6 +9,7 @@ TESTS = \ node-test \ relation-test \ slist-test \ + stack-test \ string-test \ strfunc-test \ tree-test \ @@ -23,6 +24,7 @@ list_test_LDADD = $(top_builddir)/libglib.la node_test_LDADD = $(top_builddir)/libglib.la relation_test_LDADD = $(top_builddir)/libglib.la slist_test_LDADD = $(top_builddir)/libglib.la +stack_test_LDADD = $(top_builddir)/libglib.la string_test_LDADD = $(top_builddir)/libglib.la strfunc_test_LDADD = $(top_builddir)/libglib.la tree_test_LDADD = $(top_builddir)/libglib.la diff --git a/tests/stack-test.c b/tests/stack-test.c new file mode 100644 index 000000000..19eeb5a65 --- /dev/null +++ b/tests/stack-test.c @@ -0,0 +1,37 @@ +#include + +int main() +{ + GStack *s; + + s = g_stack_new (); + + g_stack_push (s, GINT_TO_POINTER (1)); + g_assert (g_list_length (s->list) == 1); + g_stack_push (s, GINT_TO_POINTER (2)); + g_assert (g_list_length (s->list) == 2); + g_stack_push (s, GINT_TO_POINTER (3)); + g_assert (g_list_length (s->list) == 3); + g_stack_push (s, GINT_TO_POINTER (4)); + g_assert (g_list_length (s->list) == 4); + g_stack_push (s, GINT_TO_POINTER (5)); + g_assert (g_list_length (s->list) == 5); + + g_assert (g_stack_pop (s) == GPOINTER_TO_INT (5)); + g_assert (g_list_length (s->list) == 4); + g_assert (g_stack_pop (s) == GPOINTER_TO_INT (4)); + g_assert (g_list_length (s->list) == 3); + g_assert (g_stack_pop (s) == GPOINTER_TO_INT (3)); + g_assert (g_list_length (s->list) == 2); + g_assert (g_stack_pop (s) == GPOINTER_TO_INT (2)); + g_assert (g_list_length (s->list) == 1); + g_assert (g_stack_pop (s) == GPOINTER_TO_INT (1)); + g_assert (g_list_length (s->list) == 0); + g_assert (g_stack_pop (s) == NULL); + g_assert (g_list_length (s->list) == 0); + g_assert (g_stack_pop (s) == NULL); + g_assert (g_list_length (s->list) == 0); + + return 0; +} +