X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/wordchain/blobdiff_plain/ed71412555b7ef3b16544e33f21fbd521b21b9ae..3bbec421c59fe8feefefe89a5f33cf47ea4a08c8:/chain.c diff --git a/chain.c b/chain.c index 583b2a0..707097b 100644 --- a/chain.c +++ b/chain.c @@ -230,7 +230,7 @@ static int word_nav(struct xyla_bst_nodecls *cls, # endif # define INSERT do { \ if (TREE_PROBE(0, &root, word_nav, &word, &path)) { \ - printf(";; duplicate `%s'\n", buf); \ + fprintf(stderr, ";; duplicate `%s'\n", buf); \ free(node); node = 0; \ } else { \ EXTRA_NODE_SETUP; \ @@ -363,9 +363,10 @@ static bool my_Tnextl(Tbl *t, const char **k_inout, size_t *sz_inout, # endif # elif QPTRIE_ITER == QPITER_LIST # define DECL_ITER \ - struct node *list = 0, **tail = &list, *next -# define INSERT_LIST \ - do { node->next = 0; *tail = node; tail = &node->next; } while (0) + struct node *all = 0, **all_tail = &all +# define INSERT_LIST do { \ + node->next = 0; *all_tail = node; all_tail = &node->next; \ + } while (0) # endif # define DECLS \ @@ -381,7 +382,7 @@ static bool my_Tnextl(Tbl *t, const char **k_inout, size_t *sz_inout, # if QPTRIE_ITER == QPITER_LIST # define ITERATE \ - for (next = list; node = next, node; next = next->next) + for (next = all; node = next, node; next = next->next) # else # define ITERATE \ for (cur.p = 0, cur.n = 0; \ @@ -399,7 +400,7 @@ static bool my_Tnextl(Tbl *t, const char **k_inout, size_t *sz_inout, # if QPTRIE_ITER == QPITER_LIST # define FREE do { \ - for (node = list; node; node = next) { \ + for (node = all; node; node = next) { \ tbl = Tsetl(tbl, node->w.p, node->w.n, 0); \ next = node->next; free(node); \ } \ @@ -429,7 +430,7 @@ static int node_cmp(void *a, void *b) # define INSERT do { \ if (add234(root, node) != node) { \ - printf(";; duplicate `%s'\n", buf); \ + fprintf(stderr, ";; duplicate `%s'\n", buf); \ free(node); node = 0; \ } \ } while (0) @@ -467,7 +468,7 @@ static void free_node(void *n, void *arg) { free(n); } # define INSERT do { \ p = TREE_PROBE(tab, node); if (!p) bail("out of memory"); \ if (*p != node) { \ - printf(";; duplicate `%s'\n", buf); \ + fprintf(stderr, ";; duplicate `%s'\n", buf); \ free(node); node = 0; \ } \ } while (0) @@ -487,11 +488,11 @@ static void free_node(void *n, void *arg) { free(n); } # define DECLS \ sym_table tab; \ - struct node *list = 0, **tail = &list, *next; \ + struct node *all = 0, **all_tail = &all; \ unsigned foundp # define INIT do { \ - unihash_setkey(&unihash_global, /*getpid()*/ 31022); \ + unihash_setkey(&unihash_global, getpid()); \ sym_create(&tab); \ } while (0) @@ -499,11 +500,15 @@ static void free_node(void *n, void *arg) { free(n); } # define INSERT do { \ node = sym_find(&tab, buf, word.n, sizeof(*node), &foundp); \ - if (foundp) { bail(";; duplicate `%s'\n", buf); node = 0; } \ - else { node->next = 0; *tail = node; tail = &node->next; } \ + if (!foundp) { \ + node->next = 0; *all_tail = node; all_tail = &node->next; \ + } else { \ + fprintf(stderr, ";; duplicate `%s'\n", buf); \ + free(node); node = 0; \ + } \ } while (0) -# define ITERATE for (next = list; node = next, node; next = next->next) +# define ITERATE for (next = all; node = next, node; next = next->next) # define FOCUS do ; while (0) @@ -562,7 +567,7 @@ static void print_chain(struct node *node) int main(void) { DECLS; - struct node *node, *parent; + struct node *node, *parent, *winners, **winners_tail, *next; struct word word; char buf[WORDMAX]; int ch, max, nlen, plen; @@ -582,20 +587,28 @@ int main(void) CHECK; - max = 0; + max = 0; winners_tail = &winners; ITERATE { FOCUS; /* fprintf(stderr, ";; ponder `%.*s'\n", WORDLEN(node), WORDPTR(node)); */ if (WORDLEN(node) <= 1) - parent = 0; + continue; else { GETPREFIX; /* fprintf(stderr, ";; search `%.*s'\n", word.n, word.p); */ - parent = LOOKUP; + parent = LOOKUP; if (!parent) continue; } node->up = parent; nlen = node->len; - while (parent) { + for (;;) { + if (!parent) { + if (nlen >= max) { + if (nlen > max) + { max = nlen; *winners_tail = 0; winners_tail = &winners; } + *winners_tail = node; winners_tail = &node->right; + } + break; + } plen = parent->len; nlen++; if (plen > nlen) break; @@ -608,10 +621,12 @@ int main(void) node = parent; parent = node->up; } } - if (nlen > max) max = nlen; } - ITERATE if (node->len == max) { print_chain(node); putchar('\n'); } + for (*winners_tail = 0, node = winners; node; node = next) { + next = node->right; node->right = 0; + print_chain(node); putchar('\n'); + } FREE; return (0); }