Annotation of 43BSDTahoe/ucb/ex/ex_vget.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: static char *sccsid = "@(#)ex_vget.c   6.10 (Berkeley) 1/2/88";
        !             9: #endif not lint
        !            10: 
        !            11: #include "ex.h"
        !            12: #include "ex_tty.h"
        !            13: #include "ex_vis.h"
        !            14: 
        !            15: /*
        !            16:  * Input routines for open/visual.
        !            17:  * We handle upper case only terminals in visual and reading from the
        !            18:  * echo area here as well as notification on large changes
        !            19:  * which appears in the echo area.
        !            20:  */
        !            21: 
        !            22: /*
        !            23:  * Return the key.
        !            24:  */
        !            25: ungetkey(c)
        !            26:        int c;          /* mjm: char --> int */
        !            27: {
        !            28: 
        !            29:        if (Peek_key != ATTN)
        !            30:                Peek_key = c;
        !            31: }
        !            32: 
        !            33: /*
        !            34:  * Return a keystroke, but never a ^@.
        !            35:  */
        !            36: getkey()
        !            37: {
        !            38:        register int c;         /* mjm: char --> int */
        !            39: 
        !            40:        do {
        !            41:                c = getbr();
        !            42:                if (c==0)
        !            43:                        beep();
        !            44:        } while (c == 0);
        !            45:        return (c);
        !            46: }
        !            47: 
        !            48: /*
        !            49:  * Tell whether next keystroke would be a ^@.
        !            50:  */
        !            51: peekbr()
        !            52: {
        !            53: 
        !            54:        Peek_key = getbr();
        !            55:        return (Peek_key == 0);
        !            56: }
        !            57: 
        !            58: short  precbksl;
        !            59: jmp_buf        readbuf;
        !            60: int    doingread = 0;
        !            61: 
        !            62: /*
        !            63:  * Get a keystroke, including a ^@.
        !            64:  * If an key was returned with ungetkey, that
        !            65:  * comes back first.  Next comes unread input (e.g.
        !            66:  * from repeating commands with .), and finally new
        !            67:  * keystrokes.
        !            68:  *
        !            69:  * The hard work here is in mapping of \ escaped
        !            70:  * characters on upper case only terminals.
        !            71:  */
        !            72: getbr()
        !            73: {
        !            74:        char ch;
        !            75:        register int c, d;
        !            76:        register char *colp;
        !            77: #define BEEHIVE
        !            78: #ifdef BEEHIVE
        !            79:        static char Peek2key;
        !            80: #endif
        !            81:        extern short slevel, ttyindes;
        !            82: 
        !            83: getATTN:
        !            84:        if (Peek_key) {
        !            85:                c = Peek_key;
        !            86:                Peek_key = 0;
        !            87:                return (c);
        !            88:        }
        !            89: #ifdef BEEHIVE
        !            90:        if (Peek2key) {
        !            91:                c = Peek2key;
        !            92:                Peek2key = 0;
        !            93:                return (c);
        !            94:        }
        !            95: #endif
        !            96:        if (vglobp) {
        !            97:                if (*vglobp)
        !            98:                        return (lastvgk = *vglobp++);
        !            99:                lastvgk = 0;
        !           100:                return (ESCAPE);
        !           101:        }
        !           102:        if (vmacp) {
        !           103:                if (*vmacp)
        !           104:                        return(*vmacp++);
        !           105:                /* End of a macro or set of nested macros */
        !           106:                vmacp = 0;
        !           107:                if (inopen == -1)       /* don't screw up undo for esc esc */
        !           108:                        vundkind = VMANY;
        !           109:                inopen = 1;     /* restore old setting now that macro done */
        !           110:                vch_mac = VC_NOTINMAC;
        !           111:        }
        !           112:        flusho();
        !           113: again:
        !           114:        if (setjmp(readbuf))
        !           115:                goto getATTN;
        !           116:        doingread = 1;
        !           117: #ifndef        vms
        !           118:        c = read(slevel == 0 ? 0 : ttyindes, &ch, 1);
        !           119: #else
        !           120:        c = vms_read(slevel == 0 ? 0 : ttyindes, &ch, 1);
        !           121: #endif
        !           122:        doingread = 0;
        !           123:        if (c != 1) {
        !           124:                if (errno == EINTR)
        !           125:                        goto getATTN;
        !           126:                error("Input read error");
        !           127:        }
        !           128:        c = ch & TRIM;
        !           129: #ifdef BEEHIVE
        !           130:        if (XB && slevel==0 && c == ESCAPE) {
        !           131:                if (read(0, &Peek2key, 1) != 1)
        !           132:                        goto getATTN;
        !           133:                Peek2key &= TRIM;
        !           134:                switch (Peek2key) {
        !           135:                case 'C':       /* SPOW mode sometimes sends \EC for space */
        !           136:                        c = ' ';
        !           137:                        Peek2key = 0;
        !           138:                        break;
        !           139:                case 'q':       /* f2 -> ^C */
        !           140:                        c = CTRL('c');
        !           141:                        Peek2key = 0;
        !           142:                        break;
        !           143:                case 'p':       /* f1 -> esc */
        !           144:                        Peek2key = 0;
        !           145:                        break;
        !           146:                }
        !           147:        }
        !           148: #endif
        !           149: 
        !           150: #ifdef UCVISUAL
        !           151:        /*
        !           152:         * The algorithm here is that of the UNIX kernel.
        !           153:         * See the description in the programmers manual.
        !           154:         */
        !           155:        if (UPPERCASE) {
        !           156:                if (isupper(c))
        !           157:                        c = tolower(c);
        !           158:                if (c == '\\') {
        !           159:                        if (precbksl < 2)
        !           160:                                precbksl++;
        !           161:                        if (precbksl == 1)
        !           162:                                goto again;
        !           163:                } else if (precbksl) {
        !           164:                        d = 0;
        !           165:                        if (islower(c))
        !           166:                                d = toupper(c);
        !           167:                        else {
        !           168:                                colp = "({)}!|^~'~";
        !           169:                                while (d = *colp++)
        !           170:                                        if (d == c) {
        !           171:                                                d = *colp++;
        !           172:                                                break;
        !           173:                                        } else
        !           174:                                                colp++;
        !           175:                        }
        !           176:                        if (precbksl == 2) {
        !           177:                                if (!d) {
        !           178:                                        Peek_key = c;
        !           179:                                        precbksl = 0;
        !           180:                                        c = '\\';
        !           181:                                }
        !           182:                        } else if (d)
        !           183:                                c = d;
        !           184:                        else {
        !           185:                                Peek_key = c;
        !           186:                                precbksl = 0;
        !           187:                                c = '\\';
        !           188:                        }
        !           189:                }
        !           190:                if (c != '\\')
        !           191:                        precbksl = 0;
        !           192:        }
        !           193: #endif
        !           194: #ifdef TRACE
        !           195:        if (trace) {
        !           196:                if (!techoin) {
        !           197:                        tfixnl();
        !           198:                        techoin = 1;
        !           199:                        fprintf(trace, "*** Input: ");
        !           200:                }
        !           201:                tracec(c);
        !           202:        }
        !           203: #endif
        !           204:        lastvgk = 0;
        !           205:        return (c);
        !           206: }
        !           207: 
        !           208: /*
        !           209:  * Get a key, but if a delete, quit or attention
        !           210:  * is typed return 0 so we will abort a partial command.
        !           211:  */
        !           212: getesc()
        !           213: {
        !           214:        register int c;
        !           215: 
        !           216:        c = getkey();
        !           217:        switch (c) {
        !           218: 
        !           219:        case CTRL('v'):
        !           220:        case CTRL('q'):
        !           221:                c = getkey();
        !           222:                return (c);
        !           223: 
        !           224:        case ATTN:
        !           225:        case QUIT:
        !           226:                ungetkey(c);
        !           227:                return (0);
        !           228: 
        !           229:        case ESCAPE:
        !           230:                return (0);
        !           231:        }
        !           232:        return (c);
        !           233: }
        !           234: 
        !           235: /*
        !           236:  * Peek at the next keystroke.
        !           237:  */
        !           238: peekkey()
        !           239: {
        !           240: 
        !           241:        Peek_key = getkey();
        !           242:        return (Peek_key);
        !           243: }
        !           244: 
        !           245: /*
        !           246:  * Read a line from the echo area, with single character prompt c.
        !           247:  * A return value of 1 means the user blewit or blewit away.
        !           248:  */
        !           249: readecho(c)
        !           250:        char c;
        !           251: {
        !           252:        register char *sc = cursor;
        !           253:        register int (*OP)();
        !           254:        bool waste;
        !           255:        register int OPeek;
        !           256: 
        !           257:        if (WBOT == WECHO)
        !           258:                vclean();
        !           259:        else
        !           260:                vclrech(0);
        !           261:        splitw++;
        !           262:        vgoto(WECHO, 0);
        !           263:        ex_putchar(c);
        !           264:        vclreol();
        !           265:        vgoto(WECHO, 1);
        !           266:        cursor = linebuf; linebuf[0] = 0; genbuf[0] = c;
        !           267:        if (peekbr()) {
        !           268:                if (!INS[0] || (INS[0] & (QUOTE|TRIM)) == OVERBUF)
        !           269:                        goto blewit;
        !           270:                vglobp = INS;
        !           271:        }
        !           272:        OP = Pline; Pline = normline;
        !           273:        ignore(vgetline(0, genbuf + 1, &waste, c));
        !           274:        if (Outchar == termchar)
        !           275:                ex_putchar('\n');
        !           276:        vscrap();
        !           277:        Pline = OP;
        !           278:        if (Peek_key != ATTN && Peek_key != QUIT && Peek_key != CTRL('h')) {
        !           279:                cursor = sc;
        !           280:                vclreol();
        !           281:                return (0);
        !           282:        }
        !           283: blewit:
        !           284:        OPeek = Peek_key==CTRL('h') ? 0 : Peek_key; Peek_key = 0;
        !           285:        splitw = 0;
        !           286:        vclean();
        !           287:        vshow(dot, NOLINE);
        !           288:        vnline(sc);
        !           289:        Peek_key = OPeek;
        !           290:        return (1);
        !           291: }
        !           292: 
        !           293: /*
        !           294:  * A complete command has been defined for
        !           295:  * the purposes of repeat, so copy it from
        !           296:  * the working to the previous command buffer.
        !           297:  */
        !           298: setLAST()
        !           299: {
        !           300: 
        !           301:        if (vglobp || vmacp)
        !           302:                return;
        !           303:        lastreg = vreg;
        !           304:        lasthad = Xhadcnt;
        !           305:        lastcnt = Xcnt;
        !           306:        *lastcp = 0;
        !           307:        CP(lastcmd, workcmd);
        !           308: }
        !           309: 
        !           310: /*
        !           311:  * Gather up some more text from an insert.
        !           312:  * If the insertion buffer oveflows, then destroy
        !           313:  * the repeatability of the insert.
        !           314:  */
        !           315: addtext(cp)
        !           316:        char *cp;
        !           317: {
        !           318: 
        !           319:        if (vglobp)
        !           320:                return;
        !           321:        addto(INS, cp);
        !           322:        if ((INS[0] & (QUOTE|TRIM)) == OVERBUF)
        !           323:                lastcmd[0] = 0;
        !           324: }
        !           325: 
        !           326: setDEL()
        !           327: {
        !           328: 
        !           329:        ex_setBUF(DEL);
        !           330: }
        !           331: 
        !           332: /*
        !           333:  * Put text from cursor upto wcursor in BUF.
        !           334:  */
        !           335: ex_setBUF(BUF)
        !           336:        register char *BUF;
        !           337: {
        !           338:        register int c;
        !           339:        register char *wp = wcursor;
        !           340: 
        !           341:        c = *wp;
        !           342:        *wp = 0;
        !           343:        BUF[0] = 0;
        !           344:        addto(BUF, cursor);
        !           345:        *wp = c;
        !           346: }
        !           347: 
        !           348: addto(buf, str)
        !           349:        register char *buf, *str;
        !           350: {
        !           351: 
        !           352:        if ((buf[0] & (QUOTE|TRIM)) == OVERBUF)
        !           353:                return;
        !           354:        if (strlen(buf) + strlen(str) + 1 >= VBSIZE) {
        !           355:                buf[0] = OVERBUF;
        !           356:                return;
        !           357:        }
        !           358:        ignore(strcat(buf, str));
        !           359: }
        !           360: 
        !           361: /*
        !           362:  * Note a change affecting a lot of lines, or non-visible
        !           363:  * lines.  If the parameter must is set, then we only want
        !           364:  * to do this for open modes now; return and save for later
        !           365:  * notification in visual.
        !           366:  */
        !           367: noteit(must)
        !           368:        bool must;
        !           369: {
        !           370:        register int sdl = destline, sdc = destcol;
        !           371: 
        !           372:        if (notecnt < 2 || !must && state == VISUAL)
        !           373:                return (0);
        !           374:        splitw++;
        !           375:        if (WBOT == WECHO)
        !           376:                vmoveitup(1, 1);
        !           377:        vigoto(WECHO, 0);
        !           378:        ex_printf("%d %sline", notecnt, notesgn);
        !           379:        if (notecnt > 1)
        !           380:                ex_putchar('s');
        !           381:        if (*notenam) {
        !           382:                ex_printf(" %s", notenam);
        !           383:                if (*(strend(notenam) - 1) != 'e')
        !           384:                        ex_putchar('e');
        !           385:                ex_putchar('d');
        !           386:        }
        !           387:        vclreol();
        !           388:        notecnt = 0;
        !           389:        if (state != VISUAL)
        !           390:                vcnt = vcline = 0;
        !           391:        splitw = 0;
        !           392:        if (state == ONEOPEN || state == CRTOPEN)
        !           393:                vup1();
        !           394:        destline = sdl; destcol = sdc;
        !           395:        return (1);
        !           396: }
        !           397: 
        !           398: /*
        !           399:  * Rrrrringgggggg.
        !           400:  * If possible, use flash (VB).
        !           401:  */
        !           402: beep()
        !           403: {
        !           404: 
        !           405:        if (VB)
        !           406:                vputp(VB, 0);
        !           407:        else
        !           408:                vputc(CTRL('g'));
        !           409: }
        !           410: 
        !           411: /*
        !           412:  * Map the command input character c,
        !           413:  * for keypads and labelled keys which do cursor
        !           414:  * motions.  I.e. on an adm3a we might map ^K to ^P.
        !           415:  * DM1520 for example has a lot of mappable characters.
        !           416:  */
        !           417: 
        !           418: map(c,maps)
        !           419:        register int c;
        !           420:        register struct maps *maps;
        !           421: {
        !           422:        register int d;
        !           423:        register char *p, *q;
        !           424:        char b[10];     /* Assumption: no keypad sends string longer than 10 */
        !           425: 
        !           426:        /*
        !           427:         * Mapping for special keys on the terminal only.
        !           428:         * BUG: if there's a long sequence and it matches
        !           429:         * some chars and then misses, we lose some chars.
        !           430:         *
        !           431:         * For this to work, some conditions must be met.
        !           432:         * 1) Keypad sends SHORT (2 or 3 char) strings
        !           433:         * 2) All strings sent are same length & similar
        !           434:         * 3) The user is unlikely to type the first few chars of
        !           435:         *    one of these strings very fast.
        !           436:         * Note: some code has been fixed up since the above was laid out,
        !           437:         * so conditions 1 & 2 are probably not required anymore.
        !           438:         * However, this hasn't been tested with any first char
        !           439:         * that means anything else except escape.
        !           440:         */
        !           441: #ifdef MDEBUG
        !           442:        if (trace)
        !           443:                fprintf(trace,"map(%c): ",c);
        !           444: #endif
        !           445:        /*
        !           446:         * If c==0, the char came from getesc typing escape.  Pass it through
        !           447:         * unchanged.  0 messes up the following code anyway.
        !           448:         */
        !           449:        if (c==0)
        !           450:                return(0);
        !           451: 
        !           452:        b[0] = c;
        !           453:        b[1] = 0;
        !           454:        for (d=0; maps[d].mapto; d++) {
        !           455: #ifdef MDEBUG
        !           456:                if (trace)
        !           457:                        fprintf(trace,"\ntry '%s', ",maps[d].cap);
        !           458: #endif
        !           459:                if (p = maps[d].cap) {
        !           460:                        for (q=b; *p; p++, q++) {
        !           461: #ifdef MDEBUG
        !           462:                                if (trace)
        !           463:                                        fprintf(trace,"q->b[%d], ",q-b);
        !           464: #endif
        !           465:                                if (*q==0) {
        !           466:                                        /*
        !           467:                                         * Is there another char waiting?
        !           468:                                         *
        !           469:                                         * This test is oversimplified, but
        !           470:                                         * should work mostly. It handles the
        !           471:                                         * case where we get an ESCAPE that
        !           472:                                         * wasn't part of a keypad string.
        !           473:                                         */
        !           474:                                        if ((c=='#' ? peekkey() : fastpeekkey()) == 0) {
        !           475: #ifdef MDEBUG
        !           476:                                                if (trace)
        !           477:                                                        fprintf(trace,"fpk=0: will return '%c'",c);
        !           478: #endif
        !           479:                                                /*
        !           480:                                                 * Nothing waiting.  Push back
        !           481:                                                 * what we peeked at & return
        !           482:                                                 * failure (c).
        !           483:                                                 *
        !           484:                                                 * We want to be able to undo
        !           485:                                                 * commands, but it's nonsense
        !           486:                                                 * to undo part of an insertion
        !           487:                                                 * so if in input mode don't.
        !           488:                                                 */
        !           489: #ifdef MDEBUG
        !           490:                                                if (trace)
        !           491:                                                        fprintf(trace, "Call macpush, b %d %d %d\n", b[0], b[1], b[2]);
        !           492: #endif
        !           493:                                                macpush(&b[1],maps == arrows);
        !           494: #ifdef MDEBUG
        !           495:                                                if (trace)
        !           496:                                                        fprintf(trace, "return %d\n", c);       
        !           497: #endif
        !           498:                                                return(c);
        !           499:                                        }
        !           500:                                        *q = getkey();
        !           501:                                        q[1] = 0;
        !           502:                                }
        !           503:                                if (*p != *q)
        !           504:                                        goto contin;
        !           505:                        }
        !           506:                        macpush(maps[d].mapto,maps == arrows);
        !           507:                        c = getkey();
        !           508: #ifdef MDEBUG
        !           509:                        if (trace)
        !           510:                                fprintf(trace,"Success: push(%s), return %c",maps[d].mapto, c);
        !           511: #endif
        !           512:                        return(c);      /* first char of map string */
        !           513:                        contin:;
        !           514:                }
        !           515:        }
        !           516: #ifdef MDEBUG
        !           517:        if (trace)
        !           518:                fprintf(trace,"Fail: push(%s), return %c", &b[1], c);
        !           519: #endif
        !           520:        macpush(&b[1],0);
        !           521:        return(c);
        !           522: }
        !           523: 
        !           524: /*
        !           525:  * Push st onto the front of vmacp. This is tricky because we have to
        !           526:  * worry about where vmacp was previously pointing. We also have to
        !           527:  * check for overflow (which is typically from a recursive macro)
        !           528:  * Finally we have to set a flag so the whole thing can be undone.
        !           529:  * canundo is 1 iff we want to be able to undo the macro.  This
        !           530:  * is false for, for example, pushing back lookahead from fastpeekkey(),
        !           531:  * since otherwise two fast escapes can clobber our undo.
        !           532:  */
        !           533: macpush(st, canundo)
        !           534: char *st;
        !           535: int canundo;
        !           536: {
        !           537:        char tmpbuf[BUFSIZ];
        !           538: 
        !           539:        if (st==0 || *st==0)
        !           540:                return;
        !           541: #ifdef MDEBUG
        !           542:        if (trace)
        !           543:                fprintf(trace, "macpush(%s), canundo=%d\n",st,canundo);
        !           544: #endif
        !           545:        if ((vmacp ? strlen(vmacp) : 0) + strlen(st) > BUFSIZ)
        !           546:                error("Macro too long@ - maybe recursive?");
        !           547:        if (vmacp) {
        !           548:                strcpy(tmpbuf, vmacp);
        !           549:                if (!FIXUNDO)
        !           550:                        canundo = 0;    /* can't undo inside a macro anyway */
        !           551:        }
        !           552:        strcpy(vmacbuf, st);
        !           553:        if (vmacp)
        !           554:                strcat(vmacbuf, tmpbuf);
        !           555:        vmacp = vmacbuf;
        !           556:        /* arrange to be able to undo the whole macro */
        !           557:        if (canundo) {
        !           558: #ifdef notdef
        !           559:                otchng = tchng;
        !           560:                vsave();
        !           561:                saveall();
        !           562:                inopen = -1;    /* no need to save since it had to be 1 or -1 before */
        !           563:                vundkind = VMANY;
        !           564: #endif
        !           565:                vch_mac = VC_NOCHANGE;
        !           566:        }
        !           567: }
        !           568: 
        !           569: #ifdef TRACE
        !           570: visdump(s)
        !           571: char *s;
        !           572: {
        !           573:        register int i;
        !           574: 
        !           575:        if (!trace) return;
        !           576: 
        !           577:        fprintf(trace, "\n%s: basWTOP=%d, basWLINES=%d, WTOP=%d, WBOT=%d, WLINES=%d, WCOLS=%d, WECHO=%d\n",
        !           578:                s, basWTOP, basWLINES, WTOP, WBOT, WLINES, WCOLS, WECHO);
        !           579:        fprintf(trace, "   vcnt=%d, vcline=%d, cursor=%d, wcursor=%d, wdot=%d\n",
        !           580:                vcnt, vcline, cursor-linebuf, wcursor-linebuf, wdot-zero);
        !           581:        for (i=0; i<TUBELINES; i++)
        !           582:                if (vtube[i] && *vtube[i])
        !           583:                        fprintf(trace, "%d: '%s'\n", i, vtube[i]);
        !           584:        tvliny();
        !           585: }
        !           586: 
        !           587: vudump(s)
        !           588: char *s;
        !           589: {
        !           590:        register line *p;
        !           591:        char savelb[1024];
        !           592: 
        !           593:        if (!trace) return;
        !           594: 
        !           595:        fprintf(trace, "\n%s: undkind=%d, vundkind=%d, unddel=%d, undap1=%d, undap2=%d,\n",
        !           596:                s, undkind, vundkind, lineno(unddel), lineno(undap1), lineno(undap2));
        !           597:        fprintf(trace, "  undadot=%d, dot=%d, dol=%d, unddol=%d, truedol=%d\n",
        !           598:                lineno(undadot), lineno(dot), lineno(dol), lineno(unddol), lineno(truedol));
        !           599:        fprintf(trace, "  [\n");
        !           600:        CP(savelb, linebuf);
        !           601:        fprintf(trace, "linebuf = '%s'\n", linebuf);
        !           602:        for (p=zero+1; p<=truedol; p++) {
        !           603:                fprintf(trace, "%o ", *p);
        !           604:                getline(*p);
        !           605:                fprintf(trace, "'%s'\n", linebuf);
        !           606:        }
        !           607:        fprintf(trace, "]\n");
        !           608:        CP(linebuf, savelb);
        !           609: }
        !           610: #endif
        !           611: 
        !           612: /*
        !           613:  * Get a count from the keyed input stream.
        !           614:  * A zero count is indistinguishable from no count.
        !           615:  */
        !           616: vgetcnt()
        !           617: {
        !           618:        register int c, cnt;
        !           619: 
        !           620:        cnt = 0;
        !           621:        for (;;) {
        !           622:                c = getkey();
        !           623:                if (!isdigit(c))
        !           624:                        break;
        !           625:                cnt *= 10, cnt += c - '0';
        !           626:        }
        !           627:        ungetkey(c);
        !           628:        Xhadcnt = 1;
        !           629:        Xcnt = cnt;
        !           630:        return(cnt);
        !           631: }
        !           632: 
        !           633: /*
        !           634:  * fastpeekkey is just like peekkey but insists the character come in
        !           635:  * fast (within 1 second). This will succeed if it is the 2nd char of
        !           636:  * a machine generated sequence (such as a function pad from an escape
        !           637:  * flavor terminal) but fail for a human hitting escape then waiting.
        !           638:  */
        !           639: fastpeekkey()
        !           640: {
        !           641:        int trapalarm();
        !           642:        int (*Oint)();
        !           643:        register int c;
        !           644: 
        !           645:        /*
        !           646:         * If the user has set notimeout, we wait forever for a key.
        !           647:         * If we are in a macro we do too, but since it's already
        !           648:         * buffered internally it will return immediately.
        !           649:         * In other cases we force this to die in 1 second.
        !           650:         * This is pretty reliable (VMUNIX rounds it to .5 - 1.5 secs,
        !           651:         * but UNIX truncates it to 0 - 1 secs) but due to system delays
        !           652:         * there are times when arrow keys or very fast typing get counted
        !           653:         * as separate.  notimeout is provided for people who dislike such
        !           654:         * nondeterminism.
        !           655:         */
        !           656: #ifdef MDEBUG
        !           657:        if (trace)
        !           658:                fprintf(trace,"\nfastpeekkey: ",c);
        !           659: #endif
        !           660:        Oint = signal(SIGINT, trapalarm);
        !           661:        if (value(TIMEOUT) && inopen >= 0) {
        !           662:                signal(SIGALRM, trapalarm);
        !           663: #ifdef MDEBUG
        !           664:                alarm(10);
        !           665:                if (trace)
        !           666:                        fprintf(trace, "set alarm ");
        !           667: #else
        !           668:                alarm(1);
        !           669: #endif
        !           670:        }
        !           671:        CATCH
        !           672:                c = peekkey();
        !           673: #ifdef MDEBUG
        !           674:        if (trace)
        !           675:                fprintf(trace,"[OK]",c);
        !           676: #endif
        !           677:                alarm(0);
        !           678:        ONERR
        !           679:                c = 0;
        !           680: #ifdef MDEBUG
        !           681:        if (trace)
        !           682:                fprintf(trace,"[TIMEOUT]",c);
        !           683: #endif
        !           684:        ENDCATCH
        !           685: #ifdef MDEBUG
        !           686:        if (trace)
        !           687:                fprintf(trace,"[fpk:%o]",c);
        !           688: #endif
        !           689:        signal(SIGINT,Oint);
        !           690:        return(c);
        !           691: }
        !           692: 
        !           693: trapalarm() {
        !           694:        alarm(0);
        !           695:        if (vcatch)
        !           696:                longjmp(vreslab,1);
        !           697: }

unix.superglobalmegacorp.com

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