# 2.11BSD#431 - /usr/src/new/PORT/B/src/bed/vtrm.c

##### Functions

    addlines          X
    check_started     X
    clear_lines       X
    clr_to_eol        X
    countchar         X
    del_str           X
    dellines          X
    get_so_mode       X
    getpos            X
    gettermcaps       X
    ins_str           X
    lalloc            X
    move              X
    outchar           X
    put_c             X
    put_line          X
    put_str           X
    resetttymode      X
    rewrite_ok        X
    scr1down          X
    scr1up            X
    scr2down          X
    scr2up            X
    scr_lines         X
    set_blanks        X
    set_mode          X
    setttymode        X
    standend          X
    standout          X
    start_trm         X
    str0cost          X
    strcost           X
    trmbell           X
    trmend            X
    trmerr            X
    trmmess           X
    trmputdata        X
    trmreset          X
    trmscrollup       X
    trmsense          X
    trmshow           X
    trmsorry          X
    trmstart          X
    trmsync           X
    trmundefined      X

##### Variables

    BC                X
    Hidden            X
    PC                X
    Procedure         X
    UP                X
    abs_cost          X
    al_str            X
    ccc               X
    cd_str            X
    ce_str            X
    cl_str            X
    cm_str            X
    cols              X
    cp_str            X
    cr_cost           X
    cr_str            X
    cs_str            X
    cur_y             X
    dc_str            X
    del_mf            X
    del_oh            X
    dl_str            X
    dm_str            X
    do_cost           X
    do_str            X
    ed_cost           X
    ed_str            X
    ei_cost           X
    ei_str            X
    flags             X
    has_am            X
    has_da            X
    has_db            X
    has_in            X
    has_mi            X
    has_ms            X
    has_xs            X
    ho_str            X
    ic_str            X
    im_str            X
    ins_mf            X
    ins_oh            X
    know_ttys         X
    le_cost           X
    le_str            X
    line              X
    lines             X
    mode              X
    mustclear         X
    nd_cost           X
    nd_str            X
    newtty            X
    no_cursor         X
    oldtty            X
    ospeed            X
    par_al_str        X
    par_dl_str        X
    se_str            X
    sf_str            X
    so_mode           X
    so_str            X
    sp_str            X
    sr_str            X
    started           X
    te_str            X
    ti_str            X
    up_cost           X
    up_str            X
    vb_str            X
    ve_str            X
    vi_str            X

##### Macros

    CHAR              X
    COOKBITS          X
    CrWrite           X
    Delete            X
    Down              X
    Forward           X
    Hidden            X
    Infinity          X
    Insert            X
    Left              X
    Min               X
    NOCOOK            X
    NULCHAR           X
    No                X
    None              X
    Normal            X
    Off               X
    On                X
    Procedure         X
    Putstr            X
    ReWrite           X
    Right             X
    SOBIT             X
    SOCHAR            X
    SOCOOK            X
    UNKNOWN           X
    Undefined         X
    Up                X
    VOID              X
    Visible           X
    XSBIT             X
    Yes               X
    gtty              X
    stty              X

