chiark / gitweb /
more stuff found lying about
[wordchain] / chain.c
diff --git a/chain.c b/chain.c
index 583b2a01120afde3167139a2f142c572ef8396fa..707097b2344a9e219e929c99001f92e12ea696f9 100644 (file)
--- 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);
 }