/** * This deletes all the non-idiom words of the dictionary that match * the given string. Returns true if some deleted, false otherwise. * * XXX Note: this function is not currently used anywhere in the code, * but it could be useful for general dictionary editing. */ int delete_dictionary_words(Dictionary dict, const char * s) { Dict_node *pred, *pred_parent; Dict_node *parent, *to_be_deleted; if (!find_one_non_idiom_node(NULL, dict->root, s, &parent, &to_be_deleted)) return false; for(;;) { /* now parent and to_be_deleted are set */ if (to_be_deleted->file != NULL) { to_be_deleted->file->changed = true; } if (to_be_deleted->left == NULL) { set_parent_of_node(dict, parent, to_be_deleted, to_be_deleted->right); free_dict_node(to_be_deleted); } else { pred_parent = to_be_deleted; pred = to_be_deleted->left; while(pred->right != NULL) { pred_parent = pred; pred = pred->right; } to_be_deleted->string = pred->string; to_be_deleted->file = pred->file; to_be_deleted->exp = pred->exp; set_parent_of_node(dict, pred_parent, pred, pred->left); free_dict_node(pred); } if (!find_one_non_idiom_node(NULL, dict->root, s, &parent, &to_be_deleted)) return true; } }
/** * insert_list() - * p points to a list of dict_nodes connected by their left pointers. * l is the length of this list (the last ptr may not be NULL). * It inserts the list into the dictionary. * It does the middle one first, then the left half, then the right. * * Note: I think this insert middle, then left, then right, has * its origins as a lame attempt to hack around the fact that the * resulting binary tree is rather badly unbalanced. This has been * fixed by using the DSW rebalancing algo. Now, that would seem * to render this crazy bisected-insertion algo obsoloete, but .. * oddly enough, it seems to make the DSW balancing go really fast! * Faster than a simple insertion. Go figure. I think this has * something to do with the fact that the dictionaries are in * alphabetical order! This subdivision helps randomize a bit. */ static void insert_list(Dictionary dict, Dict_node * p, int l) { Dict_node * dn, *dn_head, *dn_second_half; int k, i; /* length of first half */ if (l == 0) return; k = (l-1)/2; dn = p; for (i = 0; i < k; i++) { dn = dn->left; } /* dn now points to the middle element */ dn_second_half = dn->left; dn->left = dn->right = NULL; if (contains_underbar(dn->string)) { insert_idiom(dict, dn); } else if (is_idiom_word(dn->string)) { err_ctxt ec; ec.sent = NULL; err_msg(&ec, Warn, "Warning: Word \"%s\" found near line %d.\n" "\tWords ending \".Ix\" (x a number) are reserved for idioms.\n" "\tThis word will be ignored.\n", dn->string, dict->line_number); free_dict_node(dn); } else if ((dn_head = abridged_lookup_list(dict, dn->string)) != NULL) { Dict_node *dnx; err_ctxt ec; ec.sent = NULL; err_msg(&ec, Warn, "Warning: The word \"%s\" " "found near line %d of %s matches the following words:\n", dn->string, dict->line_number, dict->name); for (dnx = dn_head; dnx != NULL; dnx = dnx->right) { fprintf(stderr, "\t%s", dnx->string); } fprintf(stderr, "\n\tThis word will be ignored.\n"); free_lookup_list(dn_head); free_dict_node(dn); } else { dict->root = insert_dict(dict, dict->root, dn); dict->num_entries++; } insert_list(dict, p, k); insert_list(dict, dn_second_half, l-k-1); }
static void free_dict_node_recursive(Dict_node * dn) { if (dn == NULL) return; free_dict_node_recursive(dn->left); free_dict_node_recursive(dn->right); free_dict_node(dn); }
/** * prune_lookup_list -- discard all list entries that don't match string * Walk the lookup list (of right links), discarding all nodes that do * not match the dictionary string s. The matching is dictionary matching: * suffixed entries will match "bare" entries. */ static Dict_node * prune_lookup_list(Dict_node *llist, const char * s) { Dict_node *dn, *dnx, *list_new; list_new = NULL; for (dn = llist; dn != NULL; dn = dnx) { dnx = dn->right; /* now put dn onto the answer list, or free it */ if (dict_match(dn->string, s)) { dn->right = list_new; list_new = dn; } else { free_dict_node(dn); } } /* now reverse the list back */ llist = NULL; for (dn = list_new; dn != NULL; dn = dnx) { dnx = dn->right; dn->right = llist; llist = dn; } return llist; }
void free_lookup_list(Dict_node *llist) { Dict_node * n; while(llist != NULL) { n = llist->right; free_dict_node(llist); llist = n; } }