##### typedef's

    bool              X
    intlet            X
    string            X

       1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
       2: static char rcsid[] = "$Header: vtrm.c,v 1.3 85/08/30 10:11:04 timo Exp $";
       3:
       4: /* History:
       5:  *	21-aug-85 GvR	added support for AL and DL (parametrized al and dl).
       6:  *	The Epoch tk	created and modified.
       7:  */
       8:
       9: /*
      10:  * Virtual TeRMinal package.
      11:  *
      12:  * This package uses termcap to determine the terminal capabilities.
      13:  *
      14:  * The lines and columns of our virtual terminal are numbered
      15:  *	y = {0...lines-1} from top to bottom, and
      16:  *	x = {0...cols-1} from left to right,
      17:  * respectively.
      18:  *
      19:  * The Visible Procedures in this package are:
      20:  *
      21:  * trmstart(&lines, &cols, &flags)
      22:  * 	Obligatory initialization call (sets tty modes etc.),
      23:  * 	Returns the height and width of the screen to the integers
      24:  * 	whose addresses are passed as parameters, and a flag that
      25:  *	describes some capabilities.
      26:  *	Function return value: Yes if all went well, No if the terminal
      27:  *	is not supported.  An error message has already been displayed.
      28:  *
      29:  * trmundefined()
      30:  *	Sets internal representation of screen and attributes to undefined.
      31:  *	This is necessary for a hard redraw, which would get optimised to
      32:  *	oblivion,
      33:  *
      34:  * trmsense(&y, &x)
      35:  *	Returns the cursor position through its parameters
      36:  *	after a possible manual change by the user.
      37:  *
      38:  * trmputdata(yfirst, ylast, indent, data)
      39:  * 	Fill lines {yfirst..ylast} with data, after skipping the initial
      40:  *	'indent' positions. It is assumed that these positions do not contain
      41:  *	anything dangerous (like standout cookies or null characters).
      42:  *
      43:  * trmscrollup(yfirst, ylast, by)
      44:  * 	Shift lines {yfirst..ylast} up by lines (down |by| if by < 0).
      45:  *
      46:  * trmsync(y, x)
      47:  * 	Call to output data to the terminal and set cursor position.
      48:  *
      49:  * trmbell()
      50:  *	Send a (possibly visible) bell, immediately (flushing stdout).
      51:  *
      52:  * trmend()
      53:  * 	Obligatory termination call (resets tty modes etc.).
      54:  *
      55:  * You may call these as one or more cycles of:
      56:  * 	+ trmstart
      57:  * 	+    zero or more times any of the other routines
      58:  * 	+ trmend
      59:  * To catch interrupts and the like, you may call trmend even in the middle
      60:  * of trmstart.
      61:  */
      62:
      63:
      64: /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      65: /* Includes and data definitions.                                           */
      66: /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      67:
      68: #include <stdio.h>
      69: #include <setjmp.h>
      70: #ifndef TERMIO
      71: #include <sgtty.h>
      72: #else
      73: #include <termio.h>
      74: #endif TERMIO
      75: #include <signal.h>
      76: #include <ctype.h>      /* for isprint() */
      77:
      78: #include "vtrm.h"
      79:
      80: #ifdef lint
      81: #define VOID (void)
      82: #else
      83: #define VOID
      84: #endif
      85:
      86: #define Forward
      87: #define Visible
      88: #define Hidden static
      89: #define Procedure
      90:
      91: typedef short intlet;
      92: typedef char *string;
      93: typedef char bool;
      94: #define Yes ((bool) 1)
      95: #define No  ((bool) 0)
      96:
      97: #define Min(a,b) ((a) <= (b) ? (a) : (b))
      98:
      99: /* tty modes */
     100: #ifndef TERMIO
     101: /* v7/BSD tty control */
     102: Hidden struct sgttyb oldtty, newtty;
     103: /* to enable type ahead for abled persons on systems that provide this: */
     104: #ifdef TIOCSETN
     105: #define stty(fd,bp) VOID ioctl(fd, TIOCSETN, bp)
     106: #endif
     107: #else
     108: /* AT&T tty control */
     109: Hidden struct termio oldtty, newtty;
     110: #define gtty(fd,bp) ioctl(fd, TCGETA, bp)
     111: #define stty(fd,bp) VOID ioctl(fd, TCSETAW, bp)
     112: #endif TERMIO
     113: Hidden bool know_ttys = No;
     114:
     115: /* visible data for termcap */
     116: char PC;
     117: char *BC;
     118: char *UP;
     119: short ospeed;
     120:
     121: Forward int outchar();      /* procedure for termcap's tputs */
     122: #define Putstr(str) tputs((str), 1, outchar)
     123: extern char *tgoto();
     124:
     125: /* termcap terminal capabilities */
     126:
     127: Hidden int lines;
     128: Hidden int cols;
     129:
     130: Hidden bool has_am;         /* has automatic margins */
     131: Hidden bool has_da;         /* display may be retained above screen */
     132: Hidden bool has_db;         /* display may be retained below screen */
     133: Hidden bool has_in;         /* not save to have null chars on the screen */
     134: Hidden bool has_mi;         /* move safely in insert (and delete?) mode */
     135: Hidden bool has_ms;         /* move safely in standout mode */
     136: Hidden bool has_xs;     /* standout not erased by overwriting */
     137:
     138: Hidden char *al_str;        /* add new blank line */
     139: Hidden char *par_al_str;    /* parametrized al (AL) */
     140: Hidden char *cd_str;        /* clear to end of display */
     141: Hidden char *ce_str;        /* clear to end of line */
     142: Hidden char *cl_str;        /* cursor home and clear screen */
     143: Hidden char *cm_str;        /* cursor motion */
     144: Hidden char *cr_str;        /* carriage return */
     145: Hidden char *cs_str;        /* change scrolling region */
     146: Hidden char *dc_str;        /* delete character */
     147: Hidden char *dl_str;        /* delete line */
     148: Hidden char *par_dl_str;    /* parametrized dl (DL) */
     149: Hidden char *do_str;        /* cursor down one line */
     150: Hidden char *dm_str;        /* enter delete mode */
     151: Hidden char *ed_str;        /* end delete mode */
     152: Hidden char *ei_str;        /* end insert mode */
     153: Hidden char *ho_str;        /* cursor home */
     154: Hidden char *ic_str;        /* insert character (iff necessary, maybe pad) */
     155: Hidden char *im_str;        /* enter insert mode */
     156: Hidden char *le_str;        /* cursor left */
     157: Hidden char *nd_str;        /* cursor right (non-destructive space) */
     158: Hidden char *se_str;        /* end standout mode */
     159: Hidden char *sf_str;        /* scroll text up (from bottom of region) */
     160: Hidden char *so_str;        /* begin standout mode */
     161: Hidden char *sr_str;        /* scroll text down (from top of region) */
     162: Hidden char *te_str;        /* end termcap */
     163: Hidden char *ti_str;        /* start termcap */
     164: Hidden char *up_str;        /* cursor up */
     165: Hidden char *vb_str;        /* visible bell */
     166: Hidden char *ve_str;        /* make cursor visible again */
     167: Hidden char *vi_str;        /* make cursor invisible */
     168:
     169: /* sense cursor position, addition to termcap */
     170: Hidden char *cp_str;        /* format of returned Cursor Position string */
     171: Hidden char *sp_str;        /* Sense cursor Position from terminal */
     172:
     173: /* terminal status */
     174:
     175: /* calling order of Visible Procs */
     176: Hidden bool started = No;
     177:
     178: /* to exports the capabilities mentioned in vtrm.h: */
     179: Hidden int flags = 0;
     180:
     181: /* cost for impossible operations */
     182: #define Infinity 9999
     183:     /* Allow for adding Infinity+Infinity within range */
     184:     /* (Range is assumed at least 2**15 - 1) */
     185:
     186: /* The following for all sorts of undefined things (except for UNKNOWN char) */
     187: #define Undefined (-1)
     188:
     189: /* current mode of putting char's */
     190: #define Normal  0
     191: #define Insert  1
     192: #define Delete  2
     193: Hidden short mode = Normal;
     194:
     195: /* current standout mode */
     196: #define Off 0
     197: #define On  0200
     198: Hidden short so_mode = Off;
     199:
     200: /* masks for char's and intlet's */
     201: #define NULCHAR '\000'
     202: #define CHAR    0177
     203: #define SOBIT   On
     204: #define SOCHAR  0377
     205: /* if (has_xs) record cookies placed on screen in extra bit */
     206: /* type of cookie is determined by the SO bit */
     207: #define XSBIT   0400
     208: #define SOCOOK  0600
     209: #define COOKBITS SOCOOK
     210: #define UNKNOWN 1
     211: #define NOCOOK  UNKNOWN
     212:
     213: /* current cursor position */
     214: Hidden intlet cur_y = Undefined, cur_x = Undefined;
     215:
     216: /* "line[y][x]" holds the char on the terminal, with the SOBIT and XSBIT.
     217:  * the SOBIT tells whether the character is standing out, the XSBIT whether
     218:  * there is a cookie on the screen at this position.
     219:  * In particular a standend-cookie may be recorded AFTER the line
     220:  * (just in case some trmputdata will write after that position).
     221:  * "lenline[y]" holds the length of the line.
     222:  * Unknown chars will be 1, so the optimising compare in putline will fail.
     223:  * (Partially) empty lines are distinghuished by "lenline[y] < cols".
     224:  */
     225: Hidden intlet **line = 0, *lenline = 0;
     226:
     227: /* Clear the screen initially iff only memory cursor addressing available */
     228: Hidden bool mustclear = No;
     229:
     230: /* Make the cursor invisible when trmsync() tries to move outside the screen */
     231: Hidden bool no_cursor = No;
     232:
     233: /* Optimise cursor motion */
     234: Hidden int abs_cost;        /* cost of absolute cursor motion */
     235: Hidden int cr_cost;         /* cost of carriage return */
     236: Hidden int do_cost;         /* cost of down */
     237: Hidden int le_cost;         /* cost of left */
     238: Hidden int nd_cost;         /* cost of right */
     239: Hidden int up_cost;         /* cost of up */
     240:
     241: /* Optimise trailing match in put_line, iff the terminal can insert and delete
     242:  * characters; the cost per n characters will be:
     243:  * 	n * MultiplyFactor + OverHead
     244:  */
     245: Hidden int ins_mf, ins_oh, del_mf, del_oh;
     246: Hidden int ed_cost, ei_cost;        /* used in move() */
     247:
     248: /* The type of scrolling possible determines which routines get used;
     249:  * these may be:
     250:  * (1) with addline and deleteline (termcap: al_str & dl_str);
     251:  * (2) with a settable scrolling region, like VT100 (cs_str, sr_str, sf_str);
     252:  * (3) no scrolling available. (NOT YET IMPLEMENTED)
     253:  */
     254: Hidden Procedure (*scr_up)();
     255: Hidden Procedure (*scr_down)();
     256: Forward Procedure scr1up();
     257: Forward Procedure scr1down();
     258: Forward Procedure scr2up();
     259: Forward Procedure scr2down();
     260: /*Forward Procedure scr3up(); */
     261: /*Forward Procedure scr3down(); */
     262:
     263: /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
     264: /* Starting, Ending and (fatal) Error.                                      */
     265: /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
     266:
     267: /*
     268:  * Initialization call.
     269:  * Determine terminal capabilities from termcap.
     270:  * Set up tty modes.
     271:  * Start up terminal and internal administration.
     272:  * Return Yes if succeeded, No if trouble (e.g., bad terminal type).
     273:  */
     274: Visible int
     275: trmstart(plines, pcols, pflags)
     276: int *plines;
     277: int *pcols;
     278: int *pflags;
     279: {
     280: #ifdef TRACE
     281: fprintf(stderr, "\ttrmstart(&li, &co, &fl);\n");
     282: #endif
     283:     if (started)
     284:         trmerr("trmstart called twice in succession");
     285:     if (!gettermcaps())
     286:         return No;
     287:     if (!setttymode())
     288:         return No;
     289:     start_trm();
     290:
     291:     *plines = lines;
     292:     *pcols = cols;
     293:     *pflags = flags;
     294:
     295:     started = Yes;
     296:     return Yes;
     297: }
     298:
     299: /*
     300:  * Termination call.
     301:  * Reset tty modes, etc.
     302:  * Beware that it might be called by a catched interrupt even in the middle
     303:  * of trmstart()!
     304:  */
     305: Visible Procedure
     306: trmend()
     307: {
     308: #ifdef TRACE
     309: fprintf(stderr, "\ttrmend();\n");
     310: #endif
     311:     set_mode(Normal);
     312:     if (so_mode != Off)
     313:         standend();
     314:     Putstr(te_str);
     315:     VOID fflush(stdout);
     316:     resetttymode();
     317:
     318:     started = No;
     319: }
     320:
     321: /*
     322:  * Set all internal statuses to undefined, especially the contents of
     323:  * the screen, so a hard redraw will not be optimised to heaven.
     324:  */
     325: Visible Procedure
     326: trmundefined()
     327: {
     328:     register int y, x;
     329: #ifdef TRACE
     330: fprintf(stderr, "\ttrmundefined();\n");
     331: #endif
     332:
     333:     cur_y = cur_x = Undefined;
     334:     mode = so_mode = Undefined;
     335:
     336:     for (y = 0; y < lines; y++) {
     337:         for (x = 0; x <= cols; x++)
     338:             line[y][x] = 1; /* impossible char, no so bits */
     339:         lenline[y] = cols;
     340:     }
     341: }
     342:
     343: /*
     344:  * Give an error message, and abort.
     345:  * The abort can be catched by the calling process.
     346:  */
     347: Hidden Procedure
     348: trmerr(mess)
     349: string mess;
     350: {
     351:     trmreset();
     352:     fprintf(stderr,
     353:         "*** System error in screen output module:\n*** %s\n", mess);
     354:     VOID fflush(stderr);
     355:     abort();
     356: }
     357:
     358: /*
     359:  * Give an error message and reset the tty modes (but don't abort).
     360:  */
     361: Hidden Procedure trmmess(mess)
     362: string mess;
     363: {
     364:     trmreset();
     365:     fprintf(stderr, "*** Fatal error: %s\n", mess);
     366:     VOID fflush(stderr);
     367: }
     368:
     369: /*
     370:  * Complain about a missing terminal feature.  Otherwise like trmmess.
     371:  */
     372: Hidden Procedure
     373: trmsorry(mess)
     374: string mess;
     375: {
     376:     trmreset();
     377:     fprintf(stderr, (
     378: #ifdef BED
     379:       "*** Sorry, this terminal isn't powerful enough to run the B editor.\n"
     380: #else
     381:       "*** Sorry, this terminal isn't powerful emough.\n"
     382: #endif
     383:     ));
     384:     fprintf(stderr, "*** The problem is: %s.\n", mess);
     385: #ifdef BED
     386:     fprintf(stderr,
     387:       "*** (You might try 'b -e' to use a standard editor instead.)\n");
     388: #endif
     389:     VOID fflush(stderr);
     390: }
     391:
     392: /*
     393:  * Prepare for giving a (more or less fatal) error message.
     394:  */
     395: Hidden Procedure
     396: trmreset()
     397: {
     398:     if (started) {
     399:         move(lines-1, 0);
     400:         clear_lines(lines-1, lines-1);
     401:     }
     402:     VOID fflush(stdout);
     403:     resetttymode();
     404: }
     405:
     406: Hidden Procedure
     407: check_started(m)
     408: char *m;
     409: {
     410:     char s[80];
     411:
     412:     if (!started) {
     413:         VOID sprintf(s, "%s called outside trmstart/trmend", m);
     414:         trmerr(s);
     415:     }
     416: }
     417:
     418: int ccc;
     419:
     420: /*ARGSUSED*/
     421: Hidden Procedure
     422: countchar(ch)
     423: char ch;
     424: {
     425:     ccc++;
     426: }
     427:
     428: Hidden int
     429: strcost(str)
     430: char *str;
     431: {
     432:     if (str == NULL)
     433:         return Infinity;
     434:     return str0cost(str);
     435: }
     436:
     437: Hidden int
     438: str0cost(str)
     439: char *str;
     440: {
     441:     ccc = 0;
     442:     tputs(str, 1, countchar);
     443:     return ccc;
     444: }
     445:
     446: Hidden int
     447: gettermcaps()           /* get terminal capabilities from termcap
     448: 				 * and related static properties
     449: 				 */
     450: {
     451:     string trmname;
     452:     char tc_buf[1024];
     453:     static char strbuf[1024];
     454:     char *area = strbuf;
     455:     char *xPC;
     456:     char *getenv();
     457:     int tgetent();
     458:     int tgetnum();
     459:     int tgetflag();
     460:     char *tgetstr();
     461:     int sg;
     462:     static bool tc_initialized = No;
     463: #ifdef TIOCGWINSZ
     464:     struct winsize win;
     465: #endif
     466:
     467:     if (tc_initialized)
     468:         return Yes;
     469:
     470:     if ((trmname=getenv("TERM")) == NULL) {
     471:         trmmess("terminal type not exported in $TERM variable");
     472:         return No;
     473:     }
     474:     if (tgetent(tc_buf, trmname) != 1) {
     475:         trmmess("unknown terminal type in $TERM envariable");
     476:         return No;
     477:     }
     478:
     479:     if (tgetflag("hc")) {
     480:         trmsorry("can't use a hardcopy terminal");
     481:         return No;
     482:     }
     483:
     484:     BC = tgetstr("le", &area);
     485:     if (BC == NULL)
     486:         BC = tgetstr("bc", &area);
     487:     if (BC == NULL)
     488:         if (tgetflag("bs"))
     489:             BC="\b";
     490:         else {
     491:             trmsorry("no LEFT cursor motion");
     492:             return No;
     493:         }
     494:     UP = tgetstr("up", &area);
     495:     if (UP == NULL) {
     496:         trmsorry("no UP cursor motion");
     497:         return No;
     498:     }
     499:     xPC = tgetstr("pc", &area);
     500:     PC = (xPC != NULL? xPC[0] : NULCHAR);
     501:
     502:     ho_str = tgetstr("ho", &area);
     503:     do_str = tgetstr("do", &area);
     504:     nd_str = tgetstr("nd", &area);
     505:     cm_str = tgetstr("cm", &area);
     506:     if (cm_str == NULL) {
     507:         cm_str = tgetstr("CM", &area);
     508:         if (cm_str == NULL) {
     509:             if (ho_str == NULL || do_str == NULL || nd_str == NULL) {
     510:                 trmsorry("no absolute cursor motion");
     511:                 return No;
     512:             }
     513:         }
     514:         else
     515:             mustclear = Yes;
     516:     }
     517:
     518:     al_str = tgetstr("al", &area);
     519:     dl_str = tgetstr("dl", &area);
     520:     par_al_str = tgetstr("AL", &area);
     521:     par_dl_str = tgetstr("DL", &area);
     522:     if (al_str && dl_str) {
     523:         scr_up = scr1up;
     524:         scr_down = scr1down;
     525:         flags |= CAN_SCROLL;
     526:     }
     527:     else {
     528:         cs_str = tgetstr("cs", &area);
     529:         sf_str = tgetstr("sf", &area);
     530:         if (sf_str == NULL)
     531:             sf_str = "\n";
     532:         sr_str = tgetstr("sr", &area);
     533:         if (cs_str && sr_str) {
     534:             scr_up = scr2up;
     535:             scr_down = scr2down;
     536:             flags |= CAN_SCROLL;
     537:         }
     538:         else {
     539:             trmsorry("can't scroll");
     540:             return No;
     541:         }
     542:     }
     543:
     544:     lines = tgetnum("li");
     545:     cols = tgetnum("co");
     546: #ifdef TIOCGWINSZ
     547:     if (ioctl (0, TIOCGWINSZ, &win) == 0) {
     548:         if (win.ws_col)
     549:             cols = win.ws_col;
     550:         if (win.ws_row)
     551:             lines = win.ws_row;
     552:     }
     553: #endif
     554:     if (lines == -1) lines = 24;
     555:     if (cols == -1) cols = 80;
     556:
     557:     has_am = tgetflag("am");
     558:     has_db = tgetflag("db");
     559:     has_in = tgetflag("in");
     560:     has_mi = tgetflag("mi");
     561:     has_ms = tgetflag("ms");
     562:     has_xs = tgetflag("xs");
     563:     if ((sg=tgetnum("sg")) == 0)
     564:         has_xs = Yes;
     565:     else if (sg > 0) {
     566:         trmsorry("video attributes take up space on the screen");
     567:         return No;
     568:     }
     569:
     570:     cd_str = tgetstr("cd", &area);
     571:     ce_str = tgetstr("ce", &area);
     572:     if (!ce_str) {
     573:         trmsorry("can't clear to end of line");
     574:         return No;
     575:     }
     576:     cl_str = tgetstr("cl", &area);
     577:     cr_str = tgetstr("cr", &area);
     578:     if (cr_str == NULL) cr_str = "\r";
     579:     dc_str = tgetstr("dc", &area);
     580:     dm_str = tgetstr("dm", &area);
     581:     if (do_str == NULL) do_str = tgetstr("nl", &area);
     582:     if (do_str == NULL) do_str = "\n";
     583:     ed_str = tgetstr("ed", &area);
     584:     ei_str = tgetstr("ei", &area);
     585:     ic_str = tgetstr("ic", &area);
     586:     im_str = tgetstr("im", &area);
     587:     le_str = BC;
     588:     se_str = tgetstr("se", &area);
     589:     so_str = tgetstr("so", &area);
     590:     te_str = tgetstr("te", &area);
     591:     ti_str = tgetstr("ti", &area);
     592:     up_str = UP;
     593:     vb_str = tgetstr("vb", &area);
     594:     if (vb_str == NULL)     /* then we will do with the audible bell */
     595:         vb_str = "\007";
     596:     ve_str = tgetstr("ve", &area);
     597:     vi_str = tgetstr("vi", &area);
     598:
     599:     /* cursor sensing (non standard) */
     600:     cp_str = tgetstr("cp", &area);
     601:     sp_str = tgetstr("sp", &area);
     602:     if (cp_str != NULL && sp_str != NULL)
     603:         flags |= CAN_SENSE;
     604:
     605:     if (so_str != NULL && se_str != NULL)
     606:         flags |= HAS_STANDOUT;
     607:
     608:     /* calculate costs of local and absolute cursor motions */
     609:     if (cm_str == NULL)
     610:         abs_cost = Infinity;
     611:     else
     612:         abs_cost = strcost(tgoto(cm_str, 0, 0));
     613:     cr_cost = strcost(cr_str);
     614:     do_cost = strcost(do_str);
     615:     le_cost = strcost(le_str);
     616:     nd_cost = strcost(nd_str);
     617:     up_cost = strcost(up_str);
     618:
     619:     /* cost of leaving insert or delete mode, used in move() */
     620:     ei_cost = str0cost(ei_str);
     621:     ed_cost = str0cost(ed_str);
     622:
     623:     /* calculate insert and delete cost multiply_factor and overhead */
     624:     if (((im_str && ei_str) || ic_str) && dc_str) {
     625:         flags |= CAN_OPTIMISE;
     626:         ins_mf = 1 + str0cost(ic_str);
     627:         ins_oh = str0cost(im_str) + ei_cost;
     628:         del_mf = str0cost(dc_str);
     629:         del_oh = str0cost(dm_str) + ed_cost;
     630:     }
     631:
     632:     tc_initialized = Yes;
     633:     return Yes;
     634: }
     635:
     636: Hidden int
     637: setttymode()
     638: {
     639:     if (!know_ttys) {
     640:         if (gtty(1, &oldtty) != 0 || gtty(1, &newtty) != 0) {
     641:             trmmess("can't get tty modes (output not a terminal)");
     642:             return No;
     643:         }
     644: #ifndef TERMIO
     645:         ospeed = oldtty.sg_ospeed;
     646: #ifdef PWB
     647:         newtty.sg_flags = (newtty.sg_flags & ~ECHO & ~CRMOD & ~XTABS)
     648:                   | RAW;
     649: #else PWB
     650:         newtty.sg_flags = (newtty.sg_flags & ~ECHO & ~CRMOD & ~XTABS)
     651:                   | CBREAK;
     652: #endif PWB
     653: #else TERMIO
     654:         ospeed= oldtty.c_lflag & CBAUD;
     655:         newtty.c_iflag &= ~ICRNL; /* No CR->NL mapping on input */
     656:         newtty.c_oflag &= ~ONLCR; /* NL doesn't output CR */
     657:         newtty.c_lflag &= ~(ICANON|ECHO); /* No line editing, no echo */
     658:         newtty.c_cc[VMIN]= 3; /* wait for 3 characters */
     659:         newtty.c_cc[VTIME]= 1; /* or 0.1 sec. */
     660: #endif TERMIO
     661:         know_ttys = Yes;
     662:     }
     663:     stty(1, &newtty);
     664:     return Yes;
     665: }
     666:
     667: Hidden Procedure
     668: resetttymode()
     669: {
     670:     if (know_ttys)
     671:         stty(1, &oldtty);
     672: }
     673:
     674: Hidden char*
     675: lalloc(size)
     676: unsigned size;
     677: {
     678:     char *l;
     679:     char *malloc();
     680:
     681:     l = malloc(size);
     682:     if (l == NULL)
     683:         trmerr("not enough memory for screen buffer");
     684:     return l;
     685: }
     686:
     687: Hidden Procedure
     688: start_trm()
     689: {
     690:     register int y;
     691:
     692:     if (line == 0) {
     693:         line = (intlet**) lalloc((unsigned) lines * sizeof(intlet*));
     694:         for (y = 0; y < lines; y++)
     695:             line[y] = (intlet*) lalloc((unsigned) ((cols+1)*sizeof(intlet)));
     696:     }
     697:     if (lenline == 0)
     698:         lenline = (intlet*) lalloc((unsigned) lines * sizeof(intlet));
     699:
     700:
     701:     trmundefined();
     702:
     703:     Putstr(ti_str);
     704:     if (cs_str)
     705:         Putstr(tgoto(cs_str, lines-1, 0));
     706:     if (mustclear)
     707:         clear_lines(0, lines-1);
     708: }
     709:
     710: /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
     711: /* Sensing and moving the cursor.                                           */
     712: /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
     713:
     714: /*
     715:  * Sense the current (y, x) cursor position, after a possible manual
     716:  * change by the user with local cursor motions.
     717:  * If the terminal cannot be asked for the current cursor position,
     718:  * or if the string returned by the terminal is garbled,
     719:  * the position is made Undefined.
     720:  */
     721: Visible Procedure
     722: trmsense(py, px)
     723:     int *py;
     724:     int *px;
     725: {
     726:     bool getpos();
     727:
     728: #ifdef TRACE
     729: fprintf(stderr, "\ttrmsense(&yy, &xx);\n");
     730: #endif
     731:     check_started("trmsense");
     732:
     733:     *py = *px = Undefined;
     734:     set_mode(Normal);
     735:     if (so_mode != Off)
     736:         standend();
     737:
     738:     if (flags&CAN_SENSE && getpos(py, px)) {
     739:         if (*py < 0 || lines <= *py || *px < 0 || cols <= *px)
     740:             *py = *px = Undefined;
     741:     }
     742:     cur_y = *py;
     743:     cur_x = *px;
     744: }
     745:
     746: Hidden bool
     747: getpos(py, px)
     748: int *py, *px;
     749: {
     750:     char *format = cp_str;
     751:     int fc;         /* current format character */
     752:     int ic;         /* current input character */
     753:     int num;
     754:     int on_y = 1;
     755:     bool incr_orig = No;
     756:     int i, ni;
     757:
     758:     Putstr(sp_str);
     759:     VOID fflush(stdout);
     760:
     761:     while (fc = *format++) {
     762:         if (fc != '%') {
     763:             if (getchar() != fc)
     764:                 return No;
     765:         }
     766:         else {
     767:             switch (fc = *format++) {
     768:             case '%':
     769:                 if (getchar() != '%')
     770:                     return No;
     771:                 continue;
     772:             case 'r':
     773:                 on_y = 1 - on_y;
     774:                 continue;
     775:             case 'i':
     776:                 incr_orig = Yes;
     777:                 continue;
     778:             case 'd':
     779:                 ic = getchar();
     780:                 if (!isdigit(ic))
     781:                     return No;
     782:                 num = ic - '0';
     783:                 while (isdigit(ic=getchar()))
     784:                     num = 10*num + ic - '0';
     785:                 VOID ungetc(ic, stdin);
     786:                 break;
     787:             case '2':
     788:             case '3':
     789:                 ni = fc - '0';
     790:                     num = 0;
     791:                 for (i=0; i<ni; i++) {
     792:                     ic = getchar();
     793:                     if (isdigit(ic))
     794:                         num = 10*num + ic - '0';
     795:                     else
     796:                         return No;
     797:                 }
     798:                 break;
     799:             case '+':
     800:                 num = getchar() - *format++;
     801:                 break;
     802:             case '-':
     803:                 num = getchar() + *format++;
     804:                 break;
     805:             default:
     806:                 return No;
     807:             }
     808:             /* assign num to parameter */
     809:             if (incr_orig)
     810:                 num--;
     811:             if (on_y)
     812:                 *py = num;
     813:             else
     814:                 *px = num;
     815:             on_y = 1 - on_y;
     816:         }
     817:     }
     818:
     819:     return Yes;
     820: }
     821:
     822: /*
     823:  * To move over characters by rewriting them, we have to check:
     824:  * (1) that the screen has been initialised on these positions;
     825:  * (2) we do not screw up characters
     826:  * when rewriting line[y] from x_from upto x_to
     827:  */
     828: Hidden bool
     829: rewrite_ok(y, xfrom, xto)
     830: int y, xfrom, xto;
     831: {
     832:     register intlet *plnyx, *plnyto;
     833:
     834:     if (xto > lenline[y])
     835:         return No;
     836:
     837:     plnyto = &line[y][xto];
     838:     for (plnyx = &line[y][xfrom]; plnyx <= plnyto; plnyx++)
     839:         if (*plnyx == UNKNOWN
     840:             ||
     841:             (!has_xs && (*plnyx & SOBIT) != so_mode)
     842:            )
     843:             return No;
     844:     return Yes;
     845: }
     846:
     847: /*
     848:  * Move to position y,x on the screen
     849:  */
     850: /* possible move types for y and x respectively: */
     851: #define None    0
     852: #define Down    1
     853: #define Up  2
     854: #define Right   1
     855: #define ReWrite 2
     856: #define Left    3
     857: #define CrWrite 4
     858:
     859: Hidden Procedure
     860: move(y, x)
     861: int y, x;
     862: {
     863:     int dy, dx;
     864:     int y_cost, x_cost, y_move, x_move;
     865:     int mode_cost;
     866:     int xi;
     867:
     868:     if (cur_y == y && cur_x == x)
     869:         return;
     870:
     871:     if (!has_mi || mode == Undefined)
     872:         set_mode(Normal);
     873:     if (!has_xs && ((!has_ms && so_mode != Off) || so_mode == Undefined))
     874:         standend();
     875:
     876:     if (cur_y == Undefined || cur_x == Undefined)
     877:         goto absmove;
     878:
     879:     dy = y - cur_y;
     880:     dx = x - cur_x;
     881:
     882:     if (dy > 0) {
     883:         y_move = Down;
     884:         y_cost = dy * do_cost;
     885:     }
     886:     else if (dy < 0) {
     887:         y_move = Up;
     888:         y_cost = -dy * up_cost;
     889:     }
     890:     else {
     891:         y_move = None;
     892:         y_cost = 0;
     893:     }
     894:     if (y_cost < abs_cost) {
     895:         switch (mode) {
     896:         case Normal:
     897:             mode_cost = 0;
     898:             break;
     899:         case Insert:
     900:             mode_cost = ei_cost;
     901:             break;
     902:         case Delete:
     903:             mode_cost = ed_cost;
     904:             break;
     905:         }
     906:         if (dx > 0) {
     907:             x_cost = dx + mode_cost;
     908:             if (dx*nd_cost < x_cost || !rewrite_ok(y, cur_x, x)) {
     909:                 x_cost = dx * nd_cost;
     910:                 x_move = Right;
     911:             }
     912:             else
     913:                 x_move = ReWrite;
     914:         }
     915:         else if (dx < 0) {
     916:             x_cost = -dx * le_cost;
     917:             x_move = Left;
     918:         }
     919:         else {
     920:             x_cost = 0;
     921:             x_move = None;
     922:         }
     923:         if (cr_cost + x + mode_cost < x_cost && rewrite_ok(y, 0, x)) {
     924:             x_move = CrWrite;
     925:             x_cost = cr_cost + x + mode_cost;
     926:         }
     927:     }
     928:     else
     929:         x_cost = abs_cost;
     930:
     931:     if (y_cost + x_cost < abs_cost) {
     932:         switch (y_move) {
     933:         case Down:
     934:             while (dy-- > 0) Putstr(do_str);
     935:             break;
     936:         case Up:
     937:             while (dy++ < 0) Putstr(up_str);
     938:             break;
     939:         }
     940:         switch (x_move) {
     941:         case Right:
     942:             while (dx-- > 0) Putstr(nd_str);
     943:             break;
     944:         case Left:
     945:             while (dx++ < 0) Putstr(le_str);
     946:             break;
     947:         case CrWrite:
     948:             Putstr(cr_str);
     949:             cur_x = 0;
     950:             /* FALL THROUGH */
     951:         case ReWrite:
     952:             set_mode(Normal);
     953:             for (xi = cur_x; xi < x; xi++)
     954:                 putchar(line[y][xi]);
     955:             break;
     956:         }
     957:     }
     958:     else
     959:     {
     960:     absmove:
     961:         if (cm_str == NULL) {
     962:             Putstr(ho_str);
     963:             for (cur_y = 0; cur_y < y; ++cur_y)
     964:                 Putstr(do_str);
     965:             /* Should try to use tabs here: */
     966:             for (cur_x = 0; cur_x < x; ++cur_x)
     967:                 Putstr(nd_str);
     968:         }
     969:         else
     970:             Putstr(tgoto(cm_str, x, y));
     971:     }
     972:
     973:     cur_y = y;
     974:     cur_x = x;
     975: }
     976:
     977: /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
     978: /* Putting data on the screen.                                              */
     979: /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
     980:
     981: /*
     982:  * Fill screen area with given data.
     983:  * Characters with the SO-bit (0200) set are put in standout mode.
     984:  */
     985: Visible Procedure
     986: trmputdata(yfirst, ylast, indent, data)
     987: int yfirst;
     988: int ylast;
     989: register int indent;
     990: register string data;
     991: {
     992:     register int y;
     993:     int x, len, lendata, space;
     994:
     995: #ifdef TRACE
     996: fprintf(stderr, "\ttrmputdata(%d, %d, %d, \"%s\");\n", yfirst, ylast, indent, data);
     997: #endif
     998:     check_started("trmputdata");
     999:
    1000:     if (yfirst < 0)
    1001:         yfirst = 0;
    1002:     if (ylast >= lines)
    1003:         ylast = lines-1;
    1004:     space = cols*(ylast-yfirst+1) - indent;
    1005:     if (space <= 0)
    1006:         return;
    1007:     yfirst += indent/cols;
    1008:     indent %= cols;
    1009:     if (data) {
    1010:         x = indent;
    1011:         lendata = strlen(data);
    1012:         if (ylast == lines-1 && lendata >= space)
    1013:             lendata = space - 1;
    1014:         len = Min(lendata, cols-x);
    1015:         for (y = yfirst; y <= ylast; ) {
    1016:             put_line(y, x, data, len);
    1017:             y++;
    1018:             lendata -= len;
    1019:             if (lendata > 0) {
    1020:                 x = 0;
    1021:                 data += len;
    1022:                 len = Min(lendata, cols);
    1023:             }
    1024:             else
    1025:                 break;
    1026:         }
    1027:     }
    1028:     if (y <= ylast)
    1029:         clear_lines(y, ylast);
    1030: }
    1031:
    1032: /*
    1033:  * We will first try to get the picture:
    1034:  *
    1035:  *                  op>>>>>>>>>>>op          oq<<<<<<<<<<<<<<<<<<<<<<<<oq
    1036:  *                  ^            ^           ^                         ^
    1037:  *           <xskip><-----m1----><----od-----><-----------m2----------->
    1038:  *   OLD:   "You're in a maze of twisty little pieces of code, all alike"
    1039:  *   NEW:          "in a maze of little twisting pieces of code, all alike"
    1040:  *                  <-----m1----><-----nd------><-----------m2----------->
    1041:  *                  ^            ^             ^                         ^
    1042:  *                  np>>>>>>>>>>>np            nq<<<<<<<<<<<<<<<<<<<<<<<<nq
    1043:  * where
    1044:  *	op, oq, np, nq are pointers to start and end of Old and New data,
    1045:  * and
    1046:  *	xskip = length of indent to be skipped,
    1047:  *	m1 = length of Matching part at start,
    1048:  *	od = length of Differing mid on screen,
    1049:  *	nd = length of Differing mid in data to be put,
    1050:  *	m2 = length of Matching trail.
    1051:  *
    1052:  * Then we will try to find a long blank-or-cleared piece in <nd+m2>:
    1053:  *
    1054:  *    <---m1---><---d1---><---nb---><---d2---><---m2--->
    1055:  *              ^         ^         ^        ^         ^
    1056:  *              np        bp        bq1      nq        nend
    1057:  * where
    1058:  *	bp, bq are pointers to start and AFTER end of blank piece,
    1059:  * and
    1060:  *	d1 = length of differing part before blank piece,
    1061:  *	nb = length of blank piece to be skipped,
    1062:  *	d2 = length of differing part after blank piece.
    1063:  * Remarks:
    1064:  *	d1 + nb + d2 == nd,
    1065:  * and
    1066:  *	d2 maybe less than 0.
    1067:  */
    1068: Hidden int
    1069: put_line(y, xskip, data, len)
    1070: int y, xskip;
    1071: string data;
    1072: int len;
    1073: {
    1074:     register intlet *op, *oq;
    1075:     register char *np, *nq, *nend;
    1076:     char *bp, *bq1, *p, *q;
    1077:     int m1, m2, od, nd, delta, dd, d1, nb, d2;
    1078:     bool skipping;
    1079:     int cost, o_cost;   /* normal and optimising cost */
    1080:
    1081:     /* calculate the magic parameters */
    1082:     op = &line[y][xskip];
    1083:     oq = &line[y][lenline[y]-1];
    1084:     np = data;
    1085:     nq = nend = data + len - 1;
    1086:     m1 = m2 = 0;
    1087:     while ((*op&SOCHAR) == (((intlet)*np)&SOCHAR) && op <= oq && np <= nq)
    1088:         op++, np++, m1++;
    1089:     if (flags & CAN_OPTIMISE)
    1090:         while ((*oq&SOCHAR) == (((intlet)*nq)&SOCHAR) && op <= oq && np <= nq)
    1091:             oq--, nq--, m2++;
    1092:     od = oq - op + 1;
    1093:     nd = nq - np + 1;
    1094:     /* now we have the first picture above */
    1095:
    1096:     if (od==0 && nd==0)
    1097:         return;
    1098:     delta = nd - od;
    1099:
    1100:     /* find the blank piece */
    1101:     p = q = bp = bq1 = np;
    1102:     oq += m2;       /* back to current eol */
    1103:     if (!has_in) {
    1104:         while (p <= nend) {
    1105:             while (q<=nend && *q==' ' && (op>oq || *op==' '))
    1106:                 q++, op++;
    1107:             if (q - p > bq1 - bp)
    1108:                 bp = p, bq1 = q;
    1109:             p = ++q;
    1110:             op++;
    1111:         }
    1112:     }
    1113:     d1 = bp - np;
    1114:     nb = bq1 - bp;
    1115:     d2 = nq - bq1 + 1;
    1116:
    1117:     /* what is cheapest:
    1118: 	 *	normal: put nd+m2;                         (dd = nd+m2)
    1119: 	 *	skipping: put d1, skip nb, put d2+m2;      (dd = d2+m2)
    1120: 	 *	optimise: put dd, insert or delete delta.  (dd = min(od,nd))
    1121: 	 */
    1122:     cost = nd + m2;     /* normal cost */
    1123:     if (nb > abs_cost || (d1 == 0 && nb > 0)) {
    1124:         skipping = Yes;
    1125:         cost -= nb - (d1>0 ? abs_cost : 0); /* skipping cost */
    1126:         dd = d2;
    1127:     }
    1128:     else {
    1129:         skipping = No;
    1130:         dd = nd;
    1131:     }
    1132:
    1133:     if (m2 != 0) {
    1134:         /* try optimising */
    1135:         o_cost = Min(od, nd);
    1136:         if (delta > 0)
    1137:             o_cost += delta * ins_mf + ins_oh;
    1138:         else if (delta < 0)
    1139:             o_cost += -delta * del_mf + del_oh;
    1140:         if (o_cost >= cost) {
    1141:             /* discard m2, no optimise */
    1142:             dd += m2;
    1143:             m2 = 0;
    1144:         }
    1145:         else {
    1146:             dd = Min(od, nd);
    1147:             skipping = No;
    1148:         }
    1149:     }
    1150:
    1151:     /* and now for the real work */
    1152:     if (!skipping || d1 > 0)
    1153:         move(y, xskip + m1);
    1154:
    1155:     if (has_xs)
    1156:         get_so_mode();
    1157:
    1158:     if (skipping) {
    1159:         if (d1 > 0) {
    1160:             set_mode(Normal);
    1161:             put_str(np, d1, No);
    1162:         }
    1163:         if (has_xs && so_mode != Off)
    1164:             standend();
    1165:         set_blanks(y, xskip+m1+d1, xskip+m1+d1+nb);
    1166:         if (dd != 0 || delta < 0) {
    1167:             move(y, xskip+m1+d1+nb);
    1168:             np = bq1;
    1169:         }
    1170:     }
    1171:
    1172:     if (dd > 0) {
    1173:         set_mode(Normal);
    1174:         put_str(np, dd, No);
    1175:     }
    1176:
    1177:     if (m2 > 0) {
    1178:         if (delta > 0) {
    1179:             set_mode(Insert);
    1180:             ins_str(np+dd, delta);
    1181:         }
    1182:         else if (delta < 0) {
    1183:             set_mode(Delete);
    1184:             del_str(-delta);
    1185:         }
    1186:     }
    1187:     else {
    1188:         if (delta < 0) {
    1189:             clr_to_eol();
    1190:             return;
    1191:         }
    1192:     }
    1193:
    1194:     lenline[y] = xskip + len;
    1195:     if (cur_x == cols) {
    1196:         if (!has_mi)
    1197:             set_mode(Normal);
    1198:         if (!has_ms)
    1199:             so_mode = Undefined;
    1200:         if (has_am)
    1201:             cur_y++;
    1202:         else
    1203:             Putstr(cr_str);
    1204:         cur_x = 0;
    1205:     }
    1206:     else if (has_xs) {
    1207:         if (m2 == 0) {
    1208:             if (so_mode == On)
    1209:                 standend();
    1210:         }
    1211:         else {
    1212:             if (!(line[cur_y][cur_x] & XSBIT)) {
    1213:                 if (so_mode != (line[cur_y][cur_x] & SOBIT))
    1214:                     (so_mode ? standend() : standout());
    1215:             }
    1216:         }
    1217:     }
    1218: }
    1219:
    1220: Hidden Procedure
    1221: set_mode(m)
    1222: int m;
    1223: {
    1224:     if (m == mode)
    1225:         return;
    1226:     switch (mode) {
    1227:     case Insert:
    1228:         Putstr(ei_str);
    1229:         break;
    1230:     case Delete:
    1231:         Putstr(ed_str);
    1232:         break;
    1233:     case Undefined:
    1234:         Putstr(ei_str);
    1235:         Putstr(ed_str);
    1236:         break;
    1237:     }
    1238:     switch (m) {
    1239:     case Insert:
    1240:         Putstr(im_str);
    1241:         break;
    1242:     case Delete:
    1243:         Putstr(dm_str);
    1244:         break;
    1245:     }
    1246:     mode = m;
    1247: }
    1248:
    1249: Hidden Procedure
    1250: get_so_mode()
    1251: {
    1252:     if (cur_x >= lenline[cur_y] || line[cur_y][cur_x] == UNKNOWN)
    1253:         so_mode = Off;
    1254:     else
    1255:         so_mode = line[cur_y][cur_x] & SOBIT;
    1256: }
    1257:
    1258: Hidden Procedure
    1259: standout()
    1260: {
    1261:     Putstr(so_str);
    1262:     so_mode = On;
    1263:     if (has_xs)
    1264:         line[cur_y][cur_x] |= SOCOOK;
    1265: }
    1266:
    1267: Hidden Procedure
    1268: standend()
    1269: {
    1270:     Putstr(se_str);
    1271:     so_mode = Off;
    1272:     if (has_xs)
    1273:         line[cur_y][cur_x] = (line[cur_y][cur_x] & ~SOBIT) | XSBIT;
    1274: }
    1275:
    1276: Hidden Procedure
    1277: put_str(data, n, inserting)
    1278: char *data;
    1279: int n;
    1280: bool inserting;
    1281: {
    1282:     register intlet c, so;
    1283:     intlet *ln_y_x, *ln_y_end;
    1284:
    1285:     so = so_mode;
    1286:     if (has_xs) {
    1287:         ln_y_x = &line[cur_y][cur_x];
    1288:         ln_y_end = &line[cur_y][lenline[cur_y]];
    1289:     }
    1290:     while (n-- > 0) {
    1291:         if (has_xs && ln_y_x <= ln_y_end && ((*ln_y_x)&XSBIT))
    1292:             so = so_mode = (*ln_y_x)&SOBIT;
    1293:             /* this also checks for the standend cookie AFTER */
    1294:             /* the line because off the equals sign in <= */
    1295:         c = ((intlet)(*data++))&SOCHAR;
    1296:         if ((c&SOBIT) != so) {
    1297:             so = c&SOBIT;
    1298:             so ? standout() : standend();
    1299:         }
    1300:         if (inserting)
    1301:             Putstr(ic_str);
    1302:         put_c(c);
    1303:         if (has_xs)
    1304:             ln_y_x++;
    1305:     }
    1306: }
    1307:
    1308: Hidden Procedure
    1309: ins_str(data, n)
    1310: char *data;
    1311: int n;
    1312: {
    1313:     int x;
    1314:
    1315:     /* x will start AFTER the line, because there might be a cookie */
    1316:     for (x = lenline[cur_y]; x >= cur_x; x--)
    1317:         line[cur_y][x+n] = line[cur_y][x];
    1318:     put_str(data, n, Yes);
    1319: }
    1320:
    1321: Hidden Procedure
    1322: del_str(n)
    1323: int n;
    1324: {
    1325:     int x, xto;
    1326:
    1327:     xto = lenline[cur_y] - n; /* again one too far because of cookie */
    1328:     if (has_xs) {
    1329:         for (x = cur_x + n; x >= cur_x; x--) {
    1330:             if (line[cur_y][x] & XSBIT)
    1331:                 break;
    1332:         }
    1333:         if (x >= cur_x)
    1334:             line[cur_y][cur_x+n] =
    1335:                 (line[cur_y][cur_x+n] & CHAR)
    1336:                 |
    1337:                 (line[cur_y][x] & COOKBITS);
    1338:     }
    1339:     for (x = cur_x; x <= xto; x++)
    1340:         line[cur_y][x] = line[cur_y][x+n];
    1341:     while (n-- > 0)
    1342:         Putstr(dc_str);
    1343: }
    1344:
    1345: Hidden Procedure
    1346: put_c(c)
    1347: intlet c;
    1348: {
    1349:     char ch;
    1350:     intlet xs_flag;
    1351:
    1352:     ch = c&CHAR;
    1353:     if (!isprint(ch) && ch != ' ') { /* V7 isprint doesn't include blank */
    1354:         ch = '?';
    1355:         c = (c&SOBIT)|'?';
    1356:     }
    1357:     putchar(ch);
    1358:     if (has_xs)
    1359:         xs_flag = line[cur_y][cur_x]&XSBIT;
    1360:     else
    1361:         xs_flag = 0;
    1362:     line[cur_y][cur_x] = (c&SOCHAR)|xs_flag;
    1363:     cur_x++;
    1364: }
    1365:
    1366: Hidden Procedure
    1367: clear_lines(yfirst, ylast)
    1368: int yfirst, ylast ;
    1369: {
    1370:     register int y;
    1371:
    1372:     if (!has_xs && so_mode != Off)
    1373:         standend();
    1374:     if (cl_str && yfirst == 0 && ylast == lines-1) {
    1375:         Putstr(cl_str);
    1376:         cur_y = cur_x = 0;
    1377:         return;
    1378:     }
    1379:     for (y = yfirst; y <= ylast; y++) {
    1380:         if (lenline[y] > 0) {
    1381:             move(y, 0);
    1382:             if (ylast == lines-1 && cd_str) {
    1383:                 Putstr(cd_str);
    1384:                 while (y <= ylast) {
    1385:                     if (has_xs) line[y][0] = NOCOOK;
    1386:                     lenline[y++] = 0;
    1387:                 }
    1388:                 break;
    1389:             }
    1390:             else {
    1391:                 clr_to_eol();
    1392:             }
    1393:         }
    1394:     }
    1395: }
    1396:
    1397: Hidden Procedure
    1398: clr_to_eol()
    1399: {
    1400:     lenline[cur_y] = cur_x;
    1401:     if (!has_xs && so_mode != Off)
    1402:         standend();
    1403:     Putstr(ce_str);
    1404:     if (has_xs) {
    1405:         if (cur_x == 0)
    1406:             line[cur_y][0] = NOCOOK;
    1407:         else if (line[cur_y][cur_x-1]&SOBIT)
    1408:             standend();
    1409:     }
    1410: }
    1411:
    1412: Hidden Procedure
    1413: set_blanks
    1414: (y, xfrom, xto)
    1415: int y, xfrom, xto;
    1416: {
    1417:     register int x;
    1418:
    1419:     for (x = xfrom; x < xto; x++) {
    1420:         line[y][x] = (line[y][x]&XSBIT) | ' ';
    1421:     }
    1422: }
    1423:
    1424: /*
    1425:  * outchar() is used by termcap's tputs;
    1426:  * we can't use putchar because that's probably a macro
    1427:  */
    1428: Hidden int
    1429: outchar(ch)
    1430: char ch;
    1431: {
    1432:     putchar(ch);
    1433: }
    1434:
    1435: /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
    1436: /* Scrolling (part of) the screen up (or down, dy<0).                       */
    1437: /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
    1438:
    1439: Visible Procedure
    1440: trmscrollup(yfirst, ylast, by)
    1441: register int yfirst;
    1442: register int ylast;
    1443: register int by;
    1444: {
    1445: #ifdef TRACE
    1446: fprintf(stderr, "\ttrmscrollup(%d, %d, %d);\n", yfirst, ylast, by);
    1447: #endif
    1448:     check_started("trmscrollup");
    1449:
    1450:     if (yfirst < 0)
    1451:         yfirst = 0;
    1452:     if (ylast >= lines)
    1453:         ylast = lines-1;
    1454:
    1455:     if (yfirst > ylast)
    1456:         return;
    1457:
    1458:     if (!has_xs && so_mode != Off)
    1459:         standend();
    1460:
    1461:     if (by > 0 && yfirst + by > ylast
    1462:         ||
    1463:         by < 0 && yfirst - by > ylast)
    1464:     {
    1465:         clear_lines(yfirst, ylast);
    1466:         return;
    1467:     }
    1468:
    1469:     if (by > 0) {
    1470:         (*scr_up)(yfirst, ylast, by);
    1471:         scr_lines(yfirst, ylast, by, 1);
    1472:     }
    1473:     else if (by < 0) {
    1474:         (*scr_down)(yfirst, ylast, -by);
    1475:         scr_lines(ylast, yfirst, -by, -1);
    1476:     }
    1477: }
    1478:
    1479: Hidden Procedure
    1480: scr_lines(yfrom, yto, n, dy)
    1481: int yfrom, yto, n, dy;
    1482: {
    1483:     register int y;
    1484:     intlet *saveln;
    1485:
    1486:     while (n-- > 0) {
    1487:         saveln = line[yfrom];
    1488:         for (y = yfrom; y != yto; y += dy) {
    1489:             line[y] = line[y+dy];
    1490:             lenline[y] = lenline[y+dy];
    1491:         }
    1492:         line[yto] = saveln;
    1493:         lenline[yto] = 0;
    1494:         if (has_xs) line[yto][0] = NOCOOK;
    1495:     }
    1496: }
    1497:
    1498: Hidden Procedure
    1499: scr1up(yfirst, ylast, n)
    1500:     int yfirst;
    1501:     int ylast;
    1502:     int n;
    1503: {
    1504:     move(yfirst, 0);
    1505:     dellines(n);
    1506:     if (ylast < lines-1) {
    1507:         move(ylast-n+1, 0);
    1508:         addlines(n);
    1509:     }
    1510: }
    1511:
    1512: Hidden Procedure
    1513: scr1down(yfirst, ylast, n)
    1514:     int yfirst;
    1515:     int ylast;
    1516:     int n;
    1517: {
    1518:     if (ylast == lines-1) {
    1519:         clear_lines(ylast-n+1, ylast);
    1520:     }
    1521:     else {
    1522:         move(ylast-n+1, 0);
    1523:         dellines(n);
    1524:     }
    1525:     move(yfirst, 0);
    1526:     addlines(n);
    1527: }
    1528:
    1529: Hidden Procedure
    1530: addlines(n)
    1531: register int n;
    1532: {
    1533:     if (par_al_str && n > 1)
    1534:             Putstr(tgoto(par_al_str, n, n));
    1535:     else {
    1536:         while (n-- > 0)
    1537:             Putstr(al_str);
    1538:     }
    1539: }
    1540:
    1541: Hidden Procedure
    1542: dellines(n)
    1543: register int n;
    1544: {
    1545:     if (par_dl_str && n > 1)
    1546:         Putstr(tgoto(par_dl_str, n, n));
    1547:     else {
    1548:         while (n-- > 0)
    1549:             Putstr(dl_str);
    1550:     }
    1551: }
    1552:
    1553: Hidden Procedure
    1554: scr2up(yfirst, ylast, n)
    1555: int yfirst, ylast, n;
    1556: {
    1557:     Putstr(tgoto(cs_str, ylast, yfirst));
    1558:     cur_y = cur_x = Undefined;
    1559:     move(ylast, 0);
    1560:     while (n-- > 0) {
    1561:         Putstr(sf_str);
    1562:         if (has_db && ylast == lines-1)
    1563:             clr_to_eol();
    1564:     }
    1565:     Putstr(tgoto(cs_str, lines-1, 0));
    1566:     cur_y = cur_x = Undefined;
    1567: }
    1568:
    1569: Hidden Procedure
    1570: scr2down(yfirst, ylast, n)
    1571: int yfirst, ylast, n;
    1572: {
    1573:     Putstr(tgoto(cs_str, ylast, yfirst));
    1574:     cur_y = cur_x = Undefined;
    1575:     move(yfirst, 0);
    1576:     while (n-- > 0) {
    1577:         Putstr(sr_str);
    1578:         if (has_da && yfirst == 0)
    1579:             clr_to_eol();
    1580:     }
    1581:     Putstr(tgoto(cs_str, lines-1, 0));
    1582:     cur_y = cur_x = Undefined;
    1583: }
    1584:
    1585: /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
    1586: /* Synchronization, move cursor to given position (or previous if < 0).     */
    1587: /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
    1588:
    1589: Visible Procedure
    1590: trmsync(y, x)
    1591:     int y;
    1592:     int x;
    1593: {
    1594: #ifdef TRACE
    1595: fprintf(stderr, "\ttrmsync(%d, %d);\n", y, x);
    1596: #endif
    1597:     check_started("trmsync");
    1598:
    1599:     if (0 <= y && y < lines && 0 <= x && x < cols) {
    1600:         move(y, x);
    1601:         if (no_cursor) {
    1602:             Putstr(ve_str);
    1603:             no_cursor = No;
    1604:         }
    1605:     }
    1606:     else if (no_cursor == No) {
    1607:         Putstr(vi_str);
    1608:         no_cursor = Yes;
    1609:     }
    1610:     VOID fflush(stdout);
    1611: }
    1612:
    1613: /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
    1614: /* Send a bell, visible if possible.                                        */
    1615: /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
    1616:
    1617: Visible Procedure
    1618: trmbell()
    1619: {
    1620: #ifdef TRACE
    1621: fprintf(stderr, "\ttrmbell();\n");
    1622: #endif
    1623:     check_started("trmbell");
    1624:
    1625:     Putstr(vb_str);
    1626:     VOID fflush(stdout);
    1627: }
    1628:
    1629: /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
    1630: /* Show the current internal statuses of the screen on stderr.              */
    1631: /* For debugging only.                                                      */
    1632: /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
    1633:
    1634: #ifdef SHOW
    1635: Visible Procedure
    1636: trmshow(s)
    1637: char *s;
    1638: {
    1639:     int y, x;
    1640:
    1641:     fprintf(stderr, "<<< %s >>>\n", s);
    1642:     for (y = 0; y < lines; y++) {
    1643:         for (x = 0; x <= lenline[y] /*** && x < cols-1 ***/ ; x++) {
    1644:             fputc(line[y][x]&CHAR, stderr);
    1645:         }
    1646:         fputc('\n', stderr);
    1647:         for (x = 0; x <= lenline[y] && x < cols-1; x++) {
    1648:             if (line[y][x]&SOBIT)
    1649:                 fputc('-', stderr);
    1650:             else
    1651:                 fputc(' ', stderr);
    1652:         }
    1653:         fputc('\n', stderr);
    1654:         for (x = 0; x <= lenline[y] && x < cols-1; x++) {
    1655:             if (line[y][x]&XSBIT)
    1656:                 fputc('+', stderr);
    1657:             else
    1658:                 fputc(' ', stderr);
    1659:         }
    1660:         fputc('\n', stderr);
    1661:     }
    1662:     fprintf(stderr, "CUR_Y = %d, CUR_X = %d.\n", cur_y, cur_x);
    1663:     VOID fflush(stderr);
    1664: }
    1665: #endif

