# 2.11BSD#431 - /usr/src/new/rn/term.c

##### Functions

    circfill          X
    eat_typeahead     X
    finish_command    X
    get_anything      X
    getcmd            X
    home_cursor       X
    in_char           X
    mac_init          X
    mac_line          X
    newkeymap         X
    no_sofire         X
    no_ulfire         X
    pad               X
    page_init         X
    print_lines       X
    printcmd          X
    pushchar          X
    pushstring        X
    putchr            X
    read_tty          X
    reprint           X
    rubout            X
    settle_down       X
    show_keymap       X
    show_macros       X
    term_init         X
    term_set          X
    underprint        X

##### Variables

    ERASECH           X
    KILLCH            X
    tcarea            X
    topmap            X

##### Macros

    KM_BOGUS          X
    KM_GMASK          X
    KM_GSHIFT         X
    KM_KEYMAP         X
    KM_NOTHIN         X
    KM_STRING         X
    KM_TMASK          X
    Tgetstr           X

##### struct's

    keymap            X

##### unions's

    km_union          X

##### typedef's

    KEYMAP            X

       1: /* $Header: term.c,v 4.3.1.3 85/09/10 11:05:23 lwall Exp $
       2:  *
       3:  * $Log:	term.c,v $
       4:  * Revision 4.3.1.3  85/09/10  11:05:23  lwall
       5:  * Improved %m in in_char().
       6:  *
       7:  * Revision 4.3.1.2  85/05/16  16:45:35  lwall
       8:  * Forced \r to \n on input.
       9:  * Fix for terminfo braindamage regarding bc emulation.
      10:  *
      11:  * Revision 4.3.1.1  85/05/10  11:41:03  lwall
      12:  * Branch for patches.
      13:  *
      14:  * Revision 4.3  85/05/01  11:51:10  lwall
      15:  * Baseline for release with 4.3bsd.
      16:  *
      17:  */
      18:
      19: #include "EXTERN.h"
      20: #include "common.h"
      21: #include "util.h"
      22: #include "final.h"
      23: #include "help.h"
      24: #include "cheat.h"
      25: #include "intrp.h"
      26: #include "INTERN.h"
      27: #include "term.h"
      28:
      29: char ERASECH;       /* rubout character */
      30: char KILLCH;        /* line delete character */
      31: char tcarea[TCSIZE];    /* area for "compiled" termcap strings */
      32:
      33: /* guarantee capability pointer != Nullch */
      34: /* (I believe terminfo will ignore the &tmpaddr argument.) */
      35:
      36: #define Tgetstr(key) ((tmpstr = tgetstr(key,&tmpaddr)) ? tmpstr : nullstr)
      37:
      38: #ifdef PUSHBACK
      39: struct keymap {
      40:     char km_type[128];
      41:     union km_union {
      42:     struct keymap *km_km;
      43:     char *km_str;
      44:     } km_ptr[128];
      45: };
      46:
      47: #define KM_NOTHIN 0
      48: #define KM_STRING 1
      49: #define KM_KEYMAP 2
      50: #define KM_BOGUS 3
      51:
      52: #define KM_TMASK 3
      53: #define KM_GSHIFT 4
      54: #define KM_GMASK 7
      55:
      56: typedef struct keymap KEYMAP;
      57:
      58: KEYMAP *topmap INIT(Null(KEYMAP*));
      59:
      60: void mac_init();
      61: KEYMAP *newkeymap();
      62: void show_keymap();
      63: void pushstring();
      64: #endif
      65:
      66: /* terminal initialization */
      67:
      68: void
      69: term_init()
      70: {
      71:     savetty();              /* remember current tty state */
      72:
      73: #ifdef TERMIO
      74:     ospeed = _tty.c_cflag & CBAUD;  /* for tputs() */
      75:     ERASECH = _tty.c_cc[VERASE];    /* for finish_command() */
      76:     KILLCH = _tty.c_cc[VKILL];      /* for finish_command() */
      77: #else
      78:     ospeed = _tty.sg_ospeed;        /* for tputs() */
      79:     ERASECH = _tty.sg_erase;        /* for finish_command() */
      80:     KILLCH = _tty.sg_kill;      /* for finish_command() */
      81: #endif
      82:
      83:     /* The following could be a table but I can't be sure that there isn't */
      84:     /* some degree of sparsity out there in the world. */
      85:
      86:     switch (ospeed) {           /* 1 second of padding */
      87: #ifdef BEXTA
      88:         case BEXTA:  just_a_sec = 1920; break;
      89: #else
      90: #ifdef B19200
      91:         case B19200: just_a_sec = 1920; break;
      92: #endif
      93: #endif
      94:         case B9600:  just_a_sec =  960; break;
      95:         case B4800:  just_a_sec =  480; break;
      96:         case B2400:  just_a_sec =  240; break;
      97:         case B1800:  just_a_sec =  180; break;
      98:         case B1200:  just_a_sec =  120; break;
      99:         case B600:   just_a_sec =   60; break;
     100:     case B300:   just_a_sec =   30; break;
     101:     /* do I really have to type the rest of this??? */
     102:         case B200:   just_a_sec =   20; break;
     103:         case B150:   just_a_sec =   15; break;
     104:         case B134:   just_a_sec =   13; break;
     105:         case B110:   just_a_sec =   11; break;
     106:         case B75:    just_a_sec =    8; break;
     107:         case B50:    just_a_sec =    5; break;
     108:         default:     just_a_sec =  960; break;
     109:                     /* if we are running detached I */
     110:     }                   /*  don't want to know about it! */
     111: }
     112:
     113: /* set terminal characteristics */
     114:
     115: void
     116: term_set(tcbuf)
     117: char *tcbuf;        /* temp area for "uncompiled" termcap entry */
     118: {
     119:     char *tmpaddr;          /* must not be register */
     120:     register char *tmpstr;
     121:     char *tgetstr();
     122:     char *s;
     123:     int status;
     124:
     125: #ifdef PENDING
     126: #ifndef FIONREAD
     127:     /* do no delay reads on something that always gets closed on exit */
     128:
     129:     devtty = open("/dev/tty",0);
     130:     if (devtty < 0) {
     131:     printf(cantopen,"/dev/tty") FLUSH;
     132:     finalize(1);
     133:     }
     134:     fcntl(devtty,F_SETFL,O_NDELAY);
     135: #endif
     136: #endif
     137:
     138:     /* get all that good termcap stuff */
     139:
     140: #ifdef HAVETERMLIB
     141:     status = tgetent(tcbuf,getenv("TERM")); /* get termcap entry */
     142:     if (status < 1) {
     143: #ifdef VERBOSE
     144:     printf("No termcap %s found.\n", status ? "file" : "entry") FLUSH;
     145: #else
     146:     fputs("Termcap botch\n",stdout) FLUSH;
     147: #endif
     148:     finalize(1);
     149:     }
     150:     tmpaddr = tcarea;           /* set up strange tgetstr pointer */
     151:     s = Tgetstr("pc");          /* get pad character */
     152:     PC = *s;                /* get it where tputs wants it */
     153:     if (!tgetflag("bs")) {      /* is backspace not used? */
     154:     BC = Tgetstr("bc");     /* find out what is */
     155:     if (BC == nullstr)      /* terminfo grok's 'bs' but not 'bc' */
     156:         BC = Tgetstr("le");
     157:     } else
     158:     BC = "\b";          /* make a backspace handy */
     159:     UP = Tgetstr("up");         /* move up a line */
     160:     if (!*UP)               /* no UP string? */
     161:     marking = 0;            /* disable any marking */
     162:     if (muck_up_clear)          /* this is for weird HPs */
     163:     CL = "\n\n\n\n";
     164:     else
     165:     CL = Tgetstr("cl");     /* get clear string */
     166:     CE = Tgetstr("ce");         /* clear to end of line string */
     167: #ifdef CLEAREOL
     168:     CM = Tgetstr("cm");         /* cursor motion - PWP */
     169:     HO = Tgetstr("ho");         /* home cursor if no CM - PWP */
     170:     CD = Tgetstr("cd");         /* clear to end of display - PWP */
     171:     if (!*CE || !*CD || (!*CM && !*HO)) /* can we CE, CD, and home? */
     172:     can_home_clear = FALSE;     /*  no, so disable use of clear eol */
     173: #endif CLEAREOL
     174:     SO = Tgetstr("so");         /* begin standout */
     175:     SE = Tgetstr("se");         /* end standout */
     176:     if ((SG = tgetnum("sg"))<0)
     177:     SG = 0;             /* blanks left by SG, SE */
     178:     US = Tgetstr("us");         /* start underline */
     179:     UE = Tgetstr("ue");         /* end underline */
     180:     if ((UG = tgetnum("ug"))<0)
     181:     UG = 0;             /* blanks left by US, UE */
     182:     if (*US)
     183:     UC = nullstr;           /* UC must not be NULL */
     184:     else
     185:     UC = Tgetstr("uc");     /* underline a character */
     186:     if (!*US && !*UC) {         /* no underline mode? */
     187:     US = SO;            /* substitute standout mode */
     188:     UE = SE;
     189:     UG = SG;
     190:     }
     191:     LINES = tgetnum("li");      /* lines per page */
     192:     COLS = tgetnum("co");       /* columns on page */
     193:
     194: #ifdef TIOCGWINSZ
     195:     { struct winsize ws;
     196:     if (ioctl(0, TIOCGWINSZ, &ws) >= 0 && ws.ws_row > 0 && ws.ws_col > 0) {
     197:         LINES = ws.ws_row;
     198:         COLS = ws.ws_col;
     199:     }
     200:     }
     201: #endif
     202:
     203:     AM = tgetflag("am");        /* terminal wraps automatically? */
     204:     XN = tgetflag("xn");        /* then eats next newline? */
     205:     VB = Tgetstr("vb");
     206:     if (!*VB)
     207:     VB = "\007";
     208:     CR = Tgetstr("cr");
     209:     if (!*CR) {
     210:     if (tgetflag("nc") && *UP) {
     211:         CR = safemalloc((MEM_SIZE)strlen(UP)+2);
     212:         sprintf(CR,"%s\r",UP);
     213:     }
     214:     else
     215:         CR = "\r";
     216:     }
     217: #else
     218:     ??????              /* Roll your own... */
     219: #endif
     220:     if (LINES > 0) {            /* is this a crt? */
     221:     if (!initlines)         /* no -i? */
     222:         if (ospeed >= B9600)    /* whole page at >= 9600 baud */
     223:         initlines = LINES;
     224:         else if (ospeed >= B4800)   /* 16 lines at 4800 */
     225:         initlines = 16;
     226:         else            /* otherwise just header */
     227:         initlines = 8;
     228:     }
     229:     else {              /* not a crt */
     230:     LINES = 30000;          /* so don't page */
     231:     CL = "\n\n";            /* put a couple of lines between */
     232:     if (!initlines)         /* make initlines reasonable */
     233:         initlines = 8;
     234:     }
     235:     if (COLS <= 0)
     236:     COLS = 80;
     237:     noecho();               /* turn off echo */
     238:     crmode();               /* enter cbreak mode */
     239:
     240: #ifdef PUSHBACK
     241:     mac_init(tcbuf);
     242: #endif
     243: }
     244:
     245: #ifdef PUSHBACK
     246: void
     247: mac_init(tcbuf)
     248: char *tcbuf;
     249: {
     250:     char tmpbuf[1024];
     251:
     252:     tmpfp = fopen(filexp(getval("RNMACRO",RNMACRO)),"r");
     253:     if (tmpfp != Nullfp) {
     254:     while (fgets(tcbuf,1024,tmpfp) != Nullch) {
     255:         mac_line(tcbuf,tmpbuf,(sizeof tmpbuf));
     256:     }
     257:     fclose(tmpfp);
     258:     }
     259: }
     260:
     261: void
     262: mac_line(line,tmpbuf,tbsize)
     263: char *line;
     264: char *tmpbuf;
     265: int tbsize;
     266: {
     267:     register char *s, *m;
     268:     register KEYMAP *curmap;
     269:     register int ch;
     270:     register int garbage = 0;
     271:     static char override[] = "\nkeymap overrides string\n";
     272:
     273:     if (topmap == Null(KEYMAP*))
     274:     topmap = newkeymap();
     275:     if (*line == '#' || *line == '\n')
     276:     return;
     277:     if (line[ch = strlen(line)-1] == '\n')
     278:     line[ch] = '\0';
     279:     m = dointerp(tmpbuf,tbsize,line," \t");
     280:     if (!*m)
     281:     return;
     282:     while (*m == ' ' || *m == '\t') m++;
     283:     for (s=tmpbuf,curmap=topmap; *s; s++) {
     284:     ch = *s & 0177;
     285:     if (s[1] == '+' && isdigit(s[2])) {
     286:         s += 2;
     287:         garbage = (*s & KM_GMASK) << KM_GSHIFT;
     288:     }
     289:     else
     290:         garbage = 0;
     291:     if (s[1]) {
     292:         if ((curmap->km_type[ch] & KM_TMASK) == KM_STRING) {
     293:         puts(override,stdout) FLUSH;
     294:         free(curmap->km_ptr[ch].km_str);
     295:         curmap->km_ptr[ch].km_str = Nullch;
     296:         }
     297:         curmap->km_type[ch] = KM_KEYMAP + garbage;
     298:         if (curmap->km_ptr[ch].km_km == Null(KEYMAP*))
     299:         curmap->km_ptr[ch].km_km = newkeymap();
     300:         curmap = curmap->km_ptr[ch].km_km;
     301:     }
     302:     else {
     303:         if ((curmap->km_type[ch] & KM_TMASK) == KM_KEYMAP)
     304:         puts(override,stdout) FLUSH;
     305:         else {
     306:         curmap->km_type[ch] = KM_STRING + garbage;
     307:         curmap->km_ptr[ch].km_str = savestr(m);
     308:         }
     309:     }
     310:     }
     311: }
     312:
     313: KEYMAP*
     314: newkeymap()
     315: {
     316:     register int i;
     317:     register KEYMAP *map;
     318:
     319: #ifndef lint
     320:     map = (KEYMAP*)safemalloc(sizeof(KEYMAP));
     321: #else
     322:     map = Null(KEYMAP*);
     323: #endif lint
     324:     for (i=127; i>=0; --i) {
     325:     map->km_ptr[i].km_km = Null(KEYMAP*);
     326:     map->km_type[i] = KM_NOTHIN;
     327:     }
     328:     return map;
     329: }
     330:
     331: void
     332: show_macros()
     333: {
     334:     char prebuf[64];
     335:
     336:     if (topmap != Null(KEYMAP*)) {
     337:     print_lines("Macros:\n",STANDOUT);
     338:     *prebuf = '\0';
     339:     show_keymap(topmap,prebuf);
     340:     }
     341: }
     342:
     343: void
     344: show_keymap(curmap,prefix)
     345: register KEYMAP *curmap;
     346: char *prefix;
     347: {
     348:     register int i;
     349:     register char *next = prefix + strlen(prefix);
     350:     register int kt;
     351:
     352:     for (i=0; i<128; i++) {
     353:     if (kt = curmap->km_type[i]) {
     354:         if (i < ' ')
     355:         sprintf(next,"^%c",i+64);
     356:         else if (i == ' ')
     357:         strcpy(next,"\\040");
     358:         else if (i == 127)
     359:         strcpy(next,"^?");
     360:         else
     361:         sprintf(next,"%c",i);
     362:         if ((kt >> KM_GSHIFT) & KM_GMASK) {
     363:         sprintf(cmd_buf,"+%d", (kt >> KM_GSHIFT) & KM_GMASK);
     364:         strcat(next,cmd_buf);
     365:         }
     366:         switch (kt & KM_TMASK) {
     367:         case KM_NOTHIN:
     368:         sprintf(cmd_buf,"%s	%c\n",prefix,i);
     369:         print_lines(cmd_buf,NOMARKING);
     370:         break;
     371:         case KM_KEYMAP:
     372:         show_keymap(curmap->km_ptr[(char)i].km_km, prefix);
     373:         break;
     374:         case KM_STRING:
     375:         sprintf(cmd_buf,"%s	%s\n",prefix,curmap->km_ptr[i].km_str);
     376:         print_lines(cmd_buf,NOMARKING);
     377:         break;
     378:         case KM_BOGUS:
     379:         sprintf(cmd_buf,"%s	BOGUS\n",prefix);
     380:         print_lines(cmd_buf,STANDOUT);
     381:         break;
     382:         }
     383:     }
     384:     }
     385: }
     386:
     387: #endif
     388:
     389: /* routine to pass to tputs */
     390:
     391: char
     392: putchr(ch)
     393: register char ch;
     394: {
     395:     putchar(ch);
     396: #ifdef lint
     397:     ch = Null(char);
     398:     ch = ch;
     399: #endif
     400: }
     401:
     402: /* input the 2nd and succeeding characters of a multi-character command */
     403: /* returns TRUE if command finished, FALSE if they rubbed out first character */
     404:
     405: bool
     406: finish_command(donewline)
     407: int donewline;
     408: {
     409:     register char *s;
     410:     register bool quoteone = FALSE;
     411:
     412:     s = buf;
     413:     if (s[1] != FINISHCMD)      /* someone faking up a command? */
     414:     return TRUE;
     415:     do {
     416:       top:
     417:     if (*s < ' ') {
     418:         putchar('^');
     419:         putchar(*s | 64);
     420:     }
     421:     else if (*s == '\177') {
     422:         putchar('^');
     423:         putchar('?');
     424:     }
     425:     else
     426:         putchar(*s);        /* echo previous character */
     427:     s++;
     428: re_read:
     429:     fflush(stdout);
     430:     getcmd(s);
     431:     if (quoteone) {
     432:         quoteone = FALSE;
     433:         continue;
     434:     }
     435:     if (errno || *s == Ctl('l')) {
     436:         *s = Ctl('r');      /* force rewrite on CONT */
     437:     }
     438:     if (*s == '\033') {     /* substitution desired? */
     439: #ifdef ESCSUBS
     440:         char tmpbuf[4], *cpybuf;
     441:
     442:         tmpbuf[0] = '%';
     443:         read_tty(&tmpbuf[1],1);
     444: #ifdef RAWONLY
     445:         tmpbuf[1] &= 0177;
     446: #endif
     447:         tmpbuf[2] = '\0';
     448:         if (tmpbuf[1] == 'h') {
     449:         (void) help_subs();
     450:         *s = '\0';
     451:         reprint();
     452:         goto re_read;
     453:         }
     454:         else if (tmpbuf[1] == '\033') {
     455:         *s = '\0';
     456:         cpybuf = savestr(buf);
     457:         interp(buf, (sizeof buf), cpybuf);
     458:         free(cpybuf);
     459:         s = buf + strlen(buf);
     460:         reprint();
     461:         goto re_read;
     462:         }
     463:         else {
     464:         interp(s,(sizeof buf) - (s-buf),tmpbuf);
     465:         fputs(s,stdout);
     466:         s += strlen(s);
     467:         }
     468:         goto re_read;
     469: #else
     470:         notincl("^[");
     471:         *s = '\0';
     472:         reprint();
     473:         goto re_read;
     474: #endif
     475:     }
     476:     else if (*s == ERASECH) {   /* they want to rubout a char? */
     477:         rubout();
     478:         s--;            /* discount the char rubbed out */
     479:         if (*s < ' ' || *s == '\177')
     480:         rubout();
     481:         if (s == buf) {     /* entire string gone? */
     482:         fflush(stdout);     /* return to single char command mode */
     483:         return FALSE;
     484:         }
     485:         else
     486:         goto re_read;
     487:     }
     488:     else if (*s == KILLCH) {    /* wipe out the whole line? */
     489:         while (s-- != buf) {    /* emulate that many ERASEs */
     490:         rubout();
     491:         if (*s < ' ' || *s == '\177')
     492:             rubout();
     493:         }
     494:         fflush(stdout);
     495:         return FALSE;       /* return to single char mode */
     496:     }
     497: #ifdef WORDERASE
     498:     else if (*s == Ctl('w')) {  /* wipe out one word? */
     499:         *s-- = ' ';
     500:         while (!isspace(*s) || isspace(s[1])) {
     501:         rubout();
     502:         if (s-- == buf) {
     503:             fflush(stdout);
     504:             return FALSE;   /* return to single char mode */
     505:         }
     506:         if (*s < ' ' || *s == '\177')
     507:             rubout();
     508:         }
     509:         s++;
     510:         goto re_read;
     511:     }
     512: #endif
     513:     else if (*s == Ctl('r')) {
     514:         *s = '\0';
     515:         reprint();
     516:         goto re_read;
     517:     }
     518:     else if (*s == Ctl('v')) {
     519:         putchar('^');
     520:         backspace();
     521:         fflush(stdout);
     522:         getcmd(s);
     523:         goto top;
     524:     }
     525:     else if (*s == '\\') {
     526:         quoteone = TRUE;
     527:     }
     528:     } while (*s != '\n');       /* till a newline (not echoed) */
     529:     *s = '\0';              /* terminate the string nicely */
     530:     if (donewline)
     531:     putchar('\n') FLUSH;
     532:     return TRUE;            /* say we succeeded */
     533: }
     534:
     535: /* discard any characters typed ahead */
     536:
     537: void
     538: eat_typeahead()
     539: {
     540: #ifdef PUSHBACK
     541:     if (!typeahead && nextin==nextout)  /* cancel only keyboard stuff */
     542: #else
     543:     if (!typeahead)
     544: #endif
     545:     {
     546: #ifdef PENDING
     547:     while (input_pending())
     548:         read_tty(buf,sizeof(buf));
     549: #else /* this is probably v7 */
     550:     ioctl(_tty_ch,TIOCSETP,&_tty);
     551: #endif
     552:     }
     553: }
     554:
     555: void
     556: settle_down()
     557: {
     558:     dingaling();
     559:     fflush(stdout);
     560:     sleep(1);
     561: #ifdef PUSHBACK
     562:     nextout = nextin;           /* empty circlebuf */
     563: #endif
     564:     eat_typeahead();
     565: }
     566:
     567: #ifdef PUSHBACK
     568: /* read a character from the terminal, with multi-character pushback */
     569:
     570: int
     571: read_tty(addr,size)
     572: char *addr;
     573: int size;
     574: {
     575:     if (nextout != nextin) {
     576:     *addr = circlebuf[nextout++];
     577:     nextout %= PUSHSIZE;
     578:     return 1;
     579:     }
     580:     else {
     581:     size = read(0,addr,size);
     582: #ifdef RAWONLY
     583:     *addr &= 0177;
     584: #endif
     585:     return size;
     586:     }
     587: }
     588:
     589: #ifdef PENDING
     590: #ifndef FIONREAD
     591: int
     592: circfill()
     593: {
     594:     register int howmany = read(devtty,circlebuf+nextin,1);
     595:
     596:     if (howmany) {
     597:     nextin += howmany;
     598:     nextin %= PUSHSIZE;
     599:     }
     600:     return howmany;
     601: }
     602: #endif PENDING
     603: #endif FIONREAD
     604:
     605: void
     606: pushchar(c)
     607: char c;
     608: {
     609:     nextout--;
     610:     if (nextout < 0)
     611:     nextout = PUSHSIZE - 1;
     612:     if (nextout == nextin) {
     613:     fputs("\npushback buffer overflow\n",stdout) FLUSH;
     614:     sig_catcher(0);
     615:     }
     616:     circlebuf[nextout] = c;
     617: }
     618:
     619: #else PUSHBACK
     620: #ifndef read_tty
     621: /* read a character from the terminal, with hacks for O_NDELAY reads */
     622:
     623: int
     624: read_tty(addr,size)
     625: char *addr;
     626: int size;
     627: {
     628:     if (is_input) {
     629:     *addr = pending_ch;
     630:     is_input = FALSE;
     631:     return 1;
     632:     }
     633:     else {
     634:     size = read(0,addr,size);
     635: #ifdef RAWONLY
     636:     *addr &= 0177;
     637: #endif
     638:     return size;
     639:     }
     640: }
     641:
     642: #endif read_tty
     643: pushchar(c) char c; { return;}
     644: #endif PUSHBACK
     645:
     646: /* print an underlined string, one way or another */
     647:
     648: void
     649: underprint(s)
     650: register char *s;
     651: {
     652:     assert(UC);
     653:     if (*UC) {      /* char by char underline? */
     654:     while (*s) {
     655:         if (*s < ' ') {
     656:         putchar('^');
     657:         backspace();/* back up over it */
     658:         underchar();/* and do the underline */
     659:         putchar(*s+64);
     660:         backspace();/* back up over it */
     661:         underchar();/* and do the underline */
     662:         }
     663:         else {
     664:         putchar(*s);
     665:         backspace();/* back up over it */
     666:         underchar();/* and do the underline */
     667:         }
     668:         s++;
     669:     }
     670:     }
     671:     else {      /* start and stop underline */
     672:     underline();    /* start underlining */
     673:     while (*s) {
     674:         if (*s < ' ') {
     675:         putchar('^');
     676:         putchar(*s+64);
     677:         }
     678:         else
     679:         putchar(*s);
     680:         s++;
     681:     }
     682:     un_underline(); /* stop underlining */
     683:     }
     684: }
     685:
     686: /* keep screen from flashing strangely on magic cookie terminals */
     687:
     688: #ifdef NOFIREWORKS
     689: void
     690: no_sofire()
     691: {
     692:     if (*UP && *SE) {       /* should we disable fireworks? */
     693:     putchar('\n');
     694:     un_standout();
     695:     up_line();
     696:     carriage_return();
     697:     }
     698: }
     699:
     700: void
     701: no_ulfire()
     702: {
     703:     if (*UP && *US) {       /* should we disable fireworks? */
     704:     putchar('\n');
     705:     un_underline();
     706:     up_line();
     707:     carriage_return();
     708:     }
     709: }
     710: #endif
     711:
     712: /* get a character into a buffer */
     713:
     714: void
     715: getcmd(whatbuf)
     716: register char *whatbuf;
     717: {
     718: #ifdef PUSHBACK
     719:     register KEYMAP *curmap;
     720:     register int i;
     721:     bool no_macros;
     722:     int times = 0;          /* loop detector */
     723:     char scrchar;
     724:
     725: tryagain:
     726:     curmap = topmap;
     727:     no_macros = (whatbuf != buf && nextin == nextout);
     728: #endif
     729:     for (;;) {
     730:     int_count = 0;
     731:     errno = 0;
     732:     if (read_tty(whatbuf,1) < 0 && !errno)
     733:         errno = EINTR;
     734:     if (errno && errno != EINTR) {
     735:         perror(readerr);
     736:         sig_catcher(0);
     737:     }
     738: #ifdef PUSHBACK
     739:     if (*whatbuf & 0200 || no_macros) {
     740:         *whatbuf &= 0177;
     741:         goto got_canonical;
     742:     }
     743:     if (curmap == Null(KEYMAP*))
     744:         goto got_canonical;
     745:     for (i = (curmap->km_type[*whatbuf] >> KM_GSHIFT) & KM_GMASK; i; --i){
     746:         read_tty(&scrchar,1);
     747:     }
     748:     switch (curmap->km_type[*whatbuf] & KM_TMASK) {
     749:     case KM_NOTHIN:         /* no entry? */
     750:         if (curmap == topmap)   /* unmapped canonical */
     751:         goto got_canonical;
     752:         settle_down();
     753:         goto tryagain;
     754:     case KM_KEYMAP:         /* another keymap? */
     755:         curmap = curmap->km_ptr[*whatbuf].km_km;
     756:         assert(curmap != Null(KEYMAP*));
     757:         break;
     758:     case KM_STRING:         /* a string? */
     759:         pushstring(curmap->km_ptr[*whatbuf].km_str);
     760:         if (++times > 20) {     /* loop? */
     761:         fputs("\nmacro loop?\n",stdout);
     762:         settle_down();
     763:         }
     764:         no_macros = FALSE;
     765:         goto tryagain;
     766:     }
     767: #else
     768: #ifdef RAWONLY
     769:     *whatbuf &= 0177;
     770: #endif
     771:     break;
     772: #endif
     773:     }
     774:
     775: got_canonical:
     776: #ifndef TERMIO
     777:     if (*whatbuf == '\r')
     778:     *whatbuf = '\n';
     779: #endif
     780:     if (whatbuf == buf)
     781:     whatbuf[1] = FINISHCMD;     /* tell finish_command to work */
     782: }
     783:
     784: #ifdef PUSHBACK
     785: void
     786: pushstring(str)
     787: char *str;
     788: {
     789:     register int i;
     790:     char tmpbuf[PUSHSIZE];
     791:     register char *s = tmpbuf;
     792:
     793:     assert(str != Nullch);
     794:     interp(s,PUSHSIZE,str);
     795:     for (i = strlen(s)-1; i >= 0; --i) {
     796:     s[i] ^= 0200;
     797:     pushchar(s[i]);
     798:     }
     799: }
     800: #endif
     801:
     802: int
     803: get_anything()
     804: {
     805:     char tmpbuf[2];
     806:
     807: reask_anything:
     808:     unflush_output();           /* disable any ^O in effect */
     809:     standout();
     810: #ifdef VERBOSE
     811:     IF(verbose)
     812:     fputs("[Type space to continue] ",stdout);
     813:     ELSE
     814: #endif
     815: #ifdef TERSE
     816:     fputs("[MORE] ",stdout);
     817: #endif
     818:     un_standout();
     819:     fflush(stdout);
     820:     eat_typeahead();
     821:     if (int_count) {
     822:     return -1;
     823:     }
     824:     collect_subjects();         /* loads subject cache until */
     825:                     /* input is pending */
     826:     getcmd(tmpbuf);
     827:     if (errno || *tmpbuf == '\f') {
     828:     putchar('\n') FLUSH;        /* if return from stop signal */
     829:     goto reask_anything;        /* give them a prompt again */
     830:     }
     831:     if (*tmpbuf == 'h') {
     832: #ifdef VERBOSE
     833:     IF(verbose)
     834:         fputs("\nType q to quit or space to continue.\n",stdout) FLUSH;
     835:     ELSE
     836: #endif
     837: #ifdef TERSE
     838:         fputs("\nq to quit, space to continue.\n",stdout) FLUSH;
     839: #endif
     840:     goto reask_anything;
     841:     }
     842:     else if (*tmpbuf != ' ' && *tmpbuf != '\n') {
     843:     carriage_return();
     844:     erase_eol();    /* erase the prompt */
     845:     return *tmpbuf == 'q' ? -1 : *tmpbuf;
     846:     }
     847:     if (*tmpbuf == '\n') {
     848:     page_line = LINES - 1;
     849:     carriage_return();
     850:     erase_eol();
     851:     }
     852:     else {
     853:     page_line = 1;
     854:     if (erase_screen)       /* -e? */
     855:         clear();            /* clear screen */
     856:     else {
     857:         carriage_return();
     858:         erase_eol();        /* erase the prompt */
     859:     }
     860:     }
     861:     return 0;
     862: }
     863:
     864: void
     865: in_char(prompt, newmode)
     866: char *prompt;
     867: char newmode;
     868: {
     869:     char oldmode = mode;
     870:
     871: reask_in_char:
     872:     unflush_output();           /* disable any ^O in effect */
     873:     fputs(prompt,stdout);
     874:     fflush(stdout);
     875:     eat_typeahead();
     876:     mode = newmode;
     877:     getcmd(buf);
     878:     if (errno || *buf == '\f') {
     879:     putchar('\n') FLUSH;        /* if return from stop signal */
     880:     goto reask_in_char;     /* give them a prompt again */
     881:     }
     882:     mode = oldmode;
     883: }
     884:
     885: int
     886: print_lines(what_to_print,hilite)
     887: char *what_to_print;
     888: int hilite;
     889: {
     890:     register char *s;
     891:     register int i;
     892:
     893:     if (page_line < 0)          /* they do not want to see this? */
     894:     return -1;
     895:     for (s=what_to_print; *s; ) {
     896:     if (page_line >= LINES || int_count) {
     897:         if (i = -1, int_count || (i = get_anything())) {
     898:         page_line = -1;     /* disable further print_lines */
     899:         return i;
     900:         }
     901:     }
     902:     page_line++;
     903:     if (hilite == STANDOUT) {
     904: #ifdef NOFIREWORKS
     905:         if (erase_screen)
     906:         no_sofire();
     907: #endif
     908:         standout();
     909:     }
     910:     else if (hilite == UNDERLINE) {
     911: #ifdef NOFIREWORKS
     912:         if (erase_screen)
     913:         no_ulfire();
     914: #endif
     915:         underline();
     916:     }
     917:     for (i=0; i<COLS; i++) {
     918:         if (!*s)
     919:         break;
     920:         if (*s >= ' ')
     921:         putchar(*s);
     922:         else if (*s == '\t') {
     923:         putchar(*s);
     924:         i = ((i+8) & ~7) - 1;
     925:         }
     926:         else if (*s == '\n') {
     927:         i = 32000;
     928:         }
     929:         else {
     930:         i++;
     931:         putchar('^');
     932:         putchar(*s + 64);
     933:         }
     934:         s++;
     935:     }
     936:     if (i) {
     937:         if (hilite == STANDOUT)
     938:         un_standout();
     939:         else if (hilite == UNDERLINE)
     940:         un_underline();
     941:         if (AM && i == COLS)
     942:         fflush(stdout);
     943:         else
     944:         putchar('\n') FLUSH;
     945:     }
     946:     }
     947:     return 0;
     948: }
     949:
     950: void
     951: page_init()
     952: {
     953:     page_line = 1;
     954:     if (erase_screen)
     955:     clear();
     956:     else
     957:     putchar('\n') FLUSH;
     958: }
     959:
     960: void
     961: pad(num)
     962: int num;
     963: {
     964:     register int i;
     965:
     966:     for (i = num; i; --i)
     967:     putchar(PC);
     968:     fflush(stdout);
     969: }
     970:
     971: /* echo the command just typed */
     972:
     973: #ifdef VERIFY
     974: void
     975: printcmd()
     976: {
     977:     if (verify && buf[1] == FINISHCMD) {
     978:     if (*buf < ' ') {
     979:         putchar('^');
     980:         putchar(*buf | 64);
     981:         backspace();
     982:         backspace();
     983:     }
     984:     else {
     985:         putchar(*buf);
     986:         backspace();
     987:     }
     988:     fflush(stdout);
     989:     }
     990: }
     991: #endif
     992:
     993: void
     994: rubout()
     995: {
     996:     backspace();            /* do the old backspace, */
     997:     putchar(' ');           /*   space, */
     998:     backspace();            /*     backspace trick */
     999: }
    1000:
    1001: void
    1002: reprint()
    1003: {
    1004:     register char *s;
    1005:
    1006:     fputs("^R\n",stdout) FLUSH;
    1007:     for (s = buf; *s; s++) {
    1008:     if (*s < ' ') {
    1009:         putchar('^');
    1010:         putchar(*s | 64);
    1011:     }
    1012:     else
    1013:         putchar(*s);
    1014:     }
    1015: }
    1016:
    1017: #ifdef CLEAREOL
    1018: /* start of additions by Paul Placeway (PWP) */
    1019:
    1020: void
    1021: home_cursor()
    1022: {
    1023:     char *tgoto();
    1024:
    1025:     if (!*HO) {         /* no home sequence? */
    1026:     if (!*CM) {     /* no cursor motion either? */
    1027:         fputs ("\n\n\n", stdout);
    1028:         return;     /* forget it. */
    1029:     }
    1030:     tputs (tgoto (CM, 0, 0), 1, putchr);    /* go to home via CM */
    1031:     return;
    1032:     }
    1033:     else {          /* we have home sequence */
    1034:     tputs (HO, 1, putchr);  /* home via HO */
    1035:     }
    1036: }
    1037: #endif CLEAREOL

