Annotation of 43BSDReno/games/warp/term.c, revision 1.1.1.1

1.1       root        1: /* $Header: term.c,v 7.0.1.2 86/12/12 17:04:09 lwall Exp $ */
                      2: 
                      3: /* $Log:       term.c,v $
                      4:  * Revision 7.0.1.2  86/12/12  17:04:09  lwall
                      5:  * Baseline for net release.
                      6:  * 
                      7:  * Revision 7.0.1.1  86/10/16  10:53:20  lwall
                      8:  * Added Damage.  Fixed random bugs.
                      9:  * 
                     10:  * Revision 7.0  86/10/08  15:14:02  lwall
                     11:  * Split into separate files.  Added amoebas and pirates.
                     12:  * 
                     13:  */
                     14: 
                     15: #include "EXTERN.h"
                     16: #include "warp.h"
                     17: #include "bang.h"
                     18: #include "intrp.h"
                     19: #include "object.h"
                     20: #include "play.h"
                     21: #include "score.h"
                     22: #include "sig.h"
                     23: #include "us.h"
                     24: #include "util.h"
                     25: #include "weapon.h"
                     26: #include "INTERN.h"
                     27: #include "term.h"
                     28: 
                     29: int typeahead = FALSE;
                     30: 
                     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) ((tstr = tgetstr(key,&tmpaddr)) ? tstr : 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 pushstring();
                     63: #endif
                     64: 
                     65: /* terminal initialization */
                     66: 
                     67: void
                     68: term_init()
                     69: {
                     70:     savetty();                         /* remember current tty state */
                     71: 
                     72: #ifdef TERMIO
                     73:     ospeed = _tty.c_cflag & CBAUD;     /* for tputs() */
                     74:     ERASECH = _tty.c_cc[VERASE];       /* for finish_command() */
                     75:     KILLCH = _tty.c_cc[VKILL];         /* for finish_command() */
                     76: #else
                     77:     ospeed = _tty.sg_ospeed;           /* for tputs() */
                     78:     ERASECH = _tty.sg_erase;           /* for finish_command() */
                     79:     KILLCH = _tty.sg_kill;             /* for finish_command() */
                     80: #endif
                     81: 
                     82:     /* The following could be a table but I can't be sure that there isn't */
                     83:     /* some degree of sparsity out there in the world. */
                     84: 
                     85:     switch (ospeed) {                  /* 1 second of padding */
                     86: #ifdef BEXTA
                     87:         case BEXTA:  just_a_sec = 1920; break;
                     88: #else
                     89: #ifdef B19200
                     90:         case B19200: just_a_sec = 1920; break;
                     91: #endif
                     92: #endif
                     93:         case B9600:  just_a_sec =  960; break;
                     94:         case B4800:  just_a_sec =  480; break;
                     95:         case B2400:  just_a_sec =  240; break;
                     96:         case B1800:  just_a_sec =  180; break;
                     97:         case B1200:  just_a_sec =  120; break;
                     98:         case B600:   just_a_sec =   60; break;
                     99:        case B300:   just_a_sec =   30; break;
                    100:        /* do I really have to type the rest of this??? */
                    101:         case B200:   just_a_sec =   20; break;
                    102:         case B150:   just_a_sec =   15; break;
                    103:         case B134:   just_a_sec =   13; break;
                    104:         case B110:   just_a_sec =   11; break;
                    105:         case B75:    just_a_sec =    8; break;
                    106:         case B50:    just_a_sec =    5; break;
                    107:         default:     just_a_sec =  960; break;
                    108:                                        /* if we are running detached I */
                    109:     }                                  /*  don't want to know about it! */
                    110: }
                    111: 
                    112: /* set terminal characteristics */
                    113: 
                    114: void
                    115: term_set(tcbuf)
                    116: char *tcbuf;           /* temp area for "uncompiled" termcap entry */
                    117: {
                    118:     char *tmpaddr;                     /* must not be register */
                    119:     Reg1 char *tstr;
                    120:     char *tgetstr();
                    121:     char *s;
                    122:     int retval;
                    123: 
                    124: #ifdef PENDING
                    125: #ifndef FIONREAD
                    126: #ifndef RDCHK
                    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");
                    132:        finalize(1);
                    133:     }
                    134:     fcntl(devtty,F_SETFL,O_NDELAY);
                    135: #endif
                    136: #endif
                    137: #endif
                    138:     
                    139:     /* get all that good termcap stuff */
                    140: 
                    141:     retval = tgetent(tcbuf,getenv("TERM"));    /* get termcap entry */
                    142:     if (retval < 1) {
                    143: #ifdef VERBOSE
                    144:        printf("No termcap %s found.\n", retval ? "file" : "entry");
                    145: #else
                    146:        fputs("Termcap botch\n",stdout);
                    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:     ND = Tgetstr("nd");                        /* non-destructive move cursor right */
                    161:     DO = Tgetstr("do");                        /* move cursor down */
                    162:     if (!*DO)
                    163:        DO = Tgetstr("nl");
                    164:     CL = Tgetstr("cl");                        /* get clear string */
                    165:     CE = Tgetstr("ce");                        /* clear to end of line string */
                    166:     CM = Tgetstr("cm");                        /* cursor motion - PWP */
                    167:     HO = Tgetstr("ho");                        /* home cursor if no CM - PWP */
                    168:     CD = Tgetstr("cd");                        /* clear to end of display - PWP */
                    169:     SO = Tgetstr("so");                        /* begin standout */
                    170:     SE = Tgetstr("se");                        /* end standout */
                    171:     if ((SG = tgetnum("sg"))<0)
                    172:        SG = 0;                         /* blanks left by SG, SE */
                    173:     US = Tgetstr("us");                        /* start underline */
                    174:     UE = Tgetstr("ue");                        /* end underline */
                    175:     if ((UG = tgetnum("ug"))<0)
                    176:        UG = 0;                         /* blanks left by US, UE */
                    177:     if (*US)
                    178:        UC = nullstr;                   /* UC must not be NULL */
                    179:     else
                    180:        UC = Tgetstr("uc");             /* underline a character */
                    181:     if (!*US && !*UC) {                        /* no underline mode? */
                    182:        US = SO;                        /* substitute standout mode */
                    183:        UE = SE;
                    184:        UG = SG;
                    185:     }
                    186:     LINES = tgetnum("li");             /* lines per page */
                    187:     COLS = tgetnum("co");              /* columns on page */
                    188:     AM = tgetflag("am");               /* terminal wraps automatically? */
                    189:     XN = tgetflag("xn");               /* then eats next newline? */
                    190:     VB = Tgetstr("vb");
                    191:     if (!*VB)
                    192:        VB = "\007";
                    193:     CR = Tgetstr("cr");
                    194:     if (!*CR) {
                    195:        if (tgetflag("nc") && *UP) {
                    196:            CR = safemalloc((MEM_SIZE)strlen(UP)+2);
                    197:            Sprintf(CR,"%s\r",UP);
                    198:        }
                    199:        else
                    200:            CR = "\r";
                    201:     }
                    202:     if (LINES <= 0)
                    203:        LINES = 24;
                    204:     if (COLS <= 0)
                    205:        COLS = 80;
                    206: 
                    207:     BCsize = comp_tc(bsptr,BC,1);
                    208:     BC = bsptr;
                    209: 
                    210:     if (!*ND)                          /* not defined? */
                    211:        NDsize = 1000;                  /* force cursor addressing */
                    212:     else {
                    213:        NDsize = comp_tc(cmbuffer,ND,1);
                    214:        myND = malloc((unsigned)NDsize);
                    215:        movc3(NDsize,cmbuffer,myND);
                    216:        if (debugging) {
                    217:            int scr;
                    218: 
                    219:            printf("ND");
                    220:            for (scr=0; scr<NDsize; scr++)
                    221:                printf(" %d",myND[scr]);
                    222:            printf("\n");
                    223:        }
                    224:     }
                    225: 
                    226:     if (!*UP)                          /* not defined? */
                    227:        UPsize = 1000;                  /* force cursor addressing */
                    228:     else {
                    229:        UPsize = comp_tc(cmbuffer,UP,1);
                    230:        myUP = malloc((unsigned)UPsize);
                    231:        movc3(UPsize,cmbuffer,myUP);
                    232:        if (debugging) {
                    233:            int scr;
                    234: 
                    235:            printf("UP");
                    236:            for (scr=0; scr<UPsize; scr++)
                    237:                printf(" %d",myUP[scr]);
                    238:            printf("\n");
                    239:        }
                    240:     }
                    241: 
                    242:     if (!*DO) {                                /* not defined? */
                    243:        myDO = DO = "\n";               /* assume a newline */
                    244:        DOsize = 1;
                    245:     }
                    246:     else {
                    247:        DOsize = comp_tc(cmbuffer,DO,1);
                    248:        myDO = malloc((unsigned)DOsize);
                    249:        movc3(DOsize,cmbuffer,myDO);
                    250:        if (debugging) {
                    251:            int scr;
                    252: 
                    253:            printf("DO");
                    254:            for (scr=0; scr<DOsize; scr++)
                    255:                printf(" %d",myDO[scr]);
                    256:            printf("\n");
                    257:        }
                    258:     }
                    259:     if (debugging)
                    260:        Fgets(cmbuffer,(sizeof cmbuffer),stdin);
                    261: 
                    262:     CMsize = comp_tc(cmbuffer,tgoto(CM,20,20),0);
                    263:     if (PC != '\0') {
                    264:        char *p;
                    265: 
                    266:        for (p=filler+(sizeof filler)-1;!*p;--p)
                    267:            *p = PC;
                    268:     }
                    269:     charsperhalfsec = ospeed >= B9600 ? 480 :
                    270:                      ospeed == B4800 ? 240 :
                    271:                      ospeed == B2400 ? 120 :
                    272:                      ospeed == B1200 ? 60 :
                    273:                      ospeed == B600 ? 30 :
                    274:              /* speed is 300 (?) */   15;
                    275: 
                    276:     gfillen = ospeed >= B9600 ? (sizeof filler) :
                    277:              ospeed == B4800 ? 13 :
                    278:              ospeed == B2400 ? 7 :
                    279:              ospeed == B1200 ? 4 :
                    280:                                1+BCsize;
                    281:     if (ospeed < B2400)
                    282:        lowspeed = TRUE;
                    283: 
                    284:     strcpy(term,ttyname(2));
                    285: 
                    286:     if (!*CM || !BCsize)
                    287:        no_can_do("dumb");
                    288:     if (!scorespec && (LINES < 24 || COLS < 80))
                    289:        no_can_do("puny");
                    290: 
                    291:     crmode();
                    292:     raw();
                    293:     noecho();                          /* turn off echo */
                    294:     nonl();
                    295: 
                    296: #ifdef PUSHBACK
                    297:     mac_init(tcbuf);
                    298: #endif
                    299: }
                    300: 
                    301: #ifdef PUSHBACK
                    302: void
                    303: mac_init(tcbuf)
                    304: char *tcbuf;
                    305: {
                    306:     char tmpbuf[1024];
                    307: 
                    308:     tmpfp = fopen(filexp(getval("WARPMACRO",WARPMACRO)),"r");
                    309:     if (tmpfp != Nullfp) {
                    310:        while (fgets(tcbuf,1024,tmpfp) != Nullch) {
                    311:            mac_line(tcbuf,tmpbuf,(sizeof tmpbuf));
                    312:        }
                    313:        Fclose(tmpfp);
                    314:     }
                    315: }
                    316: 
                    317: void
                    318: mac_line(line,tmpbuf,tbsize)
                    319: char *line;
                    320: char *tmpbuf;
                    321: int tbsize;
                    322: {
                    323:     Reg1 char *s;
                    324:     Reg2 char *m;
                    325:     Reg3 KEYMAP *curmap;
                    326:     Reg4 int ch;
                    327:     Reg5 int garbage = 0;
                    328:     static char override[] = "\r\nkeymap overrides string\r\n";
                    329: 
                    330:     if (topmap == Null(KEYMAP*))
                    331:        topmap = newkeymap();
                    332:     if (*line == '#' || *line == '\n')
                    333:        return;
                    334:     if (line[ch = strlen(line)-1] == '\n')
                    335:        line[ch] = '\0';
                    336:     m = dointerp(tmpbuf,tbsize,line," \t");
                    337:     if (!*m)
                    338:        return;
                    339:     while (*m == ' ' || *m == '\t') m++;
                    340:     for (s=tmpbuf,curmap=topmap; *s; s++) {
                    341:        ch = *s & 0177;
                    342:        if (s[1] == '+' && isdigit(s[2])) {
                    343:            s += 2;
                    344:            garbage = (*s & KM_GMASK) << KM_GSHIFT;
                    345:        }
                    346:        else
                    347:            garbage = 0;
                    348:        if (s[1]) {
                    349:            if ((curmap->km_type[ch] & KM_TMASK) == KM_STRING) {
                    350:                puts(override);
                    351:                free(curmap->km_ptr[ch].km_str);
                    352:                curmap->km_ptr[ch].km_str = Nullch;
                    353:            }
                    354:            curmap->km_type[ch] = KM_KEYMAP + garbage;
                    355:            if (curmap->km_ptr[ch].km_km == Null(KEYMAP*))
                    356:                curmap->km_ptr[ch].km_km = newkeymap();
                    357:            curmap = curmap->km_ptr[ch].km_km;
                    358:        }
                    359:        else {
                    360:            if ((curmap->km_type[ch] & KM_TMASK) == KM_KEYMAP)
                    361:                puts(override);
                    362:            else {
                    363:                curmap->km_type[ch] = KM_STRING + garbage;
                    364:                curmap->km_ptr[ch].km_str = savestr(m);
                    365:            }
                    366:        }
                    367:     }
                    368: }
                    369: 
                    370: KEYMAP*
                    371: newkeymap()
                    372: {
                    373:     Reg1 int i;
                    374:     Reg2 KEYMAP *map;
                    375: 
                    376: #ifndef lint
                    377:     map = (KEYMAP*)safemalloc(sizeof(KEYMAP));
                    378: #else
                    379:     map = Null(KEYMAP*);
                    380: #endif /* lint */
                    381:     for (i=127; i>=0; --i) {
                    382:        map->km_ptr[i].km_km = Null(KEYMAP*);
                    383:        map->km_type[i] = KM_NOTHIN;
                    384:     }
                    385:     return map;
                    386: }
                    387: 
                    388: #endif
                    389: 
                    390: /* print out a file, stopping at form feeds */
                    391: 
                    392: void
                    393: page(filename,num)
                    394: char *filename;
                    395: bool num;
                    396: {
                    397:     int linenum = 1;
                    398: 
                    399:     tmpfp = fopen(filename,"r");
                    400:     if (tmpfp != NULL) {
                    401:        while (fgets(spbuf,(sizeof spbuf),tmpfp) != NULL) {
                    402:            if (*spbuf == '\f') {
                    403:                printf("[Type anything to continue] ");
                    404:                Fflush(stdout);
                    405:                getcmd(spbuf);
                    406:                printf("\r\n");
                    407:                if (*spbuf == INTRCH)
                    408:                    finalize(0);
                    409:                if (*spbuf == 'q' || *spbuf == 'Q')
                    410:                    break;
                    411:            }
                    412:            else {
                    413:                if (num)
                    414:                    printf("%3d   %s\r",linenum++,spbuf);
                    415:                else
                    416:                    printf("%s\r",spbuf);
                    417:            }
                    418:        }
                    419:        Fclose(tmpfp);
                    420:     }
                    421: }
                    422: 
                    423: void
                    424: move(y, x, chadd)
                    425: int y, x;
                    426: int chadd;
                    427: {
                    428:     Reg1 int ydist;
                    429:     Reg2 int xdist;
                    430:     Reg3 int i;
                    431:     Reg4 char *s;
                    432: 
                    433:     ydist = y - real_y;
                    434:     xdist = x - real_x;
                    435:     i = ydist * (ydist < 0 ? -UPsize : DOsize) +
                    436:         xdist * (xdist < 0 ? -BCsize : NDsize);
                    437:     beg_qwrite();
                    438:     if (i <= CMsize) {
                    439:        if (ydist < 0)
                    440:            for (; ydist; ydist++)
                    441:                for (i=UPsize,s=myUP; i; i--)
                    442:                    qaddch(*s++);
                    443:        else
                    444:            for (; ydist; ydist--)
                    445:                for (i=DOsize,s=myDO; i; i--)
                    446:                    qaddch(*s++);
                    447:        if (xdist < 0)
                    448:            for (; xdist; xdist++)
                    449:                for (i=BCsize,s=BC; i; i--)
                    450:                    qaddch(*s++);
                    451:        else
                    452:            for (; xdist; xdist--)
                    453:                for (i=NDsize,s=myND; i; i--)
                    454:                    qaddch(*s++);
                    455:     }
                    456:     else {
                    457:        tputs(tgoto(CM,x,y),0,cmstore);
                    458:     }
                    459:     real_y = y;
                    460:     real_x = x;
                    461:     if (chadd) {
                    462:        qaddch(chadd);
                    463:     }
                    464:     if (maxcmstring != cmbuffer)
                    465:        end_qwrite();
                    466: }
                    467: 
                    468: void
                    469: do_tc(s,l)
                    470: char *s;
                    471: int l;
                    472: {
                    473:     beg_qwrite();
                    474:     tputs(s,l,cmstore);
                    475:     end_qwrite();
                    476: }
                    477: 
                    478: int
                    479: comp_tc(dest,s,l)
                    480: char *dest;
                    481: char *s;
                    482: int l;
                    483: {
                    484:     maxcmstring = dest;
                    485:     tputs(s,l,cmstore);
                    486:     return(maxcmstring-dest);
                    487: }
                    488: 
                    489: void
                    490: helper()
                    491: {
                    492:     clear();
                    493:     mvaddstr(0,4,"h or 4          left");
                    494:     mvaddstr(1,4,"j or 2          down                Use with SHIFT to fire torpedoes.");
                    495:     mvaddstr(2,4,"k or 8          up                  Use with CTRL or FUNCT to fire");
                    496:     mvaddstr(3,4,"l or 6          right                   phasers or turbolasers.");
                    497:     mvaddstr(4,4,"b or 1          down and left       Use preceded by 'a' or 'r' for");
                    498:     mvaddstr(5,4,"n or 3          down and right          attractors or repulsors.");
                    499:     mvaddstr(6,4,"y or 7          up and left         Use normally for E or B motion.");
                    500:     mvaddstr(7,4,"u or 9          up and right");
                    501:     mvaddstr(8,4,"");
                    502:     mvaddstr(9,4,"del or %        fire photon torpedoes in every (reasonable) direction.");
                    503:     mvaddstr(10,4,"s               stop all torpedoes.");
                    504:     mvaddstr(11,4,"S or 0          stop the Enterprise when in warp mode.");
                    505:     mvaddstr(12,4,"d/D             destruct all torpedoes/current vessel.");
                    506:     mvaddstr(13,4,"i/w             switch to Enterprise & put into impulse/warp mode.");
                    507:     mvaddstr(14,4,"c/v             switch to Enterprise & make cloaked/visible.");
                    508:     mvaddstr(15,4,"p               switch to Base.");
                    509:     mvaddstr(16,4,"o               toggle to other vessel (from E to B, or vice versa.)");
                    510:     mvaddstr(17,4,"z               zap (suppress) blasts near Enterprise next cycle");
                    511:     mvaddstr(18,4,"");
                    512:     mvaddstr(19,4,"^R      refresh the screen.              ^Z      suspend the game.");
                    513:     mvaddstr(20,4,"q       exit this round (if you haven't typed q within 10 cycles).");
                    514:     mvaddstr(21,4,"Q       exit this game.");
                    515:     mvaddstr(22,4,"");
                    516:     mvaddstr(23,4,"                   [Hit space to continue]");
                    517:     Fflush(stdout);
                    518:     do {
                    519:        getcmd(spbuf);
                    520:     } while (*spbuf != ' ');
                    521:     rewrite();
                    522:     
                    523: }
                    524: 
                    525: void
                    526: rewrite()
                    527: {
                    528:     Reg1 int x;
                    529:     Reg2 int y;
                    530:     Reg3 OBJECT *obj;
                    531: 
                    532:     clear();
                    533:     for (y=0; y<YSIZE; y++) {
                    534:        for (x=0; x<XSIZE; x++) {
                    535:            if (numamoebas && amb[y][x] != ' ')
                    536:                mvaddc(y+1,x*2,amb[y][x]);
                    537:            if (obj=occupant[y][x]) {
                    538:                if (obj->image != ' ')
                    539:                    mvaddc(y+1,x*2,obj->image);
                    540:            }
                    541:        }
                    542:     }
                    543:     Sprintf(spbuf,
                    544:     "%-4s E: %4d %2d B: %5d %3d Enemies: %-3d Stars: %-3d Stardate%5d.%1d %9ld",
                    545:        "   ", 0, 0, 0, 0, 0, 0, timer/10+smarts*100, timer%10, 0L);
                    546:     mvaddstr(0,0,spbuf);
                    547:     oldeenergy = oldbenergy = oldcurscore =
                    548:     oldstatus = oldetorp = oldbtorp = oldstrs = oldenemies = -1;
                    549:                                        /* force everything to fill in */
                    550:     if (damage)
                    551:        olddamage = 0;
                    552:     if (!ent)
                    553:        etorp = 0;
                    554:     if (!base)
                    555:        btorp = 0;
                    556:     display_status();
                    557: }
                    558: 
                    559: char
                    560: cmstore(ch)
                    561: Reg1 char ch;
                    562: {
                    563:     *maxcmstring++ = ch;
                    564: }
                    565: 
                    566: /* discard any characters typed ahead */
                    567: 
                    568: void
                    569: eat_typeahead()
                    570: {
                    571: #ifdef PUSHBACK
                    572:     if (!typeahead && nextin==nextout) /* cancel only keyboard stuff */
                    573: #else
                    574:     if (!typeahead)
                    575: #endif
                    576:     {
                    577: #ifdef PENDING
                    578:        while (input_pending())
                    579:            Read_tty(buf,sizeof(buf));
                    580: #else /* this is probably v7, with no rdchk() */
                    581:        ioctl(_tty_ch,TIOCSETP,&_tty);
                    582: #endif
                    583:     }
                    584: }
                    585: 
                    586: void
                    587: settle_down()
                    588: {
                    589:     dingaling();
                    590:     Fflush(stdout);
                    591:     sleep(1);
                    592: #ifdef PUSHBACK
                    593:     nextout = nextin;                  /* empty circlebuf */
                    594: #endif
                    595:     eat_typeahead();
                    596: }
                    597: 
                    598: #ifdef PUSHBACK
                    599: /* read a character from the terminal, with multi-character pushback */
                    600: 
                    601: int
                    602: read_tty(addr,size)
                    603: char *addr;
                    604: int size;      /* ignored for now */
                    605: {
                    606: #ifdef lint
                    607:     size = size;
                    608: #endif
                    609:     if (nextout != nextin) {
                    610:        *addr = circlebuf[nextout++];
                    611:        nextout %= PUSHSIZE;
                    612:        return 1;
                    613:     }
                    614:     else {
                    615:        size = read(0,addr,1);
                    616:        if (size < 0)
                    617:            sig_catcher(SIGHUP);
                    618:        if (metakey) {
                    619:            if (*addr & 0200) {
                    620:                pushchar(*addr & 0177);
                    621:                *addr = '\001';
                    622:            }
                    623:        }
                    624:        else
                    625:            *addr &= 0177;
                    626:        return 1;
                    627:     }
                    628: }
                    629: 
                    630: #ifdef PENDING
                    631: #ifndef FIONREAD
                    632: #ifndef RDCHK
                    633: int
                    634: circfill()
                    635: {
                    636:     Reg1 int howmany;
                    637:     Reg2 int i;
                    638: 
                    639:     assert (nextin == nextout);
                    640:     howmany = read(devtty,circlebuf+nextin,metakey?1:PUSHSIZE-nextin);
                    641:     if (howmany > 0) {
                    642:        if (metakey) {
                    643:            if (circlebuf[nextin] & 0200) {
                    644:                circlebuf[nextin] &= 0177;
                    645:                pushchar('\001');
                    646:            }
                    647:        }
                    648:        else
                    649:            for (i = howmany+nextin-1; i >= nextin; i--)
                    650:                circlebuf[i] &= 0177;
                    651:        nextin += howmany;
                    652:        nextin %= PUSHSIZE;     /* may end up 1 if metakey */
                    653:     }
                    654:     return howmany;
                    655: }
                    656: #endif /* RDCHK */
                    657: #endif /* FIONREAD */
                    658: #endif /* PENDING */
                    659: 
                    660: void
                    661: pushchar(ch)
                    662: char ch;
                    663: {
                    664:     nextout--;
                    665:     if (nextout < 0)
                    666:        nextout = PUSHSIZE - 1;
                    667:     if (nextout == nextin) {
                    668:        fputs("\r\npushback buffer overflow\r\n",stdout);
                    669:        sig_catcher(0);
                    670:     }
                    671:     circlebuf[nextout] = ch;
                    672: }
                    673: 
                    674: #else /* PUSHBACK */
                    675: #ifndef read_tty
                    676: /* read a character from the terminal, with hacks for O_NDELAY reads */
                    677: 
                    678: int
                    679: read_tty(addr,size)
                    680: char *addr;
                    681: int size;
                    682: {
                    683:     if (is_input) {
                    684:        *addr = pending_ch;
                    685:        is_input = FALSE;
                    686:        return 1;
                    687:     }
                    688:     else {
                    689:        size = read(0,addr,size);
                    690:        if (size < 0)
                    691:            sig_catcher(SIGHUP);
                    692:        if (metakey) {
                    693:            if (*addr & 0200) {
                    694:                pending_ch = *addr & 0177;
                    695:                is_input = TRUE;
                    696:                *addr = '\001';
                    697:            }
                    698:        }
                    699:        else
                    700:            *addr &= 0177;
                    701:        return size;
                    702:     }
                    703: }
                    704: #endif /* read_tty */
                    705: #endif /* PUSHBACK */
                    706: 
                    707: int
                    708: read_nd(buff, siz)
                    709: char *buff;
                    710: int siz;
                    711: {
                    712:     if (!input_pending())
                    713:        return 0;
                    714: 
                    715:     getcmd(buff);
                    716:     return 1;
                    717: }
                    718: 
                    719: /* get a character into a buffer */
                    720: 
                    721: void
                    722: getcmd(whatbuf)
                    723: Reg3 char *whatbuf;
                    724: {
                    725: #ifdef PUSHBACK
                    726:     Reg1 KEYMAP *curmap;
                    727:     Reg2 int i;
                    728:     bool no_macros; 
                    729:     int times = 0;                     /* loop detector */
                    730:     char scrchar;
                    731: 
                    732: tryagain:
                    733:     curmap = topmap;
                    734: /*    no_macros = (whatbuf != buf && nextin == nextout);  */
                    735:     no_macros = FALSE;
                    736: #endif
                    737:     for (;;) {
                    738:        errno = 0;
                    739:        if (read_tty(whatbuf,1) < 0 && !errno)
                    740:            errno = EINTR;
                    741: #ifdef read_tty
                    742:        if (metakey) {
                    743:            if (*whatbuf & 0200) {
                    744:                *what_buf &= 037;       /* punt and hope they don't notice */
                    745:            }
                    746:        }
                    747:        else
                    748:            *whatbuf &= 0177;
                    749: #endif /* read_tty */
                    750:        if (errno && errno != EINTR) {
                    751:            perror(readerr);
                    752:            sig_catcher(0);
                    753:        }
                    754: #ifdef PUSHBACK
                    755:        if (*whatbuf & 0200 || no_macros) {
                    756:            *whatbuf &= 0177;
                    757:            goto got_canonical;
                    758:        }
                    759:        if (curmap == Null(KEYMAP*))
                    760:            goto got_canonical;
                    761:        for (i = (curmap->km_type[*whatbuf] >> KM_GSHIFT) & KM_GMASK; i; --i){
                    762:            Read_tty(&scrchar,1);
                    763:        }
                    764:        switch (curmap->km_type[*whatbuf] & KM_TMASK) {
                    765:        case KM_NOTHIN:                 /* no entry? */
                    766:            if (curmap == topmap)       /* unmapped canonical */
                    767:                goto got_canonical;
                    768:            settle_down();
                    769:            goto tryagain;
                    770:        case KM_KEYMAP:                 /* another keymap? */
                    771:            curmap = curmap->km_ptr[*whatbuf].km_km;
                    772:            assert(curmap != Null(KEYMAP*));
                    773:            break;
                    774:        case KM_STRING:                 /* a string? */
                    775:            pushstring(curmap->km_ptr[*whatbuf].km_str);
                    776:            if (++times > 20) {         /* loop? */
                    777:                fputs("\r\nmacro loop?\r\n",stdout);
                    778:                settle_down();
                    779:            }
                    780:            no_macros = FALSE;
                    781:            goto tryagain;
                    782:        }
                    783: #else
                    784:        *whatbuf &= 0177;
                    785:        break;
                    786: #endif
                    787:     }
                    788: 
                    789: got_canonical:
                    790: #ifndef TERMIO
                    791:     if (*whatbuf == '\r')
                    792:        *whatbuf = '\n';
                    793: #endif
                    794:     if (whatbuf == buf)
                    795:        whatbuf[1] = FINISHCMD;         /* tell finish_command to work */
                    796: }
                    797: 
                    798: #ifdef PUSHBACK
                    799: void
                    800: pushstring(str)
                    801: char *str;
                    802: {
                    803:     Reg1 int i;
                    804:     char tmpbuf[PUSHSIZE];
                    805:     Reg2 char *s = tmpbuf;
                    806: 
                    807:     assert(str != Nullch);
                    808:     interp(s,PUSHSIZE,str);
                    809:     for (i = strlen(s)-1; i >= 0; --i) {
                    810:        s[i] ^= 0200; 
                    811:        pushchar(s[i]);
                    812:     }
                    813: }
                    814: #endif

unix.superglobalmegacorp.com

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