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. */
37 typedef struct _trie {
39 struct _trie *next[26];
49 fprintf (stderr, "Error: out of memory\n");
57 xrealloc (void *ptr, size_t size)
61 res = realloc (ptr, size);
63 fprintf (stderr, "Error: out of memory\n");
71 trie_init (trie_t *trie)
74 trie->is_word = FALSE;
75 for (i = 0; i < 26; i++)
84 trie = xmalloc (sizeof (trie_t));
92 trie_destroy (trie_t *trie)
96 for (i = 0; i < 26; i++)
98 trie_destroy (trie->next[i]);
103 #define TRIE_CHAR_TO_INDEX(c) (tolower (c) - 'a')
104 #define TRIE_INDEX_TO_CHAR(i) (i + 'a')
106 trie_add (trie_t *trie,
107 const char *word_chunk)
109 char c = word_chunk[0];
113 trie->is_word = TRUE;
117 i = TRIE_CHAR_TO_INDEX (c);
118 if (trie->next[i] == NULL)
119 trie->next[i] = trie_create ();
121 trie_add (trie->next[i], word_chunk + 1);
125 trie_contains (trie_t *trie,
126 const char *word_chunk)
128 char c = word_chunk[0];
132 return trie->is_word;
134 i = TRIE_CHAR_TO_INDEX (c);
135 if (trie->next[i] == NULL)
138 return trie_contains (trie->next[i], word_chunk + 1);
142 trie_print (trie_t *trie,
150 if (trie->is_word && *str)
151 printf ("%s\n", *str);
153 /* Make room for the extra character. */
156 *str = xmalloc (*str_size);
160 str_len = strlen (*str);
162 if (str_len + 1 == *str_size) {
164 *str = xrealloc (*str, *str_size);
167 (*str)[str_len + 1] = '\0';
169 /* Loop over each element, appending the character and recursing. */
170 for (i = 0; i < 26; i++) {
171 if (trie->next[i] == NULL)
174 c = TRIE_INDEX_TO_CHAR (i);
177 trie_print (trie->next[i], str, str_size);
180 (*str)[str_len] = '\0';
186 if (str[strlen (str) - 1] == '\n')
187 str[strlen (str) - 1] = '\0';
190 typedef struct _dict {
195 dict_init (dict_t *dict,
196 const char *filename)
200 size_t line_size = 0;
203 file = fopen (filename, "r");
205 fprintf (stderr, "Error: failed to open %s: %s\n",
206 filename, strerror (errno));
210 dict->trie = trie_create ();
213 bytes_read = getline (&line, &line_size, file);
214 if (bytes_read == -1)
217 trie_add (dict->trie, line);
224 dict_print (dict_t *dict)
229 trie_print (dict->trie, &str, &str_size);
239 dict_init (&dict, "words.txt");