#### Defined functions

circfill defined in line 591; used 2 times

- in /usr/src/new/rn/term.h line 28-31(2)

eat_typeahead defined in line 537; used 8 times

- in line 564, 820, 875
- in /usr/src/new/rn/art.c line 521
- in /usr/src/new/rn/ng.c line 460
- in /usr/src/new/rn/rcstuff.c line 533
- in /usr/src/new/rn/rn.c line 203
- in /usr/src/new/rn/term.h line 198

finish_command defined in line 405; used 14 times

- in /usr/src/new/rn/art.c line 615
- in /usr/src/new/rn/artsrch.c line 61
- in /usr/src/new/rn/ngsrch.c line 47
- in /usr/src/new/rn/ngstuff.c line 45, 83, 132
- in /usr/src/new/rn/rcstuff.c line 586, 607
- in /usr/src/new/rn/respond.c line 54
- in /usr/src/new/rn/rn.c line 310, 407, 435, 464
- in /usr/src/new/rn/term.h line 197

get_anything defined in line 802; used 6 times

- in line 897
- in /usr/src/new/rn/help.c line 233
- in /usr/src/new/rn/init.c line 299, 336
- in /usr/src/new/rn/kfile.c line 173
- in /usr/src/new/rn/term.h line 209

getcmd defined in line 714; used 9 times

