diff --git a/ase/cmd/awk/awk.c b/ase/cmd/awk/awk.c index 27be055d..3f57d8fa 100644 --- a/ase/cmd/awk/awk.c +++ b/ase/cmd/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c 321 2008-08-10 08:27:21Z baconevi $ + * $Id: awk.c 323 2008-08-11 10:52:25Z baconevi $ */ #include @@ -1056,9 +1056,10 @@ static void handle_args (argc, argv) } #endif -static int dump_sf (ase_sll_t* sll, ase_sll_node_t* n, void* arg) +static ase_sll_walk_t dump_sf (ase_sll_t* sll, ase_sll_node_t* n, void* arg) { ase_printf (ASE_T("%s\n"), n->data.ptr); + return ASE_SLL_WALK_FORWARD; } static int handle_args (int argc, ase_char_t* argv[], ase_sll_t* sf) @@ -1171,6 +1172,7 @@ wprintf (L"PREPEND %S\n", opt.arg); ase_printf (ASE_T("[%d]\n"), (int)ase_sll_getsize(sf)); ase_sll_walk (sf, dump_sf, ASE_NULL); + #if 0 if (srcio->input_file == ASE_NULL) { @@ -1261,6 +1263,11 @@ static ase_awk_t* open_awk (void) return awk; } +static ase_sll_walk_t dump (ase_sll_t* sll, ase_sll_node_t* node, void* arg) +{ + ase_printf (ASE_T("[%d]\n"), *(int*)node->data.ptr); + return ASE_SLL_WALK_FORWARD; +} static int awk_main (int argc, ase_char_t* argv[]) { ase_awk_t* awk; @@ -1287,7 +1294,32 @@ static int awk_main (int argc, ase_char_t* argv[]) out_of_memory (); return -1; } +{ // TODO: destroy sf.... +int i; + +ase_sll_setcopier (sf, ASE_SLL_COPIER_INLINE); +for (i = 0; i < 20; i++) +{ + /* + if (ASE_SLL_SIZE(sf) > 5) + ase_sll_insert (sf, sf->head->next->next, &i, sizeof(i)); + else + ase_sll_insert (sf, ASE_SLL_HEAD(sf), &i, sizeof(i)); + */ + ase_sll_insert (sf, ASE_NULL, &i, sizeof(i)); +} + +ase_sll_delete (sf, ASE_SLL_TAIL(sf)); +ase_sll_delete (sf, ASE_SLL_TAIL(sf)); +ase_sll_delete (sf, ASE_SLL_HEAD(sf)); +ase_printf (ASE_T("size = %d\n"), ASE_SLL_SIZE(sf)); +ase_sll_walk (sf, dump, ASE_NULL); +ase_sll_clear (sf); +ase_printf (ASE_T("size = %d\n"), ASE_SLL_SIZE(sf)); +ase_sll_close (sf); +return 0; +} i = handle_args (argc, argv, sf); if (i == -1) diff --git a/ase/include/ase/cmn/sll.h b/ase/include/ase/cmn/sll.h index 8d979f38..c1179412 100644 --- a/ase/include/ase/cmn/sll.h +++ b/ase/include/ase/cmn/sll.h @@ -17,6 +17,28 @@ typedef struct ase_sll_t ase_sll_t; typedef struct ase_sll_node_t ase_sll_node_t; typedef enum ase_sll_walk_t ase_sll_walk_t; +/* data copier */ +typedef void* (*ase_sll_copier_t) (ase_sll_t* sll, void* data, ase_size_t len); + +/* data freeer */ +typedef void (*ase_sll_freeer_t) (ase_sll_t* sll, void* data, ase_size_t len); + +/* node visitor */ +typedef ase_sll_walk_t (*ase_sll_walker_t) ( + ase_sll_t* sll, ase_sll_node_t* node, void* arg); + +struct ase_sll_t +{ + ase_mmgr_t* mmgr; + + ase_sll_copier_t copier; + ase_sll_freeer_t freeer; + + ase_size_t size; + ase_sll_node_t* head; + ase_sll_node_t* tail; +}; + struct ase_sll_node_t { struct @@ -28,9 +50,6 @@ struct ase_sll_node_t ase_sll_node_t* next; /* pointer to the next node */ }; -typedef void* (*ase_sll_copier_t) (ase_sll_t* sll, void* data, ase_size_t len); -typedef void (*ase_sll_freeer_t) (ase_sll_t* sll, void* data, ase_size_t len); -typedef ase_sll_walk_t (*ase_sll_walker_t) (ase_sll_t* sll, ase_sll_node_t* node, void* arg); enum ase_sll_walk_t { @@ -40,6 +59,10 @@ enum ase_sll_walk_t #define ASE_SLL_COPIER_INLINE ase_sll_copyinline +#define ASE_SLL_HEAD(sll) ((sll)->head) +#define ASE_SLL_TAIL(sll) ((sll)->tail) +#define ASE_SLL_SIZE(sll) ((sll)->size) + #ifdef __cplusplus extern "C" { #endif diff --git a/ase/lib/cmn/sll.c b/ase/lib/cmn/sll.c index fd032a70..4edeced1 100644 --- a/ase/lib/cmn/sll.c +++ b/ase/lib/cmn/sll.c @@ -7,18 +7,6 @@ #include #include "mem.h" -struct ase_sll_t -{ - ase_mmgr_t* mmgr; - - ase_sll_copier_t copier; - ase_sll_freeer_t freeer; - - ase_size_t size; - ase_sll_node_t* head; - ase_sll_node_t* tail; -}; - void* ase_sll_copyinline (ase_sll_t* sll, void* dptr, ase_size_t dlen) { /* this is a dummy copier */ @@ -52,20 +40,8 @@ void ase_sll_close (ase_sll_t* sll) void ase_sll_clear (ase_sll_t* sll) { - while (sll->head != ASE_NULL) - { - ase_sll_node_t* h = sll->head; - sll->head = h->next; - - if (sll->freeer != ASE_NULL) - { - sll->freeer (sll, h->data.ptr, h->data.len); - } - - ASE_FREE (sll->mmgr, h); - } - - sll->tail = ASE_NULL; + while (sll->head != ASE_NULL) ase_sll_delete (sll, sll->head); + ASE_ASSERT (sll->tail == ASE_NULL); } void* ase_sll_getextension (ase_sll_t* sll) @@ -93,7 +69,7 @@ ase_sll_copier_t ase_sll_getcopier (ase_sll_t* sll) return sll->copier; } -void ass_sll_setcopier (ase_sll_t* sll, ase_sll_copier_t copier) +void ase_sll_setcopier (ase_sll_t* sll, ase_sll_copier_t copier) { sll->copier = copier; } @@ -187,22 +163,38 @@ ase_sll_node_t* ase_sll_pushtail (ase_sll_t* sll, void* data, ase_size_t size) void ase_sll_delete (ase_sll_t* sll, ase_sll_node_t* pos) { - ASE_ASSERT (pos != ASE_NULL); + if (pos == ASE_NULL) return; /* not a valid node */ if (pos == sll->head) { + /* it is simple to delete the head node */ sll->head = pos->next; if (sll->head == ASE_NULL) sll->tail = ASE_NULL; } else { - /* take note of performance penalty */ + /* but deletion of other nodes has significant performance + * penalty as it has look for the predecessor of the + * target node */ ase_sll_node_t* n2 = sll->head; while (n2->next != pos) n2 = n2->next; + n2->next = pos->next; + + /* update the tail node if necessary */ if (pos == sll->tail) sll->tail = n2; } + if (sll->freeer != ASE_NULL) + { + /* free the actual data */ + sll->freeer (sll, pos->data.ptr, pos->data.len); + } + + /* free the node */ + ASE_FREE (sll->mmgr, pos); + + /* decrement the number of elements */ sll->size--; }