Annotation of 42BSD/bin/csh/sh.lex.c, revision 1.1

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

unix.superglobalmegacorp.com

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