- in line 430, 522, 826, 877
- in /usr/src/new/rn/art.c line 539
- in /usr/src/new/rn/ng.c line 467
- in /usr/src/new/rn/rcstuff.c line 534
- in /usr/src/new/rn/rn.c line 204
- in /usr/src/new/rn/term.h line 208

home_cursor defined in line 1020; used 3 times

- in /usr/src/new/rn/art.c line 737, 833
- in /usr/src/new/rn/term.h line 218

in_char defined in line 864; used 9 times

- in /usr/src/new/rn/ng.c line 745-750(2)
- in /usr/src/new/rn/rcstuff.c line 321, 379, 786
- in /usr/src/new/rn/respond.c line 162
- in /usr/src/new/rn/rn.c line 344-348(2)
- in /usr/src/new/rn/term.h line 210

mac_init defined in line 246; used 3 times

- in line 60, 241
- in /usr/src/new/rn/term.h line 192

mac_line defined in line 261; used 3 times

- in line 255
- in /usr/src/new/rn/ngstuff.c line 98
- in /usr/src/new/rn/term.h line 193

newkeymap defined in line 313; used 3 times

- in line 61, 274, 299

no_sofire defined in line 689; used 4 times

- in line 906
- in /usr/src/new/rn/art.c line 276
- in /usr/src/new/rn/kfile.c line 60
- in /usr/src/new/rn/term.h line 205

