Annotation of coherent/b/bin/troff/hyphen.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * hyphen.c
        !             3:  * Nroff/Troff.
        !             4:  * Hyphenation.
        !             5:  */
        !             6: 
        !             7: #include <ctype.h>
        !             8: #include "roff.h"
        !             9: 
        !            10: /*
        !            11:  * Try to hyphenate the word found in the word buffer.
        !            12:  */
        !            13: hyphen(cp1, cp2)
        !            14: CODE *cp1;
        !            15: CODE *cp2;
        !            16: {
        !            17:        register CODE *cpl;
        !            18:        register int n;
        !            19:        int wi1, wi2, len;
        !            20: 
        !            21:        cpl = cp1;
        !            22:        n = cp2 - cp1;
        !            23:        while (n--)
        !            24:                hyphbuf[n] = 0;
        !            25:        while (cp1 < cp2) {
        !            26:                n = cp2[-1].c_arg.c_code;
        !            27:                if (isascii(n) && isalpha(n))
        !            28:                        break;
        !            29:                --cp2;
        !            30:        }
        !            31:        len = cp2 - cp1;
        !            32:        while (cp1 < cp2) {
        !            33:                n = cp1->c_arg.c_code;
        !            34:                if (isascii(n) && isalpha(n))
        !            35:                        break;
        !            36:                cp1++;
        !            37:        }
        !            38:        if (len <= 4)
        !            39:                return;
        !            40:        wi1 = 0;
        !            41:        wi2 = len;
        !            42:        if (except(cpl, hyphbuf, wi1, wi2))
        !            43:                return;
        !            44:        wi2 = 1 + suffix(cpl, hyphbuf, wi2-1, wi1-1);
        !            45:        wi1 = prefix(cpl, hyphbuf, wi1, wi2);
        !            46:        middle(cpl, hyphbuf, wi1, wi2);
        !            47:        n = len;
        !            48:        hyphbuf[0] = 0;
        !            49:        hyphbuf[n-3] = 0;
        !            50:        hyphbuf[n-2] = 0;
        !            51:        hyphbuf[n-1] = 0;
        !            52:        if (wi2-wi1 <= 2) {
        !            53:                hyphbuf[wi1] = 0;
        !            54:                hyphbuf[wi2-1] = 0;
        !            55:        }
        !            56:        n = wi2;
        !            57:        if (--n>=0 && cpl[n].c_arg.c_code==LEEE) {
        !            58:                int m;
        !            59:                m = 3;
        !            60:                while (n && m--)
        !            61:                        hyphbuf[n--] = 0;
        !            62:        }
        !            63:        n = wi2;
        !            64:        if (n>=2 && cpl[--n].c_arg.c_code==LDDD &&
        !            65:            cpl[--n].c_arg.c_code==LEEE) {
        !            66:                if (--n<1 || cpl[n].c_arg.c_code!=LZZZ ||
        !            67:                    cpl[n-1].c_arg.c_code!=LIII) {
        !            68:                        if (--n >= 0)
        !            69:                                hyphbuf[n] = 0;
        !            70:                        if (--n >= 0)
        !            71:                                hyphbuf[n] = 0;
        !            72:                }
        !            73:        }
        !            74: }
        !            75: 
        !            76: /*
        !            77:  * Look for exception words.
        !            78:  */
        !            79: except(wbuf, hbuf, wi1, wi2)
        !            80: CODE *wbuf;
        !            81: char *hbuf;
        !            82: {
        !            83:        unsigned ti, ti0, ti1, ti2, wih, c1, c2;
        !            84:        register int wi, n;
        !            85:        register char *bp;
        !            86: 
        !            87:        ti = ti1 = 0;   /* ti = 0 by c.e.f triggered by lint error */
        !            88:        ti2 = EXCSIZE;
        !            89:        for (;;) {
        !            90:                ti0 = ti;
        !            91:                if ((ti=(ti1+ti2)/2) == ti0)
        !            92:                        goto fail;
        !            93:                wi = wi1;
        !            94:                wih = wi1;
        !            95:                bp = exctab[ti];
        !            96:                for (;;) {
        !            97:                        if (*bp == LEOK) {
        !            98:                                if (wi == wi2)
        !            99:                                        return 1;
        !           100:                                if (wi==wi2-1 && wbuf[wi].c_arg.c_code==LSSS)
        !           101:                                        return 1;
        !           102:                                ti1 = ti;
        !           103:                                break;
        !           104:                        }
        !           105:                        if (*bp == LHYP) {
        !           106:                                bp++;
        !           107:                                wih = wi;
        !           108:                                hbuf[wi-1] = 1;
        !           109:                                continue;
        !           110:                        }
        !           111:                        if (wi >= wi2) {
        !           112:                                ti1 = ti;
        !           113:                                break;
        !           114:                        }
        !           115:                        if ((c1=wbuf[wi++].c_arg.c_code) != (c2 = *bp++)) {
        !           116:                                if (c1 > c2)
        !           117:                                        ti1 = ti;
        !           118:                                else
        !           119:                                        ti2 = ti;
        !           120:                                break;
        !           121:                        }
        !           122:                }
        !           123:                for (wi=wi1; wi<wih; wi++)
        !           124:                        hbuf[wi] = 0;
        !           125:        }
        !           126: fail:
        !           127:        for (n=wi1; n<wi2; n++)
        !           128:                hbuf[n] = 0;
        !           129:        return 0;
        !           130: }
        !           131: 
        !           132: /*
        !           133:  * Look for prefixes.
        !           134:  */
        !           135: prefix(wbuf, hbuf, wi1, wi2)
        !           136: CODE *wbuf;
        !           137: char *hbuf;
        !           138: register int wi2;
        !           139: {
        !           140:        unsigned ti, ti0, ti1, ti2, c1, c2, con;
        !           141:        register int wi, wih;
        !           142:        register char *bp;
        !           143: 
        !           144:        do {
        !           145:                ti0 = -1;
        !           146:                ti = ti1 = 0;   /* ti = 0 by c.e.f triggered by lint */
        !           147:                ti2 = PRESIZE;
        !           148:                for (;;) {
        !           149:                        ti0 = ti;
        !           150:                        if ((ti=(ti1+ti2)/2) == ti0)
        !           151:                                return wi1;
        !           152:                        wi = wi1;
        !           153:                        wih = wi1;
        !           154:                        bp = pretab[ti];
        !           155:                        for (;;) {
        !           156:                                if (*bp == LEOK) {
        !           157:                                        bp++;
        !           158:                                        goto patn;
        !           159:                                }
        !           160:                                if (*bp == LHYP) {
        !           161:                                        bp++;
        !           162:                                        wih = wi;
        !           163:                                        hbuf[wi-1] = 1;
        !           164:                                        continue;
        !           165:                                }
        !           166:                                if (wi >= wi2)
        !           167:                                        return wi1;
        !           168:                                if ((c1=wbuf[wi++].c_arg.c_code) !=
        !           169:                                    (c2 = *bp++)) {
        !           170:                                        if (c1 > c2)
        !           171:                                                ti1 = ti;
        !           172:                                        else
        !           173:                                                ti2 = ti;
        !           174:                                        break;
        !           175:                                }
        !           176:                        }
        !           177:                        for (wi=wi1; wi<wih; wi++)
        !           178:                                hyphbuf[wi] = 0;
        !           179:                }
        !           180:        patn:
        !           181:                if (automate(bp, &wi1, &con, 1, wbuf, hbuf, wi, wi2) == 0) {
        !           182:                        while (wi > wi1)
        !           183:                                hbuf[--wi] = 0;
        !           184:                        return wi1;
        !           185:                }
        !           186:        } while (con != 0);
        !           187:        return wi1;
        !           188: }
        !           189: 
        !           190: /*
        !           191:  * Look for suffixes.
        !           192:  */
        !           193: suffix(wbuf, hbuf, wi1, wi2)
        !           194: CODE *wbuf;
        !           195: char *hbuf;
        !           196: register int wi2;
        !           197: {
        !           198:        unsigned ti, ti0, ti1, ti2, c1, c2, con;
        !           199:        register int wi, wih;
        !           200:        register char *bp;
        !           201: 
        !           202:        do {
        !           203:                ti0 = -1;
        !           204:                ti = ti1 = 0;   /* ti = 0 by cef triggered by lint */
        !           205:                ti2 = SUFSIZE;
        !           206:                for (;;) {
        !           207:                        ti0 = ti;
        !           208:                        if ((ti=(ti1+ti2)/2) == ti0)
        !           209:                                return wi1;
        !           210:                        wi = wi1;
        !           211:                        wih = wi1;
        !           212:                        bp = suftab[ti];
        !           213:                        for (;;) {
        !           214:                                if (*bp == LEOK) {
        !           215:                                        bp++;
        !           216:                                        goto patn;
        !           217:                                }
        !           218:                                if (*bp == LHYP) {
        !           219:                                        bp++;
        !           220:                                        wih = wi;
        !           221:                                        hbuf[wi] = 1;
        !           222:                                        continue;
        !           223:                                }
        !           224:                                if (wi <= wi2)
        !           225:                                        return wi1;
        !           226:                                if ((c1=wbuf[wi--].c_arg.c_code) !=
        !           227:                                    (c2 = *bp++)) {
        !           228:                                        if (c1 > c2)
        !           229:                                                ti1 = ti;
        !           230:                                        else
        !           231:                                                ti2 = ti;
        !           232:                                        break;
        !           233:                                }
        !           234:                        }
        !           235:                        for (wi=wi1; wi>wih; wi--)
        !           236:                                hyphbuf[wi] = 0;
        !           237:                }
        !           238:        patn:
        !           239:                if (automate(bp, &wi1, &con, -1, wbuf, hbuf, wi, wi2) == 0) {
        !           240:                        while (wi < wi1)
        !           241:                                hbuf[++wi] = 0;
        !           242:                        return wi1;
        !           243:                }
        !           244:        } while (con != 0);
        !           245:        return wi1;
        !           246: }
        !           247: 
        !           248: /*
        !           249:  * Try to hyphenate the middle of a word.
        !           250:  */
        !           251: middle(wbuf, hbuf, wi1, wi2)
        !           252: CODE *wbuf;
        !           253: char *hbuf;
        !           254: {
        !           255:        int new, bil, c2, c3, n;
        !           256:        unsigned con;
        !           257:        register int wi, bi, c1;
        !           258: 
        !           259:        wi = wi1;
        !           260:        bi = 0;
        !           261:        while (wi < wi2) {
        !           262:                c1 = wbuf[wi++].c_arg.c_code;
        !           263:                if (wi<wi2 && wbuf[wi].c_arg.c_code==LHHH) {
        !           264:                        wi++;
        !           265:                        switch (c1) {
        !           266:                        case LCCC:
        !           267:                                c1 = LDCH;
        !           268:                                break;
        !           269:                        case LGGG:
        !           270:                                c1 = LDGH;
        !           271:                                break;
        !           272:                        case LPPP:
        !           273:                                c1 = LDPH;
        !           274:                                break;
        !           275:                        case LSSS:
        !           276:                                c1 = LDSH;
        !           277:                                break;
        !           278:                        case LTTT:
        !           279:                                c1 = LDTH;
        !           280:                                break;
        !           281:                        default:
        !           282:                                --wi;
        !           283:                                break;
        !           284:                        }
        !           285:                }
        !           286:                hletbuf[bi] = c1;
        !           287:                hindbuf[bi++] = wi-1;
        !           288:        }
        !           289:        bil = bi-2;
        !           290:        for (bi=0; bi<bil; bi++) {
        !           291:                if (!vowel(hletbuf[bi]))
        !           292:                        continue;
        !           293:                c1 = hletbuf[bi+1];
        !           294:                c2 = hletbuf[bi+2];
        !           295:                if (c1==c2 && consn(c1)) {
        !           296:                        if (c1 == LLLL)
        !           297:                                continue;
        !           298:                        if (c1 == LSSS) {
        !           299:                                if (bi>=bil-1 || !vowel(hletbuf[bi+3]))
        !           300:                                        continue;
        !           301:                                if (automate(mm0code, &new, &con, 1,
        !           302:                                        wbuf, hbuf, hindbuf[bi+3], wi2)==0)
        !           303:                                        continue;
        !           304:                        }
        !           305:                        hbuf[hindbuf[++bi]] = 1;
        !           306:                        continue;
        !           307:                }
        !           308:                if (c1==LCCC && c2==LKKK) {
        !           309:                        hbuf[hindbuf[bi+=2]] = 1;
        !           310:                        continue;
        !           311:                }
        !           312:                if (c1==LQQQ && c2==LUUU) {
        !           313:                        hbuf[hindbuf[bi]] = 1;
        !           314:                        continue;
        !           315:                }
        !           316:                if (bi < bil-1) {
        !           317:                        c3 = hletbuf[bi+3];
        !           318:                        if (!consn(c1) || !consn(c2) || !vowel(c3))
        !           319:                                continue;
        !           320:                        if ((n=matpair(c1, c2)) == 2)
        !           321:                                continue;
        !           322:                        if (n==1 && automate(mm1code, &new, &con, 1,
        !           323:                                wbuf, hbuf, hindbuf[bi+3], wi2)==0)
        !           324:                                continue;
        !           325:                        hbuf[hindbuf[++bi]] = 1;
        !           326:                        continue;
        !           327:                }
        !           328:        }
        !           329: }
        !           330: 
        !           331: /*
        !           332:  * See if we match a set of double consonants.  If we do,
        !           333:  * return the associated number in the table.
        !           334:  */
        !           335: matpair(c1, c2)
        !           336: register int c1;
        !           337: {
        !           338:        register int c;
        !           339:        register char *cp;
        !           340: 
        !           341:        cp = dbctab;
        !           342:        while ((c = *cp++) != LNUL) {
        !           343:                if (c1 < c)
        !           344:                        return 0;
        !           345:                if (c1 > c) {
        !           346:                        cp += 2;
        !           347:                        continue;
        !           348:                }
        !           349:                if (c2 != *cp++) {
        !           350:                        cp++;
        !           351:                        continue;
        !           352:                }
        !           353:                return *cp;
        !           354:        }
        !           355:        return 0;
        !           356: }
        !           357: 
        !           358: /*
        !           359:  * Given a pattern string, execute it on the given word buffer.
        !           360:  */
        !           361: automate(patp, newp, conp, dirn, wbuf, hbuf, wi1, wi2)
        !           362: char *patp;
        !           363: int *newp;
        !           364: unsigned *conp;
        !           365: CODE *wbuf;
        !           366: char *hbuf;
        !           367: {
        !           368:        int wi, wis;
        !           369:        register int c, n;
        !           370:        register char *bp;
        !           371: 
        !           372:        bp = patp;
        !           373:        *conp = 0;
        !           374:        wi = wi1;
        !           375:        wis = wi1;
        !           376:        for (;;) {
        !           377:                switch (*bp++) {
        !           378:                case LNUL:
        !           379:                        goto succ;
        !           380:                case LHYP:
        !           381:                        wis = wi;
        !           382:                        *conp = 0;
        !           383:                        hbuf[wi-(dirn>0?1:0)] = 1;
        !           384:                        continue;
        !           385:                case LRHP:
        !           386:                        hbuf[wi-(dirn>0?1:0)] = 0;
        !           387:                        continue;
        !           388:                case LCON:
        !           389:                        *conp = 1;
        !           390:                        continue;
        !           391:                case LNEW:
        !           392:                        n = *bp++;
        !           393:                        if (wi != wi2) {
        !           394:                                c = wbuf[wi].c_arg.c_code;
        !           395:                                wi += dirn;
        !           396:                                continue;
        !           397:                        }
        !           398:                        if (n == 1)
        !           399:                                goto fail;
        !           400:                        if (n == 2)
        !           401:                                goto succ;
        !           402:                        bp += n-3;
        !           403:                        continue;
        !           404:                case LOLD:
        !           405:                        wi -= dirn;
        !           406:                        c = wbuf[wi-dirn].c_arg.c_code;
        !           407:                        continue;
        !           408:                case LBRF:
        !           409:                        goto fail;
        !           410:                case LBRS:
        !           411:                        goto succ;
        !           412:                case LCBT:
        !           413:                        if (*bp++ != c) {
        !           414:                                bp++;
        !           415:                                continue;
        !           416:                        }
        !           417:                        if ((n = *bp++) == 1)
        !           418:                                goto fail;
        !           419:                        if (n == 2)
        !           420:                                goto succ;
        !           421:                        bp += n-3;
        !           422:                        continue;
        !           423:                case LCBF:
        !           424:                        if (*bp++ == c) {
        !           425:                                bp++;
        !           426:                                continue;
        !           427:                        }
        !           428:                        if ((n = *bp++) == 1)
        !           429:                                goto fail;
        !           430:                        if (n == 2)
        !           431:                                goto succ;
        !           432:                        bp += n-3;
        !           433:                        continue;
        !           434:                default:
        !           435:                        panic("bad pattern");
        !           436:                }
        !           437:        }
        !           438: succ:
        !           439:        *newp = wis;
        !           440:        return 1;
        !           441: fail:
        !           442:        return 0;
        !           443: }
        !           444: 
        !           445: /*
        !           446:  * See if the given code is a vowel.
        !           447:  */
        !           448: vowel(c)
        !           449: register int c;
        !           450: {
        !           451:        if (c>=LAAA && c<=LYYY && contab[c-LAAA]==0)
        !           452:                return 1;
        !           453:        return 0;
        !           454: }
        !           455: 
        !           456: /*
        !           457:  * See if the given code is a consonant.
        !           458:  */
        !           459: consn(c)
        !           460: register int c;
        !           461: {
        !           462:        if (c>=LAAA && c<=LDTH && contab[c-LAAA]==1)
        !           463:                return 1;
        !           464:        return 0;
        !           465: }
        !           466: 
        !           467: /*
        !           468:  * Code to fail if we match ((er|ers)$).
        !           469:  */
        !           470: char mm0code[] ={
        !           471:         0005, 0002, 0012, 0051, 0002, 0005, 0002, 0012,
        !           472:         0066, 0002, 0005, 0001, 0012, 0067, 0002, 0005,
        !           473:         0001, 0010, 0000
        !           474: };
        !           475: 
        !           476: /*
        !           477:  * Code to fail if we match ((er|ers|age|ages|est)$).
        !           478:  */
        !           479: char mm1code[] ={
        !           480:         0005, 0002, 0011, 0051, 0030, 0012, 0045, 0002,
        !           481:         0005, 0002, 0012, 0053, 0002, 0005, 0002, 0012,
        !           482:         0051, 0002, 0005, 0001, 0012, 0067, 0002, 0005,
        !           483:         0001, 0010, 0005, 0002, 0011, 0066, 0016, 0012,
        !           484:         0067, 0002, 0005, 0002, 0012, 0070, 0002, 0005,
        !           485:         0001, 0010, 0005, 0001, 0012, 0067, 0002, 0005,
        !           486:         0001, 0010, 0000
        !           487: };
        !           488: 
        !           489: /*
        !           490:  * Table to determine whether a letter is a constant or a vowel.
        !           491:  */
        !           492: char contab[] ={
        !           493:        0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1,
        !           494:        1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1
        !           495: };
        !           496: 
        !           497: /*
        !           498:  * Pairs of consonants which aren't allowed somewhere.
        !           499:  */
        !           500: char dbctab[] ={
        !           501:        LBBB, LLLL, 2,
        !           502:        LBBB, LRRR, 2,
        !           503:        LCCC, LLLL, 2,
        !           504:        LCCC, LRRR, 2,
        !           505:        LFFF, LLLL, 2,
        !           506:        LFFF, LRRR, 2,
        !           507:        LFFF, LTTT, 1,
        !           508:        LGGG, LLLL, 2,
        !           509:        LGGG, LRRR, 2,
        !           510:        LKKK, LNNN, 2,
        !           511:        LLLL, LDDD, 1,
        !           512:        LLLL, LKKK, 2,
        !           513:        LLLL, LQQQ, 2,
        !           514:        LMMM, LPPP, 1,
        !           515:        LNNN, LDDD, 1,
        !           516:        LNNN, LGGG, 1,
        !           517:        LNNN, LKKK, 2,
        !           518:        LNNN, LSSS, 1,
        !           519:        LNNN, LTTT, 1,
        !           520:        LNNN, LXXX, 2,
        !           521:        LNNN, LDCH, 2,
        !           522:        LPPP, LLLL, 2,
        !           523:        LPPP, LRRR, 2,
        !           524:        LRRR, LGGG, 1,
        !           525:        LRRR, LKKK, 2,
        !           526:        LRRR, LMMM, 1,
        !           527:        LRRR, LNNN, 1,
        !           528:        LRRR, LTTT, 1,
        !           529:        LSSS, LPPP, 2,
        !           530:        LSSS, LQQQ, 2,
        !           531:        LSSS, LTTT, 1,
        !           532:        LTTT, LRRR, 2,
        !           533:        LTTT, LDCH, 2,
        !           534:        LWWW, LHHH, 2,
        !           535:        LWWW, LLLL, 2,
        !           536:        LWWW, LNNN, 2,
        !           537:        LWWW, LRRR, 2,
        !           538:        LDCH, LLLL, 2,
        !           539:        LDCH, LRRR, 2,
        !           540:        LDDD, LGGG, 2,
        !           541:        LDDD, LRRR, 2,
        !           542:        LDGH, LTTT, 2,
        !           543:        LDPH, LRRR, 2,
        !           544:        LDTH, LRRR, 2,
        !           545:        LNUL
        !           546: };
        !           547: 
        !           548: /* end of hyphen.c */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.