#### Defined functions

addlines defined in line 1529; used 2 times

- in line 1508, 1526

check_started defined in line 406; used 5 times

- in line 731, 998, 1448, 1597, 1623

clear_lines defined in line 1366; used 5 times

- in line 400, 707, 1029, 1465, 1519

clr_to_eol defined in line 1397; used 4 times

- in line 1189, 1391, 1563, 1579

countchar defined in line 421; used 1 times

- in line 442

del_str defined in line 1321; used 1 times

- in line 1184

dellines defined in line 1541; used 2 times

- in line 1505, 1523

get_so_mode defined in line 1249; used 1 times

- in line 1156

getpos defined in line 746; used 3 times

- in line 726, 738
- in /usr/src/new/PORT/B/src/bed/demo.c line 234

gettermcaps defined in line 446; used 1 times

- in line 285

ins_str defined in line 1308; used 1 times

- in line 1180

lalloc defined in line 674; used 3 times

- in line 693-698(3)

move defined in line 859; used 11 times

- in line 399, 1153, 1167, 1381, 1504-1507(2), 1522-1525(2), 1559, 1575, 1600

outchar defined in line 1428; used 2 times

- in line 121-122(2)

put_c defined in line 1345; used 1 times

- in line 1302

put_line defined in line 1068; used 1 times

