Commit | Line | Data |
---|---|---|
94ed9b30 | 1 | /* -*-c-*- |
2 | * | |
94ed9b30 | 3 | * Remember the longest word seen so far |
4 | * | |
5 | * (c) 2005 Mark Wooding | |
6 | */ | |
7 | ||
0279756e | 8 | /*----- Licensing notice --------------------------------------------------* |
94ed9b30 | 9 | * |
10 | * This file is part of Anag: a simple wordgame helper. | |
11 | * | |
12 | * Anag is free software; you can redistribute it and/or modify | |
13 | * it under the terms of the GNU General Public License as published by | |
14 | * the Free Software Foundation; either version 2 of the License, or | |
15 | * (at your option) any later version. | |
0279756e | 16 | * |
94ed9b30 | 17 | * Anag is distributed in the hope that it will be useful, |
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | * GNU General Public License for more details. | |
0279756e | 21 | * |
94ed9b30 | 22 | * You should have received a copy of the GNU General Public License |
23 | * along with Anag; if not, write to the Free Software Foundation, | |
24 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
25 | */ | |
26 | ||
27 | /*----- Header files ------------------------------------------------------*/ | |
28 | ||
29 | #include "anag.h" | |
30 | ||
31 | /*----- Data structures ---------------------------------------------------*/ | |
32 | ||
33 | typedef struct link { | |
34 | struct link *next; | |
35 | char *p; | |
36 | } link; | |
37 | ||
38 | typedef struct node_longest { | |
39 | node n; | |
40 | size_t len; | |
41 | link *l, **lt; | |
42 | } node_longest; | |
43 | ||
44 | /*----- Main code ---------------------------------------------------------*/ | |
45 | ||
46 | static void empty(node_longest *n) | |
47 | { | |
48 | link *l, *ll; | |
49 | ||
50 | for (l = n->l; l; l = ll) { | |
51 | ll = l->next; | |
52 | free(l->p); | |
53 | free(l); | |
54 | } | |
55 | n->l = 0; | |
56 | n->lt = &n->l; | |
57 | } | |
58 | ||
59 | static void insert(node_longest *n, const char *p, size_t sz) | |
60 | { | |
61 | link *l; | |
62 | ||
63 | n->len = sz; | |
64 | l = xmalloc(sizeof(*l)); | |
65 | l->p = xmalloc(sz + 1); | |
66 | memcpy(l->p, p, sz + 1); | |
67 | l->next = 0; | |
68 | *n->lt = l; | |
69 | n->lt = &l->next; | |
70 | } | |
71 | ||
72 | static int aa_output(void *p) | |
73 | { | |
74 | node_longest *n = p; | |
75 | link *l; | |
76 | ||
77 | if (!n->l) return (0); | |
904ac13a | 78 | for (l = n->l; l; l = l->next) puts(l->p); |
94ed9b30 | 79 | return (1); |
80 | } | |
81 | ||
82 | static int n_longest(node *nn, const char *p, size_t sz) | |
83 | { | |
84 | node_longest *n = (node_longest *)nn; | |
904ac13a MW |
85 | if (sz < n->len) return (0); |
86 | if (sz > n->len) empty(n); | |
94ed9b30 | 87 | insert(n, p, sz); |
88 | return (0); | |
89 | } | |
90 | ||
91 | static int n_shortest(node *nn, const char *p, size_t sz) | |
92 | { | |
93 | node_longest *n = (node_longest *)nn; | |
904ac13a MW |
94 | if (n->len && sz > n->len) return (0); |
95 | if (!n->len || sz < n->len) empty(n); | |
94ed9b30 | 96 | insert(n, p, sz); |
97 | return (0); | |
98 | } | |
99 | ||
100 | static node *mklongest(int (*nf)(node *, const char *, size_t), | |
101 | int (*aa)(void *)) | |
102 | { | |
103 | node_longest *n = xmalloc(sizeof(*n)); | |
104 | n->n.func = nf; | |
105 | n->len = 0; | |
106 | n->l = 0; | |
107 | n->lt = &n->l; | |
108 | atend_register(aa, n); | |
109 | return (&n->n); | |
110 | } | |
111 | ||
112 | node *longest(const char *const *av) | |
113 | { return mklongest(n_longest, aa_output); } | |
114 | node *shortest(const char *const *av) | |
115 | { return mklongest(n_shortest, aa_output); } | |
116 | ||
117 | /*----- That's all, folks -------------------------------------------------*/ |