Annotation of 40BSD/cmd/oldcsh/sh.lex.c, revision 1.1

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

unix.superglobalmegacorp.com

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