xref: /original-bsd/usr.bin/spell/spell.c (revision 8ce28e6b)
1db37af28Sbostic /*-
2*8ce28e6bSbostic  * Copyright (c) 1991, 1993
3*8ce28e6bSbostic  *	The Regents of the University of California.  All rights reserved.
4db37af28Sbostic  *
5db37af28Sbostic  * %sccs.include.proprietary.c%
6db37af28Sbostic  */
7db37af28Sbostic 
8d4aefe62Ssam #ifndef lint
9*8ce28e6bSbostic static char copyright[] =
10*8ce28e6bSbostic "@(#) Copyright (c) 1991, 1993\n\
11*8ce28e6bSbostic 	The Regents of the University of California.  All rights reserved.\n";
12db37af28Sbostic #endif /* not lint */
13db37af28Sbostic 
14db37af28Sbostic #ifndef lint
15*8ce28e6bSbostic static char sccsid[] = "@(#)spell.c	8.1 (Berkeley) 06/06/93";
16db37af28Sbostic #endif /* not lint */
17d4aefe62Ssam 
18d4aefe62Ssam #include "spell.h"
19d4aefe62Ssam #define DLEV 2
20d4aefe62Ssam 
21d4aefe62Ssam char	*strcat();
22d4aefe62Ssam int	strip();
23d4aefe62Ssam char	*skipv();
24d4aefe62Ssam int	an();
25d4aefe62Ssam int	s();
26d4aefe62Ssam int	es();
27d4aefe62Ssam int	ily();
28d4aefe62Ssam int	ncy();
29d4aefe62Ssam int	CCe();
30d4aefe62Ssam int	VCe();
31d4aefe62Ssam int	bility();
32d4aefe62Ssam int	tion();
33d4aefe62Ssam int	ize();
34d4aefe62Ssam int	y_to_e();
35d4aefe62Ssam int	i_to_y();
36d4aefe62Ssam int	nop();
37d4aefe62Ssam int	metry();
38d4aefe62Ssam 
39d4aefe62Ssam struct suftab {
40d4aefe62Ssam 	char *suf;
41d4aefe62Ssam 	int (*p1)();
42d4aefe62Ssam 	int n1;
43d4aefe62Ssam 	char *d1;
44d4aefe62Ssam 	char *a1;
45d4aefe62Ssam 	int (*p2)();
46d4aefe62Ssam 	int n2;
47d4aefe62Ssam 	char *d2;
48d4aefe62Ssam 	char *a2;
49d4aefe62Ssam } suftab[] = {
50d4aefe62Ssam 	{"ssen",ily,4,"-y+iness","+ness" },
51d4aefe62Ssam 	{"ssel",ily,4,"-y+i+less","+less" },
52d4aefe62Ssam 	{"se",s,1,"","+s",		es,2,"-y+ies","+es" },
53d4aefe62Ssam 	{"s'",s,2,"","+'s"},
54d4aefe62Ssam 	{"s",s,1,"","+s"},
55d4aefe62Ssam 	{"ecn",ncy,1,"","-t+ce"},
56d4aefe62Ssam 	{"ycn",ncy,1,"","-cy+t"},
57d4aefe62Ssam 	{"ytilb",nop,0,"",""},
58d4aefe62Ssam 	{"ytilib",bility,5,"-le+ility",""},
59d4aefe62Ssam 	{"elbaif",i_to_y,4,"-y+iable",""},
60d4aefe62Ssam 	{"elba",CCe,4,"-e+able","+able"},
61d4aefe62Ssam 	{"yti",CCe,3,"-e+ity","+ity"},
62d4aefe62Ssam 	{"ylb",y_to_e,1,"-e+y",""},
63d4aefe62Ssam 	{"yl",ily,2,"-y+ily","+ly"},
64d4aefe62Ssam 	{"laci",strip,2,"","+al"},
65d4aefe62Ssam 	{"latnem",strip,2,"","+al"},
66d4aefe62Ssam 	{"lanoi",strip,2,"","+al"},
67d4aefe62Ssam 	{"tnem",strip,4,"","+ment"},
68d4aefe62Ssam 	{"gni",CCe,3,"-e+ing","+ing"},
69d4aefe62Ssam 	{"reta",nop,0,"",""},
70d4aefe62Ssam 	{"re",strip,1,"","+r",		i_to_y,2,"-y+ier","+er"},
71d4aefe62Ssam 	{"de",strip,1,"","+d",		i_to_y,2,"-y+ied","+ed"},
72d4aefe62Ssam 	{"citsi",strip,2,"","+ic"},
73d4aefe62Ssam 	{"cihparg",i_to_y,1,"-y+ic",""},
74d4aefe62Ssam 	{"tse",strip,2,"","+st",	i_to_y,3,"-y+iest","+est"},
75d4aefe62Ssam 	{"cirtem",i_to_y,1,"-y+ic",""},
76d4aefe62Ssam 	{"yrtem",metry,0,"-ry+er",""},
77d4aefe62Ssam 	{"cigol",i_to_y,1,"-y+ic",""},
78d4aefe62Ssam 	{"tsigol",i_to_y,2,"-y+ist",""},
79d4aefe62Ssam 	{"tsi",VCe,3,"-e+ist","+ist"},
80d4aefe62Ssam 	{"msi",VCe,3,"-e+ism","+ist"},
81d4aefe62Ssam 	{"noitacif",i_to_y,6,"-y+ication",""},
82d4aefe62Ssam 	{"noitazi",ize,5,"-e+ation",""},
83d4aefe62Ssam 	{"rota",tion,2,"-e+or",""},
84d4aefe62Ssam 	{"noit",tion,3,"-e+ion","+ion"},
85d4aefe62Ssam 	{"naino",an,3,"","+ian"},
86d4aefe62Ssam 	{"na",an,1,"","+n"},
87d4aefe62Ssam 	{"evit",tion,3,"-e+ive","+ive"},
88d4aefe62Ssam 	{"ezi",CCe,3,"-e+ize","+ize"},
89d4aefe62Ssam 	{"pihs",strip,4,"","+ship"},
90d4aefe62Ssam 	{"dooh",ily,4,"-y+hood","+hood"},
91d4aefe62Ssam 	{"ekil",strip,4,"","+like"},
92d4aefe62Ssam 	0
93d4aefe62Ssam };
94d4aefe62Ssam 
95d4aefe62Ssam char *preftab[] = {
96d4aefe62Ssam 	"anti",
97d4aefe62Ssam 	"bio",
98d4aefe62Ssam 	"dis",
99d4aefe62Ssam 	"electro",
100d4aefe62Ssam 	"en",
101d4aefe62Ssam 	"fore",
102d4aefe62Ssam 	"hyper",
103d4aefe62Ssam 	"intra",
104d4aefe62Ssam 	"inter",
105d4aefe62Ssam 	"iso",
106d4aefe62Ssam 	"kilo",
107d4aefe62Ssam 	"magneto",
108d4aefe62Ssam 	"meta",
109d4aefe62Ssam 	"micro",
110d4aefe62Ssam 	"milli",
111d4aefe62Ssam 	"mis",
112d4aefe62Ssam 	"mono",
113d4aefe62Ssam 	"multi",
114d4aefe62Ssam 	"non",
115d4aefe62Ssam 	"out",
116d4aefe62Ssam 	"over",
117d4aefe62Ssam 	"photo",
118d4aefe62Ssam 	"poly",
119d4aefe62Ssam 	"pre",
120d4aefe62Ssam 	"pseudo",
121d4aefe62Ssam 	"re",
122d4aefe62Ssam 	"semi",
123d4aefe62Ssam 	"stereo",
124d4aefe62Ssam 	"sub",
125d4aefe62Ssam 	"super",
126d4aefe62Ssam 	"thermo",
127d4aefe62Ssam 	"ultra",
128d4aefe62Ssam 	"under",	/*must precede un*/
129d4aefe62Ssam 	"un",
130d4aefe62Ssam 	0
131d4aefe62Ssam };
132d4aefe62Ssam 
133d4aefe62Ssam int vflag;
134d4aefe62Ssam int xflag;
135d4aefe62Ssam char word[100];
136d4aefe62Ssam char original[100];
137d4aefe62Ssam char *deriv[40];
138d4aefe62Ssam char affix[40];
139d4aefe62Ssam 
main(argc,argv)140d4aefe62Ssam main(argc,argv)
141410275baStorek int argc;
142d4aefe62Ssam char **argv;
143d4aefe62Ssam {
144d4aefe62Ssam 	register char *ep, *cp;
145d4aefe62Ssam 	register char *dp;
146d4aefe62Ssam 	int fold;
147d4aefe62Ssam 	int j;
148d4aefe62Ssam 	FILE *file, *found;
149d4aefe62Ssam 	if(!prime(argc,argv)) {
150d4aefe62Ssam 		fprintf(stderr,
151d4aefe62Ssam 		    "spell: cannot initialize hash table\n");
152d4aefe62Ssam 		exit(1);
153d4aefe62Ssam 	}
154d4aefe62Ssam 	found = fopen(argv[2],"w");
155d4aefe62Ssam 	for(argc-=3,argv+=3; argc>0 && argv[0][0]=='-'; argc--,argv++)
156d4aefe62Ssam 		switch(argv[0][1]) {
157d4aefe62Ssam 		case 'b':
158d4aefe62Ssam 			ise();
159d4aefe62Ssam 			break;
160d4aefe62Ssam 		case 'v':
161d4aefe62Ssam 			vflag++;
162d4aefe62Ssam 			break;
163d4aefe62Ssam 		case 'x':
164d4aefe62Ssam 			xflag++;
165d4aefe62Ssam 			break;
166d4aefe62Ssam 		}
167d4aefe62Ssam 	for(;; fprintf(file,"%s%s\n",affix,original)) {
168d4aefe62Ssam 		affix[0] = 0;
169d4aefe62Ssam 		file = found;
170d4aefe62Ssam 		for(ep=word;(*ep=j=getchar())!='\n';ep++)
1710c77bd29Sbloom 			if(j == EOF) {
1720c77bd29Sbloom 				fclose(found);
173d4aefe62Ssam 				exit(0);
1740c77bd29Sbloom 			}
175d4aefe62Ssam 		for(cp=word,dp=original; cp<ep; )
176d4aefe62Ssam 			*dp++ = *cp++;
177d4aefe62Ssam 		*dp = 0;
178d4aefe62Ssam 		fold = 0;
179d4aefe62Ssam 		for(cp=word;cp<ep;cp++)
180d4aefe62Ssam 			if(islower(*cp))
181d4aefe62Ssam 				goto lcase;
182d4aefe62Ssam 		if(putsuf(ep,".",0))
183d4aefe62Ssam 			continue;
184d4aefe62Ssam 		++fold;
185d4aefe62Ssam 		for(cp=original+1,dp=word+1;dp<ep;dp++,cp++)
186d4aefe62Ssam 			*dp = Tolower(*cp);
187d4aefe62Ssam lcase:
188d4aefe62Ssam 		if(putsuf(ep,".",0)||suffix(ep,0))
189d4aefe62Ssam 			continue;
190d4aefe62Ssam 		if(isupper(word[0])) {
191d4aefe62Ssam 			for(cp=original,dp=word; *dp = *cp++; dp++)
192d4aefe62Ssam 				if (fold) *dp = Tolower(*dp);
193d4aefe62Ssam 			word[0] = Tolower(word[0]);
194d4aefe62Ssam 			goto lcase;
195d4aefe62Ssam 		}
196d4aefe62Ssam 		file = stdout;
197d4aefe62Ssam 	}
198d4aefe62Ssam }
199d4aefe62Ssam 
suffix(ep,lev)200d4aefe62Ssam suffix(ep,lev)
201d4aefe62Ssam char *ep;
202410275baStorek int lev;
203d4aefe62Ssam {
204d4aefe62Ssam 	register struct suftab *t;
205d4aefe62Ssam 	register char *cp, *sp;
206d4aefe62Ssam 	lev += DLEV;
207d4aefe62Ssam 	deriv[lev] = deriv[lev-1] = 0;
208d4aefe62Ssam 	for(t= &suftab[0];sp=t->suf;t++) {
209d4aefe62Ssam 		cp = ep;
210d4aefe62Ssam 		while(*sp)
211d4aefe62Ssam 			if(*--cp!=*sp++)
212d4aefe62Ssam 				goto next;
213d4aefe62Ssam 		for(sp=cp; --sp>=word&&!vowel(*sp); ) ;
214d4aefe62Ssam 		if(sp<word)
215d4aefe62Ssam 			return(0);
216d4aefe62Ssam 		if((*t->p1)(ep-t->n1,t->d1,t->a1,lev+1))
217d4aefe62Ssam 			return(1);
218d4aefe62Ssam 		if(t->p2!=0) {
219d4aefe62Ssam 			deriv[lev] = deriv[lev+1] = 0;
220d4aefe62Ssam 			return((*t->p2)(ep-t->n2,t->d2,t->a2,lev));
221d4aefe62Ssam 		}
222d4aefe62Ssam 		return(0);
223d4aefe62Ssam next:		;
224d4aefe62Ssam 	}
225d4aefe62Ssam 	return(0);
226d4aefe62Ssam }
227d4aefe62Ssam 
nop()228d4aefe62Ssam nop()
229d4aefe62Ssam {
230d4aefe62Ssam 	return(0);
231d4aefe62Ssam }
232d4aefe62Ssam 
strip(ep,d,a,lev)233d4aefe62Ssam strip(ep,d,a,lev)
234d4aefe62Ssam char *ep,*d,*a;
235410275baStorek int lev;
236d4aefe62Ssam {
237d4aefe62Ssam 	return(putsuf(ep,a,lev)||suffix(ep,lev));
238d4aefe62Ssam }
239d4aefe62Ssam 
s(ep,d,a,lev)240d4aefe62Ssam s(ep,d,a,lev)
241d4aefe62Ssam char *ep,*d,*a;
242410275baStorek int lev;
243d4aefe62Ssam {
244d4aefe62Ssam 	if(lev>DLEV+1)
245d4aefe62Ssam 		return(0);
246d4aefe62Ssam 	if(*ep=='s'&&ep[-1]=='s')
247d4aefe62Ssam 		return(0);
248d4aefe62Ssam 	return(strip(ep,d,a,lev));
249d4aefe62Ssam }
250d4aefe62Ssam 
an(ep,d,a,lev)251d4aefe62Ssam an(ep,d,a,lev)
252d4aefe62Ssam char *ep,*d,*a;
253410275baStorek int lev;
254d4aefe62Ssam {
255d4aefe62Ssam 	if(!isupper(*word))	/*must be proper name*/
256d4aefe62Ssam 		return(0);
257d4aefe62Ssam 	return(putsuf(ep,a,lev));
258d4aefe62Ssam }
259d4aefe62Ssam 
ize(ep,d,a,lev)260d4aefe62Ssam ize(ep,d,a,lev)
261d4aefe62Ssam char *ep,*d,*a;
262410275baStorek int lev;
263d4aefe62Ssam {
264d4aefe62Ssam 	*ep++ = 'e';
265d4aefe62Ssam 	return(strip(ep,"",d,lev));
266d4aefe62Ssam }
267d4aefe62Ssam 
y_to_e(ep,d,a,lev)268d4aefe62Ssam y_to_e(ep,d,a,lev)
269d4aefe62Ssam char *ep,*d,*a;
270410275baStorek int lev;
271d4aefe62Ssam {
272ffac4c86Sedward 	char c = *ep;
273d4aefe62Ssam 	*ep++ = 'e';
274ffac4c86Sedward 	if (strip(ep,"",d,lev))
275ffac4c86Sedward 		return (1);
276ffac4c86Sedward 	ep[-1] = c;
277ffac4c86Sedward 	return (0);
278d4aefe62Ssam }
279d4aefe62Ssam 
ily(ep,d,a,lev)280d4aefe62Ssam ily(ep,d,a,lev)
281d4aefe62Ssam char *ep,*d,*a;
282410275baStorek int lev;
283d4aefe62Ssam {
284d4aefe62Ssam 	if(ep[-1]=='i')
285d4aefe62Ssam 		return(i_to_y(ep,d,a,lev));
286d4aefe62Ssam 	else
287d4aefe62Ssam 		return(strip(ep,d,a,lev));
288d4aefe62Ssam }
289d4aefe62Ssam 
ncy(ep,d,a,lev)290d4aefe62Ssam ncy(ep,d,a,lev)
291d4aefe62Ssam char *ep, *d, *a;
292410275baStorek int lev;
293d4aefe62Ssam {
294d4aefe62Ssam 	if(skipv(skipv(ep-1))<word)
295d4aefe62Ssam 		return(0);
296d4aefe62Ssam 	ep[-1] = 't';
297d4aefe62Ssam 	return(strip(ep,d,a,lev));
298d4aefe62Ssam }
299d4aefe62Ssam 
bility(ep,d,a,lev)300d4aefe62Ssam bility(ep,d,a,lev)
301d4aefe62Ssam char *ep,*d,*a;
302410275baStorek int lev;
303d4aefe62Ssam {
304d4aefe62Ssam 	*ep++ = 'l';
305d4aefe62Ssam 	return(y_to_e(ep,d,a,lev));
306d4aefe62Ssam }
307d4aefe62Ssam 
i_to_y(ep,d,a,lev)308d4aefe62Ssam i_to_y(ep,d,a,lev)
309d4aefe62Ssam char *ep,*d,*a;
310410275baStorek int lev;
311d4aefe62Ssam {
312d4aefe62Ssam 	if(ep[-1]=='i') {
313d4aefe62Ssam 		ep[-1] = 'y';
314d4aefe62Ssam 		a = d;
315d4aefe62Ssam 	}
316d4aefe62Ssam 	return(strip(ep,"",a,lev));
317d4aefe62Ssam }
318d4aefe62Ssam 
es(ep,d,a,lev)319d4aefe62Ssam es(ep,d,a,lev)
320d4aefe62Ssam char *ep,*d,*a;
321410275baStorek int lev;
322d4aefe62Ssam {
323d4aefe62Ssam 	if(lev>DLEV)
324d4aefe62Ssam 		return(0);
325d4aefe62Ssam 	switch(ep[-1]) {
326d4aefe62Ssam 	default:
327d4aefe62Ssam 		return(0);
328d4aefe62Ssam 	case 'i':
329d4aefe62Ssam 		return(i_to_y(ep,d,a,lev));
330d4aefe62Ssam 	case 's':
331d4aefe62Ssam 	case 'h':
332d4aefe62Ssam 	case 'z':
333d4aefe62Ssam 	case 'x':
334d4aefe62Ssam 		return(strip(ep,d,a,lev));
335d4aefe62Ssam 	}
336d4aefe62Ssam }
337d4aefe62Ssam 
metry(ep,d,a,lev)338d4aefe62Ssam metry(ep,d,a,lev)
339d4aefe62Ssam char *ep, *d,*a;
340410275baStorek int lev;
341d4aefe62Ssam {
342d4aefe62Ssam 	ep[-2] = 'e';
343d4aefe62Ssam 	ep[-1] = 'r';
344d4aefe62Ssam 	return(strip(ep,d,a,lev));
345d4aefe62Ssam }
346d4aefe62Ssam 
tion(ep,d,a,lev)347d4aefe62Ssam tion(ep,d,a,lev)
348d4aefe62Ssam char *ep,*d,*a;
349410275baStorek int lev;
350d4aefe62Ssam {
351d4aefe62Ssam 	switch(ep[-2]) {
352d4aefe62Ssam 	case 'c':
353d4aefe62Ssam 	case 'r':
354d4aefe62Ssam 		return(putsuf(ep,a,lev));
355d4aefe62Ssam 	case 'a':
356d4aefe62Ssam 		return(y_to_e(ep,d,a,lev));
357d4aefe62Ssam 	}
358d4aefe62Ssam 	return(0);
359d4aefe62Ssam }
360d4aefe62Ssam 
361d4aefe62Ssam /*	possible consonant-consonant-e ending*/
CCe(ep,d,a,lev)362d4aefe62Ssam CCe(ep,d,a,lev)
363d4aefe62Ssam char *ep,*d,*a;
364410275baStorek int lev;
365d4aefe62Ssam {
366d4aefe62Ssam 	switch(ep[-1]) {
367d4aefe62Ssam 	case 'l':
368d4aefe62Ssam 		if(vowel(ep[-2]))
369d4aefe62Ssam 			break;
370d4aefe62Ssam 		switch(ep[-2]) {
371d4aefe62Ssam 		case 'l':
372d4aefe62Ssam 		case 'r':
373d4aefe62Ssam 		case 'w':
374d4aefe62Ssam 			break;
375d4aefe62Ssam 		default:
376d4aefe62Ssam 			return(y_to_e(ep,d,a,lev));
377d4aefe62Ssam 		}
378d4aefe62Ssam 		break;
379d4aefe62Ssam 	case 's':
380d4aefe62Ssam 		if(ep[-2]=='s')
381d4aefe62Ssam 			break;
382d4aefe62Ssam 	case 'c':
383d4aefe62Ssam 	case 'g':
384d4aefe62Ssam 		if(*ep=='a')
385d4aefe62Ssam 			return(0);
386d4aefe62Ssam 	case 'v':
387d4aefe62Ssam 	case 'z':
388d4aefe62Ssam 		if(vowel(ep[-2]))
389d4aefe62Ssam 			break;
390d4aefe62Ssam 	case 'u':
391d4aefe62Ssam 		if(y_to_e(ep,d,a,lev))
392d4aefe62Ssam 			return(1);
393d4aefe62Ssam 		if(!(ep[-2]=='n'&&ep[-1]=='g'))
394d4aefe62Ssam 			return(0);
395d4aefe62Ssam 	}
396d4aefe62Ssam 	return(VCe(ep,d,a,lev));
397d4aefe62Ssam }
398d4aefe62Ssam 
399d4aefe62Ssam /*	possible consonant-vowel-consonant-e ending*/
VCe(ep,d,a,lev)400d4aefe62Ssam VCe(ep,d,a,lev)
401d4aefe62Ssam char *ep,*d,*a;
402410275baStorek int lev;
403d4aefe62Ssam {
404d4aefe62Ssam 	char c;
405d4aefe62Ssam 	c = ep[-1];
406d4aefe62Ssam 	if(c=='e')
407d4aefe62Ssam 		return(0);
408d4aefe62Ssam 	if(!vowel(c) && vowel(ep[-2])) {
409d4aefe62Ssam 		c = *ep;
410d4aefe62Ssam 		*ep++ = 'e';
411d4aefe62Ssam 		if(putsuf(ep,d,lev)||suffix(ep,lev))
412d4aefe62Ssam 			return(1);
413d4aefe62Ssam 		ep--;
414d4aefe62Ssam 		*ep = c;
415d4aefe62Ssam 	}
416d4aefe62Ssam 	return(strip(ep,d,a,lev));
417d4aefe62Ssam }
418d4aefe62Ssam 
lookuppref(wp,ep)419d4aefe62Ssam char *lookuppref(wp,ep)
420d4aefe62Ssam char **wp;
421d4aefe62Ssam char *ep;
422d4aefe62Ssam {
423d4aefe62Ssam 	register char **sp;
424d4aefe62Ssam 	register char *bp,*cp;
425d4aefe62Ssam 	for(sp=preftab;*sp;sp++) {
426d4aefe62Ssam 		bp = *wp;
427d4aefe62Ssam 		for(cp= *sp;*cp;cp++,bp++)
428d4aefe62Ssam 			if(Tolower(*bp)!=*cp)
429d4aefe62Ssam 				goto next;
430d4aefe62Ssam 		for(cp=bp;cp<ep;cp++)
431d4aefe62Ssam 			if(vowel(*cp)) {
432d4aefe62Ssam 				*wp = bp;
433d4aefe62Ssam 				return(*sp);
434d4aefe62Ssam 			}
435d4aefe62Ssam next:	;
436d4aefe62Ssam 	}
437d4aefe62Ssam 	return(0);
438d4aefe62Ssam }
439d4aefe62Ssam 
putsuf(ep,a,lev)440d4aefe62Ssam putsuf(ep,a,lev)
441d4aefe62Ssam char *ep,*a;
442410275baStorek int lev;
443d4aefe62Ssam {
444d4aefe62Ssam 	register char *cp;
445d4aefe62Ssam 	char *bp;
446d4aefe62Ssam 	register char *pp;
447d4aefe62Ssam 	int val = 0;
448d4aefe62Ssam 	char space[20];
449d4aefe62Ssam 	deriv[lev] = a;
450410275baStorek 	if(putword(word,ep,lev))
451d4aefe62Ssam 		return(1);
452d4aefe62Ssam 	bp = word;
453d4aefe62Ssam 	pp = space;
454d4aefe62Ssam 	deriv[lev+1] = pp;
455d4aefe62Ssam 	while(cp=lookuppref(&bp,ep)) {
456d4aefe62Ssam 		*pp++ = '+';
457d4aefe62Ssam 		while(*pp = *cp++)
458d4aefe62Ssam 			pp++;
459410275baStorek 		if(putword(bp,ep,lev+1)) {
460d4aefe62Ssam 			val = 1;
461d4aefe62Ssam 			break;
462d4aefe62Ssam 		}
463d4aefe62Ssam 	}
464d4aefe62Ssam 	deriv[lev+1] = deriv[lev+2] = 0;
465d4aefe62Ssam 	return(val);
466d4aefe62Ssam }
467d4aefe62Ssam 
putword(bp,ep,lev)468410275baStorek putword(bp,ep,lev)
469d4aefe62Ssam char *bp,*ep;
470410275baStorek int lev;
471d4aefe62Ssam {
472d4aefe62Ssam 	register i, j;
473d4aefe62Ssam 	char duple[3];
474d4aefe62Ssam 	if(ep-bp<=1)
475d4aefe62Ssam 		return(0);
476d4aefe62Ssam 	if(vowel(*ep)) {
477d4aefe62Ssam 		if(monosyl(bp,ep))
478d4aefe62Ssam 			return(0);
479d4aefe62Ssam 	}
480d4aefe62Ssam 	i = dict(bp,ep);
481d4aefe62Ssam 	if(i==0&&vowel(*ep)&&ep[-1]==ep[-2]&&monosyl(bp,ep-1)) {
482d4aefe62Ssam 		ep--;
483d4aefe62Ssam 		deriv[++lev] = duple;
484d4aefe62Ssam 		duple[0] = '+';
485d4aefe62Ssam 		duple[1] = *ep;
486d4aefe62Ssam 		duple[2] = 0;
487d4aefe62Ssam 		i = dict(bp,ep);
488d4aefe62Ssam 	}
489d4aefe62Ssam 	if(vflag==0||i==0)
490d4aefe62Ssam 		return(i);
491d4aefe62Ssam 	j = lev;
492d4aefe62Ssam 	do {
493d4aefe62Ssam 		if(deriv[j])
494d4aefe62Ssam 			strcat(affix,deriv[j]);
495d4aefe62Ssam 	} while(--j>0);
496d4aefe62Ssam 	strcat(affix,"\t");
497d4aefe62Ssam 	return(i);
498d4aefe62Ssam }
499d4aefe62Ssam 
500d4aefe62Ssam 
monosyl(bp,ep)501d4aefe62Ssam monosyl(bp,ep)
502d4aefe62Ssam char *bp, *ep;
503d4aefe62Ssam {
504d4aefe62Ssam 	if(ep<bp+2)
505d4aefe62Ssam 		return(0);
506d4aefe62Ssam 	if(vowel(*--ep)||!vowel(*--ep)
507d4aefe62Ssam 		||ep[1]=='x'||ep[1]=='w')
508d4aefe62Ssam 		return(0);
509d4aefe62Ssam 	while(--ep>=bp)
510d4aefe62Ssam 		if(vowel(*ep))
511d4aefe62Ssam 			return(0);
512d4aefe62Ssam 	return(1);
513d4aefe62Ssam }
514d4aefe62Ssam 
515d4aefe62Ssam char *
skipv(s)516d4aefe62Ssam skipv(s)
517d4aefe62Ssam char *s;
518d4aefe62Ssam {
519d4aefe62Ssam 	if(s>=word&&vowel(*s))
520d4aefe62Ssam 		s--;
521d4aefe62Ssam 	while(s>=word&&!vowel(*s))
522d4aefe62Ssam 		s--;
523d4aefe62Ssam 	return(s);
524d4aefe62Ssam }
525d4aefe62Ssam 
vowel(c)526d4aefe62Ssam vowel(c)
527410275baStorek int c;
528d4aefe62Ssam {
529d4aefe62Ssam 	switch(Tolower(c)) {
530d4aefe62Ssam 	case 'a':
531d4aefe62Ssam 	case 'e':
532d4aefe62Ssam 	case 'i':
533d4aefe62Ssam 	case 'o':
534d4aefe62Ssam 	case 'u':
535d4aefe62Ssam 	case 'y':
536d4aefe62Ssam 		return(1);
537d4aefe62Ssam 	}
538d4aefe62Ssam 	return(0);
539d4aefe62Ssam }
540d4aefe62Ssam 
541d4aefe62Ssam /* crummy way to Britishise */
ise()542d4aefe62Ssam ise()
543d4aefe62Ssam {
544d4aefe62Ssam 	register struct suftab *p;
545d4aefe62Ssam 	for(p = suftab;p->suf;p++) {
546d4aefe62Ssam 		ztos(p->suf);
547d4aefe62Ssam 		ztos(p->d1);
548d4aefe62Ssam 		ztos(p->a1);
549d4aefe62Ssam 	}
550d4aefe62Ssam }
ztos(s)551d4aefe62Ssam ztos(s)
552d4aefe62Ssam char *s;
553d4aefe62Ssam {
554d4aefe62Ssam 	for(;*s;s++)
555d4aefe62Ssam 		if(*s=='z')
556d4aefe62Ssam 			*s = 's';
557d4aefe62Ssam }
558d4aefe62Ssam 
dict(bp,ep)559d4aefe62Ssam dict(bp,ep)
560d4aefe62Ssam char *bp, *ep;
561d4aefe62Ssam {
562d4aefe62Ssam 	register char *wp;
563d4aefe62Ssam 	long h;
564d4aefe62Ssam 	register long *lp;
565d4aefe62Ssam 	register i;
566d4aefe62Ssam 	if(xflag)
567d4aefe62Ssam 		printf("=%.*s\n",ep-bp,bp);
568d4aefe62Ssam 	for(i=0; i<NP; i++) {
569d4aefe62Ssam 		for (wp = bp, h = 0, lp = pow2[i]; wp < ep; ++wp, ++lp)
570d4aefe62Ssam 			h += *wp * *lp;
571d4aefe62Ssam 		h += '\n' * *lp;
572d4aefe62Ssam 		h %= p[i];
573d4aefe62Ssam 		if(get(h)==0)
574d4aefe62Ssam 			return(0);
575d4aefe62Ssam 	}
576d4aefe62Ssam 	return(1);
577d4aefe62Ssam }
578