From: Carl Worth Date: Mon, 18 Dec 2006 05:38:43 +0000 (-0800) Subject: dict: Add dict_for_each functions X-Git-Url: https://git.cworth.org/git?p=wordgame;a=commitdiff_plain;h=a5187a6b925208af24014e40290f323f8ecd9be7 dict: Add dict_for_each functions These new functions allow the caller to pass a callback to act on all entries within a dictionary. --- diff --git a/dict.c b/dict.c index a920293..d7edc47 100644 --- a/dict.c +++ b/dict.c @@ -209,12 +209,14 @@ trie_count (trie_t *trie, } static int -trie_print (trie_t *trie, - string_t *string, - trie_predicate_t predicate, - int length, - int min_length, - int max_length) +trie_for_each (trie_t *trie, + string_t *string, + trie_predicate_t predicate, + int length, + int min_length, + int max_length, + dict_action_t action, + void *closure) { char c; int i; @@ -223,7 +225,8 @@ trie_print (trie_t *trie, if (length >= min_length && (predicate) (trie)) { count = 1; - printf ("%s ", string->s); + + action (closure, string->s); } if (length == max_length) @@ -237,8 +240,9 @@ trie_print (trie_t *trie, c = TRIE_INDEX_TO_CHAR (i); string_append_char (string, c); - count += trie_print (trie->next[i], string, predicate, - length + 1, min_length, max_length); + count += trie_for_each (trie->next[i], string, predicate, + length + 1, min_length, max_length, + action, closure); string_chop (string); } @@ -371,16 +375,20 @@ dict_count (dict_t *dict, } int -dict_print (dict_t *dict) +dict_for_each_if (dict_t *dict, + dict_action_t action, + void *closure, + dict_entry_predicate_t predicate) + { int count; string_t string; string_init (&string); - dict_entry_predicate = NULL; - count = trie_print (dict, &string, dict_predicate, - 0, 0, -1); + dict_entry_predicate = predicate; + count = trie_for_each (dict, &string, dict_predicate, + 0, 0, -1, action, closure); string_fini (&string); @@ -388,26 +396,18 @@ dict_print (dict_t *dict) } int -dict_print_if (dict_t *dict, - dict_entry_predicate_t predicate) +dict_for_each (dict_t *dict, + dict_action_t action, + void *closure) { - int count; - string_t string; - - string_init (&string); - - dict_entry_predicate = predicate; - count = trie_print (dict, &string, dict_predicate, - 0, 0, -1); - - string_fini (&string); - - return count; + return dict_for_each_if (dict, action, closure, NULL); } int -dict_print_by_length_if (dict_t *dict, - dict_entry_predicate_t predicate) +dict_for_each_by_length_if (dict_t *dict, + dict_action_t action, + void *closure, + dict_entry_predicate_t predicate) { int length, total, words, count = 0; string_t string; @@ -420,12 +420,11 @@ dict_print_by_length_if (dict_t *dict, length = 1; do { - words = trie_print (dict, &string, dict_predicate, - 0, length, length); - if (words) { - printf ("\n"); + words = trie_for_each (dict, &string, dict_predicate, + 0, length, length, + action, closure); + if (words) count += words; - } length++; } while (count < total); @@ -433,3 +432,67 @@ dict_print_by_length_if (dict_t *dict, return count; } + +int +dict_for_each_by_length (dict_t *dict, + dict_action_t action, + void *closure) +{ + return dict_for_each_by_length_if (dict, action, closure, NULL); +} + +static void +dict_action_print (void *closure, char *word) +{ + int *length_of_last = closure; + int length = strlen (word); + + if (length == *length_of_last) + printf(" "); + else if (*length_of_last) + printf("\n"); + + printf ("%s", word); + + *length_of_last = length; +} + +int +dict_print (dict_t *dict) +{ + int length_of_last = 0; + + return dict_for_each (dict, + dict_action_print, &length_of_last); +} + +int +dict_print_by_length (dict_t *dict) +{ + int length_of_last = 0; + + return dict_for_each_by_length (dict, + dict_action_print, &length_of_last); +} + +int +dict_print_if (dict_t *dict, + dict_entry_predicate_t predicate) +{ + int length_of_last = 0; + + return dict_for_each_if (dict, + dict_action_print, &length_of_last, + predicate); +} + +int +dict_print_by_length_if (dict_t *dict, + dict_entry_predicate_t predicate) +{ + int length_of_last = 0; + + return dict_for_each_by_length_if (dict, + dict_action_print, &length_of_last, + predicate); +} diff --git a/dict.h b/dict.h index af21015..6152c72 100644 --- a/dict.h +++ b/dict.h @@ -82,6 +82,9 @@ dict_count (dict_t *dict, int dict_print (dict_t *dict); +int +dict_print_by_length (dict_t *dict); + int dict_print_if (dict_t *dict, dict_entry_predicate_t predicate); @@ -90,6 +93,31 @@ int dict_print_by_length_if (dict_t *dict, dict_entry_predicate_t predicate); +/* More general callback-based iteration of all entries */ +typedef void (* dict_action_t) (void *closure, char *word); + +int +dict_for_each (dict_t *dict, + dict_action_t action, + void *closure); + +int +dict_for_each_by_length (dict_t *dict, + dict_action_t action, + void *closure); + +int +dict_for_each_if (dict_t *dict, + dict_action_t action, + void *closure, + dict_entry_predicate_t predicate); + +int +dict_for_each_by_length_if (dict_t *dict, + dict_action_t action, + void *closure, + dict_entry_predicate_t predicate); + /* Character-by-character perusal of the dictionary */ dict_cursor_t dict_root (dict_t *dict);