Annotation of coherent/g/usr/lib/ncurses/lib_mvcur.c, revision 1.1

1.1     ! root        1: /*********************************************************************
        !             2: *                         COPYRIGHT NOTICE                           *
        !             3: **********************************************************************
        !             4: *        This software is copyright (C) 1982 by Pavel Curtis         *
        !             5: *                                                                    *
        !             6: *        Permission is granted to reproduce and distribute           *
        !             7: *        this file by any means so long as no fee is charged         *
        !             8: *        above a nominal handling fee and so long as this            *
        !             9: *        notice is always included in the copies.                    *
        !            10: *                                                                    *
        !            11: *        Other rights are reserved except as explicitly granted      *
        !            12: *        by written permission of the author.                        *
        !            13: *                Pavel Curtis                                        *
        !            14: *                Computer Science Dept.                              *
        !            15: *                405 Upson Hall                                      *
        !            16: *                Cornell University                                  *
        !            17: *                Ithaca, NY 14853                                    *
        !            18: *                                                                    *
        !            19: *                Ph- (607) 256-4934                                  *
        !            20: *                                                                    *
        !            21: *                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
        !            22: *                decvax!cornell!pavel       (UUCPnet)                *
        !            23: *********************************************************************/
        !            24: 
        !            25: /*
        !            26: **
        !            27: **     lib_mvcur.c
        !            28: **
        !            29: **     mvcur() and its subroutines
        !            30: **
        !            31: ** $Log:       lib_mvcur.c,v $
        !            32:  * Revision 1.8  93/04/12  14:13:47  bin
        !            33:  * Udo: third color update
        !            34:  * 
        !            35:  * Revision 1.2  92/04/13  14:37:43  bin
        !            36:  * update by vlad
        !            37:  * 
        !            38:  * Revision 2.2  91/04/20  19:25:30  munk
        !            39:  * Usage of register variables
        !            40:  *
        !            41:  * Revision 2.1  82/10/25  14:47:54  pavel
        !            42:  * Added Copyright Notice
        !            43:  * 
        !            44:  * Revision 2.0  82/10/25  13:46:40  pavel
        !            45:  * Beta-one Test Release
        !            46:  * 
        !            47: **
        !            48: **     Revisions needed:
        !            49: **             implement c_save instead of multiple tputs() calls
        !            50: **             routine revisions
        !            51: */
        !            52: 
        !            53: #ifdef RCSHDR
        !            54: static char RCSid[] =
        !            55:        "$Header: /src386/usr/lib/ncurses/RCS/lib_mvcur.c,v 1.8 93/04/12 14:13:47 bin Exp Locker: bin $";
        !            56: #endif
        !            57: 
        !            58: #include "term.h"
        !            59: #include "curses.h"
        !            60: #include "curses.priv.h"
        !            61: 
        !            62: 
        !            63: #define BUFSIZE        128                     /* size of strategy buffer */
        !            64: 
        !            65: struct Sequence
        !            66: {
        !            67:        int     vec[BUFSIZE],   /* vector of operations */
        !            68:                *end,           /* end of vector */
        !            69:                cost;           /* cost of vector */
        !            70: };
        !            71: 
        !            72: /*
        !            73: **     #define
        !            74: **     Make_seq_best(s1, s2)
        !            75: **     
        !            76: **     Make_seq_best() swaps the values
        !            77: **     of the pointers if s1->cost > s2->cost.
        !            78: */
        !            79: 
        !            80: #define Make_seq_best(s1, s2)          \
        !            81:        if (s1->cost > s2->cost)        \
        !            82:        {                               \
        !            83:            struct Sequence     *temp;  \
        !            84:                                        \
        !            85:            temp = s1;                  \
        !            86:            s1 = s2;                    \
        !            87:            s2 = temp;                  \
        !            88:        }                               
        !            89: 
        !            90: 
        !            91: FILE   *out_file;                              /* pointer to output file */
        !            92: 
        !            93: static int     c_count;                /* used for counting tputs output */
        !            94: 
        !            95: /*rev c_save not yet used*/
        !            96: /*static char  *c_save;*/              /* used for saving tputs output */
        !            97: 
        !            98: #define        INFINITY        1000            /* biggest, impossible sequence cost */
        !            99: 
        !           100: #define NUM_OPS                16              /* num. term. control sequences */
        !           101: #define NUM_NPARM      9               /* num. ops wo/ parameters */
        !           102: 
        !           103:        /* operator indexes into op_info */
        !           104: 
        !           105: #define        CARRIAGE_RETURN 0               /* watch out for nl mapping */
        !           106: #define        CURS_DOWN       1
        !           107: #define        CURS_HOME       2
        !           108: #define        CURS_LEFT       3
        !           109: #define        CURS_RIGHT      4
        !           110: #define        CURS_TO_LL      5
        !           111: #define        CURS_UP         6
        !           112: #define        TAB             7
        !           113: #define        BACK_TAB        8
        !           114: #define        ROW_ADDR        9
        !           115: #define        COL_ADDR        10
        !           116: #define        P_DOWN_CURS     11
        !           117: #define        P_LEFT_CURS     12
        !           118: #define        P_RIGHT_CURS    13
        !           119: #define        P_UP_CURS       14
        !           120: #define        CURS_ADDR       15
        !           121: 
        !           122: static bool    loc_init = FALSE;       /* set if op_info is init'ed */
        !           123: 
        !           124: static bool    rel_ok;                 /* set if we really know where we are */
        !           125: 
        !           126: /*
        !           127:  *     op_info[NUM_OPS]
        !           128:  *
        !           129:  *     op_info[] contains for operations with no parameters
        !           130:  *  the cost of the operation.  These ops should be first in the array.
        !           131:  *     For operations with parameters, op_info[] contains
        !           132:  *  the negative of the number of parameters.
        !           133:  */
        !           134: 
        !           135: static int     op_info[NUM_OPS] =
        !           136: {
        !           137:        0,              /* carriage_return */
        !           138:        0,              /* cursor_down */
        !           139:        0,              /* cursor_home */
        !           140:        0,              /* cursor_left */
        !           141:        0,              /* cursor_right */
        !           142:        0,              /* cursor_to_ll */
        !           143:        0,              /* cursor_up */
        !           144:        0,              /* tab */
        !           145:        0,              /* back_tab */
        !           146:        -1,             /* row_address */
        !           147:        -1,             /* column_address */
        !           148:        -1,             /* parm_down_cursor */
        !           149:        -1,             /* parm_left_cursor */
        !           150:        -1,             /* parm_right_cursor */
        !           151:        -1,             /* parm_up_cursor */
        !           152:        -2              /* cursor_address */
        !           153: };
        !           154: 
        !           155: 
        !           156: /*
        !           157: **
        !           158: **     mvcur(oldrow, oldcol, newrow, newcol)
        !           159: **
        !           160: **     mvcur() optimally moves the cursor from the position
        !           161: **  specified by (oldrow, oldcol) to (newrow, newcol).  If
        !           162: **  (oldrow, oldcol) == (-1, -1), mvcur() does not use relative
        !           163: **  cursor motions.  If the coordinates are otherwise
        !           164: **  out of bounds, it mods them into range.
        !           165: **
        !           166: **     Revisions needed:
        !           167: **             eat_newline_glitch, auto_right_margin
        !           168: */
        !           169: 
        !           170: mvcur(oldrow, oldcol, newrow, newcol)
        !           171: int    oldrow, oldcol,
        !           172:        newrow, newcol;
        !           173: {
        !           174:        struct Sequence seqA, seqB,     /* allocate work structures */
        !           175:                        col0seq,        /* sequence to get from col0 to nc */
        !           176:                        *best,          /* best sequence so far */
        !           177:                        *try;           /* next try */
        !           178: 
        !           179: #ifdef TRACE
        !           180:        if (_tracing)
        !           181:            _tracef("mvcur(%d,%d,%d,%d) called",
        !           182:                                                oldrow, oldcol, newrow, newcol);
        !           183: #endif
        !           184: 
        !           185:        update_ops();                   /* make sure op_info[] is current */
        !           186: 
        !           187:        if (oldrow < 0  ||  oldcol < 0)
        !           188:            rel_ok = FALSE;             /* relative ops ok? */
        !           189:        else
        !           190:        {
        !           191:            rel_ok = TRUE;
        !           192: 
        !           193:            oldrow %= lines;            /* mod values into range */
        !           194:            oldcol %= columns;
        !           195:        }
        !           196:        newrow %= lines;
        !           197:        newcol %= columns;
        !           198: 
        !           199:        best = &seqA;
        !           200:        try = &seqB;
        !           201: 
        !           202:                /* try out direct cursor addressing */
        !           203: 
        !           204:        zero_seq(best);
        !           205:        add_op(best, CURS_ADDR, newrow, newcol);
        !           206: 
        !           207:                /* try out independent row/column addressing */
        !           208: 
        !           209:        if (rel_ok)
        !           210:        {
        !           211:            zero_seq(try);
        !           212:            row(try, oldrow, newrow);
        !           213:            column(try, oldcol, newcol);
        !           214:            Make_seq_best(best, try);
        !           215:        }
        !           216: 
        !           217:        zero_seq(&col0seq);             /* store seq. to get from c0 to nc */
        !           218:        column(&col0seq, 0, newcol);
        !           219: 
        !           220:        if(col0seq.cost < INFINITY)     /* can get from col0 to newcol */
        !           221:        {
        !           222:                    /* try out homing and then row/column */
        !           223: 
        !           224:            if (! rel_ok  ||  newcol < oldcol  ||  newrow < oldrow)
        !           225:            {
        !           226:                zero_seq(try);
        !           227:                add_op(try, CURS_HOME, 1);
        !           228:                row(try, 0, newrow);
        !           229:                add_seq(try, &col0seq);
        !           230:                Make_seq_best(best, try);
        !           231:            }
        !           232: 
        !           233:                    /* try out homing to last line  and then row/column */
        !           234: 
        !           235:            if (! rel_ok  ||  newcol < oldcol  ||  newrow > oldrow)
        !           236:            {
        !           237:                zero_seq(try);
        !           238:                add_op(try, CURS_TO_LL, 1);
        !           239:                row(try, lines - 1, newrow);
        !           240:                add_seq(try, &col0seq);
        !           241:                Make_seq_best(best, try);
        !           242:            }
        !           243:        }
        !           244: 
        !           245: #ifdef TRACE
        !           246:        if (_tracing)
        !           247:            _tracef("\tmvcur: result follows");
        !           248: #endif
        !           249: 
        !           250:        out_seq(best);
        !           251: 
        !           252: #ifdef TRACE
        !           253:        if (_tracing)
        !           254:            _tracef("\tmvcur: end of result");
        !           255: #endif
        !           256: }
        !           257: 
        !           258: 
        !           259: /*
        !           260: **     row(outseq, oldrow, newrow)
        !           261: **
        !           262: **     row() adds the best sequence for moving
        !           263: **  the cursor from oldrow to newrow to seq.
        !           264: **     row() considers row_address, parm_up/down_cursor
        !           265: **  and cursor_up/down.
        !           266: */
        !           267: 
        !           268: static
        !           269: row(outseq, orow, nrow)
        !           270: int            orow, nrow;             /* old, new cursor locations */
        !           271: struct Sequence        *outseq;                /* where to put the output */
        !           272: {
        !           273:        struct Sequence seqA, seqB,
        !           274:                        *best,          /* best sequence so far */
        !           275:                        *try;           /* next try */
        !           276:        int     parm_cursor, one_step;
        !           277: 
        !           278:        best = &seqA;
        !           279:        try = &seqB;
        !           280: 
        !           281:        if (nrow == orow)
        !           282:            return;
        !           283: 
        !           284:        if (nrow < orow)
        !           285:        {
        !           286:            parm_cursor = P_UP_CURS;
        !           287:            one_step = CURS_UP;
        !           288:        }
        !           289:        else
        !           290:        {
        !           291:            parm_cursor = P_DOWN_CURS;
        !           292:            one_step = CURS_DOWN;
        !           293:        }
        !           294: 
        !           295:                /* try out direct row addressing */
        !           296: 
        !           297:        zero_seq(best);
        !           298:        add_op(best, ROW_ADDR, nrow);
        !           299: 
        !           300:                /* try out paramaterized up or down motion */
        !           301: 
        !           302:        if (rel_ok)
        !           303:        {
        !           304:            zero_seq(try);
        !           305:            add_op(try, parm_cursor, abs(orow - nrow));
        !           306:            Make_seq_best(best, try);
        !           307:        }
        !           308:                /* try getting there one step at a time... */
        !           309: 
        !           310:        if (rel_ok)
        !           311:        {
        !           312:            zero_seq(try);
        !           313:            add_op(try, one_step, abs(orow-nrow));
        !           314:            Make_seq_best(best, try);
        !           315:        }
        !           316: 
        !           317:        add_seq(outseq, best);
        !           318: }
        !           319: 
        !           320: 
        !           321: /*
        !           322: **     column(outseq, oldcol, newcol)
        !           323: **
        !           324: **     column() adds the best sequence for moving
        !           325: **  the cursor from oldcol to newcol to outseq.
        !           326: **     column() considers column_address, parm_left/right_cursor,
        !           327: **  simp_col(), and carriage_return followed by simp_col().
        !           328: */
        !           329: 
        !           330: static
        !           331: column(outseq, ocol, ncol)
        !           332: struct Sequence        *outseq;                        /* where to put the output */
        !           333: int            ocol, ncol;                     /* old, new cursor  column */
        !           334: {
        !           335:        struct Sequence seqA, seqB,
        !           336:                        *best, *try;
        !           337:        int             parm_cursor;    /* set to either parm_up/down_cursor */
        !           338: 
        !           339:        best = &seqA;
        !           340:        try = &seqB;
        !           341: 
        !           342:        if (ncol == ocol)
        !           343:            return;
        !           344: 
        !           345:        if (ncol < ocol)
        !           346:            parm_cursor = P_LEFT_CURS;
        !           347:        else
        !           348:            parm_cursor = P_RIGHT_CURS;
        !           349: 
        !           350:                /* try out direct column addressing */
        !           351: 
        !           352:        zero_seq(best);
        !           353:        add_op(best, COL_ADDR, ncol);
        !           354: 
        !           355:                /* try carriage_return then simp_col() */
        !           356: 
        !           357:        if (! rel_ok  ||  (ncol < ocol))
        !           358:        {
        !           359:            zero_seq(try);
        !           360:            add_op(try, CARRIAGE_RETURN, 1);
        !           361:            simp_col(try, 0, ncol);
        !           362:            Make_seq_best(best, try);
        !           363:        }
        !           364:        if (rel_ok)
        !           365:        {
        !           366:                /* try out paramaterized left or right motion */
        !           367: 
        !           368:            zero_seq(try);
        !           369:            add_op(try, parm_cursor, abs(ocol - ncol));
        !           370:            Make_seq_best(best, try);
        !           371: 
        !           372:                /* try getting there with simp_col() */
        !           373: 
        !           374:            zero_seq(try);
        !           375:            simp_col(try, ocol, ncol);
        !           376:            Make_seq_best(best, try);
        !           377:        }
        !           378: 
        !           379:        add_seq(outseq, best);
        !           380: }
        !           381: 
        !           382: 
        !           383: /*
        !           384: **     simp_col(outseq, oldcol, newcol)
        !           385: **
        !           386: **     simp_col() adds the best simple sequence for getting
        !           387: **  from oldcol to newcol to outseq.
        !           388: **     simp_col() considers (back_)tab and cursor_left/right.
        !           389: **
        !           390: **  Revisions needed:
        !           391: **     Simp_col asssumes that the cost of a (back_)tab
        !           392: **  is less then the cost of one-stepping to get to the same column.
        !           393: **     Should sometimes use overprinting instead of cursor_right.
        !           394: */
        !           395: 
        !           396: static
        !           397: simp_col(outseq, oc, nc)
        !           398: struct Sequence        *outseq;                /* place to put sequence */
        !           399: int            oc, nc;                 /* old column, new column */
        !           400: {
        !           401:        struct Sequence seqA, seqB, tabseq,
        !           402:                        *best, *try;
        !           403:        int             mytab, tabs, onepast,
        !           404:                        one_step, opp_step; 
        !           405: 
        !           406:        if (! rel_ok)
        !           407:        {
        !           408:            outseq->cost = INFINITY;
        !           409:            return;
        !           410:        }
        !           411: 
        !           412:        if (oc == nc)
        !           413:            return;
        !           414: 
        !           415:        best = &seqA;
        !           416:        try  = &seqB;
        !           417: 
        !           418:        if (oc < nc)
        !           419:        {
        !           420:            mytab = TAB;
        !           421:            if (init_tabs > 0  &&  op_info[TAB] < INFINITY)
        !           422:            {
        !           423:                tabs = nc / init_tabs - oc / init_tabs;
        !           424:                onepast = ((nc / init_tabs) + 1) * init_tabs;
        !           425:                if (tabs)
        !           426:                    oc = onepast - init_tabs;   /* consider it done */
        !           427:            }
        !           428:            else
        !           429:                tabs = 0;
        !           430: 
        !           431:            one_step = CURS_RIGHT;
        !           432:            opp_step = CURS_LEFT;
        !           433:        }
        !           434:        else
        !           435:        {
        !           436:            mytab = BACK_TAB;
        !           437:            if (init_tabs > 0  &&  op_info[BACK_TAB] < INFINITY)
        !           438:            {
        !           439:                tabs = oc / init_tabs - nc / init_tabs;
        !           440:                onepast = ((nc - 1) / init_tabs) * init_tabs;
        !           441:                if (tabs)
        !           442:                    oc = onepast + init_tabs;   /* consider it done */
        !           443:            }
        !           444:            else
        !           445:                tabs = 0;
        !           446: 
        !           447:            one_step = CURS_LEFT;
        !           448:            opp_step = CURS_RIGHT;
        !           449:        }
        !           450: 
        !           451:                /* tab as close as possible to nc */
        !           452: 
        !           453:        zero_seq(&tabseq);
        !           454:        add_op(&tabseq, mytab, tabs);
        !           455: 
        !           456:                /* try extra tab and backing up */
        !           457: 
        !           458:        zero_seq(best);
        !           459: 
        !           460:        if (onepast >= 0  &&  onepast < columns)
        !           461:        {
        !           462:            add_op(best, mytab, 1);
        !           463:            add_op(best, opp_step, abs(onepast - nc));
        !           464:        }
        !           465:        else
        !           466:            best->cost = INFINITY;      /* make sure of next swap */
        !           467: 
        !           468:                /* try stepping to nc */
        !           469: 
        !           470:        zero_seq(try);
        !           471:        add_op(try, one_step, abs(nc - oc));
        !           472:        Make_seq_best(best, try);
        !           473:        
        !           474:        if (tabseq.cost < INFINITY)
        !           475:            add_seq(outseq, &tabseq);
        !           476:        add_seq(outseq, best);
        !           477: }
        !           478: 
        !           479: 
        !           480: /*
        !           481: **     zero_seq(seq)
        !           482: **     add_seq(seq1, seq2)
        !           483: **     out_seq(seq)
        !           484: **
        !           485: **     zero_seq() empties seq.
        !           486: **     add_seq() adds seq1 to seq2.
        !           487: **     out_seq() outputs a sequence.
        !           488: */
        !           489: 
        !           490: static
        !           491: zero_seq(seq)
        !           492: struct Sequence        *seq;
        !           493: {
        !           494:        seq->end = seq->vec;
        !           495:        seq->cost = 0;
        !           496: }
        !           497: 
        !           498: 
        !           499: static
        !           500: add_seq(seq1, seq2)
        !           501: register struct Sequence *seq1, *seq2;
        !           502: {
        !           503:        int     *vptr;
        !           504: 
        !           505:        if(seq1->cost >= INFINITY  ||  seq2->cost >= INFINITY)
        !           506:            seq1->cost = INFINITY;
        !           507:        else
        !           508:        {
        !           509:            vptr = seq2->vec;
        !           510:            while (vptr != seq2->end)
        !           511:                *(seq1->end++) = *(vptr++);
        !           512:            seq1->cost += seq2->cost;
        !           513:        }
        !           514: }
        !           515: 
        !           516: 
        !           517: static
        !           518: out_seq(seq)
        !           519: register struct Sequence *seq;
        !           520: {
        !           521:        char            *tparm();
        !           522:        register int    *opptr;
        !           523:        int             prm[9], ps, p, op, outc();
        !           524:        int             count;
        !           525:        char            *sequence();
        !           526: 
        !           527:        if (seq->cost >= INFINITY)
        !           528:            return;
        !           529: 
        !           530:        for (opptr = seq->vec;  opptr < seq->end;  opptr++)
        !           531:        {
        !           532:            op = *opptr;                        /* grab operator */
        !           533:            ps = -op_info[op];
        !           534:            if(ps > 0)                          /* parameterized */
        !           535:            {
        !           536:                for (p = 0;  p < ps;  p++)      /* fill in needed parms */
        !           537:                    prm[p] = *(++opptr);
        !           538: 
        !           539:                tputs(tparm(sequence(op),
        !           540:                                prm[0], prm[1], prm[2], prm[3], prm[4],
        !           541:                                prm[5], prm[6], prm[7], prm[8]), 1, outc);
        !           542:            }
        !           543:            else
        !           544:            {
        !           545:                count = *(++opptr);
        !           546:                    /*rev should save tputs output instead of mult calls */
        !           547:                while (count--)                 /* do count times */
        !           548:                    tputs(sequence(op), 1, outc);
        !           549:            }
        !           550:        }
        !           551: }
        !           552: 
        !           553: 
        !           554: /*
        !           555: **     update_ops()
        !           556: **
        !           557: **     update_ops() makes sure that
        !           558: ** the op_info[] array is updated and initializes
        !           559: ** the cost array for SP if needed.
        !           560: */
        !           561: 
        !           562: static
        !           563: update_ops()
        !           564: {
        !           565:        char    *index();
        !           566: 
        !           567:        if (SP)                         /* SP structure exists */
        !           568:        {
        !           569:            register int op; 
        !           570: 
        !           571:            out_file = SP->_ofp;        /* set output file pointer */
        !           572: 
        !           573:            if (! SP->_costinit)        /* this term not yet assigned costs */
        !           574:            {
        !           575:                loc_init = FALSE;       /* if !SP in the future, new term */
        !           576:                init_costs(SP->_costs); /* fill term costs */
        !           577:                SP->_costinit = TRUE;
        !           578:            }
        !           579: 
        !           580:            for (op = 0;  op < NUM_NPARM;  op++)
        !           581:                op_info[op] = SP->_costs[op];   /* set up op_info */
        !           582:            
        !           583:                /* check for newline that might be mapped... */
        !           584:            if (SP->_nlmapping && (index(sequence(CURS_DOWN), '\n') != NULL))
        !           585:                op_info[CURS_DOWN] = INFINITY;
        !           586:        }
        !           587:        else
        !           588:        {
        !           589:            out_file = stdout;
        !           590: 
        !           591:            if (! loc_init)                     /* using local costs */
        !           592:            {
        !           593:                loc_init = TRUE;
        !           594:                init_costs(op_info);            /* set up op_info */
        !           595:            }
        !           596:                /* check for newline that might be mapped... */
        !           597:            if (index(sequence(CURS_DOWN), '\n') != NULL)
        !           598:                op_info[CURS_DOWN] = INFINITY;
        !           599:        }
        !           600: }
        !           601: 
        !           602: 
        !           603: /*
        !           604: **     init_costs(costs)
        !           605: **
        !           606: **     init_costs() fills the array costs[NUM_NPARM]
        !           607: ** with costs calculated by doing tputs() calls.
        !           608: */
        !           609: 
        !           610: static
        !           611: init_costs(costs)
        !           612: int    costs[];
        !           613: {
        !           614:        register int    i;
        !           615:        int             countc();
        !           616: 
        !           617:        for (i = 0;  i < NUM_NPARM;  i++)
        !           618:            if(sequence(i) != (char *) 0)
        !           619:            {
        !           620: #ifdef TRACE
        !           621:        if (_tracing)
        !           622:            _tracef("\tinit_costs: pricing %d: '%s'", i, sequence(i));
        !           623: #endif
        !           624: 
        !           625:                c_count = 0;
        !           626:                tputs(sequence(i), 1, countc);
        !           627:                costs[i] = c_count;
        !           628:            }
        !           629:            else
        !           630:                costs[i] = INFINITY;
        !           631: }
        !           632: 
        !           633: 
        !           634: /*
        !           635: **     countc()
        !           636: **     outc(c)
        !           637: **     savec(c)
        !           638: **     
        !           639: **     countc() increments global var c_count.
        !           640: **     outc() outputs a single character.
        !           641: **     savec() saves c in *c_save and increments c_save and c_count.
        !           642: */
        !           643: 
        !           644: static
        !           645: countc()
        !           646: {
        !           647:        c_count++;
        !           648: }
        !           649: 
        !           650: 
        !           651: static
        !           652: outc(c)
        !           653: char c;
        !           654: {
        !           655:        fputc(c, out_file);
        !           656: }
        !           657: 
        !           658: 
        !           659: /*rev not yet needed 
        !           660: static
        !           661: savec(c)
        !           662: char c;
        !           663: {
        !           664:        *(c_save++) = c;
        !           665:        c_count++;
        !           666: }
        !           667: */
        !           668: 
        !           669: 
        !           670: /*
        !           671: **     add_op(seq, op, p0, p1, ... , p8)
        !           672: **
        !           673: **     add_op() adds the operator op and the appropriate
        !           674: **  number of paramaters to seq.  It also increases the 
        !           675: **  cost appropriately.
        !           676: **     if op has no parameters, p0 is taken to be a count.
        !           677: */
        !           678: 
        !           679: static
        !           680: add_op(seq, op, p0, p1, p2, p3, p4, p5, p6, p7, p8)
        !           681: struct Sequence        *seq;
        !           682: int            op, p0, p1, p2, p3, p4, p5, p6, p7, p8;
        !           683: {
        !           684:        char    *tparm();
        !           685:        int     num_ps, p;
        !           686: 
        !           687: #ifdef TRACE
        !           688:        if (_tracing)
        !           689:            _tracef("\tadd_op(%o,%d,%d,%d) called", seq, op, p0, p1);
        !           690: #endif
        !           691: 
        !           692:        num_ps = - op_info[op];         /* get parms or -cost */
        !           693:        *(seq->end++) = op;
        !           694: 
        !           695:        if (num_ps == (- INFINITY)  ||  sequence(op) == (char *) 0)
        !           696:            seq->cost = INFINITY;
        !           697:        else
        !           698:            if (num_ps <= 0)            /* no parms, -cost */
        !           699:        {
        !           700:            seq->cost -= p0 * num_ps;   /* ADD count * cost */
        !           701:            *(seq->end++) = p0;
        !           702:        }
        !           703:        else
        !           704:        {
        !           705:            int pms[9];
        !           706: 
        !           707:            pms[0] = p0;  pms[1] = p1;  pms[2] = p2;
        !           708:            pms[3] = p3;  pms[4] = p4;  pms[5] = p5;
        !           709:            pms[6] = p6;  pms[7] = p7;  pms[8] = p8;  
        !           710:            for(p = 0;  p < num_ps;  p++)
        !           711:                *(seq->end++) = pms[p];
        !           712:            c_count = 0;
        !           713:            tputs(tparm(sequence(op), p0, p1, p2, p3, p4, p5, p6, p7, p8),
        !           714:                                                                 1, countc);
        !           715:            seq->cost += c_count;
        !           716:        }
        !           717: }
        !           718: 
        !           719: 
        !           720: /*
        !           721: **     char    *
        !           722: **     sequence(op)
        !           723: **
        !           724: **     sequence() returns a pointer to the op's
        !           725: **  terminal control sequence.
        !           726: */
        !           727: 
        !           728: static char    *
        !           729: sequence(op)
        !           730: register int op;
        !           731: {
        !           732:        
        !           733:        switch(op)
        !           734:        {
        !           735:            case CARRIAGE_RETURN:
        !           736:                return (carriage_return);
        !           737:            case CURS_DOWN:
        !           738:                return (cursor_down);
        !           739:            case CURS_HOME:
        !           740:                return (cursor_home);
        !           741:            case CURS_LEFT:
        !           742:                return (cursor_left);
        !           743:            case CURS_RIGHT:
        !           744:                return (cursor_right);
        !           745:            case CURS_TO_LL:
        !           746:                return (cursor_to_ll);
        !           747:            case CURS_UP:
        !           748:                return (cursor_up);
        !           749:            case TAB:
        !           750:                return (tab);
        !           751:            case BACK_TAB:
        !           752:                return (back_tab);
        !           753:            case ROW_ADDR:
        !           754:                return (row_address);
        !           755:            case COL_ADDR:
        !           756:                return (column_address);
        !           757:            case P_DOWN_CURS:
        !           758:                return (parm_down_cursor);
        !           759:            case P_LEFT_CURS:
        !           760:                return (parm_left_cursor);
        !           761:            case P_RIGHT_CURS:
        !           762:                return (parm_right_cursor);
        !           763:            case P_UP_CURS:
        !           764:                return (parm_up_cursor);
        !           765:            case CURS_ADDR:
        !           766:                return (cursor_address);
        !           767:            default:
        !           768:                return ((char *) 0);
        !           769:        }
        !           770: }

unix.superglobalmegacorp.com

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