2 * Copyright © 2006 Carl Worth
4 * This program is free software; you can redistribute it and\/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA."
19 /* Portably, schmortability. I want ease of programming. */
36 fprintf (stderr, "Error: out of memory\n");
44 xrealloc (void *ptr, size_t size)
48 res = realloc (ptr, size);
50 fprintf (stderr, "Error: out of memory\n");
61 if (s[len - 1] == '\n')
66 string_init (string_t *string)
74 string_fini (string_t *string)
83 string_append_char (string_t *string, char c)
85 if (string->size == 0) {
87 string->s = xmalloc (string->size);
92 if (string->len + 1 == string->size) {
94 string->s = xrealloc (string->s, string->size);
97 string->s[string->len++] = c;
98 string->s[string->len] = '\0';
102 string_chop (string_t *string)
104 if (string->len == 0)
107 string->s[--string->len] = '\0';
111 trie_init (trie_t *trie)
115 for (i = 0; i < 26; i++)
116 trie->next[i] = NULL;
124 trie = xmalloc (sizeof (trie_t));
132 trie_destroy (trie_t *trie)
136 for (i = 0; i < 26; i++)
138 trie_destroy (trie->next[i]);
144 trie_add (trie_t *trie,
145 const char *word_chunk)
147 char c = word_chunk[0];
151 trie->flags |= TRIE_FLAGS_IS_WORD;
155 i = TRIE_CHAR_TO_INDEX (c);
156 if (trie->next[i] == NULL)
157 trie->next[i] = trie_create ();
159 trie_add (trie->next[i], word_chunk + 1);
163 trie_find (trie_t *trie,
164 const char *word_chunk)
166 const char *s = word_chunk;
169 trie = trie->next[TRIE_CHAR_TO_INDEX (*s++)];
175 trie_print (trie_t *trie,
177 trie_predicate_t predicate)
183 if (trie->flags & TRIE_FLAGS_IS_WORD
184 && (predicate == NULL || predicate (trie)))
187 printf ("%s ", string->s);
190 /* Loop over each element, appending the character and recursing. */
191 for (i = 0; i < 26; i++) {
192 if (trie->next[i] == NULL)
195 c = TRIE_INDEX_TO_CHAR (i);
197 string_append_char (string, c);
198 count += trie_print (trie->next[i], string, predicate);
199 string_chop (string);
206 trie_seen_predicate (trie_t *trie)
208 return (trie->flags & TRIE_FLAGS_SEEN);
212 trie_print_seen (trie_t *trie, string_t *word)
214 return trie_print (trie, word, trie_seen_predicate);
218 trie_unseen_predicate (trie_t *trie)
220 return (! trie_seen_predicate (trie));
224 trie_print_unseen (trie_t *trie, string_t *word)
226 return trie_print (trie, word, trie_unseen_predicate);
230 dict_init (dict_t *dict,
231 const char *filename)
235 size_t line_size = 0;
238 file = fopen (filename, "r");
240 fprintf (stderr, "Error: failed to open %s: %s\n",
241 filename, strerror (errno));
245 dict->trie = trie_create ();
248 bytes_read = getline (&line, &line_size, file);
249 if (bytes_read == -1)
252 trie_add (dict->trie, line);
261 dict_fini (dict_t *dict)
263 trie_destroy (dict->trie);
267 dict_print (dict_t *dict)
271 string_init (&string);
273 trie_print (dict->trie, &string, NULL);
275 string_fini (&string);