Annotation of coherent/d/bin/nroff/process.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * process.c
        !             3:  * nroff/Troff.
        !             4:  * Formatting.
        !             5:  * This source module does the serious work.
        !             6:  * Environmental variables:
        !             7:  *     nlinptr points to next location in linebuf[]
        !             8:  *     nlinsiz contains current horizontal size of linebuf[]
        !             9:  *     nlindir contains non-space directive count
        !            10:  *     llinsiz contains horizontal size to end of last word which fits
        !            11:  *     tlinsiz contains horizontal size to previous tab (before expansion)
        !            12:  * Very confusing, the way the buffering works should be cleaned up eventually.
        !            13:  */
        !            14: 
        !            15: #include <ctype.h>
        !            16: #include "roff.h"
        !            17: 
        !            18: #define        CHYPHEN '-'                             /* hyphenation character */
        !            19: 
        !            20: /*
        !            21:  * Make sure there is space to add another command.
        !            22:  */
        !            23: chkcode()
        !            24: {
        !            25:        if (nlinptr >= &linebuf[LINSIZE])
        !            26:                panic("line buffer overflow");
        !            27: }
        !            28: 
        !            29: /* Flush buffered data to avoid buffer overflow. */
        !            30: flush(hpos) register int hpos;
        !            31: {
        !            32:        if (hpos)
        !            33:                hormove(-hpos);         /* reset output writer position to margin */
        !            34:        if (cdivp == mdivp)
        !            35:                flushl(linebuf, nlinptr);
        !            36:        else
        !            37:                flushd(linebuf, nlinptr);
        !            38:        setline();                      /* reset buffer pointers */
        !            39:        if (hpos)
        !            40:                hormove(hpos);          /* restore horizontal position */
        !            41: }
        !            42: 
        !            43: /*
        !            44:  * Add a character.
        !            45:  * Bump the directive count and nlinsiz.
        !            46:  */
        !            47: addchar(f, w) int f; register int w;
        !            48: {
        !            49:        chkcode();
        !            50:        nlinptr->c_arg.c_code = f & 0xFF;
        !            51:        nlinptr++->c_arg.c_move = w;
        !            52:        nlindir++;
        !            53:        nlinsiz += w;
        !            54:        spcnt = 0;
        !            55: }
        !            56: 
        !            57: /*
        !            58:  * Add a directive which takes an integer argument.
        !            59:  */
        !            60: addidir(d, i)
        !            61: {
        !            62:        chkcode();
        !            63:        nlinptr->l_arg.c_code = d;
        !            64:        nlinptr++->l_arg.c_iarg = i;
        !            65:        spcnt = 0;
        !            66: }
        !            67: 
        !            68: /*
        !            69:  * Add a transparent buffer directive.
        !            70:  */
        !            71: addtrab(bp) char *bp;
        !            72: {
        !            73:        chkcode();
        !            74:        nlinptr->b_arg.c_code = DTRAB;
        !            75:        nlinptr++->b_arg.c_bufp = bp;
        !            76: }
        !            77: 
        !            78: /*
        !            79:  * Process input, formatting text.
        !            80:  */
        !            81: process()
        !            82: {
        !            83:        register int c, w;
        !            84:        REG *rp;
        !            85:        int lastc, n;
        !            86:        char charbuf[CBFSIZE], name[2];
        !            87:        unsigned char *cp;
        !            88: 
        !            89:        c = '\n';
        !            90:        for (;;) {
        !            91:                lastc = c;
        !            92:                c = getf(1);
        !            93:        next:
        !            94:                switch (c) {
        !            95:                case EOF:               /* End of file */
        !            96:                        dprintd(DBGFILE|DBGPROC, ".end of file\n");
        !            97:                        return;
        !            98:                case EBEG:              /* Open brace \{ */
        !            99:                case EEND:              /* Close brace \} */
        !           100:                        continue;       /* ignore braces in plain text */
        !           101:                case EESC:              /* Printable version of escape */
        !           102:                        dprintd(DBGPROC, ".printable escape\n");
        !           103:                        character(esc);
        !           104:                        continue;
        !           105:                case EACA:              /* Acute accent */
        !           106:                        dprintd(DBGPROC, ".acute accent\n");
        !           107:                        character('\'');
        !           108:                        continue;
        !           109:                case EGRA:              /* Grave accent */
        !           110:                        dprintd(DBGPROC, ".grave accent\n");
        !           111:                        character('`');
        !           112:                        continue;
        !           113:                case EMIN:              /* Minus sign */
        !           114:                        dprintd(DBGPROC, ".minus sign\n");
        !           115:                        character('-');
        !           116:                        continue;
        !           117:                case EUNP:              /* Unpaddable space */
        !           118:                        dprintd(DBGPROC, ".unpaddable space\n");
        !           119:                        hormove(ssz);
        !           120:                        continue;
        !           121:                case EM06:              /* 1/6 em (narrow space) */
        !           122:                        dprintd(DBGPROC, ".narrow space\n");
        !           123:                        hormove(unit(SMNARS, SDNARS));
        !           124:                        continue;
        !           125:                case EM12:              /* 1/12 em (half narrow space) */
        !           126:                        dprintd(DBGPROC, ".half narrow space\n");
        !           127:                        hormove(unit(SMNARS, SDNARS*2));
        !           128:                        continue;
        !           129:                case ENOP:              /* Zero width character */
        !           130:                        dprintd(DBGPROC, ".zero width character\n");
        !           131:                        continue;
        !           132:                case ETLI:              /* Transparent line indicator */
        !           133:                        dprintd(DBGPROC, ".transparent line indicator\n");
        !           134:                        for (cp = charbuf; ; c = *cp++ = getl(0)) {
        !           135:                                if (c == '\n' || cp == &charbuf[CBFSIZE-1]) {
        !           136:                                        *cp = '\0';
        !           137:                                        addtrab(duplstr(charbuf));
        !           138:                                        if (c == '\n')
        !           139:                                                break;
        !           140:                                        cp = charbuf;
        !           141:                                }
        !           142:                        }
        !           143:                        continue;
        !           144:                case EHYP:              /* Potential hyphenation break */
        !           145:                        dprintd(DBGPROC, ".hyphen break\n");
        !           146:                        addidir(DHYPH, 0);
        !           147:                        continue;
        !           148:                case EBRA:              /* Bracket building function */
        !           149:                        dprintd(DBGPROC, ".bracket building\n");
        !           150: #if    1
        !           151:                        printu("bracket building");             /* $$TO_DO$$ */
        !           152:                        continue;
        !           153: #else
        !           154:                        /*
        !           155:                         * The following does not work with special characters
        !           156:                         * which include font escape sequences.
        !           157:                         */
        !           158:                        scandel(charbuf, CBFSIZE);
        !           159:                        for (w = 0, cp = charbuf; *cp; cp++) {
        !           160:                                n = width(trantab[*cp]);
        !           161:                                if (n > w)
        !           162:                                        w = n;                  /* max width */
        !           163:                        }
        !           164:                        n = cp - charbuf;                       /* count */
        !           165:                        vermove(unit(-SMVEMS * (n - 1), SDVEMS * 2));
        !           166:                        for (cp = charbuf; *cp; cp++) {
        !           167:                                addchar(trantab[*cp], 0);
        !           168:                                vermove(unit(SMVEMS, SDVEMS));
        !           169:                        }
        !           170:                        vermove(unit(-SMVEMS * (n + 1), SDVEMS * 2));
        !           171:                        hormove(w);
        !           172:                        continue;
        !           173: #endif
        !           174:                case EINT:              /* Interrupt text processing */
        !           175:                        dprintd(DBGPROC, ".interrupt proc\n");
        !           176:                        if ((c=getf(0)) != '\n')
        !           177:                                goto next;
        !           178:                        continue;
        !           179:                case EVNF:              /* 1/2 em vertical motion */
        !           180:                        dprintd(DBGPROC, ".half vertical\n");
        !           181:                        vermove(unit(SMVEMS, SDVEMS*2));
        !           182:                        continue;
        !           183:                case EFON:              /* Change font */
        !           184:                        if ((c=getf(0)) != '(') {
        !           185:                                name[0] = c;
        !           186:                                name[1] = '\0';
        !           187:                        } else {
        !           188:                                name[0] = getf(0);
        !           189:                                name[1] = getf(0);
        !           190:                        }
        !           191:                        dprint3(DBGPROC, ".font change to %c%c\n", name[0], name[1]);
        !           192:                        setfont(name, 1);
        !           193:                        continue;
        !           194:                case EHMT:              /* Local horizontal motion */
        !           195:                        n = scandel(charbuf, CBFSIZE) ? numb(charbuf, SMEMSP, SDEMSP) : 0;
        !           196:                        dprint2(DBGPROC, ".local horiz motion = %d\n", n);
        !           197:                        hormove(n);
        !           198:                        continue;
        !           199:                case EMAR:              /* Mark horizontal input place */
        !           200:                        name[0] = c = getf(0);
        !           201:                        name[1] = '\0';
        !           202:                        dprint3(DBGPROC, ".mark horizontal input in %c at %d\n", c, nlinsiz);
        !           203:                        rp = getnreg(name);
        !           204:                        rp->n_reg.r_nval = nlinsiz;
        !           205:                        continue;
        !           206:                case EHLF:              /* Horizontal line drawing function */
        !           207:                        n = scandel(charbuf, CBFSIZE) ? numb(charbuf, 1L, 1L) : 0;
        !           208:                        dprint2(DBGPROC, ".horiz line %d\n", n);
        !           209:                        draw_line(n, 1);
        !           210:                        continue;
        !           211:                case EVLF:              /* Vertical line drawing function */
        !           212:                        n = scandel(charbuf, CBFSIZE) ? numb(charbuf, 1L, 1L) : 0;
        !           213:                        dprint2(DBGPROC, ".vert line %d\n", n);
        !           214:                        draw_line(n, 0);
        !           215:                        continue;
        !           216:                case EOVS:              /* Overstrike */
        !           217:                        dprintd(DBGPROC, ".overstrike\n");
        !           218:                        scandel(charbuf, CBFSIZE);
        !           219:                        for (w = 0, cp = charbuf; *cp; cp++) {
        !           220:                                n = width(trantab[*cp]);
        !           221:                                if (n > w)
        !           222:                                        w = n;                  /* max width */
        !           223:                        }
        !           224:                        for (cp = charbuf; *cp; cp++) {
        !           225:                                n = width(trantab[*cp]);
        !           226:                                hormove((w-n)/2);
        !           227:                                addchar(trantab[*cp], 0);       /* centered */
        !           228:                                hormove((n-w)/2);
        !           229:                        }
        !           230:                        hormove(w);
        !           231:                        continue;
        !           232:                case ESPR:              /* Break and spread output line */
        !           233:                        dprintd(DBGPROC, ".break and spread\n");
        !           234:                        wordbreak(DNULL);
        !           235:                        linebreak(1);
        !           236:                        continue;
        !           237:                case EVRM:              /* Reverse 1 em vertically */
        !           238:                        dprintd(DBGPROC, ".reverse vertical\n");
        !           239:                        vermove(unit(-SMVEMS, SDVEMS));
        !           240:                        continue;
        !           241:                case EPSZ:              /* Change pointsize */
        !           242:                        dprintd(DBGPROC, ".pointsize change\n");
        !           243:                        if (scanoptdel(charbuf, CBFSIZE)) {
        !           244:                                n = number(charbuf, SMPOIN, SDPOIN, psz, 0, oldpsz);
        !           245:                                if (n == 0)
        !           246:                                        n = oldpsz;
        !           247:                                newpsze(n);
        !           248:                        }
        !           249:                        continue;
        !           250:                case EVRN:              /* Reverse 1 en vertically */
        !           251:                        dprintd(DBGPROC, ".reverse 1 en vert\n");
        !           252:                        vermove(unit(-SMVEMS, SDVEMS*2));
        !           253:                        continue;
        !           254:                case EVMT:              /* Local vertical motion */
        !           255:                        n = scandel(charbuf, CBFSIZE) ? number(charbuf, SMUNIT, SDUNIT, 0, 1, 0) : 0;
        !           256:                        dprint2(DBGPROC, ".local vert move %d\n", n);
        !           257:                        vermove(n);
        !           258:                        continue;
        !           259:                case EXLS:              /* Extra line spacing */
        !           260:                        n = scandel(charbuf, CBFSIZE) ? number(charbuf, SMUNIT, SDUNIT, 0, 1, 0) : 0;
        !           261:                        dprint2(DBGPROC, ".extra line space %d\n", n);
        !           262:                        if (n < 0) {
        !           263:                                if (-n > preexls)
        !           264:                                        preexls = -n;
        !           265:                        } else {
        !           266:                                if (n > posexls)
        !           267:                                        posexls = n;
        !           268:                        }
        !           269:                        continue;
        !           270:                case EZWD:              /* Print character with zero width */
        !           271:                        dprintd(DBGPROC, ".print with zero width\n");
        !           272:                        addchar(trantab[getf(0)], 0);
        !           273:                        continue;
        !           274:                case ECOD:              /* Processed text */
        !           275:                        dprintd(DBGPROC, ".processed text\n");
        !           276:                        c = diverse();
        !           277:                        lastc = '\n';
        !           278:                        goto next;
        !           279:                case '\001':
        !           280:                case ELDR:
        !           281:                        dprintd(DBGPROC, ".leader character\n");
        !           282:                        wordbreak(DHMOV);
        !           283:                        movetab(ldc);
        !           284:                        continue;
        !           285:                case '\t':
        !           286:                case ETAB:
        !           287:                        dprintd(DBGPROC, ".tab\n");
        !           288:                        wordbreak(DHMOV);
        !           289:                        movetab(tbc);
        !           290:                        continue;
        !           291:                case '\n':
        !           292:                        dprintd(DBGPROC, ".newline\n");
        !           293:                        wordbreak(DPADC);
        !           294:                        switch (lastc) {
        !           295:                        case '\n':
        !           296:                                setbreak();
        !           297:                                nlindir++;
        !           298:                                setbreak();
        !           299:                                break;
        !           300:                        case '.':
        !           301:                        case '!':
        !           302:                        case '?':
        !           303:                                pad(2 * ssz);
        !           304:                                break;
        !           305:                        default:
        !           306:                                pad(ssz);
        !           307:                        }
        !           308:                        if (fill == 0 || cec != 0) {
        !           309:                                linebreak(1);
        !           310:                                if (cec != 0)
        !           311:                                        --cec;
        !           312:                        }
        !           313:                        if (ulc) {
        !           314:                                if (--ulc == 0)
        !           315:                                        setfontnum(ufp, 1);
        !           316:                        }
        !           317:                        if (inpltrc) {
        !           318:                                if (--inpltrc == 0)
        !           319:                                        execute(inptrap);
        !           320:                        }
        !           321:                        continue;
        !           322:                case ' ':
        !           323:                        if (lastc == '\n')
        !           324:                                setbreak();
        !           325:                        else
        !           326:                                wordbreak(DPADC);
        !           327:                        if (fill || varsp) {
        !           328:                                pad(ssz);
        !           329:                                continue;
        !           330:                        }
        !           331:                case EDWS:              /* Digit width space */
        !           332:                        dprintd(DBGPROC, ".digit width space\n");
        !           333:                        hormove(width('0'));
        !           334:                        continue;
        !           335:                default:
        !           336:                        if (lastc == '\n') {
        !           337:                                if (c == ccc) {
        !           338:                                        request();
        !           339:                                        c = '\n';
        !           340:                                        continue;
        !           341:                                } else if (c == nbc) {
        !           342:                                        nbrflag = 1;
        !           343:                                        request();
        !           344:                                        nbrflag = 0;
        !           345:                                        c = '\n';
        !           346:                                        continue;
        !           347:                                }
        !           348:                        }
        !           349: #if    0
        !           350:                        /* Ignore non-ASCII characters. */
        !           351:                        if (!isascii(c))
        !           352:                                continue;
        !           353: #endif
        !           354:                        character(trantab[c]);
        !           355:                }
        !           356:        }
        !           357: }
        !           358: 
        !           359: /*
        !           360:  * Draw a horizontal (if hflag) or vertical (if !hflag) line of given length.
        !           361:  * This does not handle line drawing with characters other than '_' or '|';
        !           362:  * to make it do so, modify number() to store a pointer past the last used char.
        !           363:  * If len is positive, draw right or draw down.
        !           364:  * If len is negative, move horizontally and then draw right, or draw up.
        !           365:  */
        !           366: draw_line(len, hflag) register int len; int hflag;
        !           367: {
        !           368:        register int c, move, hmove, vmove, hpos, negflag, count, excess, savfont;
        !           369: 
        !           370:        if (len == 0)
        !           371:                return;                         /* no work */
        !           372:        hpos = nlinsiz;                         /* current horizontal position */
        !           373:        if (hflag && len > 0)
        !           374:                hpos += len;                    /* hpos after line drawn */
        !           375: 
        !           376: #if    1
        !           377:        /*
        !           378:         * Implement PostScript lines with PostScript.
        !           379:         * If conditionalized out, troff -p uses character line drawing.
        !           380:         */
        !           381:        if (pflag) {
        !           382:                addidir((hflag) ? DHLIN : DVLIN, len);
        !           383:                flush(hpos);
        !           384:                return;
        !           385:        }
        !           386: #endif
        !           387:        negflag = (len < 0);                    /* movement is negative */
        !           388:        if (negflag)
        !           389:                len = -len;                     /* absolute length */
        !           390:        savfont = curfont;
        !           391:        dev_font(ufn);                          /* use underline font */
        !           392:        if (hflag) {
        !           393:                /* Horizontal line. */
        !           394:                c = '_';                        /* character */
        !           395:                move = hmove = width(c);        /* horizontal movement */
        !           396:                vmove = 0;                      /* vertical movement */
        !           397:        } else {
        !           398:                /* Vertical line. */
        !           399:                c = '|';                        /* character */
        !           400:                hmove = 0;                      /* effective width */
        !           401:                move = vmove = unit(SMVEMS, SDVEMS);    /* movement */
        !           402:                hormove(-width(c)/2);           /* center the '|' */
        !           403:                if (!negflag)
        !           404:                        vermove(vmove);         /* start below current pos */
        !           405:        }
        !           406:        count = len / move;                     /* number of full chars */
        !           407:        excess = len % move;                    /* remainder */
        !           408:        if (negflag) {
        !           409:                if (hflag)
        !           410:                        hormove(-len);          /* back up horizontally */
        !           411:                else {
        !           412:                        vmove = -vmove;         /* draw vertical line upward */
        !           413:                        excess = -excess;
        !           414:                }
        !           415:        }
        !           416: 
        !           417:        /* Output single '_' or '|' characters, move appropriately. */
        !           418:        while (count--) {
        !           419:                addchar(c, hmove);
        !           420:                if (vmove)
        !           421:                        vermove(vmove);
        !           422:        }
        !           423: 
        !           424:        /* Fudge last character position for remaining excess. */
        !           425:        if (excess != 0) {
        !           426:                if (hflag)
        !           427:                        hormove(excess - hmove);
        !           428:                else
        !           429:                        vermove(excess - vmove);
        !           430:                addchar(c, hmove);
        !           431:                if (vmove)
        !           432:                        vermove(vmove);
        !           433:        }
        !           434: 
        !           435:        /* Adjust final position. */
        !           436:        if (!hflag) {
        !           437:                hormove(width(c)/2);
        !           438:                if (!negflag)
        !           439:                        vermove(-vmove);
        !           440:        }
        !           441: 
        !           442:        /* Restore original font. */
        !           443:        dev_font(savfont);
        !           444: 
        !           445:        /* Flush to avoid buffer overflow. */
        !           446:        flush(hpos);
        !           447: }
        !           448: 
        !           449: /*
        !           450:  * Horizontal move code.
        !           451:  */
        !           452: hormove(n)
        !           453: int    n;
        !           454: {
        !           455:        addidir(DHMOV, n);
        !           456:        nlinsiz += n;
        !           457: }
        !           458: 
        !           459: /*
        !           460:  * Vertical move code.
        !           461:  */
        !           462: vermove(n)
        !           463: int    n;
        !           464: {
        !           465:        addidir(DVMOV, n);
        !           466:        cdivp->d_rpos += n;
        !           467: }
        !           468: 
        !           469: /*
        !           470:  * Character code.
        !           471:  */
        !           472: character(f) register int f;
        !           473: {
        !           474:        register int w;
        !           475:        CODE *cp;
        !           476: 
        !           477:        /* Should this complain about 0-width characters?  Silent for now. */
        !           478:        w = width(f);                           /* scaled width */
        !           479:        dprint3(DBGCHAR, "** char ='%c', width = %d\n", f, w);
        !           480:        if (csz != 0 && csz != w) {
        !           481:                /*
        !           482:                 * Constant width desired.
        !           483:                 * Adjust previous character width so this character
        !           484:                 * ends up centered in the constant width space.
        !           485:                 */
        !           486:                w = (csz-w) / 2;                /* previous char width adjust */
        !           487:                cp = llinptr - 1;
        !           488:                if (cp >= linebuf && is_char(cp->c_arg.c_code))
        !           489:                        cp->c_arg.c_move += w;
        !           490:                else
        !           491:                        hormove(w);
        !           492:                w = csz - w;                    /* current char width adjust */
        !           493:        }
        !           494:        addchar(f, w);                          /* output a character */
        !           495: }
        !           496: 
        !           497: /*
        !           498:  * Read text from a diversion.
        !           499:  * Whoever thought up the way diversions work in NROFF/TROFF
        !           500:  * should have done something else.
        !           501:  */
        !           502: int
        !           503: diverse()
        !           504: {
        !           505:        register int code, arg;
        !           506:        int c, lastcode, cvls, clsp;
        !           507:        char *tp;
        !           508: 
        !           509:        lastcode = ' ';
        !           510:        for (c = ECOD;  c == ECOD;  c = getf(1)) {
        !           511:                code = codeval.l_arg.c_code;
        !           512:                arg = codeval.l_arg.c_iarg;
        !           513: #if    0
        !           514:                fprintf(stderr, "diverse(): code=%d arg=%d\n", code, arg);
        !           515: #endif
        !           516:                switch (code) {
        !           517:                case DSPAR:
        !           518:                        if (arg==0) {
        !           519:                                break;          /* discard empty newline codes */
        !           520:                        } else if (fill) {
        !           521:                                wordbreak(DPADC);
        !           522:                                padspace(lastcode);
        !           523:                        } else {
        !           524:                                wordbreak(DNULL);
        !           525:                                cvls = vls;
        !           526:                                clsp = lsp;
        !           527:                                vls = 0;
        !           528:                                lsp = 1;
        !           529:                                linebreak(1);
        !           530:                                vls = cvls;
        !           531:                                lsp = clsp;
        !           532:                                sspace(arg);
        !           533:                        }
        !           534:                        if (inpltrc && --inpltrc == 0)
        !           535:                                execute(inptrap);
        !           536:                        break;
        !           537:                case DPADC:
        !           538:                        wordbreak(DPADC);
        !           539:                        if (fill)
        !           540:                                padspace(lastcode);
        !           541:                        else
        !           542:                                pad(arg);
        !           543:                        break;
        !           544:                case DHYPC:
        !           545:                        if (fill) {
        !           546:                                register int    c;
        !           547:        
        !           548:                                addidir(DHYPH, 0);
        !           549:                                while ((c=getf(0))==ECOD
        !           550:                                 && codeval.l_arg.c_code==DSPAR
        !           551:                                 && codeval.l_arg.c_iarg==0 )
        !           552:                                        ;
        !           553:                                if (c!=ECOD || codeval.l_arg.c_code!=DSPAR)
        !           554:                                        panic("cannot dehyphenate");
        !           555:                        } else {
        !           556:                                nlindir++;
        !           557:                                addidir(code, arg);
        !           558:                                nlinsiz += arg;
        !           559:                        }
        !           560:                        break;
        !           561:                case DHMOV:
        !           562:                        nlinsiz += arg;
        !           563:                        /* fall through... */
        !           564:                case DNULL:
        !           565:                case DVMOV:
        !           566:                case DHYPH:
        !           567:                        addidir(code, arg);
        !           568:                        break;
        !           569:                case DFONT:
        !           570:                        dev_font(arg);
        !           571:                        break;
        !           572:                case DPSZE:
        !           573:                        dev_ps(arg);
        !           574:                        break;
        !           575:                case DTRAB:
        !           576:                        tp = codeval.b_arg.c_bufp;
        !           577:                        adscore(tp);
        !           578:                        strp->x3.s_srel = tp;
        !           579:                        break;
        !           580:                default:
        !           581:                        addchar(code, codeval.c_arg.c_move);
        !           582:                        break;
        !           583:                }
        !           584:                lastcode = code;
        !           585:        }
        !           586:        return c;
        !           587: }
        !           588: 
        !           589: pad(n) register int n;
        !           590: {
        !           591:        llinptr->l_arg.c_iarg += n;
        !           592:        nlinsiz += n;
        !           593:        spcnt += n;
        !           594: }
        !           595: 
        !           596: padspace(lastcode) int lastcode;
        !           597: {
        !           598:        switch (lastcode) {
        !           599:        case '!':
        !           600:        case '?':
        !           601:        case '.':
        !           602:                pad(2 * ssz);
        !           603:                break;
        !           604:        default:
        !           605:                pad(ssz);
        !           606:                break;
        !           607:        }
        !           608: }
        !           609: 
        !           610: /*
        !           611:  * End the current line and left justify it.
        !           612:  */
        !           613: setbreak()
        !           614: {
        !           615:        register int savfill;
        !           616: 
        !           617: #if    0
        !           618:        fprintf(stderr, "setbreak()\n");
        !           619: #endif
        !           620:        if (nbrflag)
        !           621:                return;
        !           622:        wordbreak(DNULL);
        !           623:        savfill = fill;
        !           624:        fill = 0;
        !           625:        linebreak(1);
        !           626:        fill = savfill;
        !           627: }
        !           628: 
        !           629: /*
        !           630:  * End the current word.  The given directive type is added onto
        !           631:  * the end of the line.
        !           632:  */
        !           633: wordbreak(dir) int dir;
        !           634: {
        !           635:        int n, s, d;
        !           636: 
        !           637: #if    0
        !           638:        fprintf(stderr, "wordbreak(%d)\n", dir);
        !           639: #endif
        !           640:        if (nlindir == llindir)
        !           641:                return;
        !           642:        if (llinptr == linebuf)
        !           643:                setwork();
        !           644:        else if (fill != 0 && nlinsiz > lln) {
        !           645:                n = nlinptr - (llinptr+1);
        !           646:                s = nlinsiz - llinsiz - llinptr->l_arg.c_iarg;
        !           647:                d = nlindir - llindir;
        !           648:                if (hyp==0 || (hypf = fitword(&n, &s, &d))==0)
        !           649:                        copystr(wordbuf, llinptr+1, sizeof (CODE), n);
        !           650:                if (n > WORSIZE)
        !           651:                        panic("word buffer overflow");
        !           652:                linebreak(0);
        !           653:                hypf = 0;
        !           654:                copystr(nlinptr, wordbuf, sizeof (CODE), n);
        !           655:                nlinptr += n;
        !           656:                nlinsiz += s;
        !           657:                nlindir += d;
        !           658:                setwork();
        !           659:        }
        !           660:        if (mrc != '\0')                /* Added by dag */
        !           661:                mrch = mrc;
        !           662:        llinptr = nlinptr;
        !           663:        llinsiz = nlinsiz;
        !           664:        llindir = nlindir;
        !           665:        addidir(dir, 0);
        !           666: }
        !           667: 
        !           668: /*
        !           669:  * Set up working parameters for the line.
        !           670:  */
        !           671: setwork()
        !           672: {
        !           673:        if (tif)
        !           674:                tif = 0;
        !           675:        else
        !           676:                tin = ind;
        !           677:        linebuf[0].l_arg.c_iarg += tin;
        !           678:        llinsiz += tin;
        !           679:        nlinsiz += tin;
        !           680:        tlinsiz += tin;
        !           681: }
        !           682: 
        !           683: /*
        !           684:  * Try to hyphenate and fit the last word in a line.
        !           685:  * This routine is really part of the routine 'wordbreak'.
        !           686:  * The arguments are pointers to variables in 'wordbreak'.
        !           687:  */
        !           688: fitword(np, sp, dp) int *dp; int *sp; int *np;
        !           689: {
        !           690:        CODE *wp;
        !           691:        int hflag, b1, b2, h, d, s, n, sav;
        !           692:        register CODE *cp;
        !           693:        register int c;
        !           694:        register char *hp;
        !           695: 
        !           696:        hyphen(wp=llinptr+1, nlinptr);
        !           697:        h = width(CHYPHEN);
        !           698:        b1 = nlinsiz - lln;
        !           699:        b2 = b1 + h;
        !           700:        d = 0;
        !           701:        s = 0;
        !           702:        n = 0;
        !           703:        cp = nlinptr;
        !           704:        hp = &hyphbuf[nlinptr-wp];
        !           705:        for (;;) {
        !           706:                if (--cp < wp)
        !           707:                        return 0;
        !           708:                c = cp->l_arg.c_code;
        !           709:                if (cp>wp && c==CHYPHEN && s>=b1) {
        !           710:                        hflag = 0;
        !           711:                        break;
        !           712:                }
        !           713:                if (*--hp) {
        !           714:                        if (s >= b2) {
        !           715:                                hflag = 1;
        !           716:                                break;
        !           717:                        }
        !           718:                }
        !           719:                if (is_char(c)) {
        !           720:                        d++;
        !           721:                        s += cp->c_arg.c_move;
        !           722:                        continue;
        !           723:                }
        !           724:                if (c==DHMOV || c==DPADC) {
        !           725:                        s += cp->l_arg.c_iarg;
        !           726:                        continue;
        !           727:                }
        !           728:        }
        !           729:        n = nlinptr - ++cp;
        !           730:        copystr(wordbuf, cp, sizeof (CODE), n);
        !           731:        llinptr = cp;
        !           732:        llinsiz = nlinsiz - s;
        !           733:        llindir = nlindir - d;
        !           734:        if (hflag) {
        !           735:                nlinptr = llinptr;
        !           736:                sav = nlinsiz;
        !           737:                addchar(CHYPHEN, h);
        !           738:                nlinsiz = sav;
        !           739:                llinptr = nlinptr;
        !           740:                llinsiz += h;
        !           741:                llindir = nlindir;
        !           742:        }
        !           743:        *dp = d;
        !           744:        *sp = s;
        !           745:        *np = n;
        !           746:        return 1;
        !           747: }
        !           748: 
        !           749: /*
        !           750:  * End the current line.
        !           751:  * This must be called after calling wordbreak.
        !           752:  */
        !           753: linebreak(flag) int flag;
        !           754: {
        !           755:        int slsiz, sldir;
        !           756:        CODE *slptr;
        !           757: 
        !           758: #if    0
        !           759:        fprintf(stderr, "linebreak() llindir=%d\n", llindir);
        !           760: #endif
        !           761:        if (llindir == 0) {
        !           762:                if (nlinptr != llinptr)
        !           763:                        lineflush();
        !           764:                return;
        !           765:        }
        !           766:        movetab(EOF);
        !           767:        justify();
        !           768:        if (mrch != '\0' && llinsiz != 0) {
        !           769: 
        !           770:                /* Output margin character at mar from right margin. */
        !           771:                slsiz = nlinsiz;
        !           772:                sldir = nlindir;
        !           773:                slptr = nlinptr;
        !           774:                nlinsiz = llinsiz;
        !           775:                nlinptr = llinptr;
        !           776:                nlindir = llindir;
        !           777: #if    0
        !           778:                /* Debug print-out to stderr */
        !           779:                fprintf(stderr, "margin char %c %d %d %d %d\n",
        !           780:                        mrch, mar, lln, llinsiz, (lln-llinsiz) + mar);
        !           781: #endif
        !           782:                hormove((lln - llinsiz) + mar);
        !           783:                character(mrch);
        !           784:                llinsiz = nlinsiz;
        !           785:                llindir = nlindir;
        !           786:                llinptr = nlinptr;
        !           787:                nlinsiz = slsiz;
        !           788:                nlindir = sldir;
        !           789:                nlinptr = slptr;
        !           790:                mrch = '\0';
        !           791:        }
        !           792:        if (llinsiz > cdivp->d_maxw)
        !           793:                cdivp->d_maxw = llinsiz;
        !           794:        sspace(preexls);
        !           795:        if (cdivp == mdivp) {
        !           796:                n_reg = llinsiz - linebuf[0].l_arg.c_iarg;
        !           797:                /* Kludge nroff output page offset; for troff, cf. output.c. */
        !           798:                if (ntroff == NROFF)
        !           799:                        linebuf[0].l_arg.c_iarg += pof;
        !           800:                flushl(linebuf, llinptr);
        !           801:                nsm = 0;
        !           802:        } else
        !           803:                flushd(linebuf, llinptr);
        !           804:        if (flag && nlinptr != llinptr)
        !           805:                lineflush();
        !           806:        a_reg = posexls;
        !           807:        setline();
        !           808:        lspace(vls+posexls);
        !           809:        nrnlreg->n_reg.r_nval = mdivp->d_rpos;
        !           810:        sspace((lsp-1)*vls);
        !           811: }
        !           812: 
        !           813: /*
        !           814:  * The unflushed part of a buffered line can contain significant directives,
        !           815:  * notably pointsize and font changes.
        !           816:  * This flushes directives which would otherwise get ignored.
        !           817:  * There must be a better way...
        !           818:  */
        !           819: lineflush()
        !           820: {
        !           821:        register CODE *cp;
        !           822: 
        !           823:        for (cp = llinptr; cp < nlinptr; cp++) {
        !           824:                switch(cp->l_arg.c_code) {
        !           825:                case DFONT:     break;
        !           826:                case DPSZE:     break;
        !           827:                default:        continue;
        !           828:                }
        !           829:                if (cdivp == mdivp)
        !           830:                        flushl(cp, cp+1);
        !           831:                else
        !           832:                        flushd(cp, cp+1);
        !           833:        }
        !           834:        setline();
        !           835: }
        !           836: 
        !           837: /*
        !           838:  * Justify the current line.
        !           839:  */
        !           840: justify()
        !           841: {
        !           842:        register CODE *cp, *cp0;
        !           843:        int t;
        !           844:        register int n, r;
        !           845: 
        !           846:        n = cec  ?  CJUS  :  (fill==0||adm==0) ? LJUS : adj;
        !           847:        switch (n) {
        !           848:        case LJUS:
        !           849:                n = 0;
        !           850:                break;
        !           851:        case CJUS:
        !           852:                n = (lln-llinsiz) / 2;
        !           853:                break;
        !           854:        case RJUS:
        !           855:                n = lln - llinsiz;
        !           856:                break;
        !           857:        case FJUS:
        !           858:                r = 0;
        !           859:                /*
        !           860:                 * Walk backward through the line looking for horizontal move.
        !           861:                 * If found, do not pad characters to its left.
        !           862:                 */
        !           863:                for (cp0 = llinptr-1; cp0 > linebuf; cp0--)
        !           864:                         if (cp0->l_arg.c_code == DHMOV)
        !           865:                                break;
        !           866:                for (cp = cp0; cp < llinptr; cp++)
        !           867:                        if (cp->l_arg.c_code == DPADC)
        !           868:                                r++;            /* paddable character count */
        !           869:                if (r == 0)
        !           870:                        return;                 /* no paddable characters */
        !           871:                n = lln - llinsiz;              /* padding required */
        !           872: 
        !           873:                /*
        !           874:                 * Because tabs get expanded ex post facto,
        !           875:                 * a tab in fill mode can make the line grow too large.
        !           876:                 * If the line requires negative padding, tough matzohs.
        !           877:                 * Avoid tabs in fill mode!
        !           878:                 */
        !           879:                if (n < 0)
        !           880:                        return;
        !           881:                t = n%r;                        /* padding remainder */
        !           882:                n = 1 + n/r;                    /* starting pad amount */
        !           883:                r = t;                          /* to do before decrementing */
        !           884:                for (cp = cp0; cp < llinptr; cp++) {
        !           885:                        if (cp->l_arg.c_code != DPADC)
        !           886:                                continue;
        !           887:                        if (r-- == 0)
        !           888:                                --n;            /* decrement padding amount */
        !           889:                        cp->l_arg.c_iarg += n;  /* pad by n */
        !           890:                }
        !           891:                llinsiz = lln;                  /* dag for mrc/mrch */
        !           892:                return;
        !           893:        }
        !           894:        llinsiz += n;                           /* dag for mrc/mrch */
        !           895:        linebuf[0].l_arg.c_iarg += n;
        !           896: }
        !           897: 
        !           898: /*
        !           899:  * Tab to the next tab stop, filling intermediate space with character c.
        !           900:  * Because center and right justified tab spacing is determined by the
        !           901:  * text following the tab, the code determines the spacing for
        !           902:  * the tab before the one entered; arg c==EOF is passed
        !           903:  * at the end of a line to finish up the final tab stop.
        !           904:  * This must be called right after calling wordbreak().
        !           905:  */
        !           906: movetab(c) int c;
        !           907: {
        !           908:        register TAB *tp;
        !           909:        int n, w, d2, savfont, ls;
        !           910:        register int d, d1;
        !           911:        register int pos;
        !           912: 
        !           913:        ls = (nlinsiz != llinsiz) ? nlinsiz : llinsiz;
        !           914:        if (spcnt) {
        !           915:                /* Adjust for space padding following tab. */
        !           916:                llinsiz -= spcnt;
        !           917:                ls -= spcnt;
        !           918:        }
        !           919:        tp = tabptr;
        !           920:        pos = tp->t_pos;
        !           921:        if (cdivp == mdivp)
        !           922:                pos += tin;             /* relative to indent */
        !           923: #if    0
        !           924:        fprintf(stderr, "movetab(%d) tab#%d ltabchr=%d pos=%d tlinsiz=%d ls=%d\n",
        !           925:                c, tabptr-tab, ltabchr, pos, tlinsiz, ls);
        !           926: #endif
        !           927:        switch (tp->t_jus) {
        !           928:        case LJUS:
        !           929:                d = pos - tlinsiz;
        !           930:                break;
        !           931:        case CJUS:
        !           932:                d = pos - (ls+tlinsiz)/2;
        !           933:                break;
        !           934:        case RJUS:
        !           935:                d = pos - ls;
        !           936:                break;
        !           937:        case NJUS:
        !           938:                llinptr->l_arg.c_iarg += ssz;
        !           939:                return;
        !           940:        }
        !           941:        if (ltabchr == 0) {
        !           942:                /* Blank tabs. */
        !           943:                tlinptr->l_arg.c_iarg += d;
        !           944:        } else {
        !           945:                /* Leader dots or nonblank tabs. */
        !           946:                if ((n = nlinptr - (tlinptr+1)) > WORSIZE)
        !           947:                        panic("word buffer overflow");
        !           948:                copystr(wordbuf, tlinptr+1, sizeof (CODE), n);  /* save */
        !           949:                nlinptr = tlinptr + 1;
        !           950:                savfont = curfont;
        !           951:                dev_font(tfn);                          /* tab font */
        !           952:                if ((w = tbs) == 0)
        !           953:                        w = width(ltabchr);             /* tab char width */
        !           954:                if ((d2 = (d1 = tlinsiz) % w) != 0) {
        !           955:                        /* Futz start position to tab char width multiple. */
        !           956:                        d1 += w-d2;
        !           957:                        tlinptr->l_arg.c_iarg += w-d2;
        !           958:                }
        !           959:                d2 = tlinsiz + d;                       /* end position */
        !           960:                while ((d1 += w) <= d2)
        !           961:                        addchar(ltabchr, w);            /* write a tab char */
        !           962:                addidir(DHMOV, d2-(d1-w));              /* skip remaining space */
        !           963:                dev_font(savfont);                      /* restore font */
        !           964:                if (nlinptr+n >= &linebuf[LINSIZE])
        !           965:                        panic("line buffer overflow");
        !           966:                copystr(nlinptr, wordbuf, sizeof (CODE), n);    /* restore */
        !           967:                llinptr = nlinptr += n;
        !           968:                --llinptr;
        !           969:        }
        !           970:        tlinsiz = nlinsiz = llinsiz += d;
        !           971:        tlinptr = llinptr;
        !           972:        if (c == EOF)
        !           973:                return;
        !           974:        ls = (cdivp == mdivp) ? llinsiz-tin : llinsiz;
        !           975:        while ((++tp)->t_jus != NJUS && tp->t_pos <= ls)
        !           976:                ;
        !           977:        tabptr = tp;
        !           978:        ltabchr = c;
        !           979: }
        !           980: 
        !           981: /*
        !           982:  * Initialize line data for a new line.
        !           983:  */
        !           984: setline()
        !           985: {
        !           986: #if    0
        !           987:        fprintf(stderr, "setline()\n");
        !           988: #endif
        !           989:        llinptr = nlinptr = tlinptr = linebuf;
        !           990:        llinsiz = nlinsiz = tlinsiz = 0;
        !           991:        llindir = nlindir = 0;
        !           992:        tabptr = tab;
        !           993:        ltabchr = '\0';
        !           994:        preexls = posexls = 0;
        !           995:        addidir(DHMOV, 0);
        !           996: }
        !           997: 
        !           998: /* end of process.c */

unix.superglobalmegacorp.com

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