- in line 1016

put_str defined in line 1276; used 3 times

- in line 1161, 1174, 1318

resetttymode defined in line 667; used 2 times

- in line 316, 403

rewrite_ok defined in line 828; used 2 times

- in line 908, 923

scr1down defined in line 1512; used 2 times

- in line 257, 524

scr1up defined in line 1498; used 2 times

- in line 256, 523

scr2down defined in line 1569; used 2 times

- in line 259, 535

scr2up defined in line 1553; used 2 times

- in line 258, 534

scr_lines defined in line 1479; used 2 times

- in line 1471-1475(2)

set_blanks defined in line 1412; used 1 times

- in line 1165

set_mode defined in line 1220; used 9 times

- in line 311, 734, 872, 952, 1160, 1173, 1179-1183(2), 1197

setttymode defined in line 636; used 1 times

- in line 287

standend defined in line 1267; used 11 times

- in line 313, 736, 874, 1164, 1209-1214(2), 1298, 1373, 1402, 1408, 1459

standout defined in line 1258; used 2 times

- in line 1214, 1298

start_trm defined in line 687; used 1 times

- in line 289

str0cost defined in line 437; used 7 times

- in line 434, 620-629(6)

strcost defined in line 428; used 6 times

- in line 612-617(6)

trmbell defined in line 1617; used 2 times