no_ulfire defined in line 700; used 4 times

- in line 913
- in /usr/src/new/rn/art.c line 239, 283
- in /usr/src/new/rn/term.h line 206

pad defined in line 960; used 6 times

- in /usr/src/new/rn/ng.c line 652, 691, 701
- in /usr/src/new/rn/ngstuff.c line 163, 181
- in /usr/src/new/rn/term.h line 213

page_init defined in line 950; used 9 times

- in /usr/src/new/rn/help.c line 36, 91, 174, 248
- in /usr/src/new/rn/ng.c line 838
- in /usr/src/new/rn/ngstuff.c line 90
- in /usr/src/new/rn/rcstuff.c line 228, 684
- in /usr/src/new/rn/term.h line 212

print_lines defined in line 885; used 43 times

- in line 337, 369, 376-380(2)
- in /usr/src/new/rn/help.c line 37-40(2), 47, 58-62(2), 70-74(2), 92-95(2), 102, 110, 121, 130, 138-142(2), 152, 175-180(2), 190, 197, 203, 209, 216, 224, 249-252(2), 259, 265, 273, 282, 288, 294, 303
- in /usr/src/new/rn/ng.c line 856, 871
- in /usr/src/new/rn/rcstuff.c line 231, 685, 698
- in /usr/src/new/rn/term.h line 211

