1*3e5d0078SDavid du Colombier #include <u.h>
2*3e5d0078SDavid du Colombier #include <libc.h>
3*3e5d0078SDavid du Colombier #include <bio.h>
4*3e5d0078SDavid du Colombier #include <ctype.h>
5*3e5d0078SDavid du Colombier
6*3e5d0078SDavid du Colombier #define NULL ((void *)0)
7*3e5d0078SDavid du Colombier
8*3e5d0078SDavid du Colombier #define WORD_LIST "/sys/games/lib/anawords"
9*3e5d0078SDavid du Colombier #define VOWELS "aeiouy"
10*3e5d0078SDavid du Colombier #define ALPHAS 26
11*3e5d0078SDavid du Colombier #define LENLIMIT 64
12*3e5d0078SDavid du Colombier
13*3e5d0078SDavid du Colombier #define talloc(t) salloc(sizeof (t))
14*3e5d0078SDavid du Colombier #define MAP(c) ((c) - 'a')
15*3e5d0078SDavid du Colombier
16*3e5d0078SDavid du Colombier enum
17*3e5d0078SDavid du Colombier {
18*3e5d0078SDavid du Colombier in_fd,
19*3e5d0078SDavid du Colombier out_fd,
20*3e5d0078SDavid du Colombier err_fd,
21*3e5d0078SDavid du Colombier };
22*3e5d0078SDavid du Colombier
23*3e5d0078SDavid du Colombier typedef struct word word;
24*3e5d0078SDavid du Colombier
25*3e5d0078SDavid du Colombier struct word
26*3e5d0078SDavid du Colombier {
27*3e5d0078SDavid du Colombier char *text;
28*3e5d0078SDavid du Colombier int length;
29*3e5d0078SDavid du Colombier ulong mask;
30*3e5d0078SDavid du Colombier word *next;
31*3e5d0078SDavid du Colombier };
32*3e5d0078SDavid du Colombier
33*3e5d0078SDavid du Colombier typedef word *set[LENLIMIT];
34*3e5d0078SDavid du Colombier
35*3e5d0078SDavid du Colombier typedef struct
36*3e5d0078SDavid du Colombier {
37*3e5d0078SDavid du Colombier int count[ALPHAS];
38*3e5d0078SDavid du Colombier int length;
39*3e5d0078SDavid du Colombier ulong mask;
40*3e5d0078SDavid du Colombier }
41*3e5d0078SDavid du Colombier target;
42*3e5d0078SDavid du Colombier
43*3e5d0078SDavid du Colombier int fixed;
44*3e5d0078SDavid du Colombier int maxwords;
45*3e5d0078SDavid du Colombier set words;
46*3e5d0078SDavid du Colombier word *list[LENLIMIT];
47*3e5d0078SDavid du Colombier
48*3e5d0078SDavid du Colombier void
error(char * s)49*3e5d0078SDavid du Colombier error(char *s)
50*3e5d0078SDavid du Colombier {
51*3e5d0078SDavid du Colombier fprint(err_fd, "fatal error: %s\n", s);
52*3e5d0078SDavid du Colombier exits("fatal error");
53*3e5d0078SDavid du Colombier }
54*3e5d0078SDavid du Colombier
55*3e5d0078SDavid du Colombier void *
salloc(ulong z)56*3e5d0078SDavid du Colombier salloc(ulong z)
57*3e5d0078SDavid du Colombier {
58*3e5d0078SDavid du Colombier void *p;
59*3e5d0078SDavid du Colombier
60*3e5d0078SDavid du Colombier if ((p = malloc(z)) == NULL)
61*3e5d0078SDavid du Colombier error("ran out of memory");
62*3e5d0078SDavid du Colombier
63*3e5d0078SDavid du Colombier return p;
64*3e5d0078SDavid du Colombier }
65*3e5d0078SDavid du Colombier
66*3e5d0078SDavid du Colombier void
clean_word(char * s)67*3e5d0078SDavid du Colombier clean_word(char *s)
68*3e5d0078SDavid du Colombier {
69*3e5d0078SDavid du Colombier while (*s && *s != '\n')
70*3e5d0078SDavid du Colombier {
71*3e5d0078SDavid du Colombier if (isupper(*s))
72*3e5d0078SDavid du Colombier *s = tolower(*s);
73*3e5d0078SDavid du Colombier
74*3e5d0078SDavid du Colombier s++;
75*3e5d0078SDavid du Colombier }
76*3e5d0078SDavid du Colombier if (*s == '\n')
77*3e5d0078SDavid du Colombier *s = 0;
78*3e5d0078SDavid du Colombier }
79*3e5d0078SDavid du Colombier
80*3e5d0078SDavid du Colombier int
word_ok(word * w)81*3e5d0078SDavid du Colombier word_ok(word *w)
82*3e5d0078SDavid du Colombier {
83*3e5d0078SDavid du Colombier char *s;
84*3e5d0078SDavid du Colombier int vowel;
85*3e5d0078SDavid du Colombier
86*3e5d0078SDavid du Colombier if (w->length == 0 || w->length >= LENLIMIT)
87*3e5d0078SDavid du Colombier return 0;
88*3e5d0078SDavid du Colombier
89*3e5d0078SDavid du Colombier if (w->length == 1)
90*3e5d0078SDavid du Colombier return strchr("aio", w->text[0]) != NULL;
91*3e5d0078SDavid du Colombier
92*3e5d0078SDavid du Colombier vowel = 0;
93*3e5d0078SDavid du Colombier s = w->text;
94*3e5d0078SDavid du Colombier
95*3e5d0078SDavid du Colombier while (*s != '\0')
96*3e5d0078SDavid du Colombier {
97*3e5d0078SDavid du Colombier if (!isalpha(*s))
98*3e5d0078SDavid du Colombier return 0;
99*3e5d0078SDavid du Colombier
100*3e5d0078SDavid du Colombier switch (*s)
101*3e5d0078SDavid du Colombier {
102*3e5d0078SDavid du Colombier case 'a':
103*3e5d0078SDavid du Colombier case 'e':
104*3e5d0078SDavid du Colombier case 'i':
105*3e5d0078SDavid du Colombier case 'o':
106*3e5d0078SDavid du Colombier case 'u':
107*3e5d0078SDavid du Colombier case 'y':
108*3e5d0078SDavid du Colombier vowel = 1;
109*3e5d0078SDavid du Colombier }
110*3e5d0078SDavid du Colombier
111*3e5d0078SDavid du Colombier s++;
112*3e5d0078SDavid du Colombier }
113*3e5d0078SDavid du Colombier
114*3e5d0078SDavid du Colombier return vowel;
115*3e5d0078SDavid du Colombier }
116*3e5d0078SDavid du Colombier
117*3e5d0078SDavid du Colombier ulong
str_to_mask(char * s)118*3e5d0078SDavid du Colombier str_to_mask(char *s)
119*3e5d0078SDavid du Colombier {
120*3e5d0078SDavid du Colombier ulong m;
121*3e5d0078SDavid du Colombier
122*3e5d0078SDavid du Colombier m = 0;
123*3e5d0078SDavid du Colombier
124*3e5d0078SDavid du Colombier while (*s != '\0')
125*3e5d0078SDavid du Colombier m |= 1 << MAP(*s++);
126*3e5d0078SDavid du Colombier
127*3e5d0078SDavid du Colombier return m;
128*3e5d0078SDavid du Colombier }
129*3e5d0078SDavid du Colombier
130*3e5d0078SDavid du Colombier word *
get_word(Biobuf * bp)131*3e5d0078SDavid du Colombier get_word(Biobuf *bp)
132*3e5d0078SDavid du Colombier {
133*3e5d0078SDavid du Colombier char *s;
134*3e5d0078SDavid du Colombier word *w;
135*3e5d0078SDavid du Colombier
136*3e5d0078SDavid du Colombier retry:
137*3e5d0078SDavid du Colombier if ((s = Brdline(bp, '\n')) == NULL)
138*3e5d0078SDavid du Colombier return NULL;
139*3e5d0078SDavid du Colombier
140*3e5d0078SDavid du Colombier clean_word(s);
141*3e5d0078SDavid du Colombier
142*3e5d0078SDavid du Colombier w = talloc(word);
143*3e5d0078SDavid du Colombier w->length = strlen(s);
144*3e5d0078SDavid du Colombier w->text = strcpy(salloc(w->length+1), s);
145*3e5d0078SDavid du Colombier w->mask = str_to_mask(s);
146*3e5d0078SDavid du Colombier
147*3e5d0078SDavid du Colombier if (!word_ok(w))
148*3e5d0078SDavid du Colombier {
149*3e5d0078SDavid du Colombier free(w->text);
150*3e5d0078SDavid du Colombier free(w);
151*3e5d0078SDavid du Colombier goto retry;
152*3e5d0078SDavid du Colombier }
153*3e5d0078SDavid du Colombier
154*3e5d0078SDavid du Colombier return w;
155*3e5d0078SDavid du Colombier }
156*3e5d0078SDavid du Colombier
157*3e5d0078SDavid du Colombier void
build_wordlist(void)158*3e5d0078SDavid du Colombier build_wordlist(void)
159*3e5d0078SDavid du Colombier {
160*3e5d0078SDavid du Colombier Biobuf *bp;
161*3e5d0078SDavid du Colombier word *w;
162*3e5d0078SDavid du Colombier word **p;
163*3e5d0078SDavid du Colombier
164*3e5d0078SDavid du Colombier bp = Bopen(WORD_LIST, OREAD);
165*3e5d0078SDavid du Colombier if (!bp)
166*3e5d0078SDavid du Colombier {
167*3e5d0078SDavid du Colombier perror(WORD_LIST);
168*3e5d0078SDavid du Colombier exits(WORD_LIST);
169*3e5d0078SDavid du Colombier }
170*3e5d0078SDavid du Colombier
171*3e5d0078SDavid du Colombier while ((w = get_word(bp)) != NULL)
172*3e5d0078SDavid du Colombier {
173*3e5d0078SDavid du Colombier p = &words[w->length];
174*3e5d0078SDavid du Colombier w->next = *p;
175*3e5d0078SDavid du Colombier *p = w;
176*3e5d0078SDavid du Colombier }
177*3e5d0078SDavid du Colombier }
178*3e5d0078SDavid du Colombier
179*3e5d0078SDavid du Colombier void
count_letters(target * t,char * s)180*3e5d0078SDavid du Colombier count_letters(target *t, char *s)
181*3e5d0078SDavid du Colombier {
182*3e5d0078SDavid du Colombier int i;
183*3e5d0078SDavid du Colombier
184*3e5d0078SDavid du Colombier for (i = 0; i < ALPHAS; i++)
185*3e5d0078SDavid du Colombier t->count[i] = 0;
186*3e5d0078SDavid du Colombier
187*3e5d0078SDavid du Colombier t->length = 0;
188*3e5d0078SDavid du Colombier
189*3e5d0078SDavid du Colombier while (*s != '\0')
190*3e5d0078SDavid du Colombier {
191*3e5d0078SDavid du Colombier t->count[MAP(*s++)]++;
192*3e5d0078SDavid du Colombier t->length++;
193*3e5d0078SDavid du Colombier }
194*3e5d0078SDavid du Colombier }
195*3e5d0078SDavid du Colombier
196*3e5d0078SDavid du Colombier int
contained(word * i,target * t)197*3e5d0078SDavid du Colombier contained(word *i, target *t)
198*3e5d0078SDavid du Colombier {
199*3e5d0078SDavid du Colombier int n;
200*3e5d0078SDavid du Colombier char *v;
201*3e5d0078SDavid du Colombier target it;
202*3e5d0078SDavid du Colombier
203*3e5d0078SDavid du Colombier if ((i->mask & t->mask) != i->mask)
204*3e5d0078SDavid du Colombier return 0;
205*3e5d0078SDavid du Colombier
206*3e5d0078SDavid du Colombier count_letters(&it, i->text);
207*3e5d0078SDavid du Colombier
208*3e5d0078SDavid du Colombier for (n = 0; n < ALPHAS; n++)
209*3e5d0078SDavid du Colombier {
210*3e5d0078SDavid du Colombier if (it.count[n] > t->count[n])
211*3e5d0078SDavid du Colombier return 0;
212*3e5d0078SDavid du Colombier }
213*3e5d0078SDavid du Colombier
214*3e5d0078SDavid du Colombier if (it.length == t->length)
215*3e5d0078SDavid du Colombier return 1;
216*3e5d0078SDavid du Colombier
217*3e5d0078SDavid du Colombier for (v = VOWELS; *v != '\0'; v++)
218*3e5d0078SDavid du Colombier {
219*3e5d0078SDavid du Colombier if (t->count[MAP(*v)] > it.count[MAP(*v)])
220*3e5d0078SDavid du Colombier return 1;
221*3e5d0078SDavid du Colombier }
222*3e5d0078SDavid du Colombier
223*3e5d0078SDavid du Colombier return 0;
224*3e5d0078SDavid du Colombier }
225*3e5d0078SDavid du Colombier
226*3e5d0078SDavid du Colombier int
prune(set in,int m,target * filter,set out)227*3e5d0078SDavid du Colombier prune(set in, int m, target *filter, set out)
228*3e5d0078SDavid du Colombier {
229*3e5d0078SDavid du Colombier word *i, *o, *t;
230*3e5d0078SDavid du Colombier int n;
231*3e5d0078SDavid du Colombier int nz;
232*3e5d0078SDavid du Colombier
233*3e5d0078SDavid du Colombier nz = 0;
234*3e5d0078SDavid du Colombier
235*3e5d0078SDavid du Colombier for (n = 1; n < LENLIMIT; n++)
236*3e5d0078SDavid du Colombier {
237*3e5d0078SDavid du Colombier if (n > m)
238*3e5d0078SDavid du Colombier {
239*3e5d0078SDavid du Colombier out[n] = NULL;
240*3e5d0078SDavid du Colombier continue;
241*3e5d0078SDavid du Colombier }
242*3e5d0078SDavid du Colombier
243*3e5d0078SDavid du Colombier o = NULL;
244*3e5d0078SDavid du Colombier
245*3e5d0078SDavid du Colombier for (i = in[n]; i != NULL; i = i->next)
246*3e5d0078SDavid du Colombier {
247*3e5d0078SDavid du Colombier if (contained(i, filter))
248*3e5d0078SDavid du Colombier {
249*3e5d0078SDavid du Colombier t = talloc(word);
250*3e5d0078SDavid du Colombier *t = *i;
251*3e5d0078SDavid du Colombier t->next = o;
252*3e5d0078SDavid du Colombier o = t;
253*3e5d0078SDavid du Colombier nz = 1;
254*3e5d0078SDavid du Colombier }
255*3e5d0078SDavid du Colombier }
256*3e5d0078SDavid du Colombier
257*3e5d0078SDavid du Colombier out[n] = o;
258*3e5d0078SDavid du Colombier }
259*3e5d0078SDavid du Colombier
260*3e5d0078SDavid du Colombier return nz;
261*3e5d0078SDavid du Colombier }
262*3e5d0078SDavid du Colombier
263*3e5d0078SDavid du Colombier void
print_set(set s)264*3e5d0078SDavid du Colombier print_set(set s)
265*3e5d0078SDavid du Colombier {
266*3e5d0078SDavid du Colombier word *w;
267*3e5d0078SDavid du Colombier int n;
268*3e5d0078SDavid du Colombier
269*3e5d0078SDavid du Colombier for (n = 1; n < LENLIMIT; n++)
270*3e5d0078SDavid du Colombier {
271*3e5d0078SDavid du Colombier for (w = s[n]; w != NULL; w = w->next)
272*3e5d0078SDavid du Colombier fprint(out_fd, "%s\n", w->text);
273*3e5d0078SDavid du Colombier }
274*3e5d0078SDavid du Colombier }
275*3e5d0078SDavid du Colombier
276*3e5d0078SDavid du Colombier ulong
target_mask(int c[])277*3e5d0078SDavid du Colombier target_mask(int c[])
278*3e5d0078SDavid du Colombier {
279*3e5d0078SDavid du Colombier ulong m;
280*3e5d0078SDavid du Colombier int i;
281*3e5d0078SDavid du Colombier
282*3e5d0078SDavid du Colombier m = 0;
283*3e5d0078SDavid du Colombier
284*3e5d0078SDavid du Colombier for (i = 0; i < ALPHAS; i++)
285*3e5d0078SDavid du Colombier {
286*3e5d0078SDavid du Colombier if (c[i] != 0)
287*3e5d0078SDavid du Colombier m |= 1 << i;
288*3e5d0078SDavid du Colombier }
289*3e5d0078SDavid du Colombier
290*3e5d0078SDavid du Colombier return m;
291*3e5d0078SDavid du Colombier }
292*3e5d0078SDavid du Colombier
293*3e5d0078SDavid du Colombier void
dump_list(word ** e)294*3e5d0078SDavid du Colombier dump_list(word **e)
295*3e5d0078SDavid du Colombier {
296*3e5d0078SDavid du Colombier word **p;
297*3e5d0078SDavid du Colombier
298*3e5d0078SDavid du Colombier fprint(out_fd, "%d", (int)(e - list + 1));
299*3e5d0078SDavid du Colombier
300*3e5d0078SDavid du Colombier for (p = list; p <= e; p++)
301*3e5d0078SDavid du Colombier fprint(out_fd, " %s", (*p)->text);
302*3e5d0078SDavid du Colombier
303*3e5d0078SDavid du Colombier fprint(out_fd, "\n");
304*3e5d0078SDavid du Colombier }
305*3e5d0078SDavid du Colombier
306*3e5d0078SDavid du Colombier void
free_set(set s)307*3e5d0078SDavid du Colombier free_set(set s)
308*3e5d0078SDavid du Colombier {
309*3e5d0078SDavid du Colombier int i;
310*3e5d0078SDavid du Colombier word *p, *q;
311*3e5d0078SDavid du Colombier
312*3e5d0078SDavid du Colombier for (i = 1; i < LENLIMIT; i++)
313*3e5d0078SDavid du Colombier {
314*3e5d0078SDavid du Colombier for (p = s[i]; p != NULL; p = q)
315*3e5d0078SDavid du Colombier {
316*3e5d0078SDavid du Colombier q = p->next;
317*3e5d0078SDavid du Colombier free(p);
318*3e5d0078SDavid du Colombier }
319*3e5d0078SDavid du Colombier }
320*3e5d0078SDavid du Colombier }
321*3e5d0078SDavid du Colombier
322*3e5d0078SDavid du Colombier void
enumerate(word ** p,target * i,set c)323*3e5d0078SDavid du Colombier enumerate(word **p, target *i, set c)
324*3e5d0078SDavid du Colombier {
325*3e5d0078SDavid du Colombier target t;
326*3e5d0078SDavid du Colombier set o;
327*3e5d0078SDavid du Colombier word *w, *h;
328*3e5d0078SDavid du Colombier char *s;
329*3e5d0078SDavid du Colombier int l, m, b;
330*3e5d0078SDavid du Colombier
331*3e5d0078SDavid du Colombier l = p - list;
332*3e5d0078SDavid du Colombier b = (i->length + (maxwords - l - 1)) / (maxwords - l);
333*3e5d0078SDavid du Colombier
334*3e5d0078SDavid du Colombier for (m = i->length; m >= b; m--)
335*3e5d0078SDavid du Colombier {
336*3e5d0078SDavid du Colombier h = c[m];
337*3e5d0078SDavid du Colombier
338*3e5d0078SDavid du Colombier for (w = h; w != NULL; w = w->next)
339*3e5d0078SDavid du Colombier {
340*3e5d0078SDavid du Colombier if (i->length == m)
341*3e5d0078SDavid du Colombier {
342*3e5d0078SDavid du Colombier *p = w;
343*3e5d0078SDavid du Colombier dump_list(p);
344*3e5d0078SDavid du Colombier continue;
345*3e5d0078SDavid du Colombier }
346*3e5d0078SDavid du Colombier
347*3e5d0078SDavid du Colombier if (l == maxwords - 1)
348*3e5d0078SDavid du Colombier continue;
349*3e5d0078SDavid du Colombier
350*3e5d0078SDavid du Colombier t = *i;
351*3e5d0078SDavid du Colombier t.length -= m;
352*3e5d0078SDavid du Colombier
353*3e5d0078SDavid du Colombier for (s = w->text; *s != '\0'; s++)
354*3e5d0078SDavid du Colombier t.count[MAP(*s)]--;
355*3e5d0078SDavid du Colombier
356*3e5d0078SDavid du Colombier t.mask = target_mask(t.count);
357*3e5d0078SDavid du Colombier c[m] = w->next;
358*3e5d0078SDavid du Colombier
359*3e5d0078SDavid du Colombier if (prune(c, m, &t, o))
360*3e5d0078SDavid du Colombier {
361*3e5d0078SDavid du Colombier *p = w;
362*3e5d0078SDavid du Colombier enumerate(p + 1, &t, o);
363*3e5d0078SDavid du Colombier free_set(o);
364*3e5d0078SDavid du Colombier }
365*3e5d0078SDavid du Colombier }
366*3e5d0078SDavid du Colombier
367*3e5d0078SDavid du Colombier c[m] = h;
368*3e5d0078SDavid du Colombier }
369*3e5d0078SDavid du Colombier }
370*3e5d0078SDavid du Colombier
371*3e5d0078SDavid du Colombier void
clean(char * s)372*3e5d0078SDavid du Colombier clean(char *s)
373*3e5d0078SDavid du Colombier {
374*3e5d0078SDavid du Colombier char *p, *q;
375*3e5d0078SDavid du Colombier
376*3e5d0078SDavid du Colombier for (p = s, q = s; *p != '\0'; p++)
377*3e5d0078SDavid du Colombier {
378*3e5d0078SDavid du Colombier if (islower(*p))
379*3e5d0078SDavid du Colombier *q++ = *p;
380*3e5d0078SDavid du Colombier else if (isupper(*p))
381*3e5d0078SDavid du Colombier *q++ = tolower(*p);
382*3e5d0078SDavid du Colombier }
383*3e5d0078SDavid du Colombier
384*3e5d0078SDavid du Colombier *q = '\0';
385*3e5d0078SDavid du Colombier }
386*3e5d0078SDavid du Colombier
387*3e5d0078SDavid du Colombier void
anagramulate(char * s)388*3e5d0078SDavid du Colombier anagramulate(char *s)
389*3e5d0078SDavid du Colombier {
390*3e5d0078SDavid du Colombier target t;
391*3e5d0078SDavid du Colombier set subjects;
392*3e5d0078SDavid du Colombier
393*3e5d0078SDavid du Colombier clean(s);
394*3e5d0078SDavid du Colombier
395*3e5d0078SDavid du Colombier if (fixed)
396*3e5d0078SDavid du Colombier maxwords = fixed;
397*3e5d0078SDavid du Colombier else if ((maxwords = strlen(s) / 4) < 3)
398*3e5d0078SDavid du Colombier maxwords = 3;
399*3e5d0078SDavid du Colombier
400*3e5d0078SDavid du Colombier fprint(out_fd, "%s:\n", s);
401*3e5d0078SDavid du Colombier t.mask = str_to_mask(s);
402*3e5d0078SDavid du Colombier count_letters(&t, s);
403*3e5d0078SDavid du Colombier
404*3e5d0078SDavid du Colombier if (!prune(words,t.length, &t, subjects))
405*3e5d0078SDavid du Colombier return;
406*3e5d0078SDavid du Colombier
407*3e5d0078SDavid du Colombier enumerate(&list[0], &t, subjects);
408*3e5d0078SDavid du Colombier }
409*3e5d0078SDavid du Colombier
410*3e5d0078SDavid du Colombier void
set_fixed(char * s)411*3e5d0078SDavid du Colombier set_fixed(char *s)
412*3e5d0078SDavid du Colombier {
413*3e5d0078SDavid du Colombier if ((fixed = atoi(s)) < 1)
414*3e5d0078SDavid du Colombier fixed = 1;
415*3e5d0078SDavid du Colombier }
416*3e5d0078SDavid du Colombier
417*3e5d0078SDavid du Colombier void
read_words(void)418*3e5d0078SDavid du Colombier read_words(void)
419*3e5d0078SDavid du Colombier {
420*3e5d0078SDavid du Colombier char *s;
421*3e5d0078SDavid du Colombier Biobuf b;
422*3e5d0078SDavid du Colombier
423*3e5d0078SDavid du Colombier Binit(&b, in_fd, OREAD);
424*3e5d0078SDavid du Colombier while ((s = Brdline(&b, '\n')) != NULL)
425*3e5d0078SDavid du Colombier {
426*3e5d0078SDavid du Colombier s[Blinelen(&b)-1] = '\0';
427*3e5d0078SDavid du Colombier if (isdigit(s[0]))
428*3e5d0078SDavid du Colombier {
429*3e5d0078SDavid du Colombier set_fixed(s);
430*3e5d0078SDavid du Colombier fprint(out_fd, "Fixed = %d.\n", fixed);
431*3e5d0078SDavid du Colombier }
432*3e5d0078SDavid du Colombier else
433*3e5d0078SDavid du Colombier {
434*3e5d0078SDavid du Colombier anagramulate(s);
435*3e5d0078SDavid du Colombier fprint(out_fd, "Done.\n");
436*3e5d0078SDavid du Colombier }
437*3e5d0078SDavid du Colombier
438*3e5d0078SDavid du Colombier }
439*3e5d0078SDavid du Colombier }
440*3e5d0078SDavid du Colombier
441*3e5d0078SDavid du Colombier void
main(int argc,char ** argv)442*3e5d0078SDavid du Colombier main(int argc, char **argv)
443*3e5d0078SDavid du Colombier {
444*3e5d0078SDavid du Colombier build_wordlist();
445*3e5d0078SDavid du Colombier
446*3e5d0078SDavid du Colombier if (argc > 1)
447*3e5d0078SDavid du Colombier set_fixed(argv[1]);
448*3e5d0078SDavid du Colombier
449*3e5d0078SDavid du Colombier read_words();
450*3e5d0078SDavid du Colombier exits(0);
451*3e5d0078SDavid du Colombier }
452