- in /usr/src/new/PORT/B/src/bed/erro.c line 48
- in /usr/src/new/PORT/B/src/bed/help.c line 118

trmend defined in line 305; used 1 times

- in /usr/src/new/PORT/B/src/bed/scrn.c line 420

trmerr defined in line 347; used 3 times

- in line 284, 414, 683

trmmess defined in line 361; used 3 times

- in line 471-475(2), 641

trmputdata defined in line 985; used 10 times

- in /usr/src/new/PORT/B/src/bed/erro.c line 78
- in /usr/src/new/PORT/B/src/bed/help.c line 98, 110-114(2), 121
- in /usr/src/new/PORT/B/src/bed/outp.c line 201
- in /usr/src/new/PORT/B/src/bed/scrn.c line 110, 270, 418, 479

trmreset defined in line 395; used 3 times

- in line 351, 364, 376

trmscrollup defined in line 1439; used 8 times

- in /usr/src/new/PORT/B/src/bed/help.c line 99
- in /usr/src/new/PORT/B/src/bed/scrn.c line 77, 107, 144, 194, 207-212(2), 242

trmsense defined in line 721; used 1 times

- in /usr/src/new/PORT/B/src/bed/term.c line 64

trmshow defined in line 1635; never used
trmsorry defined in line 372; used 7 times