printcmd defined in line 974; used 9 times

- in /usr/src/new/rn/ng.c line 549, 755
- in /usr/src/new/rn/rcstuff.c line 325, 383, 544, 790
- in /usr/src/new/rn/respond.c line 166
- in /usr/src/new/rn/rn.c line 211
- in /usr/src/new/rn/term.h line 214

pushchar defined in line 643; used 8 times

- in line 797
- in /usr/src/new/rn/art.c line 761
- in /usr/src/new/rn/ng.c line 812, 858, 873
- in /usr/src/new/rn/rcstuff.c line 700
- in /usr/src/new/rn/rn.c line 390
- in /usr/src/new/rn/term.h line 191

pushstring defined in line 785; used 2 times

- in line 63, 759

putchr defined in line 391; used 3 times

- in line 1030-1034(2)
- in /usr/src/new/rn/term.h line 196

read_tty defined in line 623; never used
reprint defined in line 1001; used 5 times

- in line 451, 460, 472, 515
- in /usr/src/new/rn/term.h line 216

rubout defined in line 993; used 7 times

- in line 477-480(2), 490-492(2), 501, 507
- in /usr/src/new/rn/term.h line 215

settle_down defined in line 555; used 13 times

- in line 752, 762
- in /usr/src/new/rn/art.c line 872
- in /usr/src/new/rn/ng.c line 781, 997
- in /usr/src/new/rn/rcstuff.c line 359, 405, 619, 814
- in /usr/src/new/rn/respond.c line 198
- in /usr/src/new/rn/rn.c line 364, 497
- in /usr/src/new/rn/term.h line 199

