aboutsummaryrefslogtreecommitdiff
path: root/dictionary.c
diff options
context:
space:
mode:
Diffstat (limited to 'dictionary.c')
-rw-r--r--dictionary.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/dictionary.c b/dictionary.c
new file mode 100644
index 0000000..7d9523b
--- /dev/null
+++ b/dictionary.c
@@ -0,0 +1,140 @@
+#include "jdtalk.h"
+
+struct Dictionary *dictionary_new() {
+ struct Dictionary *dict;
+ dict = calloc(1, sizeof(*dict));
+ dict->words = calloc(DICT_INITIAL_SIZE, sizeof(**dict->words));
+ dict->nelem_alloc = DICT_INITIAL_SIZE;
+ dict->nelem_inuse = 0;
+ return dict;
+}
+
+void dictionary_append(struct Dictionary **dict, char *s, unsigned type) {
+ if ((*dict)->nelem_inuse + 1 > (*dict)->nelem_alloc) {
+ struct Word **tmp;
+ (*dict)->nelem_alloc += DICT_INITIAL_SIZE;
+ tmp = realloc((*dict)->words, (*dict)->nelem_alloc * sizeof((*dict)->words));
+ if (!tmp) {
+ perror("Unable to extend word list");
+ exit(1);
+ }
+ (*dict)->words = tmp;
+ }
+ (*dict)->words[(*dict)->nelem_inuse] = calloc(1, sizeof(**(*dict)->words));
+ (*dict)->words[(*dict)->nelem_inuse]->word = strdup(s);
+ (*dict)->words[(*dict)->nelem_inuse]->nchar = strlen(s) - 1;
+ *((*dict)->words[(*dict)->nelem_inuse]->word + ((*dict)->words[(*dict)->nelem_inuse]->nchar)) = '\0';
+ (*dict)->words[(*dict)->nelem_inuse]->type = type;
+ (*dict)->nelem_inuse++;
+}
+
+int dictionary_read(FILE *fp, struct Dictionary **dict, unsigned type) {
+ //char buf[DICT_WORD_SIZE_MAX];
+ char *bufp = calloc(DICT_WORD_SIZE_MAX, sizeof(char));
+ //bufp = buf;
+ while ((fgets(bufp, DICT_WORD_SIZE_MAX - 1, fp) != NULL)) {
+ if (errno) {
+ return errno;
+ }
+ if (*bufp == '\0' || *bufp == '\n')
+ continue;
+ dictionary_append(&(*dict), bufp, type);
+ }
+ free(bufp);
+ return 0;
+}
+
+struct Dictionary *dictionary_populate() {
+ FILE *fp;
+ struct Dictionary *dict;
+ const char *files[] = {
+ "nouns.txt",
+ "adjectives.txt",
+ "adverbs.txt",
+ "verbs.txt",
+ NULL,
+ };
+
+ const unsigned files_type[] = {
+ WT_NOUN,
+ WT_ADJECTIVE,
+ WT_ADVERB,
+ WT_VERB,
+ };
+
+ dict = dictionary_new();
+ for (size_t i = 0; files[i] != NULL; i++) {
+ char *datadir;
+ char filename[PATH_MAX];
+ filename[0] = '\0';
+ datadir = getenv("JDTALK_DATA");
+
+ if (!datadir) {
+ fprintf(stderr, "JDTALK_DATA environment variable is not set\n");
+ exit(1);
+ }
+
+ sprintf(filename, "%s/%s", datadir, files[i]);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ fprintf(stderr, "Unable to open dictionary: %s", filename);
+ exit(1);
+ }
+ dictionary_read(fp, &dict, files_type[i]);
+ fclose(fp);
+ }
+ return dict;
+}
+
+int dictionary_contains(struct Dictionary *dict, const char *s, unsigned type) {
+ int result;
+ unsigned icase;
+
+ icase = type & WT_ICASE;
+ type &= 0x7f;
+ result = 0;
+
+ for (size_t i = 0; i < dict->nelem_inuse; i++) {
+ if (*s != *dict->words[i]->word) {
+ // Didn't start with first character in s
+ continue;
+ }
+
+ if (type != WT_ANY && dict->words[i]->type != type) {
+ // Incorrect type of word
+ continue;
+ }
+
+ if (icase) {
+ result = strcasecmp(dict->words[i]->word, s) == 0;
+ } else {
+ result = strcmp(dict->words[i]->word, s) == 0;
+ }
+
+ if (result) {
+ break;
+ }
+ }
+ return result;
+}
+
+char *dictionary_word(struct Dictionary *dict, unsigned type) {
+ struct Word *word;
+ while (1) {
+ size_t index = rand() % dict->nelem_inuse;
+ word = dict->words[index];
+ if (word->type == type || type == WT_ANY) {
+ return word->word;
+ }
+ }
+}
+
+void dictionary_free(struct Dictionary *dict) {
+ for (size_t i = 0; i < dict->nelem_inuse; i++) {
+ free(dict->words[i]->word);
+ free(dict->words[i]);
+ }
+ free(dict->words);
+ free(dict);
+}
+