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

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

unix.superglobalmegacorp.com

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