Annotation of 43BSDReno/bin/csh/sh.lex.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 = "@(#)sh.lex.c    5.7 (Berkeley) 9/27/88";
        !             9: #endif
        !            10: 
        !            11: #include "sh.h"
        !            12: #include <sgtty.h>
        !            13: 
        !            14: /*
        !            15:  * C shell
        !            16:  */
        !            17: 
        !            18: /*
        !            19:  * These lexical routines read input and form lists of words.
        !            20:  * There is some involved processing here, because of the complications
        !            21:  * of input buffering, and especially because of history substitution.
        !            22:  */
        !            23: 
        !            24: char   *word();
        !            25: 
        !            26: /*
        !            27:  * Peekc is a peek characer for getC, peekread for readc.
        !            28:  * There is a subtlety here in many places... history routines
        !            29:  * will read ahead and then insert stuff into the input stream.
        !            30:  * If they push back a character then they must push it behind
        !            31:  * the text substituted by the history substitution.  On the other
        !            32:  * hand in several places we need 2 peek characters.  To make this
        !            33:  * all work, the history routines read with getC, and make use both
        !            34:  * of ungetC and unreadc.  The key observation is that the state
        !            35:  * of getC at the call of a history reference is such that calls
        !            36:  * to getC from the history routines will always yield calls of
        !            37:  * readc, unless this peeking is involved.  That is to say that during
        !            38:  * getexcl the variables lap, exclp, and exclnxt are all zero.
        !            39:  *
        !            40:  * Getdol invokes history substitution, hence the extra peek, peekd,
        !            41:  * which it can ungetD to be before history substitutions.
        !            42:  */
        !            43: char   peekc, peekd;
        !            44: char   peekread;
        !            45: 
        !            46: char   *exclp;                 /* (Tail of) current word from ! subst */
        !            47: struct wordent *exclnxt;       /* The rest of the ! subst words */
        !            48: int    exclc;                  /* Count of remainig words in ! subst */
        !            49: char   *alvecp;                /* "Globp" for alias resubstitution */
        !            50: 
        !            51: /*
        !            52:  * Lex returns to its caller not only a wordlist (as a "var" parameter)
        !            53:  * but also whether a history substitution occurred.  This is used in
        !            54:  * the main (process) routine to determine whether to echo, and also
        !            55:  * when called by the alias routine to determine whether to keep the
        !            56:  * argument list.
        !            57:  */
        !            58: bool   hadhist;
        !            59: 
        !            60: char getCtmp;
        !            61: #define getC(f)                ((getCtmp = peekc) ? (peekc = 0, getCtmp) : getC1(f))
        !            62: #define        ungetC(c)       peekc = c
        !            63: #define        ungetD(c)       peekd = c
        !            64: 
        !            65: lex(hp)
        !            66:        register struct wordent *hp;
        !            67: {
        !            68:        register struct wordent *wdp;
        !            69:        int c;
        !            70: 
        !            71:        lineloc = btell();
        !            72:        hp->next = hp->prev = hp;
        !            73:        hp->word = "";
        !            74:        alvecp = 0, hadhist = 0;
        !            75:        do
        !            76:                c = readc(0);
        !            77:        while (c == ' ' || c == '\t');
        !            78:        if (c == HISTSUB && intty)
        !            79:                /* ^lef^rit     from tty is short !:s^lef^rit */
        !            80:                getexcl(c);
        !            81:        else
        !            82:                unreadc(c);
        !            83:        wdp = hp;
        !            84:        /*
        !            85:         * The following loop is written so that the links needed
        !            86:         * by freelex will be ready and rarin to go even if it is
        !            87:         * interrupted.
        !            88:         */
        !            89:        do {
        !            90:                register struct wordent *new = (struct wordent *) xalloc(sizeof *wdp);
        !            91: 
        !            92:                new->word = 0;
        !            93:                new->prev = wdp;
        !            94:                new->next = hp;
        !            95:                wdp->next = new;
        !            96:                wdp = new;
        !            97:                wdp->word = word();
        !            98:        } while (wdp->word[0] != '\n');
        !            99:        hp->prev = wdp;
        !           100:        return (hadhist);
        !           101: }
        !           102: 
        !           103: prlex(sp0)
        !           104:        struct wordent *sp0;
        !           105: {
        !           106:        register struct wordent *sp = sp0->next;
        !           107: 
        !           108:        for (;;) {
        !           109:                printf("%s", sp->word);
        !           110:                sp = sp->next;
        !           111:                if (sp == sp0)
        !           112:                        break;
        !           113:                if (sp->word[0] != '\n')
        !           114:                        cshputchar(' ');
        !           115:        }
        !           116: }
        !           117: 
        !           118: copylex(hp, fp)
        !           119:        register struct wordent *hp;
        !           120:        register struct wordent *fp;
        !           121: {
        !           122:        register struct wordent *wdp;
        !           123: 
        !           124:        wdp = hp;
        !           125:        fp = fp->next;
        !           126:        do {
        !           127:                register struct wordent *new = (struct wordent *) xalloc(sizeof *wdp);
        !           128: 
        !           129:                new->prev = wdp;
        !           130:                new->next = hp;
        !           131:                wdp->next = new;
        !           132:                wdp = new;
        !           133:                wdp->word = savestr(fp->word);
        !           134:                fp = fp->next;
        !           135:        } while (wdp->word[0] != '\n');
        !           136:        hp->prev = wdp;
        !           137: }
        !           138: 
        !           139: freelex(vp)
        !           140:        register struct wordent *vp;
        !           141: {
        !           142:        register struct wordent *fp;
        !           143: 
        !           144:        while (vp->next != vp) {
        !           145:                fp = vp->next;
        !           146:                vp->next = fp->next;
        !           147:                XFREE(fp->word)
        !           148:                XFREE((char *)fp)
        !           149:        }
        !           150:        vp->prev = vp;
        !           151: }
        !           152: 
        !           153: char *
        !           154: word()
        !           155: {
        !           156:        register char c, c1;
        !           157:        register char *wp;
        !           158:        char wbuf[BUFSIZ];
        !           159:        register bool dolflg;
        !           160:        register int i;
        !           161: 
        !           162:        wp = wbuf;
        !           163:        i = BUFSIZ - 4;
        !           164: loop:
        !           165:        while ((c = getC(DOALL)) == ' ' || c == '\t')
        !           166:                ;
        !           167:        if (cmap(c, _META|_ESC))
        !           168:                switch (c) {
        !           169:                case '&':
        !           170:                case '|':
        !           171:                case '<':
        !           172:                case '>':
        !           173:                        *wp++ = c;
        !           174:                        c1 = getC(DOALL);
        !           175:                        if (c1 == c)
        !           176:                                *wp++ = c1;
        !           177:                        else
        !           178:                                ungetC(c1);
        !           179:                        goto ret;
        !           180: 
        !           181:                case '#':
        !           182:                        if (intty)
        !           183:                                break;
        !           184:                        c = 0;
        !           185:                        do {
        !           186:                                c1 = c;
        !           187:                                c = getC(0);
        !           188:                        } while (c != '\n');
        !           189:                        if (c1 == '\\')
        !           190:                                goto loop;
        !           191:                        /* fall into ... */
        !           192: 
        !           193:                case ';':
        !           194:                case '(':
        !           195:                case ')':
        !           196:                case '\n':
        !           197:                        *wp++ = c;
        !           198:                        goto ret;
        !           199: 
        !           200:                case '\\':
        !           201:                        c = getC(0);
        !           202:                        if (c == '\n') {
        !           203:                                if (onelflg == 1)
        !           204:                                        onelflg = 2;
        !           205:                                goto loop;
        !           206:                        }
        !           207:                        if (c != HIST)
        !           208:                                *wp++ = '\\', --i;
        !           209:                        c |= QUOTE;
        !           210:                }
        !           211:        c1 = 0;
        !           212:        dolflg = DOALL;
        !           213:        for (;;) {
        !           214:                if (c1) {
        !           215:                        if (c == c1) {
        !           216:                                c1 = 0;
        !           217:                                dolflg = DOALL;
        !           218:                        } else if (c == '\\') {
        !           219:                                c = getC(0);
        !           220:                                if (c == HIST)
        !           221:                                        c |= QUOTE;
        !           222:                                else {
        !           223:                                        if (c == '\n')
        !           224:                                                /*
        !           225:                                                if (c1 == '`')
        !           226:                                                        c = ' ';
        !           227:                                                else
        !           228:                                                */
        !           229:                                                        c |= QUOTE;
        !           230:                                        ungetC(c);
        !           231:                                        c = '\\';
        !           232:                                }
        !           233:                        } else if (c == '\n') {
        !           234:                                seterrc("Unmatched ", c1);
        !           235:                                ungetC(c);
        !           236:                                break;
        !           237:                        }
        !           238:                } else if (cmap(c, _META|_Q|_Q1|_ESC)) {
        !           239:                        if (c == '\\') {
        !           240:                                c = getC(0);
        !           241:                                if (c == '\n') {
        !           242:                                        if (onelflg == 1)
        !           243:                                                onelflg = 2;
        !           244:                                        break;
        !           245:                                }
        !           246:                                if (c != HIST)
        !           247:                                        *wp++ = '\\', --i;
        !           248:                                c |= QUOTE;
        !           249:                        } else if (cmap(c, _Q|_Q1)) {           /* '"` */
        !           250:                                c1 = c;
        !           251:                                dolflg = c == '"' ? DOALL : DOEXCL;
        !           252:                        } else if (c != '#' || !intty) {
        !           253:                                ungetC(c);
        !           254:                                break;
        !           255:                        }
        !           256:                }
        !           257:                if (--i > 0) {
        !           258:                        *wp++ = c;
        !           259:                        c = getC(dolflg);
        !           260:                } else {
        !           261:                        seterr("Word too long");
        !           262:                        wp = &wbuf[1];
        !           263:                        break;
        !           264:                }
        !           265:        }
        !           266: ret:
        !           267:        *wp = 0;
        !           268:        return (savestr(wbuf));
        !           269: }
        !           270: 
        !           271: getC1(flag)
        !           272:        register int flag;
        !           273: {
        !           274:        register char c;
        !           275: 
        !           276: top:
        !           277:        if (c = peekc) {
        !           278:                peekc = 0;
        !           279:                return (c);
        !           280:        }
        !           281:        if (lap) {
        !           282:                if ((c = *lap++) == 0)
        !           283:                        lap = 0;
        !           284:                else {
        !           285:                        if (cmap(c, _META|_Q|_Q1))
        !           286:                                c |= QUOTE;
        !           287:                        return (c);
        !           288:                }
        !           289:        }
        !           290:        if (c = peekd) {
        !           291:                peekd = 0;
        !           292:                return (c);
        !           293:        }
        !           294:        if (exclp) {
        !           295:                if (c = *exclp++)
        !           296:                        return (c);
        !           297:                if (exclnxt && --exclc >= 0) {
        !           298:                        exclnxt = exclnxt->next;
        !           299:                        setexclp(exclnxt->word);
        !           300:                        return (' ');
        !           301:                }
        !           302:                exclp = 0;
        !           303:                exclnxt = 0;
        !           304:        }
        !           305:        if (exclnxt) {
        !           306:                exclnxt = exclnxt->next;
        !           307:                if (--exclc < 0)
        !           308:                        exclnxt = 0;
        !           309:                else
        !           310:                        setexclp(exclnxt->word);
        !           311:                goto top;
        !           312:        }
        !           313:        c = readc(0);
        !           314:        if (c == '$' && (flag & DODOL)) {
        !           315:                getdol();
        !           316:                goto top;
        !           317:        }
        !           318:        if (c == HIST && (flag & DOEXCL)) {
        !           319:                getexcl(0);
        !           320:                goto top;
        !           321:        }
        !           322:        return (c);
        !           323: }
        !           324: 
        !           325: getdol()
        !           326: {
        !           327:        register char *np;
        !           328:        char name[40];
        !           329:        register int c;
        !           330:        int sc;
        !           331:        bool special = 0;
        !           332: 
        !           333:        np = name, *np++ = '$';
        !           334:        c = sc = getC(DOEXCL);
        !           335:        if (any(c, "\t \n")) {
        !           336:                ungetD(c);
        !           337:                ungetC('$' | QUOTE);
        !           338:                return;
        !           339:        }
        !           340:        if (c == '{')
        !           341:                *np++ = c, c = getC(DOEXCL);
        !           342:        if (c == '#' || c == '?')
        !           343:                special++, *np++ = c, c = getC(DOEXCL);
        !           344:        *np++ = c;
        !           345:        switch (c) {
        !           346:        
        !           347:        case '<':
        !           348:        case '$':
        !           349:                if (special)
        !           350:                        goto vsyn;
        !           351:                goto ret;
        !           352: 
        !           353:        case '\n':
        !           354:                ungetD(c);
        !           355:                np--;
        !           356:                goto vsyn;
        !           357: 
        !           358:        case '*':
        !           359:                if (special)
        !           360:                        goto vsyn;
        !           361:                goto ret;
        !           362: 
        !           363:        default:
        !           364:                if (digit(c)) {
        !           365: /*
        !           366:  * let $?0 pass for now
        !           367:                        if (special)
        !           368:                                goto vsyn;
        !           369: */
        !           370:                        while (digit(c = getC(DOEXCL))) {
        !           371:                                if (np < &name[sizeof name / 2])
        !           372:                                        *np++ = c;
        !           373:                        }
        !           374:                } else if (letter(c))
        !           375:                        while (letter(c = getC(DOEXCL))) {
        !           376:                                if (np < &name[sizeof name / 2])
        !           377:                                        *np++ = c;
        !           378:                        }
        !           379:                else
        !           380:                        goto vsyn;
        !           381:        }
        !           382:        if (c == '[') {
        !           383:                *np++ = c;
        !           384:                do {
        !           385:                        c = getC(DOEXCL);
        !           386:                        if (c == '\n') {
        !           387:                                ungetD(c);
        !           388:                                np--;
        !           389:                                goto vsyn;
        !           390:                        }
        !           391:                        if (np >= &name[sizeof name - 8])
        !           392:                                goto vsyn;
        !           393:                        *np++ = c;
        !           394:                } while (c != ']');
        !           395:                c = getC(DOEXCL);
        !           396:        }
        !           397:        if (c == ':') {
        !           398:                *np++ = c, c = getC(DOEXCL);
        !           399:                if (c == 'g')
        !           400:                        *np++ = c, c = getC(DOEXCL);
        !           401:                *np++ = c;
        !           402:                if (!any(c, "htrqxe"))
        !           403:                        goto vsyn;
        !           404:        } else
        !           405:                ungetD(c);
        !           406:        if (sc == '{') {
        !           407:                c = getC(DOEXCL);
        !           408:                if (c != '}') {
        !           409:                        ungetC(c);
        !           410:                        goto vsyn;
        !           411:                }
        !           412:                *np++ = c;
        !           413:        }
        !           414: ret:
        !           415:        *np = 0;
        !           416:        addla(name);
        !           417:        return;
        !           418: 
        !           419: vsyn:
        !           420:        seterr("Variable syntax");
        !           421:        goto ret;
        !           422: }
        !           423: 
        !           424: addla(cp)
        !           425:        char *cp;
        !           426: {
        !           427:        char buf[BUFSIZ];
        !           428: 
        !           429:        if (strlen(cp) + (lap ? strlen(lap) : 0) >= sizeof (labuf) - 4) {
        !           430:                seterr("Expansion buffer overflow");
        !           431:                return;
        !           432:        }
        !           433:        if (lap)
        !           434:                (void) strcpy(buf, lap);
        !           435:        (void) strcpy(labuf, cp);
        !           436:        if (lap)
        !           437:                (void) strcat(labuf, buf);
        !           438:        lap = labuf;
        !           439: }
        !           440: 
        !           441: char   lhsb[32];
        !           442: char   slhs[32];
        !           443: char   rhsb[64];
        !           444: int    quesarg;
        !           445: 
        !           446: getexcl(sc)
        !           447:        char sc;
        !           448: {
        !           449:        register struct wordent *hp, *ip;
        !           450:        int left, right, dol;
        !           451:        register int c;
        !           452: 
        !           453:        if (sc == 0) {
        !           454:                sc = getC(0);
        !           455:                if (sc != '{') {
        !           456:                        ungetC(sc);
        !           457:                        sc = 0;
        !           458:                }
        !           459:        }
        !           460:        quesarg = -1;
        !           461:        lastev = eventno;
        !           462:        hp = gethent(sc);
        !           463:        if (hp == 0)
        !           464:                return;
        !           465:        hadhist = 1;
        !           466:        dol = 0;
        !           467:        if (hp == alhistp)
        !           468:                for (ip = hp->next->next; ip != alhistt; ip = ip->next)
        !           469:                        dol++;
        !           470:        else
        !           471:                for (ip = hp->next->next; ip != hp->prev; ip = ip->next)
        !           472:                        dol++;
        !           473:        left = 0, right = dol;
        !           474:        if (sc == HISTSUB) {
        !           475:                ungetC('s'), unreadc(HISTSUB), c = ':';
        !           476:                goto subst;
        !           477:        }
        !           478:        c = getC(0);
        !           479:        if (!any(c, ":^$*-%"))
        !           480:                goto subst;
        !           481:        left = right = -1;
        !           482:        if (c == ':') {
        !           483:                c = getC(0);
        !           484:                unreadc(c);
        !           485:                if (letter(c) || c == '&') {
        !           486:                        c = ':';
        !           487:                        left = 0, right = dol;
        !           488:                        goto subst;
        !           489:                }
        !           490:        } else
        !           491:                ungetC(c);
        !           492:        if (!getsel(&left, &right, dol))
        !           493:                return;
        !           494:        c = getC(0);
        !           495:        if (c == '*')
        !           496:                ungetC(c), c = '-';
        !           497:        if (c == '-') {
        !           498:                if (!getsel(&left, &right, dol))
        !           499:                        return;
        !           500:                c = getC(0);
        !           501:        }
        !           502: subst:
        !           503:        exclc = right - left + 1;
        !           504:        while (--left >= 0)
        !           505:                hp = hp->next;
        !           506:        if (sc == HISTSUB || c == ':') {
        !           507:                do {
        !           508:                        hp = getsub(hp);
        !           509:                        c = getC(0);
        !           510:                } while (c == ':');
        !           511:        }
        !           512:        unreadc(c);
        !           513:        if (sc == '{') {
        !           514:                c = getC(0);
        !           515:                if (c != '}')
        !           516:                        seterr("Bad ! form");
        !           517:        }
        !           518:        exclnxt = hp;
        !           519: }
        !           520: 
        !           521: struct wordent *
        !           522: getsub(en)
        !           523:        struct wordent *en;
        !           524: {
        !           525:        register char *cp;
        !           526:        int delim;
        !           527:        register int c;
        !           528:        int sc;
        !           529:        bool global = 0;
        !           530:        char orhsb[sizeof rhsb];
        !           531: 
        !           532:        exclnxt = 0;
        !           533:        sc = c = getC(0);
        !           534:        if (c == 'g')
        !           535:                global++, c = getC(0);
        !           536:        switch (c) {
        !           537: 
        !           538:        case 'p':
        !           539:                justpr++;
        !           540:                goto ret;
        !           541: 
        !           542:        case 'x':
        !           543:        case 'q':
        !           544:                global++;
        !           545:                /* fall into ... */
        !           546: 
        !           547:        case 'h':
        !           548:        case 'r':
        !           549:        case 't':
        !           550:        case 'e':
        !           551:                break;
        !           552: 
        !           553:        case '&':
        !           554:                if (slhs[0] == 0) {
        !           555:                        seterr("No prev sub");
        !           556:                        goto ret;
        !           557:                }
        !           558:                (void) strcpy(lhsb, slhs);
        !           559:                break;
        !           560: 
        !           561: /*
        !           562:        case '~':
        !           563:                if (lhsb[0] == 0)
        !           564:                        goto badlhs;
        !           565:                break;
        !           566: */
        !           567: 
        !           568:        case 's':
        !           569:                delim = getC(0);
        !           570:                if (letter(delim) || digit(delim) || any(delim, " \t\n")) {
        !           571:                        unreadc(delim);
        !           572: bads:
        !           573:                        lhsb[0] = 0;
        !           574:                        seterr("Bad substitute");
        !           575:                        goto ret;
        !           576:                }
        !           577:                cp = lhsb;
        !           578:                for (;;) {
        !           579:                        c = getC(0);
        !           580:                        if (c == '\n') {
        !           581:                                unreadc(c);
        !           582:                                break;
        !           583:                        }
        !           584:                        if (c == delim)
        !           585:                                break;
        !           586:                        if (cp > &lhsb[sizeof lhsb - 2])
        !           587:                                goto bads;
        !           588:                        if (c == '\\') {
        !           589:                                c = getC(0);
        !           590:                                if (c != delim && c != '\\')
        !           591:                                        *cp++ = '\\';
        !           592:                        }
        !           593:                        *cp++ = c;
        !           594:                }
        !           595:                if (cp != lhsb)
        !           596:                        *cp++ = 0;
        !           597:                else if (lhsb[0] == 0) {
        !           598: /*badlhs:*/
        !           599:                        seterr("No prev lhs");
        !           600:                        goto ret;
        !           601:                }
        !           602:                cp = rhsb;
        !           603:                (void) strcpy(orhsb, cp);
        !           604:                for (;;) {
        !           605:                        c = getC(0);
        !           606:                        if (c == '\n') {
        !           607:                                unreadc(c);
        !           608:                                break;
        !           609:                        }
        !           610:                        if (c == delim)
        !           611:                                break;
        !           612: /*
        !           613:                        if (c == '~') {
        !           614:                                if (&cp[strlen(orhsb)] > &rhsb[sizeof rhsb - 2])
        !           615:                                        goto toorhs;
        !           616:                                (void) strcpy(cp, orhsb);
        !           617:                                cp = strend(cp);
        !           618:                                continue;
        !           619:                        }
        !           620: */
        !           621:                        if (cp > &rhsb[sizeof rhsb - 2]) {
        !           622: /*toorhs:*/
        !           623:                                seterr("Rhs too long");
        !           624:                                goto ret;
        !           625:                        }
        !           626:                        if (c == '\\') {
        !           627:                                c = getC(0);
        !           628:                                if (c != delim /* && c != '~' */)
        !           629:                                        *cp++ = '\\';
        !           630:                        }
        !           631:                        *cp++ = c;
        !           632:                }
        !           633:                *cp++ = 0;
        !           634:                break;
        !           635: 
        !           636:        default:
        !           637:                if (c == '\n')
        !           638:                        unreadc(c);
        !           639:                seterrc("Bad ! modifier: ", c);
        !           640:                goto ret;
        !           641:        }
        !           642:        (void) strcpy(slhs, lhsb);
        !           643:        if (exclc)
        !           644:                en = dosub(sc, en, global);
        !           645: ret:
        !           646:        return (en);
        !           647: }
        !           648: 
        !           649: struct wordent *
        !           650: dosub(sc, en, global)
        !           651:        int sc;
        !           652:        struct wordent *en;
        !           653:        bool global;
        !           654: {
        !           655:        struct wordent lex;
        !           656:        bool didsub = 0;
        !           657:        struct wordent *hp = &lex;
        !           658:        register struct wordent *wdp;
        !           659:        register int i = exclc;
        !           660: 
        !           661:        wdp = hp;
        !           662:        while (--i >= 0) {
        !           663:                register struct wordent *new = (struct wordent *) calloc(1, sizeof *wdp);
        !           664: 
        !           665:                new->prev = wdp;
        !           666:                new->next = hp;
        !           667:                wdp->next = new;
        !           668:                wdp = new;
        !           669:                en = en->next;
        !           670:                wdp->word = global || didsub == 0 ?
        !           671:                    subword(en->word, sc, &didsub) : savestr(en->word);
        !           672:        }
        !           673:        if (didsub == 0)
        !           674:                seterr("Modifier failed");
        !           675:        hp->prev = wdp;
        !           676:        return (&enthist(-1000, &lex, 0)->Hlex);
        !           677: }
        !           678: 
        !           679: char *
        !           680: subword(cp, type, adid)
        !           681:        char *cp;
        !           682:        int type;
        !           683:        bool *adid;
        !           684: {
        !           685:        char wbuf[BUFSIZ];
        !           686:        register char *wp, *mp, *np;
        !           687:        register int i;
        !           688: 
        !           689:        switch (type) {
        !           690: 
        !           691:        case 'r':
        !           692:        case 'e':
        !           693:        case 'h':
        !           694:        case 't':
        !           695:        case 'q':
        !           696:        case 'x':
        !           697:                wp = domod(cp, type);
        !           698:                if (wp == 0)
        !           699:                        return (savestr(cp));
        !           700:                *adid = 1;
        !           701:                return (wp);
        !           702: 
        !           703:        default:
        !           704:                wp = wbuf;
        !           705:                i = BUFSIZ - 4;
        !           706:                for (mp = cp; *mp; mp++)
        !           707:                        if (matchs(mp, lhsb)) {
        !           708:                                for (np = cp; np < mp;)
        !           709:                                        *wp++ = *np++, --i;
        !           710:                                for (np = rhsb; *np; np++) switch (*np) {
        !           711: 
        !           712:                                case '\\':
        !           713:                                        if (np[1] == '&')
        !           714:                                                np++;
        !           715:                                        /* fall into ... */
        !           716: 
        !           717:                                default:
        !           718:                                        if (--i < 0)
        !           719:                                                goto ovflo;
        !           720:                                        *wp++ = *np;
        !           721:                                        continue;
        !           722: 
        !           723:                                case '&':
        !           724:                                        i -= strlen(lhsb);
        !           725:                                        if (i < 0)
        !           726:                                                goto ovflo;
        !           727:                                        *wp = 0;
        !           728:                                        (void) strcat(wp, lhsb);
        !           729:                                        wp = strend(wp);
        !           730:                                        continue;
        !           731:                                }
        !           732:                                mp += strlen(lhsb);
        !           733:                                i -= strlen(mp);
        !           734:                                if (i < 0) {
        !           735: ovflo:
        !           736:                                        seterr("Subst buf ovflo");
        !           737:                                        return ("");
        !           738:                                }
        !           739:                                *wp = 0;
        !           740:                                (void) strcat(wp, mp);
        !           741:                                *adid = 1;
        !           742:                                return (savestr(wbuf));
        !           743:                        }
        !           744:                return (savestr(cp));
        !           745:        }
        !           746: }
        !           747: 
        !           748: char *
        !           749: domod(cp, type)
        !           750:        char *cp;
        !           751:        int type;
        !           752: {
        !           753:        register char *wp, *xp;
        !           754:        register int c;
        !           755: 
        !           756:        switch (type) {
        !           757: 
        !           758:        case 'x':
        !           759:        case 'q':
        !           760:                wp = savestr(cp);
        !           761:                for (xp = wp; c = *xp; xp++)
        !           762:                        if ((c != ' ' && c != '\t') || type == 'q')
        !           763:                                *xp |= QUOTE;
        !           764:                return (wp);
        !           765: 
        !           766:        case 'h':
        !           767:        case 't':
        !           768:                if (!any('/', cp))
        !           769:                        return (type == 't' ? savestr(cp) : 0);
        !           770:                wp = strend(cp);
        !           771:                while (*--wp != '/')
        !           772:                        continue;
        !           773:                if (type == 'h')
        !           774:                        xp = savestr(cp), xp[wp - cp] = 0;
        !           775:                else
        !           776:                        xp = savestr(wp + 1);
        !           777:                return (xp);
        !           778: 
        !           779:        case 'e':
        !           780:        case 'r':
        !           781:                wp = strend(cp);
        !           782:                for (wp--; wp >= cp && *wp != '/'; wp--)
        !           783:                        if (*wp == '.') {
        !           784:                                if (type == 'e')
        !           785:                                        xp = savestr(wp + 1);
        !           786:                                else
        !           787:                                        xp = savestr(cp), xp[wp - cp] = 0;
        !           788:                                return (xp);
        !           789:                        }
        !           790:                return (savestr(type == 'e' ? "" : cp));
        !           791:        }
        !           792:        return (0);
        !           793: }
        !           794: 
        !           795: matchs(str, pat)
        !           796:        register char *str, *pat;
        !           797: {
        !           798: 
        !           799:        while (*str && *pat && *str == *pat)
        !           800:                str++, pat++;
        !           801:        return (*pat == 0);
        !           802: }
        !           803: 
        !           804: getsel(al, ar, dol)
        !           805:        register int *al, *ar;
        !           806:        int dol;
        !           807: {
        !           808:        register int c = getC(0);
        !           809:        register int i;
        !           810:        bool first = *al < 0;
        !           811: 
        !           812:        switch (c) {
        !           813: 
        !           814:        case '%':
        !           815:                if (quesarg == -1)
        !           816:                        goto bad;
        !           817:                if (*al < 0)
        !           818:                        *al = quesarg;
        !           819:                *ar = quesarg;
        !           820:                break;
        !           821: 
        !           822:        case '-':
        !           823:                if (*al < 0) {
        !           824:                        *al = 0;
        !           825:                        *ar = dol - 1;
        !           826:                        unreadc(c);
        !           827:                }
        !           828:                return (1);
        !           829: 
        !           830:        case '^':
        !           831:                if (*al < 0)
        !           832:                        *al = 1;
        !           833:                *ar = 1;
        !           834:                break;
        !           835: 
        !           836:        case '$':
        !           837:                if (*al < 0)
        !           838:                        *al = dol;
        !           839:                *ar = dol;
        !           840:                break;
        !           841: 
        !           842:        case '*':
        !           843:                if (*al < 0)
        !           844:                        *al = 1;
        !           845:                *ar = dol;
        !           846:                if (*ar < *al) {
        !           847:                        *ar = 0;
        !           848:                        *al = 1;
        !           849:                        return (1);
        !           850:                }
        !           851:                break;
        !           852: 
        !           853:        default:
        !           854:                if (digit(c)) {
        !           855:                        i = 0;
        !           856:                        while (digit(c)) {
        !           857:                                i = i * 10 + c - '0';
        !           858:                                c = getC(0);
        !           859:                        }
        !           860:                        if (i < 0)
        !           861:                                i = dol + 1;
        !           862:                        if (*al < 0)
        !           863:                                *al = i;
        !           864:                        *ar = i;
        !           865:                } else
        !           866:                        if (*al < 0)
        !           867:                                *al = 0, *ar = dol;
        !           868:                        else
        !           869:                                *ar = dol - 1;
        !           870:                unreadc(c);
        !           871:                break;
        !           872:        }
        !           873:        if (first) {
        !           874:                c = getC(0);
        !           875:                unreadc(c);
        !           876:                if (any(c, "-$*"))
        !           877:                        return (1);
        !           878:        }
        !           879:        if (*al > *ar || *ar > dol) {
        !           880: bad:
        !           881:                seterr("Bad ! arg selector");
        !           882:                return (0);
        !           883:        }
        !           884:        return (1);
        !           885: 
        !           886: }
        !           887: 
        !           888: struct wordent *
        !           889: gethent(sc)
        !           890:        int sc;
        !           891: {
        !           892:        register struct Hist *hp;
        !           893:        register char *np;
        !           894:        register int c;
        !           895:        int event;
        !           896:        bool back = 0;
        !           897: 
        !           898:        c = sc == HISTSUB ? HIST : getC(0);
        !           899:        if (c == HIST) {
        !           900:                if (alhistp)
        !           901:                        return (alhistp);
        !           902:                event = eventno;
        !           903:                goto skip;
        !           904:        }
        !           905:        switch (c) {
        !           906: 
        !           907:        case ':':
        !           908:        case '^':
        !           909:        case '$':
        !           910:        case '*':
        !           911:        case '%':
        !           912:                ungetC(c);
        !           913:                if (lastev == eventno && alhistp)
        !           914:                        return (alhistp);
        !           915:                event = lastev;
        !           916:                break;
        !           917: 
        !           918:        case '-':
        !           919:                back = 1;
        !           920:                c = getC(0);
        !           921:                goto number;
        !           922: 
        !           923:        case '#':                       /* !# is command being typed in (mrh) */
        !           924:                return(&paraml);
        !           925: 
        !           926:        default:
        !           927:                if (any(c, "(=~")) {
        !           928:                        unreadc(c);
        !           929:                        ungetC(HIST);
        !           930:                        return (0);
        !           931:                }
        !           932:                if (digit(c))
        !           933:                        goto number;
        !           934:                np = lhsb;
        !           935:                while (!any(c, ": \t\\\n}")) {
        !           936:                        if (np < &lhsb[sizeof lhsb - 2])
        !           937:                                *np++ = c;
        !           938:                        c = getC(0);
        !           939:                }
        !           940:                unreadc(c);
        !           941:                if (np == lhsb) {
        !           942:                        ungetC(HIST);
        !           943:                        return (0);
        !           944:                }
        !           945:                *np++ = 0;
        !           946:                hp = findev(lhsb, 0);
        !           947:                if (hp)
        !           948:                        lastev = hp->Hnum;
        !           949:                return (&hp->Hlex);
        !           950: 
        !           951:        case '?':
        !           952:                np = lhsb;
        !           953:                for (;;) {
        !           954:                        c = getC(0);
        !           955:                        if (c == '\n') {
        !           956:                                unreadc(c);
        !           957:                                break;
        !           958:                        }
        !           959:                        if (c == '?')
        !           960:                                break;
        !           961:                        if (np < &lhsb[sizeof lhsb - 2])
        !           962:                                *np++ = c;
        !           963:                }
        !           964:                if (np == lhsb) {
        !           965:                        if (lhsb[0] == 0) {
        !           966:                                seterr("No prev search");
        !           967:                                return (0);
        !           968:                        }
        !           969:                } else
        !           970:                        *np++ = 0;
        !           971:                hp = findev(lhsb, 1);
        !           972:                if (hp)
        !           973:                        lastev = hp->Hnum;
        !           974:                return (&hp->Hlex);
        !           975: 
        !           976:        number:
        !           977:                event = 0;
        !           978:                while (digit(c)) {
        !           979:                        event = event * 10 + c - '0';
        !           980:                        c = getC(0);
        !           981:                }
        !           982:                if (back)
        !           983:                        event = eventno + (alhistp == 0) - (event ? event : 0);
        !           984:                unreadc(c);
        !           985:                break;
        !           986:        }
        !           987: skip:
        !           988:        for (hp = Histlist.Hnext; hp; hp = hp->Hnext)
        !           989:                if (hp->Hnum == event) {
        !           990:                        hp->Href = eventno;
        !           991:                        lastev = hp->Hnum;
        !           992:                        return (&hp->Hlex);
        !           993:                }
        !           994:        np = putn(event);
        !           995:        noev(np);
        !           996:        return (0);
        !           997: }
        !           998: 
        !           999: struct Hist *
        !          1000: findev(cp, anyarg)
        !          1001:        char *cp;
        !          1002:        bool anyarg;
        !          1003: {
        !          1004:        register struct Hist *hp;
        !          1005: 
        !          1006:        for (hp = Histlist.Hnext; hp; hp = hp->Hnext) {
        !          1007:                char *dp;
        !          1008:                register char *p, *q;
        !          1009:                register struct wordent *lp = hp->Hlex.next;
        !          1010:                int argno = 0;
        !          1011: 
        !          1012:                /*
        !          1013:                 * The entries added by alias substitution don't
        !          1014:                 * have a newline but do have a negative event number.
        !          1015:                 * Savehist() trims off these entries, but it happens
        !          1016:                 * before alias expansion, too early to delete those
        !          1017:                 * from the previous command.
        !          1018:                 */
        !          1019:                if (hp->Hnum < 0)
        !          1020:                        continue;
        !          1021:                if (lp->word[0] == '\n')
        !          1022:                        continue;
        !          1023:                if (!anyarg) {
        !          1024:                        p = cp;
        !          1025:                        q = lp->word;
        !          1026:                        do
        !          1027:                                if (!*p)
        !          1028:                                        return (hp);
        !          1029:                        while (*p++ == *q++);
        !          1030:                        continue;
        !          1031:                }
        !          1032:                do {
        !          1033:                        for (dp = lp->word; *dp; dp++) {
        !          1034:                                p = cp;
        !          1035:                                q = dp;
        !          1036:                                do
        !          1037:                                        if (!*p) {
        !          1038:                                                quesarg = argno;
        !          1039:                                                return (hp);
        !          1040:                                        }
        !          1041:                                while (*p++ == *q++);
        !          1042:                        }
        !          1043:                        lp = lp->next;
        !          1044:                        argno++;
        !          1045:                } while (lp->word[0] != '\n');
        !          1046:        }
        !          1047:        noev(cp);
        !          1048:        return (0);
        !          1049: }
        !          1050: 
        !          1051: noev(cp)
        !          1052:        char *cp;
        !          1053: {
        !          1054: 
        !          1055:        seterr2(cp, ": Event not found");
        !          1056: }
        !          1057: 
        !          1058: setexclp(cp)
        !          1059:        register char *cp;
        !          1060: {
        !          1061: 
        !          1062:        if (cp && cp[0] == '\n')
        !          1063:                return;
        !          1064:        exclp = cp;
        !          1065: }
        !          1066: 
        !          1067: unreadc(c)
        !          1068:        char c;
        !          1069: {
        !          1070: 
        !          1071:        peekread = c;
        !          1072: }
        !          1073: 
        !          1074: readc(wanteof)
        !          1075:        bool wanteof;
        !          1076: {
        !          1077:        register int c;
        !          1078:        static sincereal;
        !          1079: 
        !          1080:        if (c = peekread) {
        !          1081:                peekread = 0;
        !          1082:                return (c);
        !          1083:        }
        !          1084: top:
        !          1085:        if (alvecp) {
        !          1086:                if (c = *alvecp++)
        !          1087:                        return (c);
        !          1088:                if (*alvec) {
        !          1089:                        alvecp = *alvec++;
        !          1090:                        return (' ');
        !          1091:                }
        !          1092:        }
        !          1093:        if (alvec) {
        !          1094:                if (alvecp = *alvec) {
        !          1095:                        alvec++;
        !          1096:                        goto top;
        !          1097:                }
        !          1098:                /* Infinite source! */
        !          1099:                return ('\n');
        !          1100:        }
        !          1101:        if (evalp) {
        !          1102:                if (c = *evalp++)
        !          1103:                        return (c);
        !          1104:                if (*evalvec) {
        !          1105:                        evalp = *evalvec++;
        !          1106:                        return (' ');
        !          1107:                }
        !          1108:                evalp = 0;
        !          1109:        }
        !          1110:        if (evalvec) {
        !          1111:                if (evalvec == (char **)1) {
        !          1112:                        doneinp = 1;
        !          1113:                        reset();
        !          1114:                }
        !          1115:                if (evalp = *evalvec) {
        !          1116:                        evalvec++;
        !          1117:                        goto top;
        !          1118:                }
        !          1119:                evalvec = (char **)1;
        !          1120:                return ('\n');
        !          1121:        }
        !          1122:        do {
        !          1123:                if (arginp == (char *) 1 || onelflg == 1) {
        !          1124:                        if (wanteof)
        !          1125:                                return (-1);
        !          1126:                        exitstat();
        !          1127:                }
        !          1128:                if (arginp) {
        !          1129:                        if ((c = *arginp++) == 0) {
        !          1130:                                arginp = (char *) 1;
        !          1131:                                return ('\n');
        !          1132:                        }
        !          1133:                        return (c);
        !          1134:                }
        !          1135: reread:
        !          1136:                c = bgetc();
        !          1137:                if (c < 0) {
        !          1138:                        struct sgttyb tty;
        !          1139: 
        !          1140:                        if (wanteof)
        !          1141:                                return (-1);
        !          1142:                        /* was isatty but raw with ignoreeof yields problems */
        !          1143:                        if (ioctl(SHIN, TIOCGETP, (char *)&tty) == 0 &&
        !          1144:                            (tty.sg_flags & RAW) == 0) {
        !          1145:                                /* was 'short' for FILEC */
        !          1146:                                int ctpgrp;
        !          1147: 
        !          1148:                                if (++sincereal > 25)
        !          1149:                                        goto oops;
        !          1150:                                if (tpgrp != -1 &&
        !          1151:                                    ioctl(FSHTTY, TIOCGPGRP, (char *)&ctpgrp) == 0 &&
        !          1152:                                    tpgrp != ctpgrp) {
        !          1153:                                        (void) ioctl(FSHTTY, TIOCSPGRP,
        !          1154:                                                (char *)&tpgrp);
        !          1155:                                        (void) killpg(ctpgrp, SIGHUP);
        !          1156: printf("Reset tty pgrp from %d to %d\n", ctpgrp, tpgrp);
        !          1157:                                        goto reread;
        !          1158:                                }
        !          1159:                                if (adrof("ignoreeof")) {
        !          1160:                                        if (loginsh)
        !          1161:                                                printf("\nUse \"logout\" to logout.\n");
        !          1162:                                        else
        !          1163:                                                printf("\nUse \"exit\" to leave csh.\n");
        !          1164:                                        reset();
        !          1165:                                }
        !          1166:                                if (chkstop == 0)
        !          1167:                                        panystop(1);
        !          1168:                        }
        !          1169: oops:
        !          1170:                        doneinp = 1;
        !          1171:                        reset();
        !          1172:                }
        !          1173:                sincereal = 0;
        !          1174:                if (c == '\n' && onelflg)
        !          1175:                        onelflg--;
        !          1176:        } while (c == 0);
        !          1177:        return (c);
        !          1178: }
        !          1179: 
        !          1180: bgetc()
        !          1181: {
        !          1182:        register int buf, off, c;
        !          1183: #ifdef FILEC
        !          1184:        char ttyline[BUFSIZ];
        !          1185:        register int numleft = 0, roomleft;
        !          1186: #endif
        !          1187: 
        !          1188: #ifdef TELL
        !          1189:        if (cantell) {
        !          1190:                if (fseekp < fbobp || fseekp > feobp) {
        !          1191:                        fbobp = feobp = fseekp;
        !          1192:                        (void) lseek(SHIN, fseekp, 0);
        !          1193:                }
        !          1194:                if (fseekp == feobp) {
        !          1195:                        fbobp = feobp;
        !          1196:                        do
        !          1197:                                c = read(SHIN, fbuf[0], BUFSIZ);
        !          1198:                        while (c < 0 && errno == EINTR);
        !          1199:                        if (c <= 0)
        !          1200:                                return (-1);
        !          1201:                        feobp += c;
        !          1202:                }
        !          1203:                c = fbuf[0][fseekp - fbobp];
        !          1204:                fseekp++;
        !          1205:                return (c);
        !          1206:        }
        !          1207: #endif
        !          1208: again:
        !          1209:        buf = (int) fseekp / BUFSIZ;
        !          1210:        if (buf >= fblocks) {
        !          1211:                register char **nfbuf =
        !          1212:                        (char **) calloc((unsigned) (fblocks + 2),
        !          1213:                                sizeof (char **));
        !          1214: 
        !          1215:                if (fbuf) {
        !          1216:                        (void) blkcpy(nfbuf, fbuf);
        !          1217:                        xfree((char *)fbuf);
        !          1218:                }
        !          1219:                fbuf = nfbuf;
        !          1220:                fbuf[fblocks] = calloc(BUFSIZ, sizeof (char));
        !          1221:                fblocks++;
        !          1222:                goto again;
        !          1223:        }
        !          1224:        if (fseekp >= feobp) {
        !          1225:                buf = (int) feobp / BUFSIZ;
        !          1226:                off = (int) feobp % BUFSIZ;
        !          1227: #ifndef FILEC
        !          1228:                for (;;) {
        !          1229:                        c = read(SHIN, fbuf[buf] + off, BUFSIZ - off);
        !          1230: #else
        !          1231:                roomleft = BUFSIZ - off;
        !          1232:                for (;;) {
        !          1233:                        if (filec && intty) {
        !          1234:                                c = numleft ? numleft : tenex(ttyline, BUFSIZ);
        !          1235:                                if (c > roomleft) {
        !          1236:                                        /* start with fresh buffer */
        !          1237:                                        feobp = fseekp = fblocks * BUFSIZ;
        !          1238:                                        numleft = c;
        !          1239:                                        goto again;
        !          1240:                                }
        !          1241:                                if (c > 0)
        !          1242:                                        copy(fbuf[buf] + off, ttyline, c);
        !          1243:                                numleft = 0;
        !          1244:                        } else
        !          1245:                                c = read(SHIN, fbuf[buf] + off, roomleft);
        !          1246: #endif
        !          1247:                        if (c >= 0)
        !          1248:                                break;
        !          1249:                        if (errno == EWOULDBLOCK) {
        !          1250:                                int off = 0;
        !          1251: 
        !          1252:                                (void) ioctl(SHIN, FIONBIO, (char *)&off);
        !          1253:                        } else if (errno != EINTR)
        !          1254:                                break;
        !          1255:                }
        !          1256:                if (c <= 0)
        !          1257:                        return (-1);
        !          1258:                feobp += c;
        !          1259: #ifndef FILEC
        !          1260:                goto again;
        !          1261: #else
        !          1262:                if (filec && !intty)
        !          1263:                        goto again;
        !          1264: #endif
        !          1265:        }
        !          1266:        c = fbuf[buf][(int) fseekp % BUFSIZ];
        !          1267:        fseekp++;
        !          1268:        return (c);
        !          1269: }
        !          1270: 
        !          1271: bfree()
        !          1272: {
        !          1273:        register int sb, i;
        !          1274: 
        !          1275: #ifdef TELL
        !          1276:        if (cantell)
        !          1277:                return;
        !          1278: #endif
        !          1279:        if (whyles)
        !          1280:                return;
        !          1281:        sb = (int) (fseekp - 1) / BUFSIZ;
        !          1282:        if (sb > 0) {
        !          1283:                for (i = 0; i < sb; i++)
        !          1284:                        xfree(fbuf[i]);
        !          1285:                (void) blkcpy(fbuf, &fbuf[sb]);
        !          1286:                fseekp -= BUFSIZ * sb;
        !          1287:                feobp -= BUFSIZ * sb;
        !          1288:                fblocks -= sb;
        !          1289:        }
        !          1290: }
        !          1291: 
        !          1292: bseek(l)
        !          1293:        off_t l;
        !          1294: {
        !          1295:        register struct whyle *wp;
        !          1296: 
        !          1297:        fseekp = l;
        !          1298: #ifdef TELL
        !          1299:        if (!cantell) {
        !          1300: #endif
        !          1301:                if (!whyles)
        !          1302:                        return;
        !          1303:                for (wp = whyles; wp->w_next; wp = wp->w_next)
        !          1304:                        continue;
        !          1305:                if (wp->w_start > l)
        !          1306:                        l = wp->w_start;
        !          1307: #ifdef TELL
        !          1308:        }
        !          1309: #endif
        !          1310: }
        !          1311: 
        !          1312: /* any similarity to bell telephone is purely accidental */
        !          1313: #ifndef btell
        !          1314: off_t
        !          1315: btell()
        !          1316: {
        !          1317: 
        !          1318:        return (fseekp);
        !          1319: }
        !          1320: #endif
        !          1321: 
        !          1322: btoeof()
        !          1323: {
        !          1324: 
        !          1325:        (void) lseek(SHIN, (off_t)0, 2);
        !          1326:        fseekp = feobp;
        !          1327:        wfree();
        !          1328:        bfree();
        !          1329: }
        !          1330: 
        !          1331: #ifdef TELL
        !          1332: settell()
        !          1333: {
        !          1334: 
        !          1335:        cantell = 0;
        !          1336:        if (arginp || onelflg || intty)
        !          1337:                return;
        !          1338:        if (lseek(SHIN, (off_t)0, 1) < 0 || errno == ESPIPE)
        !          1339:                return;
        !          1340:        fbuf = (char **) calloc(2, sizeof (char **));
        !          1341:        fblocks = 1;
        !          1342:        fbuf[0] = calloc(BUFSIZ, sizeof (char));
        !          1343:        fseekp = fbobp = feobp = lseek(SHIN, (off_t)0, 1);
        !          1344:        cantell = 1;
        !          1345: }
        !          1346: #endif

unix.superglobalmegacorp.com

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