summaryrefslogtreecommitdiff
path: root/word.c
diff options
context:
space:
mode:
Diffstat (limited to 'word.c')
-rw-r--r--word.c161
1 files changed, 138 insertions, 23 deletions
diff --git a/word.c b/word.c
index 0e84ae2..00fbf42 100644
--- a/word.c
+++ b/word.c
@@ -20,21 +20,28 @@
#include <stdlib.h>
#include <string.h>
#include "mainwin.h"
+#include "main.h"
#include "word.h"
#include "dict.h"
Word *words;
-static char **sorted = NULL;
+SortedWords user_words;
+static SortedWords sorted = {0, NULL};
+
+static Word *find_word(Word *, const char *);
+/*third argument of find_parent() should be NULL when func is to be called*/
+static void find_parent(Word *, const Word *, Word **);
static void sort_words(const Word *);
+static Word *get_the_rightest(Word *);
static inline char *wordcpy(char *);
-static inline void free_word_record(Word *);
+static inline void free_word(Word *);
unsigned int get_words_count(const Word *root)
{
unsigned int cnt = 0;
- if (root == NULL)
+ if (!root)
return 0;
else {
cnt += get_words_count(root->lsibl);
@@ -44,19 +51,55 @@ unsigned int get_words_count(const Word *root)
}
}
-int to_list(char *word)
+void del_word(Word **root, char *word)
{
- if (!is_in_dict(word, dict)) {
- words = add_word_record(words, word);
+ Word *node, *parent = NULL;
+ Word **parent_leaf = NULL;
+
+ node = find_word(*root, word);
+ find_parent(*root, node, &parent);
+ if ((parent)&&(parent->lsibl == node))
+ parent_leaf = &parent->lsibl;
+ else if ((parent)&&(parent->rsibl == node))
+ parent_leaf = &parent->rsibl;
+ /*NOTE that (root == node) is a special case (without parent)*/
+ if ((!node->lsibl)&&(!node->rsibl)) {
+ if (parent)
+ *parent_leaf = NULL;
+ else
+ *root = NULL;
+ free_word(node);
+ return ;
+ }
+ if ((node->lsibl)&&(!node->rsibl)) {
+ if (parent)
+ *parent_leaf = node->lsibl;
+ else
+ *root = node->lsibl;
+ free_word(node);
+ } else if ((!node->lsibl)&&(node->rsibl)) {
+ if (parent)
+ *parent_leaf = node->rsibl;
+ else
+ *root = node->rsibl;
+ free_word(node);
+ } else {
+ Word *temp;
+ temp = get_the_rightest(node->lsibl);
+ temp->rsibl = node->rsibl;
+ if (parent)
+ *parent_leaf = node->lsibl;
+ else
+ *root = node->lsibl;
+ free_word(node);
}
- return 0;
}
-Word *add_word_record(Word *root, char *word)
+Word *add_word(Word *root, char *word)
{
int cond;
- if (root == NULL) {
+ if (!root) {
root = malloc(sizeof(Word));
root->word = wordcpy(word);
root->lsibl = root->rsibl = NULL;
@@ -64,43 +107,115 @@ Word *add_word_record(Word *root, char *word)
else {
cond = strcmp(word, root->word);
if (cond > 0)
- root->rsibl = add_word_record(root->rsibl, word);
+ root->rsibl = add_word(root->rsibl, word);
else if (cond < 0)
- root->lsibl = add_word_record(root->lsibl, word);
+ root->lsibl = add_word(root->lsibl, word);
}
return root;
}
-char **get_sorted(Word *root)
+static Word *find_word(Word *root, const char *word)
+{
+ int cond;
+
+ if (root) {
+ cond = strcmp(word, root->word);
+ if (cond > 0)
+ return find_word(root->rsibl, word);
+ else if (cond < 0)
+ return find_word(root->lsibl, word);
+ else
+ return root;
+ } else
+ return NULL;
+}
+
+static void find_parent(Word *root, const Word *sibling, Word **parent)
+{
+ if (root) {
+ if (*parent)
+ return ;
+ if (root->lsibl != sibling)
+ find_parent(root->lsibl, sibling, parent);
+ else {
+ *parent = root;
+ return ;
+ }
+ if (*parent)
+ return ;
+ if (root->rsibl != sibling)
+ find_parent(root->rsibl, sibling, parent);
+ else{
+ *parent = root;
+ return ;
+ }
+ }
+}
+
+SortedWords get_sorted(Word *root)
{
unsigned int cnt;
cnt = get_words_count(root);
- sorted = malloc(cnt*sizeof(char*));
- sort_words(root);
- return (sorted - cnt);
+ sorted.count = cnt;
+ sorted.by_az = NULL;
+ if (cnt) {
+ sorted.by_az = malloc(cnt*sizeof(char*));
+ sort_words(root);
+ sorted.by_az = sorted.by_az - cnt;
+ }
+ return sorted;
}
static void sort_words(const Word *root)
{
- if (root->lsibl != NULL)
+ if (root) {
sort_words(root->lsibl);
- *sorted = root->word;
- sorted++;
- if (root->rsibl != NULL)
+ *sorted.by_az = root->word;
+ sorted.by_az++;
sort_words(root->rsibl);
+ }
+}
+
+void save_words(FILE *tofile, SortedWords words, SaveOpt options)
+{
+ int i, j;
+ char format[10] = {0};
+
+ sprintf(format, "%%-%us", options.col_width);
+ i = 0;
+ while (i < words.count) {
+ for (j = 0; (j < options.columns)&&(i < words.count); j++) {
+ if (j == options.columns-1)
+ fprintf(tofile, "%s\n", *words.by_az);
+ else
+ fprintf(tofile, format, *words.by_az);
+ words.by_az++;
+ i++;
+ }
+ }
+}
+
+static Word *get_the_rightest(Word *root)
+{
+ if (root->rsibl)
+ return get_the_rightest(root->rsibl);
+ else
+ return root;
+ /*it's useless but GCC wants it to be*/
+ return NULL;
}
void free_words(Word *root)
{
- if (root->lsibl != NULL)
+ if (root->lsibl)
free_words(root->lsibl);
- if (root->rsibl != NULL)
+ if (root->rsibl)
free_words(root->rsibl);
- free_word_record(root);
+ free_word(root);
}
-static inline void free_word_record(Word *record)
+static inline void free_word(Word *record)
{
free(record->word);
free(record);