|
|
1.1 ! root 1: /* @(#)spellprog.c 1.1 */ ! 2: #include <stdio.h> ! 3: #include <ctype.h> ! 4: #define Tolower(c) (isupper(c)?tolower(c):c) ! 5: #define pair(a,b) (((a)<<8)|(b)) ! 6: #define DLEV 2 ! 7: ! 8: char *strcat(); ! 9: int strip(); ! 10: int cstrip(); ! 11: int subst(); ! 12: char *skipv(); ! 13: int an(); ! 14: int s(); ! 15: int es(); ! 16: int ily(); ! 17: int CCe(); ! 18: int VCe(); ! 19: int bility(); ! 20: int tion(); ! 21: int ize(); ! 22: int y_to_e(); ! 23: int i_to_y(); ! 24: int nop(); ! 25: ! 26: struct suftab { ! 27: char *suf; ! 28: int (*p1)(); ! 29: int n1; ! 30: char *d1; ! 31: char *a1; ! 32: int (*p2)(); ! 33: int n2; ! 34: char *d2; ! 35: char *a2; ! 36: }; ! 37: struct suftab stabc[] = { ! 38: {"citsi",strip,2,"","+ic"}, ! 39: {"citi",ize,1,"-e+ic",""}, ! 40: {"cihparg",i_to_y,1,"-y+ic",""}, ! 41: {"cipocs",ize,1,"-e+ic",""}, ! 42: {"cirtem",i_to_y,1,"-y+ic",""}, ! 43: {"cigol",i_to_y,1,"-y+ic",""}, ! 44: 0 ! 45: }; ! 46: struct suftab stabd[] = { ! 47: {"de",strip,1,"","+d", i_to_y,2,"-y+ied","+ed"}, ! 48: {"dooh",ily,4,"-y+ihood","+hood"}, ! 49: 0 ! 50: }; ! 51: struct suftab stabe[] = { ! 52: {"ecn",subst,1,"-t+ce",""}, ! 53: {"elbaif",i_to_y,4,"-y+iable",""}, ! 54: {"elba",CCe,4,"-e+able","+able"}, ! 55: {"evi",subst,0,"-ion+ive",""}, ! 56: {"ezi",CCe,3,"-e+ize","+ize"}, ! 57: {"ekil",strip,4,"","+like"}, ! 58: 0 ! 59: }; ! 60: struct suftab stabg[] = { ! 61: {"gni",CCe,3,"-e+ing","+ing"}, ! 62: 0 ! 63: }; ! 64: struct suftab stabl[] = { ! 65: {"laci",strip,2,"","+al"}, ! 66: {"latnem",strip,2,"","+al"}, ! 67: {"lanoi",strip,2,"","+al"}, ! 68: {"luf",ily,3,"-y+iful","+ful"}, ! 69: 0 ! 70: }; ! 71: struct suftab stabm[] = { ! 72: {"msi",CCe,3,"-e+ism","ism"}, ! 73: 0 ! 74: }; ! 75: struct suftab stabn[] = { ! 76: {"noitacifi",i_to_y,6,"-y+ication",""}, ! 77: {"noitazi",ize,4,"-e+ation",""}, ! 78: {"noit",tion,3,"-e+ion","+ion"}, ! 79: {"naino",an,3,"","+ian"}, ! 80: {"na",an,1,"","+n"}, ! 81: 0 ! 82: }; ! 83: struct suftab stabp[] = { ! 84: {"pihs",strip,4,"","+ship"}, ! 85: 0 ! 86: }; ! 87: struct suftab stabr[] = { ! 88: {"reta",nop,0,"",""}, ! 89: {"retc",nop,0,"",""}, ! 90: {"re",strip,1,"","+r", i_to_y,2,"-y+ier","+er"}, ! 91: {"rota",tion,2,"-e+or",""}, ! 92: {"rotc",tion,2,"","+or"}, ! 93: 0 ! 94: }; ! 95: struct suftab stabs[] = { ! 96: {"ssen",ily,4,"-y+iness","+ness" }, ! 97: {"ssel",ily,4,"-y+i+less","+less" }, ! 98: {"se",s,1,"","+s", es,2,"-y+ies","+es" }, ! 99: {"s'",s,2,"","+'s"}, ! 100: {"s",s,1,"","+s"}, ! 101: 0 ! 102: }; ! 103: struct suftab stabt[] = { ! 104: {"tnem",strip,4,"","+ment"}, ! 105: {"tse",strip,2,"","+st", i_to_y,3,"-y+iest","+est"}, ! 106: {"tsigol",i_to_y,2,"-y+ist",""}, ! 107: {"tsi",CCe,3,"-e+ist","+ist"}, ! 108: 0 ! 109: }; ! 110: struct suftab staby[] = { ! 111: {"ycn",subst,1,"-t+cy",""}, ! 112: {"ytilb",nop,0,"",""}, ! 113: {"ytilib",bility,5,"-le+ility",""}, ! 114: {"yti",CCe,3,"-e+ity","+ity"}, ! 115: {"ylb",y_to_e,1,"-e+y",""}, ! 116: {"ylc",nop,0,"",""}, ! 117: {"yl",ily,2,"-y+ily","+ly"}, ! 118: {"yrtem",subst,0,"-er+ry",""}, ! 119: 0 ! 120: }; ! 121: struct suftab stabz[] = { ! 122: 0 ! 123: }; ! 124: struct suftab *suftab[] = { ! 125: stabz, ! 126: stabz, ! 127: stabc, ! 128: stabd, ! 129: stabe, ! 130: stabz, ! 131: stabg, ! 132: stabz, ! 133: stabz, ! 134: stabz, ! 135: stabz, ! 136: stabl, ! 137: stabm, ! 138: stabn, ! 139: stabz, ! 140: stabp, ! 141: stabz, ! 142: stabr, ! 143: stabs, ! 144: stabt, ! 145: stabz, ! 146: stabz, ! 147: stabz, ! 148: stabz, ! 149: staby, ! 150: stabz, ! 151: }; ! 152: ! 153: ! 154: char *ptaba[] = { ! 155: "anti", ! 156: "auto", ! 157: 0 ! 158: }; ! 159: char *ptabb[] = { ! 160: "bio", ! 161: 0 ! 162: }; ! 163: char *ptabc[] = { ! 164: "counter", ! 165: 0 ! 166: }; ! 167: char *ptabd[] = { ! 168: "dis", ! 169: 0 ! 170: }; ! 171: char *ptabe[] = { ! 172: "electro", ! 173: "en", ! 174: 0 ! 175: }; ! 176: char *ptabf[] = { ! 177: "femto", ! 178: "fore", ! 179: 0 ! 180: }; ! 181: char *ptabg[] = { ! 182: "geo", ! 183: "giga", ! 184: 0 ! 185: }; ! 186: char *ptabh[] = { ! 187: "hyper", ! 188: 0 ! 189: }; ! 190: char *ptabi[] = { ! 191: "intra", ! 192: "inter", ! 193: "iso", ! 194: 0 ! 195: }; ! 196: char *ptabj[] = { ! 197: 0 ! 198: }; ! 199: char *ptabk[] = { ! 200: "kilo", ! 201: 0 ! 202: }; ! 203: char *ptabl[] = { ! 204: 0 ! 205: }; ! 206: char *ptabm[] = { ! 207: "magneto", ! 208: "mega", ! 209: "meta", ! 210: "micro", ! 211: "mid", ! 212: "milli", ! 213: "mis", ! 214: "mono", ! 215: "multi", ! 216: 0 ! 217: }; ! 218: char *ptabn[] = { ! 219: "nano", ! 220: "non", ! 221: 0 ! 222: }; ! 223: char *ptabo[] = { ! 224: "out", ! 225: "over", ! 226: 0 ! 227: }; ! 228: char *ptabp[] = { ! 229: "photo", ! 230: "pico", ! 231: "poly", ! 232: "pre", ! 233: "pseudo", ! 234: "psycho", ! 235: 0 ! 236: }; ! 237: char *ptabq[] = { ! 238: "quasi", ! 239: 0 ! 240: }; ! 241: char *ptabr[] = { ! 242: "re", ! 243: 0 ! 244: }; ! 245: char *ptabs[] = { ! 246: "semi", ! 247: "stereo", ! 248: "sub", ! 249: "super", ! 250: 0 ! 251: }; ! 252: char *ptabt[] = { ! 253: "tele", ! 254: "thermo", ! 255: 0 ! 256: }; ! 257: char *ptabu[] = { ! 258: "ultra", ! 259: "under", /*must precede un*/ ! 260: "un", ! 261: 0 ! 262: }; ! 263: char *ptabv[] = { ! 264: 0 ! 265: }; ! 266: char *ptabw[] = { ! 267: 0 ! 268: }; ! 269: char *ptabx[] = { ! 270: 0 ! 271: }; ! 272: char *ptaby[] = { ! 273: 0 ! 274: }; ! 275: char *ptabz[] = { ! 276: 0 ! 277: }; ! 278: ! 279: char **preftab[] = { ! 280: ptaba, ! 281: ptabb, ! 282: ptabc, ! 283: ptabd, ! 284: ptabe, ! 285: ptabf, ! 286: ptabg, ! 287: ptabh, ! 288: ptabi, ! 289: ptabj, ! 290: ptabk, ! 291: ptabl, ! 292: ptabm, ! 293: ptabn, ! 294: ptabo, ! 295: ptabp, ! 296: ptabq, ! 297: ptabr, ! 298: ptabs, ! 299: ptabt, ! 300: ptabu, ! 301: ptabv, ! 302: ptabw, ! 303: ptabx, ! 304: ptaby, ! 305: ptabz, ! 306: }; ! 307: ! 308: int bflag; ! 309: int vflag; ! 310: int xflag; ! 311: char word[100]; ! 312: char original[100]; ! 313: char *deriv[40]; ! 314: char affix[40]; ! 315: char errmsg[] = "spell: cannot initialize hash table\n"; ! 316: FILE *found; ! 317: /* deriv is stack of pointers to notes like +micro +ed ! 318: * affix is concatenated string of notes ! 319: * the buffer size 141 stems from the sizes of original and affix. ! 320: */ ! 321: ! 322: /* ! 323: * in an attempt to defray future maintenance misunderstandings, here is an attempt to ! 324: * describe the input/output expectations of the spell program. ! 325: * ! 326: * spellprog is intended to be called from the shell file spell. ! 327: * because of this, there is little error checking (this is historical, not ! 328: * necessarily advisable). ! 329: * ! 330: * spellprog hashed-list pass options ! 331: * ! 332: * the hashed-list is a list of the form made by spellin. ! 333: * there are 2 types of hashed lists: ! 334: * 1. a stop list: this specifies words that by the rules embodied in ! 335: * spellprog would be recognized as correct, BUT are really errors. ! 336: * 2. a dictionary of correctly spelled words. ! 337: * the pass number determines how the words found in the specified hashed-list ! 338: * are treated. If the pass number is 1, the hashed-list is treated as the stop-list, ! 339: * otherwise, it is treated as the regular dictionary list. in this case, the ! 340: * value of "pass" is a filename. Found words are written to this file. ! 341: * In the normal case, the filename = /dev/null. However, if the v option is ! 342: * specified, the derivations are written to this file. ! 343: * the spellprog looks up words in the hashed-list; if a word is found, it is ! 344: * printed to the stdout. if the hashed-list was the stop-list, the words found ! 345: * are presumed to be misspellings. in this case, ! 346: * a control character is printed ( a "-" is appended to the word. ! 347: * a hyphen will never occur naturally in the input list because deroff ! 348: * is used in the shell file before calling spellprog.) ! 349: * if the regualar spelling list was used (hlista or hlistb), the words are correct, ! 350: * and may be ditched. (unless the -v option was used - see the manual page). ! 351: ! 352: * spellprog should be called twice : first with the stop-list, to flag all ! 353: * a priori incorrectly spelled words; second with the dictionary. ! 354: * ! 355: * spellprog hstop 1 |\ ! 356: * spellprog hlista /dev/null ! 357: * ! 358: * for a complete scenario, see the shell file: spell. ! 359: * ! 360: */ ! 361: main(argc,argv) ! 362: char **argv; ! 363: { ! 364: register char *ep, *cp; ! 365: register char *dp; ! 366: int fold; ! 367: int j; ! 368: int pass; ! 369: if(!prime(argc,argv)) { ! 370: fwrite(errmsg, sizeof(*errmsg), sizeof(errmsg), stderr); ! 371: exit(1); ! 372: } ! 373: /* ! 374: * if pass is not 1, it is assumed to be a filename. ! 375: * found words are written to this file. ! 376: */ ! 377: pass = argv[2][0] ; ! 378: if ( pass != '1' ) ! 379: found = fopen(argv[2],"w"); ! 380: for(argc-=3,argv+=3; argc>0 && argv[0][0]=='-'; argc--,argv++) ! 381: switch(argv[0][1]) { ! 382: case 'b': ! 383: bflag++; ! 384: ise(); ! 385: break; ! 386: case 'v': ! 387: vflag++; ! 388: break; ! 389: case 'x': ! 390: xflag++; ! 391: break; ! 392: } ! 393: for(;;) { ! 394: affix[0] = 0; ! 395: for(ep=word;(*ep=j=getchar())!='\n';ep++) ! 396: if(j == EOF) ! 397: exit(0); ! 398: for(cp=word,dp=original; cp<ep; ) ! 399: *dp++ = *cp++; ! 400: *dp = 0; ! 401: /* ! 402: * here is the hyphen processing. these words were found in the stop ! 403: * list. however, if they exist as is, (no derivations tried) in the ! 404: * dictionary, let them through as correct. ! 405: * ! 406: */ ! 407: if(ep[-1]=='-') { ! 408: *--dp = *--ep = 0; ! 409: if(tryword(word,ep,0)) ! 410: continue; ! 411: if(!isupper(word[0])) ! 412: goto notfound; ! 413: if(isupper(word[1])) { ! 414: for(cp=word+1;cp<ep;cp++) { ! 415: if(islower(*cp)) ! 416: goto notfound; ! 417: *cp = Tolower(*cp); ! 418: } ! 419: } ! 420: if(tryword(word,ep,0)) ! 421: continue; ! 422: word[0] = Tolower(word[0]); ! 423: if(tryword(word,ep,0)) ! 424: continue; ! 425: goto notfound; ! 426: } ! 427: fold = 0; ! 428: for(cp=word;cp<ep;cp++) ! 429: if(islower(*cp)) ! 430: goto lcase; ! 431: if(trypref(ep,".",0)) ! 432: goto foundit; ! 433: ++fold; ! 434: for(cp=original+1,dp=word+1;dp<ep;dp++,cp++) ! 435: *dp = Tolower(*cp); ! 436: lcase: ! 437: if(trypref(ep,".",0)||trysuff(ep,0)) ! 438: goto foundit; ! 439: if(isupper(word[0])) { ! 440: for(cp=original,dp=word; *dp = *cp++; dp++) ! 441: if (fold) *dp = Tolower(*dp); ! 442: word[0] = Tolower(word[0]); ! 443: goto lcase; ! 444: } ! 445: notfound: ! 446: printf("%s\n", original); ! 447: continue; ! 448: ! 449: foundit: ! 450: if(pass=='1') ! 451: printf("%s-\n", original); ! 452: else if(affix[0]!=0 && affix[0]!='.') { ! 453: fprintf(found, "%s\t%s\n", affix, original); ! 454: } ! 455: } ! 456: } ! 457: ! 458: /* strip exactly one suffix and do ! 459: * indicated routine(s), which may recursively ! 460: * strip suffixes ! 461: */ ! 462: trysuff(ep,lev) ! 463: char *ep; ! 464: { ! 465: register struct suftab *t; ! 466: register char *cp, *sp; ! 467: int initchar = ep[-1]; ! 468: lev += DLEV; ! 469: deriv[lev] = deriv[lev-1] = 0; ! 470: if(!islower(initchar)) ! 471: return(0); ! 472: for(t=suftab[initchar-'a'];sp=t->suf;t++) { ! 473: cp = ep; ! 474: while(*sp) ! 475: if(*--cp!=*sp++) ! 476: goto next; ! 477: for(sp=cp; --sp>=word&&!vowel(*sp); ) ; ! 478: if(sp<word) ! 479: return(0); ! 480: if((*t->p1)(ep-t->n1,t->d1,t->a1,lev+1)) ! 481: return(1); ! 482: if(t->p2!=0) { ! 483: deriv[lev] = deriv[lev+1] = 0; ! 484: return((*t->p2)(ep-t->n2,t->d2,t->a2,lev)); ! 485: } ! 486: return(0); ! 487: next: ; ! 488: } ! 489: return(0); ! 490: } ! 491: ! 492: nop() ! 493: { ! 494: return(0); ! 495: } ! 496: ! 497: cstrip(ep,d,a,lev) ! 498: char *ep,*d,*a; ! 499: { ! 500: register temp = ep[0]; ! 501: if(vowel(temp)&&vowel(ep[-1])) { ! 502: switch(pair(ep[-1],ep[0])) { ! 503: case pair('a', 'a'): ! 504: case pair('a', 'e'): ! 505: case pair('a', 'i'): ! 506: case pair('e', 'a'): ! 507: case pair('e', 'e'): ! 508: case pair('e', 'i'): ! 509: case pair('i', 'i'): ! 510: case pair('o', 'a'): ! 511: return(0); ! 512: } ! 513: } else if(temp==ep[-1]&&temp==ep[-2]) ! 514: return(0); ! 515: return(strip(ep,d,a,lev)); ! 516: } ! 517: ! 518: strip(ep,d,a,lev) ! 519: char *ep,*d,*a; ! 520: { ! 521: return(trypref(ep,a,lev)||trysuff(ep,lev)); ! 522: } ! 523: ! 524: s(ep,d,a,lev) ! 525: char *ep,*d,*a; ! 526: { ! 527: if(lev>DLEV+1) ! 528: return(0); ! 529: if(*ep=='s') { ! 530: switch(ep[-1]) { ! 531: case 'y': ! 532: if(vowel(ep[-2])) ! 533: break; ! 534: case 'x': ! 535: case 'z': ! 536: case 's': ! 537: return(0); ! 538: case 'h': ! 539: switch(ep[-2]) { ! 540: case 'c': ! 541: case 's': ! 542: return(0); ! 543: } ! 544: } ! 545: } ! 546: return(strip(ep,d,a,lev)); ! 547: } ! 548: ! 549: an(ep,d,a,lev) ! 550: char *ep,*d,*a; ! 551: { ! 552: if(!isupper(*word)) /*must be proper name*/ ! 553: return(0); ! 554: return(trypref(ep,a,lev)); ! 555: } ! 556: ! 557: ize(ep,d,a,lev) ! 558: char *ep,*d,*a; ! 559: { ! 560: register temp = ep[-1]; ! 561: register val; ! 562: ep[-1] = 'e'; ! 563: val = strip(ep,"",d,lev); ! 564: ep[-1] = temp; ! 565: return(val); ! 566: } ! 567: ! 568: y_to_e(ep,d,a,lev) ! 569: char *ep,*d,*a; ! 570: { ! 571: register val, temp; ! 572: switch(ep[-1]) { ! 573: case 'a': ! 574: case 'e': ! 575: case 'i': ! 576: return 0; ! 577: } ! 578: temp = *ep; ! 579: *ep++ = 'e'; ! 580: val = strip(ep,"",d,lev); ! 581: *--ep = temp; ! 582: return(val); ! 583: } ! 584: ! 585: ily(ep,d,a,lev) ! 586: char *ep,*d,*a; ! 587: { ! 588: register temp = ep[0]; ! 589: if(temp==ep[-1]&&temp==ep[-2]) ! 590: return(0); ! 591: if(ep[-1]=='i') ! 592: return(i_to_y(ep,d,a,lev)); ! 593: else ! 594: return(cstrip(ep,d,a,lev)); ! 595: } ! 596: ! 597: bility(ep,d,a,lev) ! 598: char *ep,*d,*a; ! 599: { ! 600: *ep++ = 'l'; ! 601: return(y_to_e(ep,d,a,lev)); ! 602: } ! 603: ! 604: i_to_y(ep,d,a,lev) ! 605: char *ep,*d,*a; ! 606: { ! 607: register val, temp; ! 608: if((temp=ep[-1])=='i'&&!vowel(ep[-2])) { ! 609: ep[-1] = 'y'; ! 610: a = d; ! 611: } ! 612: val = cstrip(ep,"",a,lev); ! 613: ep[-1] = temp; ! 614: return(val); ! 615: } ! 616: ! 617: es(ep,d,a,lev) ! 618: char *ep,*d,*a; ! 619: { ! 620: if(lev>DLEV) ! 621: return(0); ! 622: switch(ep[-1]) { ! 623: default: ! 624: return(0); ! 625: case 'i': ! 626: return(i_to_y(ep,d,a,lev)); ! 627: case 's': ! 628: case 'h': ! 629: case 'z': ! 630: case 'x': ! 631: return(strip(ep,d,a,lev)); ! 632: } ! 633: } ! 634: ! 635: subst(ep,d,a,lev) ! 636: char *ep, *d, *a; ! 637: { ! 638: char *u,*t; ! 639: int val; ! 640: if(skipv(skipv(ep-1))<word) ! 641: return(0); ! 642: for(t=d;*t!='+';t++) ! 643: continue; ! 644: for(u=ep;*--t!='-'; ) ! 645: *--u = *t; ! 646: val = strip(ep,"",d,lev); ! 647: while(*++t!='+') ! 648: continue; ! 649: while(*++t) ! 650: *u++ = *t; ! 651: return(val); ! 652: } ! 653: ! 654: ! 655: tion(ep,d,a,lev) ! 656: char *ep,*d,*a; ! 657: { ! 658: switch(ep[-2]) { ! 659: case 'c': ! 660: case 'r': ! 661: return(trypref(ep,a,lev)); ! 662: case 'a': ! 663: return(y_to_e(ep,d,a,lev)); ! 664: } ! 665: return(0); ! 666: } ! 667: ! 668: /* possible consonant-consonant-e ending*/ ! 669: CCe(ep,d,a,lev) ! 670: char *ep,*d,*a; ! 671: { ! 672: switch(ep[-1]) { ! 673: case 'l': ! 674: if(vowel(ep[-2])) ! 675: break; ! 676: switch(ep[-2]) { ! 677: case 'l': ! 678: case 'r': ! 679: case 'w': ! 680: break; ! 681: default: ! 682: return(y_to_e(ep,d,a,lev)); ! 683: } ! 684: break; ! 685: case 's': ! 686: if(ep[-2]=='s') ! 687: break; ! 688: case 'c': ! 689: case 'g': ! 690: if(*ep=='a') ! 691: return(0); ! 692: case 'v': ! 693: case 'z': ! 694: if(vowel(ep[-2])) ! 695: break; ! 696: case 'u': ! 697: if(y_to_e(ep,d,a,lev)) ! 698: return(1); ! 699: if(!(ep[-2]=='n'&&ep[-1]=='g')) ! 700: return(0); ! 701: } ! 702: return(VCe(ep,d,a,lev)); ! 703: } ! 704: ! 705: /* possible consonant-vowel-consonant-e ending*/ ! 706: VCe(ep,d,a,lev) ! 707: char *ep,*d,*a; ! 708: { ! 709: char c; ! 710: c = ep[-1]; ! 711: if(c=='e') ! 712: return(0); ! 713: if(!vowel(c) && vowel(ep[-2])) { ! 714: if(bflag&&c=='l'&&ep[-2]=='e') /* UK modelled vs US modeled */ ! 715: return(0); ! 716: c = *ep; ! 717: *ep++ = 'e'; ! 718: if(trypref(ep,d,lev)||trysuff(ep,lev)) ! 719: return(1); ! 720: ep--; ! 721: *ep = c; ! 722: } ! 723: return(cstrip(ep,d,a,lev)); ! 724: } ! 725: ! 726: char *lookuppref(wp,ep) ! 727: char **wp; ! 728: char *ep; ! 729: { ! 730: register char **sp; ! 731: register char *bp,*cp; ! 732: int initchar = Tolower(**wp); ! 733: if(!isalpha(initchar)) ! 734: return(0); ! 735: for(sp=preftab[initchar-'a'];*sp;sp++) { ! 736: bp = *wp; ! 737: for(cp= *sp;*cp;cp++,bp++) ! 738: if(Tolower(*bp)!=*cp) ! 739: goto next; ! 740: for(cp=bp;cp<ep;cp++) ! 741: if(vowel(*cp)) { ! 742: *wp = bp; ! 743: return(*sp); ! 744: } ! 745: next: ; ! 746: } ! 747: return(0); ! 748: } ! 749: ! 750: /* while word is not in dictionary try stripping ! 751: * prefixes. Fail if no more prefixes. ! 752: */ ! 753: trypref(ep,a,lev) ! 754: char *ep,*a; ! 755: { ! 756: register char *cp; ! 757: char *bp; ! 758: register char *pp; ! 759: int val = 0; ! 760: char space[20]; ! 761: deriv[lev] = a; ! 762: if(tryword(word,ep,lev)) ! 763: return(1); ! 764: bp = word; ! 765: pp = space; ! 766: deriv[lev+1] = pp; ! 767: while(cp=lookuppref(&bp,ep)) { ! 768: *pp++ = '+'; ! 769: while(*pp = *cp++) ! 770: pp++; ! 771: if(tryword(bp,ep,lev+1)) { ! 772: val = 1; ! 773: break; ! 774: } ! 775: } ! 776: deriv[lev+1] = deriv[lev+2] = 0; ! 777: return(val); ! 778: } ! 779: ! 780: tryword(bp,ep,lev) ! 781: char *bp,*ep; ! 782: { ! 783: register i, j; ! 784: char duple[3]; ! 785: if(ep-bp<=1) ! 786: return(0); ! 787: if(vowel(*ep)) { ! 788: if(monosyl(bp,ep)) ! 789: return(0); ! 790: } ! 791: i = dict(bp,ep); ! 792: /* doubled consonant in monosyllables and UK 'modelled', etc */ ! 793: if(i==0&&vowel(*ep)&&ep[-1]==ep[-2]&& ! 794: (monosyl(bp,ep-1)||bflag&&ep[-1]=='l'&&ep[-3]=='e')) { ! 795: ep--; ! 796: deriv[++lev] = duple; ! 797: duple[0] = '+'; ! 798: duple[1] = *ep; ! 799: duple[2] = 0; ! 800: i = dict(bp,ep); ! 801: } ! 802: if(vflag==0||i==0) ! 803: return(i); ! 804: /* when derivations are wanted, collect them ! 805: * for printing ! 806: */ ! 807: j = lev; ! 808: do { ! 809: if(deriv[j]) ! 810: strcat(affix,deriv[j]); ! 811: } while(--j>0); ! 812: return(i); ! 813: } ! 814: ! 815: ! 816: monosyl(bp,ep) ! 817: char *bp, *ep; ! 818: { ! 819: if(ep<bp+2) ! 820: return(0); ! 821: if(vowel(*--ep)||!vowel(*--ep) ! 822: ||ep[1]=='x'||ep[1]=='w') ! 823: return(0); ! 824: while(--ep>=bp) ! 825: if(vowel(*ep)&&!(ep[-1]=='q'&&*ep=='u')) ! 826: return(0); ! 827: return(1); ! 828: } ! 829: ! 830: char * ! 831: skipv(s) ! 832: char *s; ! 833: { ! 834: if(s>=word&&vowel(*s)) ! 835: s--; ! 836: while(s>=word&&!vowel(*s)) ! 837: s--; ! 838: return(s); ! 839: } ! 840: ! 841: vowel(c) ! 842: { ! 843: switch(Tolower(c)) { ! 844: case 'a': ! 845: case 'e': ! 846: case 'i': ! 847: case 'o': ! 848: case 'u': ! 849: case 'y': ! 850: return(1); ! 851: } ! 852: return(0); ! 853: } ! 854: ! 855: /* crummy way to Britishise */ ! 856: ise() ! 857: { ! 858: register struct suftab *p; ! 859: register i; ! 860: for(i=0; i<26; i++) { ! 861: for(p = suftab[i];p->suf;p++) { ! 862: ztos(p->suf); ! 863: ztos(p->d1); ! 864: ztos(p->a1); ! 865: } ! 866: } ! 867: } ! 868: ztos(s) ! 869: char *s; ! 870: { ! 871: for(;*s;s++) ! 872: if(*s=='z') ! 873: *s = 's'; ! 874: } ! 875: ! 876: dict(bp,ep) ! 877: char *bp, *ep; ! 878: { ! 879: register temp, result; ! 880: if(xflag) ! 881: fprintf(stderr, "=%.*s\n", ep-bp, bp); ! 882: temp = *ep; ! 883: *ep = 0; ! 884: result = hashlook(bp); ! 885: *ep = temp; ! 886: return(result); ! 887: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.