show_keymap defined in line 343; used 3 times

- in line 62, 339, 372

show_macros defined in line 331; used 3 times

- in /usr/src/new/rn/help.c line 235
- in /usr/src/new/rn/ngstuff.c line 91
- in /usr/src/new/rn/term.h line 194

term_init defined in line 68; used 2 times

- in /usr/src/new/rn/init.c line 75
- in /usr/src/new/rn/term.h line 188

term_set defined in line 115; used 2 times

- in /usr/src/new/rn/init.c line 113
- in /usr/src/new/rn/term.h line 189

underprint defined in line 648; used 2 times

- in /usr/src/new/rn/art.c line 262
- in /usr/src/new/rn/term.h line 203

#### Defined variables

ERASECH defined in line 29; used 3 times

- in line 75-79(2), 476

KILLCH defined in line 30; used 3 times

- in line 76-80(2), 488

tcarea defined in line 31; used 1 times

- in line 150

topmap defined in line 58; used 7 times

- in line 273-274(2), 283, 336-339(2), 726, 750

#### Defined struct's

keymap defined in line 39; used 4 times

- in line 42(2), 56(2)

#### Defined union's

km_union defined in line 41; never used

#### Defined typedef's

KEYMAP defined in line 56; used 17 times

- in line 58-61(2), 313, 345-58(2), 268-273(2), 298, 317-325(5), 336, 719, 743, 756

#### Defined macros

KM_BOGUS defined in line 50; used 1 times

- in line 378

KM_GMASK defined in line 54; used 4 times

- in line 287, 362-363(2), 745

KM_GSHIFT defined in line 53; used 4 times

- in line 287, 362-363(2), 745

KM_KEYMAP defined in line 49; used 3 times

- in line 297, 303, 371

KM_NOTHIN defined in line 47; used 2 times

- in line 326, 367

KM_STRING defined in line 48; used 3 times

- in line 292, 306, 374

KM_TMASK defined in line 52; used 4 times

- in line 292, 303, 366, 748

Tgetstr defined in line 36; used 16 times

- in line 151-159(4), 165-179(9), 185, 205-208(2)

Last modified: 1989-04-22 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2478 |