- in line 480, 491-496(2), 510, 539, 566, 573

trmstart defined in line 274; used 1 times

- in /usr/src/new/PORT/B/src/bed/scrn.c line 389

trmsync defined in line 1589; used 5 times

- in /usr/src/new/PORT/B/src/bed/help.c line 100, 115
- in /usr/src/new/PORT/B/src/bed/scrn.c line 116-118(2), 419

trmundefined defined in line 325; used 3 times

- in line 701
- in /usr/src/new/PORT/B/src/bed/demo.c line 371
- in /usr/src/new/PORT/B/src/bed/help.c line 106

#### Defined variables

BC defined in line 117; used 6 times

- in line 484-489(5), 587

Hidden defined in line 674; never used
PC defined in line 116; used 1 times

- in line 500

Procedure defined in line 667; never used
UP defined in line 118; used 3 times

- in line 494-495(2), 592

abs_cost defined in line 234; used 7 times

- in line 610-612(2), 894, 929-931(2), 1123-1125(2)

al_str defined in line 138; used 3 times

- in line 518-522(2), 1537

ccc defined in line 418; used 3 times

- in line 425, 441-443(2)

cd_str defined in line 140; used 3 times

- in line 570, 1382-1383(2)

ce_str defined in line 141; used 3 times

- in line 571-572(2), 1403

