Annotation of 43BSD/contrib/rn/term.c, revision 1.1

1.1     ! root        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:     AM = tgetflag("am");               /* terminal wraps automatically? */
        !           194:     XN = tgetflag("xn");               /* then eats next newline? */
        !           195:     VB = Tgetstr("vb");
        !           196:     if (!*VB)
        !           197:        VB = "\007";
        !           198:     CR = Tgetstr("cr");
        !           199:     if (!*CR) {
        !           200:        if (tgetflag("nc") && *UP) {
        !           201:            CR = safemalloc((MEM_SIZE)strlen(UP)+2);
        !           202:            sprintf(CR,"%s\r",UP);
        !           203:        }
        !           204:        else
        !           205:            CR = "\r";
        !           206:     }
        !           207: #else
        !           208:     ??????                             /* Roll your own... */
        !           209: #endif
        !           210:     if (LINES > 0) {                   /* is this a crt? */
        !           211:        if (!initlines)                 /* no -i? */
        !           212:            if (ospeed >= B9600)        /* whole page at >= 9600 baud */
        !           213:                initlines = LINES;
        !           214:            else if (ospeed >= B4800)   /* 16 lines at 4800 */
        !           215:                initlines = 16;
        !           216:            else                        /* otherwise just header */
        !           217:                initlines = 8;
        !           218:     }
        !           219:     else {                             /* not a crt */
        !           220:        LINES = 30000;                  /* so don't page */
        !           221:        CL = "\n\n";                    /* put a couple of lines between */
        !           222:        if (!initlines)                 /* make initlines reasonable */
        !           223:            initlines = 8;
        !           224:     }
        !           225:     if (COLS <= 0)
        !           226:        COLS = 80;
        !           227:     noecho();                          /* turn off echo */
        !           228:     crmode();                          /* enter cbreak mode */
        !           229: 
        !           230: #ifdef PUSHBACK
        !           231:     mac_init(tcbuf);
        !           232: #endif
        !           233: }
        !           234: 
        !           235: #ifdef PUSHBACK
        !           236: void
        !           237: mac_init(tcbuf)
        !           238: char *tcbuf;
        !           239: {
        !           240:     char tmpbuf[1024];
        !           241: 
        !           242:     tmpfp = fopen(filexp(getval("RNMACRO",RNMACRO)),"r");
        !           243:     if (tmpfp != Nullfp) {
        !           244:        while (fgets(tcbuf,1024,tmpfp) != Nullch) {
        !           245:            mac_line(tcbuf,tmpbuf,(sizeof tmpbuf));
        !           246:        }
        !           247:        fclose(tmpfp);
        !           248:     }
        !           249: }
        !           250: 
        !           251: void
        !           252: mac_line(line,tmpbuf,tbsize)
        !           253: char *line;
        !           254: char *tmpbuf;
        !           255: int tbsize;
        !           256: {
        !           257:     register char *s, *m;
        !           258:     register KEYMAP *curmap;
        !           259:     register int ch;
        !           260:     register int garbage = 0;
        !           261:     static char override[] = "\nkeymap overrides string\n";
        !           262: 
        !           263:     if (topmap == Null(KEYMAP*))
        !           264:        topmap = newkeymap();
        !           265:     if (*line == '#' || *line == '\n')
        !           266:        return;
        !           267:     if (line[ch = strlen(line)-1] == '\n')
        !           268:        line[ch] = '\0';
        !           269:     m = dointerp(tmpbuf,tbsize,line," \t");
        !           270:     if (!*m)
        !           271:        return;
        !           272:     while (*m == ' ' || *m == '\t') m++;
        !           273:     for (s=tmpbuf,curmap=topmap; *s; s++) {
        !           274:        ch = *s & 0177;
        !           275:        if (s[1] == '+' && isdigit(s[2])) {
        !           276:            s += 2;
        !           277:            garbage = (*s & KM_GMASK) << KM_GSHIFT;
        !           278:        }
        !           279:        else
        !           280:            garbage = 0;
        !           281:        if (s[1]) {
        !           282:            if ((curmap->km_type[ch] & KM_TMASK) == KM_STRING) {
        !           283:                puts(override,stdout) FLUSH;
        !           284:                free(curmap->km_ptr[ch].km_str);
        !           285:                curmap->km_ptr[ch].km_str = Nullch;
        !           286:            }
        !           287:            curmap->km_type[ch] = KM_KEYMAP + garbage;
        !           288:            if (curmap->km_ptr[ch].km_km == Null(KEYMAP*))
        !           289:                curmap->km_ptr[ch].km_km = newkeymap();
        !           290:            curmap = curmap->km_ptr[ch].km_km;
        !           291:        }
        !           292:        else {
        !           293:            if ((curmap->km_type[ch] & KM_TMASK) == KM_KEYMAP)
        !           294:                puts(override,stdout) FLUSH;
        !           295:            else {
        !           296:                curmap->km_type[ch] = KM_STRING + garbage;
        !           297:                curmap->km_ptr[ch].km_str = savestr(m);
        !           298:            }
        !           299:        }
        !           300:     }
        !           301: }
        !           302: 
        !           303: KEYMAP*
        !           304: newkeymap()
        !           305: {
        !           306:     register int i;
        !           307:     register KEYMAP *map;
        !           308: 
        !           309: #ifndef lint
        !           310:     map = (KEYMAP*)safemalloc(sizeof(KEYMAP));
        !           311: #else
        !           312:     map = Null(KEYMAP*);
        !           313: #endif lint
        !           314:     for (i=127; i>=0; --i) {
        !           315:        map->km_ptr[i].km_km = Null(KEYMAP*);
        !           316:        map->km_type[i] = KM_NOTHIN;
        !           317:     }
        !           318:     return map;
        !           319: }
        !           320: 
        !           321: void
        !           322: show_macros()
        !           323: {
        !           324:     char prebuf[64];
        !           325: 
        !           326:     if (topmap != Null(KEYMAP*)) {
        !           327:        print_lines("Macros:\n",STANDOUT);
        !           328:        *prebuf = '\0';
        !           329:        show_keymap(topmap,prebuf);
        !           330:     }
        !           331: }
        !           332: 
        !           333: void
        !           334: show_keymap(curmap,prefix)
        !           335: register KEYMAP *curmap;
        !           336: char *prefix;
        !           337: {
        !           338:     register int i;
        !           339:     register char *next = prefix + strlen(prefix);
        !           340:     register int kt;
        !           341: 
        !           342:     for (i=0; i<128; i++) {
        !           343:        if (kt = curmap->km_type[i]) {
        !           344:            if (i < ' ')
        !           345:                sprintf(next,"^%c",i+64);
        !           346:            else if (i == ' ')
        !           347:                strcpy(next,"\\040");
        !           348:            else if (i == 127)
        !           349:                strcpy(next,"^?");
        !           350:            else
        !           351:                sprintf(next,"%c",i);
        !           352:            if ((kt >> KM_GSHIFT) & KM_GMASK) {
        !           353:                sprintf(cmd_buf,"+%d", (kt >> KM_GSHIFT) & KM_GMASK);
        !           354:                strcat(next,cmd_buf);
        !           355:            }
        !           356:            switch (kt & KM_TMASK) {
        !           357:            case KM_NOTHIN:
        !           358:                sprintf(cmd_buf,"%s     %c\n",prefix,i);
        !           359:                print_lines(cmd_buf,NOMARKING);
        !           360:                break;
        !           361:            case KM_KEYMAP:
        !           362:                show_keymap(curmap->km_ptr[(char)i].km_km, prefix);
        !           363:                break;
        !           364:            case KM_STRING:
        !           365:                sprintf(cmd_buf,"%s     %s\n",prefix,curmap->km_ptr[i].km_str);
        !           366:                print_lines(cmd_buf,NOMARKING);
        !           367:                break;
        !           368:            case KM_BOGUS:
        !           369:                sprintf(cmd_buf,"%s     BOGUS\n",prefix);
        !           370:                print_lines(cmd_buf,STANDOUT);
        !           371:                break;
        !           372:            }
        !           373:        }
        !           374:     }
        !           375: }
        !           376: 
        !           377: #endif
        !           378: 
        !           379: /* routine to pass to tputs */
        !           380: 
        !           381: char
        !           382: putchr(ch)
        !           383: register char ch;
        !           384: {
        !           385:     putchar(ch);
        !           386: #ifdef lint
        !           387:     ch = Null(char);
        !           388:     ch = ch;
        !           389: #endif
        !           390: }
        !           391: 
        !           392: /* input the 2nd and succeeding characters of a multi-character command */
        !           393: /* returns TRUE if command finished, FALSE if they rubbed out first character */
        !           394: 
        !           395: bool
        !           396: finish_command(donewline)
        !           397: int donewline;
        !           398: {
        !           399:     register char *s;
        !           400:     register bool quoteone = FALSE;
        !           401: 
        !           402:     s = buf;
        !           403:     if (s[1] != FINISHCMD)             /* someone faking up a command? */
        !           404:        return TRUE;
        !           405:     do {
        !           406:       top:
        !           407:        if (*s < ' ') {
        !           408:            putchar('^');
        !           409:            putchar(*s | 64);
        !           410:        }
        !           411:        else if (*s == '\177') {
        !           412:            putchar('^');
        !           413:            putchar('?');
        !           414:        }
        !           415:        else
        !           416:            putchar(*s);                /* echo previous character */
        !           417:        s++;
        !           418: re_read:
        !           419:        fflush(stdout);
        !           420:        getcmd(s);
        !           421:        if (quoteone) {
        !           422:            quoteone = FALSE;
        !           423:            continue;
        !           424:        }
        !           425:        if (errno || *s == Ctl('l')) {
        !           426:            *s = Ctl('r');              /* force rewrite on CONT */
        !           427:        }
        !           428:        if (*s == '\033') {             /* substitution desired? */
        !           429: #ifdef ESCSUBS
        !           430:            char tmpbuf[4], *cpybuf;
        !           431: 
        !           432:            tmpbuf[0] = '%';
        !           433:            read_tty(&tmpbuf[1],1);
        !           434: #ifdef RAWONLY
        !           435:            tmpbuf[1] &= 0177;
        !           436: #endif
        !           437:            tmpbuf[2] = '\0';
        !           438:            if (tmpbuf[1] == 'h') {
        !           439:                (void) help_subs();
        !           440:                *s = '\0';
        !           441:                reprint();
        !           442:                goto re_read;
        !           443:            }
        !           444:            else if (tmpbuf[1] == '\033') {
        !           445:                *s = '\0';
        !           446:                cpybuf = savestr(buf);
        !           447:                interp(buf, (sizeof buf), cpybuf);
        !           448:                free(cpybuf);
        !           449:                s = buf + strlen(buf);
        !           450:                reprint();
        !           451:                goto re_read;
        !           452:            }
        !           453:            else {
        !           454:                interp(s,(sizeof buf) - (s-buf),tmpbuf);
        !           455:                fputs(s,stdout);
        !           456:                s += strlen(s);
        !           457:            }
        !           458:            goto re_read;
        !           459: #else
        !           460:            notincl("^[");
        !           461:            *s = '\0';
        !           462:            reprint();
        !           463:            goto re_read;
        !           464: #endif
        !           465:        }
        !           466:        else if (*s == ERASECH) {       /* they want to rubout a char? */
        !           467:            rubout();
        !           468:            s--;                        /* discount the char rubbed out */
        !           469:            if (*s < ' ' || *s == '\177')
        !           470:                rubout();
        !           471:            if (s == buf) {             /* entire string gone? */
        !           472:                fflush(stdout);         /* return to single char command mode */
        !           473:                return FALSE;
        !           474:            }
        !           475:            else
        !           476:                goto re_read;
        !           477:        }
        !           478:        else if (*s == KILLCH) {        /* wipe out the whole line? */
        !           479:            while (s-- != buf) {        /* emulate that many ERASEs */
        !           480:                rubout();
        !           481:                if (*s < ' ' || *s == '\177')
        !           482:                    rubout();
        !           483:            }
        !           484:            fflush(stdout);
        !           485:            return FALSE;               /* return to single char mode */
        !           486:        }
        !           487: #ifdef WORDERASE
        !           488:        else if (*s == Ctl('w')) {      /* wipe out one word? */
        !           489:            *s-- = ' ';
        !           490:            while (!isspace(*s) || isspace(s[1])) {
        !           491:                rubout();
        !           492:                if (s-- == buf) {
        !           493:                    fflush(stdout);
        !           494:                    return FALSE;       /* return to single char mode */
        !           495:                }
        !           496:                if (*s < ' ' || *s == '\177')
        !           497:                    rubout();
        !           498:            }
        !           499:            s++;
        !           500:            goto re_read;
        !           501:        }
        !           502: #endif
        !           503:        else if (*s == Ctl('r')) {
        !           504:            *s = '\0';
        !           505:            reprint();
        !           506:            goto re_read;
        !           507:        }
        !           508:        else if (*s == Ctl('v')) {
        !           509:            putchar('^');
        !           510:            backspace();
        !           511:            fflush(stdout);
        !           512:            getcmd(s);
        !           513:            goto top;
        !           514:        }
        !           515:        else if (*s == '\\') {
        !           516:            quoteone = TRUE;
        !           517:        }
        !           518:     } while (*s != '\n');              /* till a newline (not echoed) */
        !           519:     *s = '\0';                         /* terminate the string nicely */
        !           520:     if (donewline)
        !           521:        putchar('\n') FLUSH;
        !           522:     return TRUE;                       /* say we succeeded */
        !           523: }
        !           524: 
        !           525: /* discard any characters typed ahead */
        !           526: 
        !           527: void
        !           528: eat_typeahead()
        !           529: {
        !           530: #ifdef PUSHBACK
        !           531:     if (!typeahead && nextin==nextout) /* cancel only keyboard stuff */
        !           532: #else
        !           533:     if (!typeahead)
        !           534: #endif
        !           535:     {
        !           536: #ifdef PENDING
        !           537:        while (input_pending())
        !           538:            read_tty(buf,sizeof(buf));
        !           539: #else /* this is probably v7 */
        !           540:        ioctl(_tty_ch,TIOCSETP,&_tty);
        !           541: #endif
        !           542:     }
        !           543: }
        !           544: 
        !           545: void
        !           546: settle_down()
        !           547: {
        !           548:     dingaling();
        !           549:     fflush(stdout);
        !           550:     sleep(1);
        !           551: #ifdef PUSHBACK
        !           552:     nextout = nextin;                  /* empty circlebuf */
        !           553: #endif
        !           554:     eat_typeahead();
        !           555: }
        !           556: 
        !           557: #ifdef PUSHBACK
        !           558: /* read a character from the terminal, with multi-character pushback */
        !           559: 
        !           560: int
        !           561: read_tty(addr,size)
        !           562: char *addr;
        !           563: int size;
        !           564: {
        !           565:     if (nextout != nextin) {
        !           566:        *addr = circlebuf[nextout++];
        !           567:        nextout %= PUSHSIZE;
        !           568:        return 1;
        !           569:     }
        !           570:     else {
        !           571:        size = read(0,addr,size);
        !           572: #ifdef RAWONLY
        !           573:        *addr &= 0177;
        !           574: #endif
        !           575:        return size;
        !           576:     }
        !           577: }
        !           578: 
        !           579: #ifdef PENDING
        !           580: #ifndef FIONREAD
        !           581: int
        !           582: circfill()
        !           583: {
        !           584:     register int howmany = read(devtty,circlebuf+nextin,1);
        !           585: 
        !           586:     if (howmany) {
        !           587:        nextin += howmany;
        !           588:        nextin %= PUSHSIZE;
        !           589:     }
        !           590:     return howmany;
        !           591: }
        !           592: #endif PENDING
        !           593: #endif FIONREAD
        !           594: 
        !           595: void
        !           596: pushchar(c)
        !           597: char c;
        !           598: {
        !           599:     nextout--;
        !           600:     if (nextout < 0)
        !           601:        nextout = PUSHSIZE - 1;
        !           602:     if (nextout == nextin) {
        !           603:        fputs("\npushback buffer overflow\n",stdout) FLUSH;
        !           604:        sig_catcher(0);
        !           605:     }
        !           606:     circlebuf[nextout] = c;
        !           607: }
        !           608: 
        !           609: #else PUSHBACK
        !           610: #ifndef read_tty
        !           611: /* read a character from the terminal, with hacks for O_NDELAY reads */
        !           612: 
        !           613: int
        !           614: read_tty(addr,size)
        !           615: char *addr;
        !           616: int size;
        !           617: {
        !           618:     if (is_input) {
        !           619:        *addr = pending_ch;
        !           620:        is_input = FALSE;
        !           621:        return 1;
        !           622:     }
        !           623:     else {
        !           624:        size = read(0,addr,size);
        !           625: #ifdef RAWONLY
        !           626:        *addr &= 0177;
        !           627: #endif
        !           628:        return size;
        !           629:     }
        !           630: }
        !           631: #endif read_tty
        !           632: #endif PUSHBACK
        !           633: 
        !           634: /* print an underlined string, one way or another */
        !           635: 
        !           636: void
        !           637: underprint(s)
        !           638: register char *s;
        !           639: {
        !           640:     assert(UC);
        !           641:     if (*UC) {         /* char by char underline? */
        !           642:        while (*s) {
        !           643:            if (*s < ' ') {
        !           644:                putchar('^');
        !           645:                backspace();/* back up over it */
        !           646:                underchar();/* and do the underline */
        !           647:                putchar(*s+64);
        !           648:                backspace();/* back up over it */
        !           649:                underchar();/* and do the underline */
        !           650:            }
        !           651:            else {
        !           652:                putchar(*s);
        !           653:                backspace();/* back up over it */
        !           654:                underchar();/* and do the underline */
        !           655:            }
        !           656:            s++;
        !           657:        }
        !           658:     }
        !           659:     else {             /* start and stop underline */
        !           660:        underline();    /* start underlining */
        !           661:        while (*s) {
        !           662:            if (*s < ' ') {
        !           663:                putchar('^');
        !           664:                putchar(*s+64);
        !           665:            }
        !           666:            else
        !           667:                putchar(*s);
        !           668:            s++;
        !           669:        }
        !           670:        un_underline(); /* stop underlining */
        !           671:     }
        !           672: }
        !           673: 
        !           674: /* keep screen from flashing strangely on magic cookie terminals */
        !           675: 
        !           676: #ifdef NOFIREWORKS
        !           677: void
        !           678: no_sofire()
        !           679: {
        !           680:     if (*UP && *SE) {          /* should we disable fireworks? */
        !           681:        putchar('\n');
        !           682:        un_standout();
        !           683:        up_line();
        !           684:        carriage_return();
        !           685:     }
        !           686: }
        !           687: 
        !           688: void
        !           689: no_ulfire()
        !           690: {
        !           691:     if (*UP && *US) {          /* should we disable fireworks? */
        !           692:        putchar('\n');
        !           693:        un_underline();
        !           694:        up_line();
        !           695:        carriage_return();
        !           696:     }
        !           697: }
        !           698: #endif
        !           699: 
        !           700: /* get a character into a buffer */
        !           701: 
        !           702: void
        !           703: getcmd(whatbuf)
        !           704: register char *whatbuf;
        !           705: {
        !           706: #ifdef PUSHBACK
        !           707:     register KEYMAP *curmap;
        !           708:     register int i;
        !           709:     bool no_macros; 
        !           710:     int times = 0;                     /* loop detector */
        !           711:     char scrchar;
        !           712: 
        !           713: tryagain:
        !           714:     curmap = topmap;
        !           715:     no_macros = (whatbuf != buf && nextin == nextout); 
        !           716: #endif
        !           717:     for (;;) {
        !           718:        int_count = 0;
        !           719:        errno = 0;
        !           720:        if (read_tty(whatbuf,1) < 0 && !errno)
        !           721:            errno = EINTR;
        !           722:        if (errno && errno != EINTR) {
        !           723:            perror(readerr);
        !           724:            sig_catcher(0);
        !           725:        }
        !           726: #ifdef PUSHBACK
        !           727:        if (*whatbuf & 0200 || no_macros) {
        !           728:            *whatbuf &= 0177;
        !           729:            goto got_canonical;
        !           730:        }
        !           731:        if (curmap == Null(KEYMAP*))
        !           732:            goto got_canonical;
        !           733:        for (i = (curmap->km_type[*whatbuf] >> KM_GSHIFT) & KM_GMASK; i; --i){
        !           734:            read_tty(&scrchar,1);
        !           735:        }
        !           736:        switch (curmap->km_type[*whatbuf] & KM_TMASK) {
        !           737:        case KM_NOTHIN:                 /* no entry? */
        !           738:            if (curmap == topmap)       /* unmapped canonical */
        !           739:                goto got_canonical;
        !           740:            settle_down();
        !           741:            goto tryagain;
        !           742:        case KM_KEYMAP:                 /* another keymap? */
        !           743:            curmap = curmap->km_ptr[*whatbuf].km_km;
        !           744:            assert(curmap != Null(KEYMAP*));
        !           745:            break;
        !           746:        case KM_STRING:                 /* a string? */
        !           747:            pushstring(curmap->km_ptr[*whatbuf].km_str);
        !           748:            if (++times > 20) {         /* loop? */
        !           749:                fputs("\nmacro loop?\n",stdout);
        !           750:                settle_down();
        !           751:            }
        !           752:            no_macros = FALSE;
        !           753:            goto tryagain;
        !           754:        }
        !           755: #else
        !           756: #ifdef RAWONLY
        !           757:        *whatbuf &= 0177;
        !           758: #endif
        !           759:        break;
        !           760: #endif
        !           761:     }
        !           762: 
        !           763: got_canonical:
        !           764: #ifndef TERMIO
        !           765:     if (*whatbuf == '\r')
        !           766:        *whatbuf = '\n';
        !           767: #endif
        !           768:     if (whatbuf == buf)
        !           769:        whatbuf[1] = FINISHCMD;         /* tell finish_command to work */
        !           770: }
        !           771: 
        !           772: #ifdef PUSHBACK
        !           773: void
        !           774: pushstring(str)
        !           775: char *str;
        !           776: {
        !           777:     register int i;
        !           778:     char tmpbuf[PUSHSIZE];
        !           779:     register char *s = tmpbuf;
        !           780: 
        !           781:     assert(str != Nullch);
        !           782:     interp(s,PUSHSIZE,str);
        !           783:     for (i = strlen(s)-1; i >= 0; --i) {
        !           784:        s[i] ^= 0200; 
        !           785:        pushchar(s[i]);
        !           786:     }
        !           787: }
        !           788: #endif
        !           789: 
        !           790: int
        !           791: get_anything()
        !           792: {
        !           793:     char tmpbuf[2];
        !           794: 
        !           795: reask_anything:
        !           796:     unflush_output();                  /* disable any ^O in effect */
        !           797:     standout();
        !           798: #ifdef VERBOSE
        !           799:     IF(verbose)
        !           800:        fputs("[Type space to continue] ",stdout);
        !           801:     ELSE
        !           802: #endif
        !           803: #ifdef TERSE
        !           804:        fputs("[MORE] ",stdout);
        !           805: #endif
        !           806:     un_standout();
        !           807:     fflush(stdout);
        !           808:     eat_typeahead();
        !           809:     if (int_count) {
        !           810:        return -1;
        !           811:     }
        !           812:     collect_subjects();                        /* loads subject cache until */
        !           813:                                        /* input is pending */
        !           814:     getcmd(tmpbuf);
        !           815:     if (errno || *tmpbuf == '\f') {
        !           816:        putchar('\n') FLUSH;            /* if return from stop signal */
        !           817:        goto reask_anything;            /* give them a prompt again */
        !           818:     }
        !           819:     if (*tmpbuf == 'h') {
        !           820: #ifdef VERBOSE
        !           821:        IF(verbose)
        !           822:            fputs("\nType q to quit or space to continue.\n",stdout) FLUSH;
        !           823:        ELSE
        !           824: #endif
        !           825: #ifdef TERSE
        !           826:            fputs("\nq to quit, space to continue.\n",stdout) FLUSH;
        !           827: #endif
        !           828:        goto reask_anything;
        !           829:     }
        !           830:     else if (*tmpbuf != ' ' && *tmpbuf != '\n') {
        !           831:        carriage_return();
        !           832:        erase_eol();    /* erase the prompt */
        !           833:        return *tmpbuf == 'q' ? -1 : *tmpbuf;
        !           834:     }
        !           835:     if (*tmpbuf == '\n') {
        !           836:        page_line = LINES - 1;
        !           837:        carriage_return();
        !           838:        erase_eol();
        !           839:     }
        !           840:     else {
        !           841:        page_line = 1;
        !           842:        if (erase_screen)               /* -e? */
        !           843:            clear();                    /* clear screen */
        !           844:        else {
        !           845:            carriage_return();
        !           846:            erase_eol();                /* erase the prompt */
        !           847:        }
        !           848:     }
        !           849:     return 0;
        !           850: }
        !           851: 
        !           852: void
        !           853: in_char(prompt, newmode)
        !           854: char *prompt;
        !           855: char newmode;
        !           856: {
        !           857:     char oldmode = mode;
        !           858: 
        !           859: reask_in_char:
        !           860:     unflush_output();                  /* disable any ^O in effect */
        !           861:     fputs(prompt,stdout);
        !           862:     fflush(stdout);
        !           863:     eat_typeahead();
        !           864:     mode = newmode;
        !           865:     getcmd(buf);
        !           866:     if (errno || *buf == '\f') {
        !           867:        putchar('\n') FLUSH;            /* if return from stop signal */
        !           868:        goto reask_in_char;             /* give them a prompt again */
        !           869:     }
        !           870:     mode = oldmode;
        !           871: }
        !           872: 
        !           873: int
        !           874: print_lines(what_to_print,hilite)
        !           875: char *what_to_print;
        !           876: int hilite;
        !           877: {
        !           878:     register char *s;
        !           879:     register int i;
        !           880: 
        !           881:     if (page_line < 0)                 /* they do not want to see this? */
        !           882:        return -1;
        !           883:     for (s=what_to_print; *s; ) {
        !           884:        if (page_line >= LINES || int_count) {
        !           885:            if (i = -1, int_count || (i = get_anything())) {
        !           886:                page_line = -1;         /* disable further print_lines */
        !           887:                return i;
        !           888:            }
        !           889:        }
        !           890:        page_line++;
        !           891:        if (hilite == STANDOUT) {
        !           892: #ifdef NOFIREWORKS
        !           893:            if (erase_screen)
        !           894:                no_sofire();
        !           895: #endif
        !           896:            standout();
        !           897:        }
        !           898:        else if (hilite == UNDERLINE) {
        !           899: #ifdef NOFIREWORKS
        !           900:            if (erase_screen)
        !           901:                no_ulfire();
        !           902: #endif
        !           903:            underline();
        !           904:        }
        !           905:        for (i=0; i<COLS; i++) {
        !           906:            if (!*s)
        !           907:                break;
        !           908:            if (*s >= ' ')
        !           909:                putchar(*s);
        !           910:            else if (*s == '\t') {
        !           911:                putchar(*s);
        !           912:                i = ((i+8) & ~7) - 1; 
        !           913:            }
        !           914:            else if (*s == '\n') {
        !           915:                i = 32000;
        !           916:            }
        !           917:            else {
        !           918:                i++;
        !           919:                putchar('^');
        !           920:                putchar(*s + 64);
        !           921:            }
        !           922:            s++;
        !           923:        }
        !           924:        if (i) {
        !           925:            if (hilite == STANDOUT)
        !           926:                un_standout();
        !           927:            else if (hilite == UNDERLINE)
        !           928:                un_underline();
        !           929:            if (AM && i == COLS)
        !           930:                fflush(stdout);
        !           931:            else
        !           932:                putchar('\n') FLUSH;
        !           933:        }
        !           934:     }
        !           935:     return 0;
        !           936: }
        !           937: 
        !           938: void
        !           939: page_init()
        !           940: {
        !           941:     page_line = 1;
        !           942:     if (erase_screen)
        !           943:        clear();
        !           944:     else
        !           945:        putchar('\n') FLUSH;
        !           946: }
        !           947: 
        !           948: void
        !           949: pad(num)
        !           950: int num;
        !           951: {
        !           952:     register int i;
        !           953: 
        !           954:     for (i = num; i; --i)
        !           955:        putchar(PC);
        !           956:     fflush(stdout);
        !           957: }
        !           958: 
        !           959: /* echo the command just typed */
        !           960: 
        !           961: #ifdef VERIFY
        !           962: void
        !           963: printcmd()
        !           964: {
        !           965:     if (verify && buf[1] == FINISHCMD) {
        !           966:        if (*buf < ' ') {
        !           967:            putchar('^');
        !           968:            putchar(*buf | 64);
        !           969:            backspace();
        !           970:            backspace();
        !           971:        }
        !           972:        else {
        !           973:            putchar(*buf);
        !           974:            backspace();
        !           975:        }
        !           976:        fflush(stdout);
        !           977:     }
        !           978: }
        !           979: #endif
        !           980: 
        !           981: void
        !           982: rubout()
        !           983: {
        !           984:     backspace();                       /* do the old backspace, */
        !           985:     putchar(' ');                      /*   space, */
        !           986:     backspace();                       /*     backspace trick */
        !           987: }
        !           988: 
        !           989: void
        !           990: reprint()
        !           991: {
        !           992:     register char *s;
        !           993: 
        !           994:     fputs("^R\n",stdout) FLUSH;
        !           995:     for (s = buf; *s; s++) {
        !           996:        if (*s < ' ') {
        !           997:            putchar('^');
        !           998:            putchar(*s | 64);
        !           999:        }
        !          1000:        else
        !          1001:            putchar(*s);
        !          1002:     }
        !          1003: }
        !          1004: 
        !          1005: #ifdef CLEAREOL
        !          1006: /* start of additions by Paul Placeway (PWP) */
        !          1007: 
        !          1008: void
        !          1009: home_cursor()
        !          1010: {
        !          1011:     char *tgoto();
        !          1012: 
        !          1013:     if (!*HO) {                        /* no home sequence? */
        !          1014:        if (!*CM) {             /* no cursor motion either? */
        !          1015:            fputs ("\n\n\n", stdout);
        !          1016:            return;             /* forget it. */
        !          1017:        }
        !          1018:        tputs (tgoto (CM, 0, 0), 1, putchr);    /* go to home via CM */
        !          1019:        return;
        !          1020:     }
        !          1021:     else {                     /* we have home sequence */
        !          1022:        tputs (HO, 1, putchr);  /* home via HO */
        !          1023:     }
        !          1024: }
        !          1025: #endif CLEAREOL

unix.superglobalmegacorp.com

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