Annotation of 43BSD/bin/csh/sh.lex.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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