cl_str defined in line 142; used 3 times

- in line 576, 1374-1375(2)

cm_str defined in line 143; used 8 times

- in line 505-508(4), 609-612(2), 961, 970

cols defined in line 128; used 18 times

- in line 292, 337-339(2), 545-549(2), 555(2), 695, 739, 1004-1008(3), 1014, 1022, 1195, 1599, 1647, 1654

cp_str defined in line 170; used 3 times

- in line 600-602(2), 750

cr_cost defined in line 235; used 3 times

- in line 613, 923-925(2)

cr_str defined in line 144; used 6 times

- in line 577-578(3), 613, 948, 1203

cs_str defined in line 145; used 8 times

- in line 528-533(2), 704-705(2), 1557, 1565, 1573, 1581

cur_y defined in line 214; used 42 times

- in line 333, 742, 868, 876-879(2), 963(3), 973, 1201, 1212-1213(2), 1252-1255(3), 1264, 1273(2), 1287-1288(3), 1316-1317(3), 1327-1340(7), 1359-1362(2), 1376, 1400, 1406-1407(2), 1558, 1566, 1574, 1582, 1662

dc_str defined in line 146; used 4 times

- in line 579, 624-628(2), 1342

del_mf defined in line 245; used 2 times

- in line 628, 1139

del_oh defined in line 245; used 2 times

