Print this page
3727 british people can't spell
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/spell/spellprog.c
+++ new/usr/src/cmd/spell/spellprog.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License, Version 1.0 only
6 6 * (the "License"). You may not use this file except in compliance
7 7 * with the License.
8 8 *
9 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 * or http://www.opensolaris.org/os/licensing.
11 11 * See the License for the specific language governing permissions
12 12 * and limitations under the License.
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
13 13 *
14 14 * When distributing Covered Code, include this CDDL HEADER in each
15 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 * If applicable, add the following below this CDDL HEADER, with the
17 17 * fields enclosed by brackets "[]" replaced with your own identifying
18 18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 19 *
20 20 * CDDL HEADER END
21 21 */
22 22 /*
23 + * Copyright 2015 Gary Mills
23 24 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 25 * Use is subject to license terms.
25 26 */
26 27
27 28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 29 /* All Rights Reserved */
29 30
30 -#pragma ident "%Z%%M% %I% %E% SMI"
31 -
32 31 #include <stdlib.h>
33 32 #include <unistd.h>
34 33 #include <limits.h>
35 34 #include <string.h>
36 35 #include <stdio.h>
37 36 #include <ctype.h>
38 37 #include <locale.h>
39 38 #include "hash.h"
40 39
41 40 #define Tolower(c) (isupper(c)?tolower(c):c)
42 41 #define DLEV 2
43 42
44 43 /*
45 44 * ANSI prototypes
46 45 */
47 46 static int ily(char *, char *, char *, int);
48 47 static int s(char *, char *, char *, int);
49 48 static int es(char *, char *, char *, int);
50 49 static int subst(char *, char *, char *, int);
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
51 50 static int nop(void);
52 51 static int bility(char *, char *, char *, int);
53 52 static int i_to_y(char *, char *, char *, int);
54 53 static int CCe(char *, char *, char *, int);
55 54 static int y_to_e(char *, char *, char *, int);
56 55 static int strip(char *, char *, char *, int);
57 56 static int ize(char *, char *, char *, int);
58 57 static int tion(char *, char *, char *, int);
59 58 static int an(char *, char *, char *, int);
60 59 int prime(char *);
61 -static void ise(void);
62 60 static int tryword(char *, char *, int);
63 61 static int trypref(char *, char *, int);
64 62 static int trysuff(char *, int);
65 63 static int vowel(int);
66 64 static int dict(char *, char *);
67 65 static int monosyl(char *, char *);
68 66 static int VCe(char *, char *, char *, int);
69 67 static char *skipv(char *);
70 -static void ztos(char *);
71 68
72 -static struct suftab {
69 +struct suftab {
73 70 char *suf;
74 71 int (*p1)();
75 72 int n1;
76 73 char *d1;
77 74 char *a1;
78 75 int (*p2)();
79 76 int n2;
80 77 char *d2;
81 78 char *a2;
82 -} suftab[] = {
79 +};
80 +
81 +static struct suftab sufa[] = {
83 82 {"ssen", ily, 4, "-y+iness", "+ness" },
84 83 {"ssel", ily, 4, "-y+i+less", "+less" },
85 84 {"se", s, 1, "", "+s", es, 2, "-y+ies", "+es" },
86 85 {"s'", s, 2, "", "+'s"},
87 86 {"s", s, 1, "", "+s"},
88 87 {"ecn", subst, 1, "-t+ce", ""},
89 88 {"ycn", subst, 1, "-t+cy", ""},
90 89 {"ytilb", nop, 0, "", ""},
91 90 {"ytilib", bility, 5, "-le+ility", ""},
92 91 {"elbaif", i_to_y, 4, "-y+iable", ""},
93 92 {"elba", CCe, 4, "-e+able", "+able"},
94 93 {"yti", CCe, 3, "-e+ity", "+ity"},
95 94 {"ylb", y_to_e, 1, "-e+y", ""},
96 95 {"yl", ily, 2, "-y+ily", "+ly"},
97 96 {"laci", strip, 2, "", "+al"},
98 97 {"latnem", strip, 2, "", "+al"},
99 98 {"lanoi", strip, 2, "", "+al"},
100 99 {"tnem", strip, 4, "", "+ment"},
101 100 {"gni", CCe, 3, "-e+ing", "+ing"},
102 101 {"reta", nop, 0, "", ""},
103 102 {"retc", nop, 0, "", ""},
104 103 {"re", strip, 1, "", "+r", i_to_y, 2, "-y+ier", "+er"},
105 104 {"de", strip, 1, "", "+d", i_to_y, 2, "-y+ied", "+ed"},
106 105 {"citsi", strip, 2, "", "+ic"},
107 106 {"citi", ize, 1, "-ic+e", ""},
108 107 {"cihparg", i_to_y, 1, "-y+ic", ""},
109 108 {"tse", strip, 2, "", "+st", i_to_y, 3, "-y+iest", "+est"},
110 109 {"cirtem", i_to_y, 1, "-y+ic", ""},
111 110 {"yrtem", subst, 0, "-er+ry", ""},
112 111 {"cigol", i_to_y, 1, "-y+ic", ""},
113 112 {"tsigol", i_to_y, 2, "-y+ist", ""},
114 113 {"tsi", CCe, 3, "-e+ist", "+ist"},
115 114 {"msi", CCe, 3, "-e+ism", "+ist"},
116 115 {"noitacifi", i_to_y, 6, "-y+ication", ""},
117 116 {"noitazi", ize, 4, "-e+ation", ""},
118 117 {"rota", tion, 2, "-e+or", ""},
119 118 {"rotc", tion, 2, "", "+or"},
120 119 {"noit", tion, 3, "-e+ion", "+ion"},
121 120 {"naino", an, 3, "", "+ian"},
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
122 121 {"na", an, 1, "", "+n"},
123 122 {"evi", subst, 0, "-ion+ive", ""},
124 123 {"ezi", CCe, 3, "-e+ize", "+ize"},
125 124 {"pihs", strip, 4, "", "+ship"},
126 125 {"dooh", ily, 4, "-y+ihood", "+hood"},
127 126 {"luf", ily, 3, "-y+iful", "+ful"},
128 127 {"ekil", strip, 4, "", "+like"},
129 128 0
130 129 };
131 130
131 +static struct suftab sufb[] = {
132 + {"ssen", ily, 4, "-y+iness", "+ness" },
133 + {"ssel", ily, 4, "-y+i+less", "+less" },
134 + {"se", s, 1, "", "+s", es, 2, "-y+ies", "+es" },
135 + {"s'", s, 2, "", "+'s"},
136 + {"s", s, 1, "", "+s"},
137 + {"ecn", subst, 1, "-t+ce", ""},
138 + {"ycn", subst, 1, "-t+cy", ""},
139 + {"ytilb", nop, 0, "", ""},
140 + {"ytilib", bility, 5, "-le+ility", ""},
141 + {"elbaif", i_to_y, 4, "-y+iable", ""},
142 + {"elba", CCe, 4, "-e+able", "+able"},
143 + {"yti", CCe, 3, "-e+ity", "+ity"},
144 + {"ylb", y_to_e, 1, "-e+y", ""},
145 + {"yl", ily, 2, "-y+ily", "+ly"},
146 + {"laci", strip, 2, "", "+al"},
147 + {"latnem", strip, 2, "", "+al"},
148 + {"lanoi", strip, 2, "", "+al"},
149 + {"tnem", strip, 4, "", "+ment"},
150 + {"gni", CCe, 3, "-e+ing", "+ing"},
151 + {"reta", nop, 0, "", ""},
152 + {"retc", nop, 0, "", ""},
153 + {"re", strip, 1, "", "+r", i_to_y, 2, "-y+ier", "+er"},
154 + {"de", strip, 1, "", "+d", i_to_y, 2, "-y+ied", "+ed"},
155 + {"citsi", strip, 2, "", "+ic"},
156 + {"citi", ize, 1, "-ic+e", ""},
157 + {"cihparg", i_to_y, 1, "-y+ic", ""},
158 + {"tse", strip, 2, "", "+st", i_to_y, 3, "-y+iest", "+est"},
159 + {"cirtem", i_to_y, 1, "-y+ic", ""},
160 + {"yrtem", subst, 0, "-er+ry", ""},
161 + {"cigol", i_to_y, 1, "-y+ic", ""},
162 + {"tsigol", i_to_y, 2, "-y+ist", ""},
163 + {"tsi", CCe, 3, "-e+ist", "+ist"},
164 + {"msi", CCe, 3, "-e+ism", "+ist"},
165 + {"noitacifi", i_to_y, 6, "-y+ication", ""},
166 + {"noitasi", ize, 4, "-e+ation", ""},
167 + {"rota", tion, 2, "-e+or", ""},
168 + {"rotc", tion, 2, "", "+or"},
169 + {"noit", tion, 3, "-e+ion", "+ion"},
170 + {"naino", an, 3, "", "+ian"},
171 + {"na", an, 1, "", "+n"},
172 + {"evi", subst, 0, "-ion+ive", ""},
173 + {"esi", CCe, 3, "-e+ise", "+ise"},
174 + {"pihs", strip, 4, "", "+ship"},
175 + {"dooh", ily, 4, "-y+ihood", "+hood"},
176 + {"luf", ily, 3, "-y+iful", "+ful"},
177 + {"ekil", strip, 4, "", "+like"},
178 + 0
179 +};
180 +
132 181 static char *preftab[] = {
133 182 "anti",
134 183 "auto",
135 184 "bio",
136 185 "counter",
137 186 "dis",
138 187 "electro",
139 188 "en",
140 189 "fore",
141 190 "geo",
142 191 "hyper",
143 192 "intra",
144 193 "inter",
145 194 "iso",
146 195 "kilo",
147 196 "magneto",
148 197 "meta",
149 198 "micro",
150 199 "mid",
151 200 "milli",
152 201 "mis",
153 202 "mono",
154 203 "multi",
155 204 "non",
156 205 "out",
157 206 "over",
158 207 "photo",
159 208 "poly",
160 209 "pre",
161 210 "pseudo",
162 211 "psycho",
163 212 "re",
164 213 "semi",
165 214 "stereo",
↓ open down ↓ |
24 lines elided |
↑ open up ↑ |
166 215 "sub",
167 216 "super",
168 217 "tele",
169 218 "thermo",
170 219 "ultra",
171 220 "under", /* must precede un */
172 221 "un",
173 222 0
174 223 };
175 224
225 +static int bflag;
176 226 static int vflag;
177 227 static int xflag;
228 +static struct suftab *suftab;
178 229 static char *prog;
179 230 static char word[LINE_MAX];
180 231 static char original[LINE_MAX];
181 232 static char *deriv[LINE_MAX];
182 233 static char affix[LINE_MAX];
183 234 static FILE *file, *found;
184 235 /*
185 236 * deriv is stack of pointers to notes like +micro +ed
186 237 * affix is concatenated string of notes
187 238 * the buffer size 141 stems from the sizes of original and affix.
188 239 */
189 240
190 241 /*
191 242 * in an attempt to defray future maintenance misunderstandings, here is
192 243 * an attempt to describe the input/output expectations of the spell
193 244 * program.
194 245 *
195 246 * spellprog is intended to be called from the shell file spell.
196 247 * because of this, there is little error checking (this is historical, not
197 248 * necessarily advisable).
198 249 *
199 250 * spellprog options hashed-list pass
200 251 *
201 252 * the hashed-list is a list of the form made by spellin.
202 253 * there are 2 types of hashed lists:
203 254 * 1. a stop list: this specifies words that by the rules embodied
204 255 * in spellprog would be recognized as correct, BUT are really
205 256 * errors.
206 257 * 2. a dictionary of correctly spelled words.
207 258 * the pass number determines how the words found in the specified
208 259 * hashed-list are treated. If the pass number is 1, the hashed-list is
209 260 * treated as the stop-list, otherwise, it is treated as the regular
210 261 * dictionary list. in this case, the value of "pass" is a filename. Found
211 262 * words are written to this file.
212 263 *
213 264 * In the normal case, the filename = /dev/null. However, if the v option
214 265 * is specified, the derivations are written to this file.
215 266 * The spellprog looks up words in the hashed-list; if a word is found, it
216 267 * is printed to the stdout. If the hashed-list was the stop-list, the
217 268 * words found are presumed to be misspellings. in this case,
218 269 * a control character is printed ( a "-" is appended to the word.
219 270 * a hyphen will never occur naturally in the input list because deroff
220 271 * is used in the shell file before calling spellprog.)
221 272 * If the regualar spelling list was used (hlista or hlistb), the words
222 273 * are correct, and may be ditched. (unless the -v option was used -
223 274 * see the manual page).
224 275 *
225 276 * spellprog should be called twice : first with the stop-list, to flag all
226 277 * a priori incorrectly spelled words; second with the dictionary.
227 278 *
228 279 * spellprog hstop 1 |\
229 280 * spellprog hlista /dev/null
230 281 *
231 282 * for a complete scenario, see the shell file: spell.
232 283 *
233 284 */
234 285
235 286 int
236 287 main(int argc, char **argv)
237 288 {
238 289 char *ep, *cp;
239 290 char *dp;
240 291 int fold;
241 292 int c, j;
242 293 int pass;
243 294
244 295 /* Set locale environment variables local definitions */
245 296 (void) setlocale(LC_ALL, "");
↓ open down ↓ |
58 lines elided |
↑ open up ↑ |
246 297 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
247 298 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */
248 299 #endif
249 300 (void) textdomain(TEXT_DOMAIN);
250 301
251 302
252 303 prog = argv[0];
253 304 while ((c = getopt(argc, argv, "bvx")) != EOF) {
254 305 switch (c) {
255 306 case 'b':
256 - ise();
307 + bflag++;
257 308 break;
258 309 case 'v':
259 310 vflag++;
260 311 break;
261 312 case 'x':
262 313 xflag++;
263 314 break;
264 315 }
265 316 }
266 317
267 318 argc -= optind;
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
268 319 argv = &argv[optind];
269 320
270 321 if ((argc < 2) || !prime(*argv)) {
271 322 (void) fprintf(stderr,
272 323 gettext("%s: cannot initialize hash table\n"), prog);
273 324 exit(1);
274 325 }
275 326 argc--;
276 327 argv++;
277 328
329 + /* Select the correct suffix table */
330 + suftab = (bflag == 0) ? sufa : sufb;
331 +
278 332 /*
279 333 * if pass is not 1, it is assumed to be a filename.
280 334 * found words are written to this file.
281 335 */
282 336 pass = **argv;
283 337 if (pass != '1')
284 338 found = fopen(*argv, "w");
285 339
286 340 for (;;) {
287 341 affix[0] = 0;
288 342 file = stdout;
289 343 for (ep = word; (*ep = j = getchar()) != '\n'; ep++)
290 344 if (j == EOF)
291 345 exit(0);
292 346 /*
293 347 * here is the hyphen processing. these words were found in the stop
294 348 * list. however, if they exist as is, (no derivations tried) in the
295 349 * dictionary, let them through as correct.
296 350 *
297 351 */
298 352 if (ep[-1] == '-') {
299 353 *--ep = 0;
300 354 if (!tryword(word, ep, 0))
301 355 (void) fprintf(file, "%s\n", word);
302 356 continue;
303 357 }
304 358 for (cp = word, dp = original; cp < ep; )
305 359 *dp++ = *cp++;
306 360 *dp = 0;
307 361 fold = 0;
308 362 for (cp = word; cp < ep; cp++)
309 363 if (islower(*cp))
310 364 goto lcase;
311 365 if (((ep - word) == 1) &&
312 366 ((word[0] == 'A') || (word[0] == 'I')))
313 367 continue;
314 368 if (trypref(ep, ".", 0))
315 369 goto foundit;
316 370 ++fold;
317 371 for (cp = original+1, dp = word+1; dp < ep; dp++, cp++)
318 372 *dp = Tolower(*cp);
319 373 lcase:
320 374 if (((ep - word) == 1) && (word[0] == 'a'))
321 375 continue;
322 376 if (trypref(ep, ".", 0)||trysuff(ep, 0))
323 377 goto foundit;
324 378 if (isupper(word[0])) {
325 379 for (cp = original, dp = word; *dp = *cp++; dp++)
326 380 if (fold) *dp = Tolower(*dp);
327 381 word[0] = Tolower(word[0]);
328 382 goto lcase;
329 383 }
330 384 (void) fprintf(file, "%s\n", original);
331 385 continue;
332 386
333 387 foundit:
334 388 if (pass == '1')
335 389 (void) fprintf(file, "%s-\n", original);
336 390 else if (affix[0] != 0 && affix[0] != '.') {
337 391 file = found;
338 392 (void) fprintf(file, "%s\t%s\n", affix,
339 393 original);
340 394 }
341 395 }
342 396 }
343 397
344 398 /*
345 399 * strip exactly one suffix and do
346 400 * indicated routine(s), which may recursively
347 401 * strip suffixes
↓ open down ↓ |
60 lines elided |
↑ open up ↑ |
348 402 */
349 403
350 404 static int
351 405 trysuff(char *ep, int lev)
352 406 {
353 407 struct suftab *t;
354 408 char *cp, *sp;
355 409
356 410 lev += DLEV;
357 411 deriv[lev] = deriv[lev-1] = 0;
358 - for (t = &suftab[0]; (sp = t->suf) != 0; t++) {
412 + for (t = &suftab[0]; (t != 0 && (sp = t->suf) != 0); t++) {
359 413 cp = ep;
360 414 while (*sp)
361 415 if (*--cp != *sp++)
362 416 goto next;
363 - for (sp = cp; --sp >= word && !vowel(*sp); );
417 + for (sp = cp; --sp >= word && !vowel(*sp); )
418 + ;
364 419 if (sp < word)
365 420 return (0);
366 421 if ((*t->p1)(ep-t->n1, t->d1, t->a1, lev+1))
367 422 return (1);
368 423 if (t->p2 != 0) {
369 424 deriv[lev] = deriv[lev+1] = 0;
370 425 return ((*t->p2)(ep-t->n2, t->d2, t->a2, lev));
371 426 }
372 427 return (0);
373 428 next:;
374 429 }
375 430 return (0);
376 431 }
377 432
378 433 static int
379 434 nop(void)
380 435 {
381 436 return (0);
382 437 }
383 438
384 439 /* ARGSUSED */
385 440 static int
386 441 strip(char *ep, char *d, char *a, int lev)
387 442 {
388 443 return (trypref(ep, a, lev)||trysuff(ep, lev));
389 444 }
390 445
391 446 static int
392 447 s(char *ep, char *d, char *a, int lev)
393 448 {
394 449 if (lev > DLEV+1)
395 450 return (0);
396 451 if (*ep == 's' && ep[-1] == 's')
397 452 return (0);
398 453 return (strip(ep, d, a, lev));
399 454 }
400 455
401 456 /* ARGSUSED */
402 457 static int
403 458 an(char *ep, char *d, char *a, int lev)
404 459 {
405 460 if (!isupper(*word)) /* must be proper name */
406 461 return (0);
407 462 return (trypref(ep, a, lev));
408 463 }
409 464
410 465 /* ARGSUSED */
411 466 static int
412 467 ize(char *ep, char *d, char *a, int lev)
413 468 {
414 469 ep[-1] = 'e';
415 470 return (strip(ep, "", d, lev));
416 471 }
417 472
418 473 /* ARGSUSED */
419 474 static int
420 475 y_to_e(char *ep, char *d, char *a, int lev)
421 476 {
422 477 *ep++ = 'e';
423 478 return (strip(ep, "", d, lev));
424 479 }
425 480
426 481 static int
427 482 ily(char *ep, char *d, char *a, int lev)
428 483 {
429 484 if (ep[-1] == 'i')
430 485 return (i_to_y(ep, d, a, lev));
431 486 else
432 487 return (strip(ep, d, a, lev));
433 488 }
434 489
435 490 static int
436 491 bility(char *ep, char *d, char *a, int lev)
437 492 {
438 493 *ep++ = 'l';
439 494 return (y_to_e(ep, d, a, lev));
440 495 }
441 496
442 497 static int
443 498 i_to_y(char *ep, char *d, char *a, int lev)
444 499 {
445 500 if (ep[-1] == 'i') {
446 501 ep[-1] = 'y';
447 502 a = d;
448 503 }
449 504 return (strip(ep, "", a, lev));
450 505 }
451 506
452 507 static int
453 508 es(char *ep, char *d, char *a, int lev)
454 509 {
455 510 if (lev > DLEV)
456 511 return (0);
457 512 switch (ep[-1]) {
458 513 default:
459 514 return (0);
460 515 case 'i':
461 516 return (i_to_y(ep, d, a, lev));
462 517 case 's':
463 518 case 'h':
464 519 case 'z':
465 520 case 'x':
466 521 return (strip(ep, d, a, lev));
467 522 }
468 523 }
469 524
470 525 /* ARGSUSED */
471 526 static int
472 527 subst(char *ep, char *d, char *a, int lev)
473 528 {
474 529 char *u, *t;
475 530
476 531 if (skipv(skipv(ep-1)) < word)
477 532 return (0);
478 533 for (t = d; *t != '+'; t++)
479 534 continue;
480 535 for (u = ep; *--t != '-'; )
481 536 *--u = *t;
482 537 return (strip(ep, "", d, lev));
483 538 }
484 539
485 540
486 541 static int
487 542 tion(char *ep, char *d, char *a, int lev)
488 543 {
489 544 switch (ep[-2]) {
490 545 case 'c':
491 546 case 'r':
492 547 return (trypref(ep, a, lev));
493 548 case 'a':
494 549 return (y_to_e(ep, d, a, lev));
495 550 }
496 551 return (0);
497 552 }
498 553
499 554 /* possible consonant-consonant-e ending */
500 555 static int
501 556 CCe(char *ep, char *d, char *a, int lev)
502 557 {
503 558 switch (ep[-1]) {
504 559 case 'r':
505 560 if (ep[-2] == 't')
506 561 return (y_to_e(ep, d, a, lev));
507 562 break;
508 563 case 'l':
509 564 if (vowel(ep[-2]))
510 565 break;
511 566 switch (ep[-2]) {
512 567 case 'l':
513 568 case 'r':
514 569 case 'w':
515 570 break;
516 571 default:
517 572 return (y_to_e(ep, d, a, lev));
518 573 }
519 574 break;
520 575 case 's':
521 576 if (ep[-2] == 's')
522 577 break;
523 578 if (*ep == 'a')
524 579 return (0);
525 580 if (vowel(ep[-2]))
526 581 break;
527 582 if (y_to_e(ep, d, a, lev))
528 583 return (1);
529 584 if (!(ep[-2] == 'n' && ep[-1] == 'g'))
530 585 return (0);
531 586 break;
532 587 case 'c':
533 588 case 'g':
534 589 if (*ep == 'a')
535 590 return (0);
536 591 if (vowel(ep[-2]))
537 592 break;
538 593 if (y_to_e(ep, d, a, lev))
539 594 return (1);
540 595 if (!(ep[-2] == 'n' && ep[-1] == 'g'))
541 596 return (0);
542 597 break;
543 598 case 'v':
544 599 case 'z':
545 600 if (vowel(ep[-2]))
546 601 break;
547 602 if (y_to_e(ep, d, a, lev))
548 603 return (1);
549 604 if (!(ep[-2] == 'n' && ep[-1] == 'g'))
550 605 return (0);
551 606 break;
552 607 case 'u':
553 608 if (y_to_e(ep, d, a, lev))
554 609 return (1);
555 610 if (!(ep[-2] == 'n' && ep[-1] == 'g'))
556 611 return (0);
557 612 break;
558 613 }
559 614 return (VCe(ep, d, a, lev));
560 615 }
561 616
562 617 /* possible consonant-vowel-consonant-e ending */
563 618 static int
564 619 VCe(char *ep, char *d, char *a, int lev)
565 620 {
566 621 char c;
567 622 c = ep[-1];
568 623 if (c == 'e')
569 624 return (0);
570 625 if (!vowel(c) && vowel(ep[-2])) {
571 626 c = *ep;
572 627 *ep++ = 'e';
573 628 if (trypref(ep, d, lev)||trysuff(ep, lev))
574 629 return (1);
575 630 ep--;
576 631 *ep = c;
577 632 }
578 633 return (strip(ep, d, a, lev));
579 634 }
580 635
581 636 static char *
582 637 lookuppref(char **wp, char *ep)
583 638 {
584 639 char **sp;
585 640 char *bp, *cp;
586 641
587 642 for (sp = preftab; *sp; sp++) {
588 643 bp = *wp;
589 644 for (cp = *sp; *cp; cp++, bp++)
590 645 if (Tolower(*bp) != *cp)
591 646 goto next;
592 647 for (cp = bp; cp < ep; cp++)
593 648 if (vowel(*cp)) {
594 649 *wp = bp;
595 650 return (*sp);
596 651 }
597 652 next:;
598 653 }
599 654 return (0);
600 655 }
601 656
602 657 /*
603 658 * while word is not in dictionary try stripping
604 659 * prefixes. Fail if no more prefixes.
605 660 */
606 661 static int
607 662 trypref(char *ep, char *a, int lev)
608 663 {
609 664 char *cp;
610 665 char *bp;
611 666 char *pp;
612 667 int val = 0;
613 668 char space[LINE_MAX * 2];
614 669 deriv[lev] = a;
615 670 if (tryword(word, ep, lev))
616 671 return (1);
617 672 bp = word;
618 673 pp = space;
619 674 deriv[lev+1] = pp;
620 675 while (cp = lookuppref(&bp, ep)) {
621 676 *pp++ = '+';
622 677 while (*pp = *cp++)
623 678 pp++;
624 679 if (tryword(bp, ep, lev+1)) {
625 680 val = 1;
626 681 break;
627 682 }
628 683 }
629 684 deriv[lev+1] = deriv[lev+2] = 0;
630 685 return (val);
631 686 }
632 687
633 688 static int
634 689 tryword(char *bp, char *ep, int lev)
635 690 {
636 691 int i, j;
637 692 char duple[3];
638 693 if (ep-bp <= 1)
639 694 return (0);
640 695 if (vowel(*ep)) {
641 696 if (monosyl(bp, ep))
642 697 return (0);
643 698 }
644 699 i = dict(bp, ep);
645 700 if (i == 0 && vowel(*ep) && ep[-1] == ep[-2] && monosyl(bp, ep-1)) {
646 701 ep--;
647 702 deriv[++lev] = duple;
648 703 duple[0] = '+';
649 704 duple[1] = *ep;
650 705 duple[2] = 0;
651 706 i = dict(bp, ep);
652 707 }
653 708 if (vflag == 0 || i == 0)
654 709 return (i);
655 710 /*
656 711 * when derivations are wanted, collect them
657 712 * for printing
658 713 */
659 714 j = lev;
660 715 do {
661 716 if (deriv[j])
662 717 (void) strcat(affix, deriv[j]);
663 718 } while (--j > 0);
664 719 return (i);
665 720 }
666 721
667 722
668 723 static int
669 724 monosyl(char *bp, char *ep)
670 725 {
671 726 if (ep < bp+2)
672 727 return (0);
673 728 if (vowel(*--ep) || !vowel(*--ep) || ep[1] == 'x' || ep[1] == 'w')
674 729 return (0);
675 730 while (--ep >= bp)
676 731 if (vowel(*ep))
677 732 return (0);
678 733 return (1);
679 734 }
680 735
681 736 static char *
682 737 skipv(char *s)
683 738 {
684 739 if (s >= word&&vowel(*s))
685 740 s--;
686 741 while (s >= word && !vowel(*s))
687 742 s--;
688 743 return (s);
689 744 }
690 745
691 746 static int
692 747 vowel(int c)
693 748 {
694 749 switch (Tolower(c)) {
695 750 case 'a':
↓ open down ↓ |
322 lines elided |
↑ open up ↑ |
696 751 case 'e':
697 752 case 'i':
698 753 case 'o':
699 754 case 'u':
700 755 case 'y':
701 756 return (1);
702 757 }
703 758 return (0);
704 759 }
705 760
706 -/* crummy way to Britishise */
707 -static void
708 -ise(void)
709 -{
710 - struct suftab *p;
711 -
712 - for (p = suftab; p->suf; p++) {
713 - ztos(p->suf);
714 - ztos(p->d1);
715 - ztos(p->a1);
716 - }
717 -}
718 -
719 -static void
720 -ztos(char *s)
721 -{
722 - for (; *s; s++)
723 - if (*s == 'z')
724 - *s = 's';
725 -}
726 -
727 761 static int
728 762 dict(char *bp, char *ep)
729 763 {
730 764 int temp, result;
731 765 if (xflag)
732 766 (void) fprintf(stdout, "=%.*s\n", ep-bp, bp);
733 767 temp = *ep;
734 768 *ep = 0;
735 769 result = hashlook(bp);
736 770 *ep = temp;
737 771 return (result);
738 772 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX