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