- in line 629, 1139

dl_str defined in line 147; used 3 times

- in line 519-522(2), 1549

dm_str defined in line 150; used 3 times

- in line 580, 629, 1243

do_cost defined in line 236; used 2 times

- in line 614, 884

do_str defined in line 149; used 9 times

- in line 503, 509, 581-582(4), 614, 934, 964

ed_cost defined in line 246; used 3 times

- in line 621, 629, 903

ed_str defined in line 151; used 4 times

- in line 583, 621, 1231-1235(2)

ei_cost defined in line 246; used 3 times

- in line 620, 627, 900

ei_str defined in line 152; used 5 times

- in line 584, 620-624(2), 1228, 1234

flags defined in line 179; used 8 times

- in line 293, 525, 536, 603-606(2), 625, 738, 1089

has_am defined in line 130; used 2 times

- in line 557, 1200

has_da defined in line 131; used 1 times

- in line 1578

has_db defined in line 132; used 2 times

- in line 558, 1562

has_in defined in line 133; used 2 times

- in line 559, 1103

has_mi defined in line 134; used 3 times

- in line 560, 871, 1196

has_ms defined in line 135; used 3 times

- in line 561, 873, 1198

has_xs defined in line 136; used 20 times

- in line 562-564(2), 841, 873, 1155, 1163, 1206, 1263, 1272, 1286-1291(2), 1303, 1328, 1358, 1372, 1385, 1401-1404(2), 1458, 1494

ho_str defined in line 153; used 3 times

- in line 502, 509, 962

ic_str defined in line 154; used 4 times

- in line 585, 624-626(2), 1301

im_str defined in line 155; used 4 times

- in line 586, 624-627(2), 1240

ins_mf defined in line 245; used 2 times

- in line 626, 1137

ins_oh defined in line 245; used 2 times

- in line 627, 1137

know_ttys defined in line 113; used 3 times

- in line 639, 661, 670

le_cost defined in line 237; used 2 times

- in line 615, 916

le_str defined in line 156; used 3 times

- in line 587, 615, 945

line defined in line 225; used 41 times

- in line 338, 692-695(3), 837-838(2), 954, 1082-1083(2), 1212-1213(2), 1252-1255(2), 1264, 1273(2), 1287-1288(2), 1317(2), 1330-1340(6), 1359-1362(2), 1385, 1406-1407(2), 1420(2), 1487-1494(5), 1644-1648(2), 1655

lines defined in line 127; used 29 times

- in line 291, 336, 399-400(3), 544, 551-554(3), 693-698(3), 705-707(2), 739, 1002-1003(2), 1012, 1374, 1382, 1452-1453(2), 1506, 1518, 1562-1565(2), 1581, 1599, 1642

mode defined in line 193; used 6 times

- in line 334, 871, 895, 1224-1226(2), 1246

mustclear defined in line 228; used 2 times

- in line 515, 706

nd_cost defined in line 238; used 3 times

- in line 616, 908-909(2)

nd_str defined in line 157; used 5 times

- in line 504-509(2), 616, 942, 967

newtty defined in line 109; used 11 times

- in line 640, 647-663(10)

no_cursor defined in line 231; used 4 times

- in line 1601-1608(4)

oldtty defined in line 109; used 4 times

- in line 640-645(2), 654, 671

ospeed defined in line 119; used 2 times

- in line 645, 654

par_al_str defined in line 139; used 3 times

- in line 520, 1533-1534(2)

par_dl_str defined in line 148; used 3 times

- in line 521, 1545-1546(2)

rcsid defined in line 2; never used
se_str defined in line 158; used 3 times

- in line 588, 605, 1270

sf_str defined in line 159; used 4 times

- in line 529-531(3), 1561

so_mode defined in line 198; used 20 times

- in line 312, 334, 735, 841, 873(2), 1163, 1199, 1208-1214(3), 1253-1255(2), 1262, 1271, 1285, 1292, 1372, 1401, 1458

so_str defined in line 160; used 3 times

- in line 589, 605, 1261

sp_str defined in line 171; used 3 times

- in line 601-602(2), 758

sr_str defined in line 161; used 3 times

- in line 532-533(2), 1577

started defined in line 176; used 5 times

- in line 283, 295, 318, 398, 412

te_str defined in line 162; used 2 times

- in line 314, 590

ti_str defined in line 163; used 2 times

- in line 591, 703

up_cost defined in line 239; used 2 times

- in line 617, 888

up_str defined in line 164; used 3 times

- in line 592, 617, 937

vb_str defined in line 165; used 4 times

- in line 593-595(3), 1625

ve_str defined in line 166; used 2 times

- in line 596, 1602

vi_str defined in line 167; used 2 times

- in line 597, 1607

#### Defined typedef's

bool defined in line 93; used 20 times

- in line 113, 130-136(7), 176, 228-231(2), 746, 828, 1280-95(3), 462, 726, 755, 1078

intlet defined in line 91; used 18 times

- in line 214, 225, 1347-698(7), 832, 1074, 1087-1090(2), 1282-1283(2), 1295, 1350, 1484

string defined in line 92; used 6 times

- in line 349, 362, 374, 990, 1071-451(2)

#### Defined macros

CHAR defined in line 202; used 3 times

- in line 1335, 1352, 1644

COOKBITS defined in line 209; used 1 times

- in line 1337

CrWrite defined in line 857; used 1 times

- in line 924

Delete defined in line 192; used 1 times

- in line 1183

Down defined in line 852; used 1 times

- in line 883

Forward defined in line 86; used 5 times

- in line 121, 256-259(4)

Hidden defined in line 88; used 95 times

- in line 102, 109-113(2), 127-179(43), 193-198(2), 214, 225-239(9), 245-246(2), 254-255(2), 347, 361, 372, 395, 406, 421, 428, 437, 446, 687, 746, 828, 859, 1068, 1220, 1249, 1258, 1267, 1276, 1308, 1321, 1345, 1366, 1397, 1412, 1428, 1479, 1498, 1512, 1529, 1541, 1553, 1569

Infinity defined in line 182; used 2 times

- in line 433, 610

Insert defined in line 191; used 1 times

- in line 1179

Left defined in line 856; used 1 times

- in line 917

Min defined in line 97; used 4 times

- in line 1014, 1022, 1135, 1146

NOCOOK defined in line 211; used 3 times

- in line 1385, 1406, 1494

NULCHAR defined in line 201; used 1 times

- in line 500

No defined in line 95; used 32 times

- in line 113, 176, 228-231(2), 286-288(2), 318, 462, 472-481(3), 492-497(2), 511, 540, 567, 574, 642, 755, 764, 770, 781, 796, 806, 835, 843, 1129, 1147, 1161, 1174, 1603-1606(2)

None defined in line 851; used 2 times

- in line 891, 921

Normal defined in line 190; used 8 times

- in line 193, 311, 734, 872, 952, 1160, 1173, 1197

Off defined in line 196; used 10 times

- in line 198, 312, 735, 873, 1163, 1253, 1271, 1372, 1401, 1458

On defined in line 197; used 3 times

- in line 203, 1208, 1262

Procedure defined in line 89; used 38 times

- in line 256-259(4), 305, 325, 347, 361, 372, 395, 406, 421, 687, 721, 859, 985, 1220, 1249, 1258, 1267, 1276, 1308, 1321, 1345, 1366, 1397, 1412, 1439, 1479, 1498, 1512, 1529, 1541, 1553, 1569, 1589, 1617, 1635

Putstr defined in line 122; used 40 times

- in line 314, 703-705(2), 758, 934-948(5), 962-970(4), 1203, 1228-1243(6), 1261, 1270, 1301, 1342, 1375, 1383, 1403, 1534-1537(2), 1546-1549(2), 1557-1565(3), 1573-1581(3), 1602-1607(2), 1625

ReWrite defined in line 855; used 1 times

- in line 913

Right defined in line 854; used 1 times

- in line 910

SOBIT defined in line 203; used 10 times

- in line 841, 1213, 1255, 1273, 1292-1297(3), 1355, 1407, 1648

SOCHAR defined in line 204; used 6 times

- in line 1087-1090(4), 1295, 1362

SOCOOK defined in line 208; used 2 times

- in line 209, 1264

UNKNOWN defined in line 210; used 3 times

- in line 211, 839, 1252

Undefined defined in line 187; used 15 times

- in line 214(2), 333-334(2), 733, 740, 871-876(4), 1199, 1558, 1566, 1574, 1582

Up defined in line 853; used 1 times

- in line 887

VOID defined in line 83; used 13 times

- in line 105, 111, 315, 354, 366, 389, 402, 413, 759, 785, 1610, 1626, 1663

Visible defined in line 87; used 9 times

- in line 274, 305, 325, 721, 985, 1439, 1589, 1617, 1635

XSBIT defined in line 207; used 7 times

- in line 1212, 1273, 1291, 1330, 1359, 1420, 1655

Yes defined in line 94; used 15 times

- in line 295-296(2), 468, 515, 564, 632-633(2), 661-664(2), 776, 819, 844, 1124, 1318, 1608

gtty defined in line 110; used 2 times

- in line 640(2)

stty defined in line 111; used 2 times

- in line 663, 671

Last modified: 1985-11-27 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 5379 |