Annotation of 43BSDTahoe/bin/csh/sh.set.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.set.c    5.3 (Berkeley) 5/19/88";
                      9: #endif
                     10: 
                     11: #include "sh.h"
                     12: 
                     13: /*
                     14:  * C Shell
                     15:  */
                     16: 
                     17: doset(v)
                     18:        register char **v;
                     19: {
                     20:        register char *p;
                     21:        char *vp, op;
                     22:        char **vecp;
                     23:        bool hadsub;
                     24:        int subscr;
                     25: 
                     26:        v++;
                     27:        p = *v++;
                     28:        if (p == 0) {
                     29:                prvars();
                     30:                return;
                     31:        }
                     32:        do {
                     33:                hadsub = 0;
                     34:                for (vp = p; alnum(*p); p++)
                     35:                        continue;
                     36:                if (vp == p || !letter(*vp))
                     37:                        goto setsyn;
                     38:                if (*p == '[') {
                     39:                        hadsub++;
                     40:                        p = getinx(p, &subscr);
                     41:                }
                     42:                if (op = *p) {
                     43:                        *p++ = 0;
                     44:                        if (*p == 0 && *v && **v == '(')
                     45:                                p = *v++;
                     46:                } else if (*v && eq(*v, "=")) {
                     47:                        op = '=', v++;
                     48:                        if (*v)
                     49:                                p = *v++;
                     50:                }
                     51:                if (op && op != '=')
                     52: setsyn:
                     53:                        bferr("Syntax error");
                     54:                if (eq(p, "(")) {
                     55:                        register char **e = v;
                     56: 
                     57:                        if (hadsub)
                     58:                                goto setsyn;
                     59:                        for (;;) {
                     60:                                if (!*e)
                     61:                                        bferr("Missing )");
                     62:                                if (**e == ')')
                     63:                                        break;
                     64:                                e++;
                     65:                        }
                     66:                        p = *e;
                     67:                        *e = 0;
                     68:                        vecp = saveblk(v);
                     69:                        set1(vp, vecp, &shvhed);
                     70:                        *e = p;
                     71:                        v = e + 1;
                     72:                } else if (hadsub)
                     73:                        asx(vp, subscr, savestr(p));
                     74:                else
                     75:                        set(vp, savestr(p));
                     76:                if (eq(vp, "path")) {
                     77:                        exportpath(adrof("path")->vec);
                     78:                        dohash();
                     79:                } else if (eq(vp, "histchars")) {
                     80:                        register char *p = value("histchars");
                     81: 
                     82:                        HIST = *p++;
                     83:                        HISTSUB = *p;
                     84:                } else if (eq(vp, "user"))
                     85:                        setenv("USER", value(vp));
                     86:                else if (eq(vp, "term"))
                     87:                        setenv("TERM", value(vp));
                     88:                else if (eq(vp, "home"))
                     89:                        setenv("HOME", value(vp));
                     90: #ifdef FILEC
                     91:                else if (eq(vp, "filec"))
                     92:                        filec = 1;
                     93: #endif
                     94:        } while (p = *v++);
                     95: }
                     96: 
                     97: char *
                     98: getinx(cp, ip)
                     99:        register char *cp;
                    100:        register int *ip;
                    101: {
                    102: 
                    103:        *ip = 0;
                    104:        *cp++ = 0;
                    105:        while (*cp && digit(*cp))
                    106:                *ip = *ip * 10 + *cp++ - '0';
                    107:        if (*cp++ != ']')
                    108:                bferr("Subscript error");
                    109:        return (cp);
                    110: }
                    111: 
                    112: asx(vp, subscr, p)
                    113:        char *vp;
                    114:        int subscr;
                    115:        char *p;
                    116: {
                    117:        register struct varent *v = getvx(vp, subscr);
                    118: 
                    119:        xfree(v->vec[subscr - 1]);
                    120:        v->vec[subscr - 1] = globone(p);
                    121: }
                    122: 
                    123: struct varent *
                    124: getvx(vp, subscr)
                    125:        char *vp;
                    126: {
                    127:        register struct varent *v = adrof(vp);
                    128: 
                    129:        if (v == 0)
                    130:                udvar(vp);
                    131:        if (subscr < 1 || subscr > blklen(v->vec))
                    132:                bferr("Subscript out of range");
                    133:        return (v);
                    134: }
                    135: 
                    136: char   plusplus[2] = { '1', 0 };
                    137: 
                    138: dolet(v)
                    139:        char **v;
                    140: {
                    141:        register char *p;
                    142:        char *vp, c, op;
                    143:        bool hadsub;
                    144:        int subscr;
                    145: 
                    146:        v++;
                    147:        p = *v++;
                    148:        if (p == 0) {
                    149:                prvars();
                    150:                return;
                    151:        }
                    152:        do {
                    153:                hadsub = 0;
                    154:                for (vp = p; alnum(*p); p++)
                    155:                        continue;
                    156:                if (vp == p || !letter(*vp))
                    157:                        goto letsyn;
                    158:                if (*p == '[') {
                    159:                        hadsub++;
                    160:                        p = getinx(p, &subscr);
                    161:                }
                    162:                if (*p == 0 && *v)
                    163:                        p = *v++;
                    164:                if (op = *p)
                    165:                        *p++ = 0;
                    166:                else
                    167:                        goto letsyn;
                    168:                vp = savestr(vp);
                    169:                if (op == '=') {
                    170:                        c = '=';
                    171:                        p = xset(p, &v);
                    172:                } else {
                    173:                        c = *p++;
                    174:                        if (any(c, "+-")) {
                    175:                                if (c != op || *p)
                    176:                                        goto letsyn;
                    177:                                p = plusplus;
                    178:                        } else {
                    179:                                if (any(op, "<>")) {
                    180:                                        if (c != op)
                    181:                                                goto letsyn;
                    182:                                        c = *p++;
                    183: letsyn:
                    184:                                        bferr("Syntax error");
                    185:                                }
                    186:                                if (c != '=')
                    187:                                        goto letsyn;
                    188:                                p = xset(p, &v);
                    189:                        }
                    190:                }
                    191:                if (op == '=')
                    192:                        if (hadsub)
                    193:                                asx(vp, subscr, p);
                    194:                        else
                    195:                                set(vp, p);
                    196:                else
                    197:                        if (hadsub)
                    198: #ifndef V6
                    199:                                /* avoid bug in vax CC */
                    200:                                {
                    201:                                        struct varent *gv = getvx(vp, subscr);
                    202: 
                    203:                                        asx(vp, subscr, operate(op, gv->vec[subscr - 1], p));
                    204:                                }
                    205: #else
                    206:                                asx(vp, subscr, operate(op, getvx(vp, subscr)->vec[subscr - 1], p));
                    207: #endif
                    208:                        else
                    209:                                set(vp, operate(op, value(vp), p));
                    210:                if (eq(vp, "path")) {
                    211:                        exportpath(adrof("path")->vec);
                    212:                        dohash();
                    213:                }
                    214:                XFREE(vp)
                    215:                if (c != '=')
                    216:                        XFREE(p)
                    217:        } while (p = *v++);
                    218: }
                    219: 
                    220: char *
                    221: xset(cp, vp)
                    222:        char *cp, ***vp;
                    223: {
                    224:        register char *dp;
                    225: 
                    226:        if (*cp) {
                    227:                dp = savestr(cp);
                    228:                --(*vp);
                    229:                xfree(**vp);
                    230:                **vp = dp;
                    231:        }
                    232:        return (putn(exp(vp)));
                    233: }
                    234: 
                    235: char *
                    236: operate(op, vp, p)
                    237:        char op, *vp, *p;
                    238: {
                    239:        char opr[2];
                    240:        char *vec[5];
                    241:        register char **v = vec;
                    242:        char **vecp = v;
                    243:        register int i;
                    244: 
                    245:        if (op != '=') {
                    246:                if (*vp)
                    247:                        *v++ = vp;
                    248:                opr[0] = op;
                    249:                opr[1] = 0;
                    250:                *v++ = opr;
                    251:                if (op == '<' || op == '>')
                    252:                        *v++ = opr;
                    253:        }
                    254:        *v++ = p;
                    255:        *v++ = 0;
                    256:        i = exp(&vecp);
                    257:        if (*vecp)
                    258:                bferr("Expression syntax");
                    259:        return (putn(i));
                    260: }
                    261: 
                    262: static char *putp;
                    263:  
                    264: char *
                    265: putn(n)
                    266:        register int n;
                    267: {
                    268:        static char number[15];
                    269: 
                    270:        putp = number;
                    271:        if (n < 0) {
                    272:                n = -n;
                    273:                *putp++ = '-';
                    274:        }
                    275:        if (sizeof (int) == 2 && n == -32768) {
                    276:                *putp++ = '3';
                    277:                n = 2768;
                    278: #ifdef pdp11
                    279:        }
                    280: #else
                    281:        } else if (sizeof (int) == 4 && n == -2147483648) {
                    282:                *putp++ = '2';
                    283:                n = 147483648;
                    284:        }
                    285: #endif
                    286:        putn1(n);
                    287:        *putp = 0;
                    288:        return (savestr(number));
                    289: }
                    290: 
                    291: putn1(n)
                    292:        register int n;
                    293: {
                    294:        if (n > 9)
                    295:                putn1(n / 10);
                    296:        *putp++ = n % 10 + '0';
                    297: }
                    298: 
                    299: getn(cp)
                    300:        register char *cp;
                    301: {
                    302:        register int n;
                    303:        int sign;
                    304: 
                    305:        sign = 0;
                    306:        if (cp[0] == '+' && cp[1])
                    307:                cp++;
                    308:        if (*cp == '-') {
                    309:                sign++;
                    310:                cp++;
                    311:                if (!digit(*cp))
                    312:                        goto badnum;
                    313:        }
                    314:        n = 0;
                    315:        while (digit(*cp))
                    316:                n = n * 10 + *cp++ - '0';
                    317:        if (*cp)
                    318:                goto badnum;
                    319:        return (sign ? -n : n);
                    320: badnum:
                    321:        bferr("Badly formed number");
                    322:        return (0);
                    323: }
                    324: 
                    325: char *
                    326: value1(var, head)
                    327:        char *var;
                    328:        struct varent *head;
                    329: {
                    330:        register struct varent *vp;
                    331: 
                    332:        vp = adrof1(var, head);
                    333:        return (vp == 0 || vp->vec[0] == 0 ? "" : vp->vec[0]);
                    334: }
                    335: 
                    336: struct varent *
                    337: madrof(pat, vp)
                    338:        char *pat;
                    339:        register struct varent *vp;
                    340: {
                    341:        register struct varent *vp1;
                    342: 
                    343:        for (; vp; vp = vp->v_right) {
                    344:                if (vp->v_left && (vp1 = madrof(pat, vp->v_left)))
                    345:                        return vp1;
                    346:                if (Gmatch(vp->v_name, pat))
                    347:                        return vp;
                    348:        }
                    349:        return vp;
                    350: }
                    351: 
                    352: struct varent *
                    353: adrof1(name, v)
                    354:        register char *name;
                    355:        register struct varent *v;
                    356: {
                    357:        register cmp;
                    358: 
                    359:        v = v->v_left;
                    360:        while (v && ((cmp = *name - *v->v_name) ||
                    361:                     (cmp = strcmp(name, v->v_name))))
                    362:                if (cmp < 0)
                    363:                        v = v->v_left;
                    364:                else
                    365:                        v = v->v_right;
                    366:        return v;
                    367: }
                    368: 
                    369: /*
                    370:  * The caller is responsible for putting value in a safe place
                    371:  */
                    372: set(var, val)
                    373:        char *var, *val;
                    374: {
                    375:        register char **vec = (char **) xalloc(2 * sizeof (char **));
                    376: 
                    377:        vec[0] = onlyread(val) ? savestr(val) : val;
                    378:        vec[1] = 0;
                    379:        set1(var, vec, &shvhed);
                    380: }
                    381: 
                    382: set1(var, vec, head)
                    383:        char *var, **vec;
                    384:        struct varent *head;
                    385: {
                    386:        register char **oldv = vec;
                    387: 
                    388:        gflag = 0; tglob(oldv);
                    389:        if (gflag) {
                    390:                vec = glob(oldv);
                    391:                if (vec == 0) {
                    392:                        bferr("No match");
                    393:                        blkfree(oldv);
                    394:                        return;
                    395:                }
                    396:                blkfree(oldv);
                    397:                gargv = 0;
                    398:        }
                    399:        setq(var, vec, head);
                    400: }
                    401: 
                    402: setq(name, vec, p)
                    403:        char *name, **vec;
                    404:        register struct varent *p;
                    405: {
                    406:        register struct varent *c;
                    407:        register f;
                    408: 
                    409:        f = 0;                  /* tree hangs off the header's left link */
                    410:        while (c = p->v_link[f]) {
                    411:                if ((f = *name - *c->v_name) == 0 &&
                    412:                    (f = strcmp(name, c->v_name)) == 0) {
                    413:                        blkfree(c->vec);
                    414:                        goto found;
                    415:                }
                    416:                p = c;
                    417:                f = f > 0;
                    418:        }
                    419:        p->v_link[f] = c = (struct varent *)xalloc(sizeof (struct varent));
                    420:        c->v_name = savestr(name);
                    421:        c->v_bal = 0;
                    422:        c->v_left = c->v_right = 0;
                    423:        c->v_parent = p;
                    424:        balance(p, f, 0);
                    425: found:
                    426:        trim(c->vec = vec);
                    427: }
                    428: 
                    429: unset(v)
                    430:        char *v[];
                    431: {
                    432: 
                    433:        unset1(v, &shvhed);
                    434:        if (adrof("histchars") == 0) {
                    435:                HIST = '!';
                    436:                HISTSUB = '^';
                    437:        }
                    438: #ifdef FILEC
                    439:        if (adrof("filec") == 0)
                    440:                filec = 0;
                    441: #endif
                    442: }
                    443: 
                    444: unset1(v, head)
                    445:        register char *v[];
                    446:        struct varent *head;
                    447: {
                    448:        register struct varent *vp;
                    449:        register int cnt;
                    450: 
                    451:        while (*++v) {
                    452:                cnt = 0;
                    453:                while (vp = madrof(*v, head->v_left))
                    454:                        unsetv1(vp), cnt++;
                    455:                if (cnt == 0)
                    456:                        setname(*v);
                    457:        }
                    458: }
                    459: 
                    460: unsetv(var)
                    461:        char *var;
                    462: {
                    463:        register struct varent *vp;
                    464: 
                    465:        if ((vp = adrof1(var, &shvhed)) == 0)
                    466:                udvar(var);
                    467:        unsetv1(vp);
                    468: }
                    469: 
                    470: unsetv1(p)
                    471:        register struct varent *p;
                    472: {
                    473:        register struct varent *c, *pp;
                    474:        register f;
                    475: 
                    476:        /*
                    477:         * Free associated memory first to avoid complications.
                    478:         */
                    479:        blkfree(p->vec);
                    480:        XFREE(p->v_name);
                    481:        /*
                    482:         * If p is missing one child, then we can move the other
                    483:         * into where p is.  Otherwise, we find the predecessor
                    484:         * of p, which is guaranteed to have no right child, copy
                    485:         * it into p, and move it's left child into it.
                    486:         */
                    487:        if (p->v_right == 0)
                    488:                c = p->v_left;
                    489:        else if (p->v_left == 0)
                    490:                c = p->v_right;
                    491:        else {
                    492:                for (c = p->v_left; c->v_right; c = c->v_right)
                    493:                        ;
                    494:                p->v_name = c->v_name;
                    495:                p->vec = c->vec;
                    496:                p = c;
                    497:                c = p->v_left;
                    498:        }
                    499:        /*
                    500:         * Move c into where p is.
                    501:         */
                    502:        pp = p->v_parent;
                    503:        f = pp->v_right == p;
                    504:        if (pp->v_link[f] = c)
                    505:                c->v_parent = pp;
                    506:        /*
                    507:         * Free the deleted node, and rebalance.
                    508:         */
                    509:        XFREE((char *)p);
                    510:        balance(pp, f, 1);
                    511: }
                    512: 
                    513: setNS(cp)
                    514:        char *cp;
                    515: {
                    516: 
                    517:        set(cp, "");
                    518: }
                    519: 
                    520: shift(v)
                    521:        register char **v;
                    522: {
                    523:        register struct varent *argv;
                    524:        register char *name;
                    525: 
                    526:        v++;
                    527:        name = *v;
                    528:        if (name == 0)
                    529:                name = "argv";
                    530:        else
                    531:                (void) strip(name);
                    532:        argv = adrof(name);
                    533:        if (argv == 0)
                    534:                udvar(name);
                    535:        if (argv->vec[0] == 0)
                    536:                bferr("No more words");
                    537:        lshift(argv->vec, 1);
                    538: }
                    539: 
                    540: exportpath(val)
                    541: char **val;
                    542: {
                    543:        char exppath[BUFSIZ];
                    544: 
                    545:        exppath[0] = 0;
                    546:        if (val)
                    547:                while (*val) {
                    548:                        if (strlen(*val) + strlen(exppath) + 2 > BUFSIZ) {
                    549:                                printf("Warning: ridiculously long PATH truncated\n");
                    550:                                break;
                    551:                        }
                    552:                        (void) strcat(exppath, *val++);
                    553:                        if (*val == 0 || eq(*val, ")"))
                    554:                                break;
                    555:                        (void) strcat(exppath, ":");
                    556:                }
                    557:        setenv("PATH", exppath);
                    558: }
                    559: 
                    560:        /* macros to do single rotations on node p */
                    561: #define rright(p) (\
                    562:        t = (p)->v_left,\
                    563:        (t)->v_parent = (p)->v_parent,\
                    564:        ((p)->v_left = t->v_right) ? (t->v_right->v_parent = (p)) : 0,\
                    565:        (t->v_right = (p))->v_parent = t,\
                    566:        (p) = t)
                    567: #define rleft(p) (\
                    568:        t = (p)->v_right,\
                    569:        (t)->v_parent = (p)->v_parent,\
                    570:        ((p)->v_right = t->v_left) ? (t->v_left->v_parent = (p)) : 0,\
                    571:        (t->v_left = (p))->v_parent = t,\
                    572:        (p) = t)
                    573: 
                    574: /*
                    575:  * Rebalance a tree, starting at p and up.
                    576:  * F == 0 means we've come from p's left child.
                    577:  * D == 1 means we've just done a delete, otherwise an insert.
                    578:  */
                    579: balance(p, f, d)
                    580:        register struct varent *p;
                    581:        register f;
                    582: {
                    583:        register struct varent *pp;
                    584:        register struct varent *t;              /* used by the rotate macros */
                    585:        register ff;
                    586: 
                    587:        /*
                    588:         * Ok, from here on, p is the node we're operating on;
                    589:         * pp is it's parent; f is the branch of p from which we have come;
                    590:         * ff is the branch of pp which is p.
                    591:         */
                    592:        for (; pp = p->v_parent; p = pp, f = ff) {
                    593:                ff = pp->v_right == p;
                    594:                if (f ^ d) {            /* right heavy */
                    595:                        switch (p->v_bal) {
                    596:                        case -1:                /* was left heavy */
                    597:                                p->v_bal = 0;
                    598:                                break;
                    599:                        case 0:                 /* was balanced */
                    600:                                p->v_bal = 1;
                    601:                                break;
                    602:                        case 1:                 /* was already right heavy */
                    603:                                switch (p->v_right->v_bal) {
                    604:                                case 1:                 /* sigle rotate */
                    605:                                        pp->v_link[ff] = rleft(p);
                    606:                                        p->v_left->v_bal = 0;
                    607:                                        p->v_bal = 0;
                    608:                                        break;
                    609:                                case 0:                 /* single rotate */
                    610:                                        pp->v_link[ff] = rleft(p);
                    611:                                        p->v_left->v_bal = 1;
                    612:                                        p->v_bal = -1;
                    613:                                        break;
                    614:                                case -1:                /* double rotate */
                    615:                                        rright(p->v_right);
                    616:                                        pp->v_link[ff] = rleft(p);
                    617:                                        p->v_left->v_bal =
                    618:                                                p->v_bal < 1 ? 0 : -1;
                    619:                                        p->v_right->v_bal =
                    620:                                                p->v_bal > -1 ? 0 : 1;
                    621:                                        p->v_bal = 0;
                    622:                                        break;
                    623:                                }
                    624:                                break;
                    625:                        }
                    626:                } else {                /* left heavy */
                    627:                        switch (p->v_bal) {
                    628:                        case 1:                 /* was right heavy */
                    629:                                p->v_bal = 0;
                    630:                                break;
                    631:                        case 0:                 /* was balanced */
                    632:                                p->v_bal = -1;
                    633:                                break;
                    634:                        case -1:                /* was already left heavy */
                    635:                                switch (p->v_left->v_bal) {
                    636:                                case -1:                /* single rotate */
                    637:                                        pp->v_link[ff] = rright(p);
                    638:                                        p->v_right->v_bal = 0;
                    639:                                        p->v_bal = 0;
                    640:                                        break;
                    641:                                case 0:                 /* signle rotate */
                    642:                                        pp->v_link[ff] = rright(p);
                    643:                                        p->v_right->v_bal = -1;
                    644:                                        p->v_bal = 1;
                    645:                                        break;
                    646:                                case 1:                 /* double rotate */
                    647:                                        rleft(p->v_left);
                    648:                                        pp->v_link[ff] = rright(p);
                    649:                                        p->v_left->v_bal =
                    650:                                                p->v_bal < 1 ? 0 : -1;
                    651:                                        p->v_right->v_bal =
                    652:                                                p->v_bal > -1 ? 0 : 1;
                    653:                                        p->v_bal = 0;
                    654:                                        break;
                    655:                                }
                    656:                                break;
                    657:                        }
                    658:                }
                    659:                /*
                    660:                 * If from insert, then we terminate when p is balanced.
                    661:                 * If from delete, then we terminate when p is unbalanced.
                    662:                 */
                    663:                if ((p->v_bal == 0) ^ d)
                    664:                        break;
                    665:        }
                    666: }
                    667: 
                    668: plist(p)
                    669:        register struct varent *p;
                    670: {
                    671:        register struct varent *c;
                    672:        register len;
                    673: 
                    674:        if (setintr)
                    675:                (void) sigsetmask(sigblock(0) & ~ sigmask(SIGINT));
                    676:        for (;;) {
                    677:                while (p->v_left)
                    678:                        p = p->v_left;
                    679:        x:
                    680:                if (p->v_parent == 0)           /* is it the header? */
                    681:                        return;
                    682:                len = blklen(p->vec);
                    683:                printf(p->v_name);
                    684:                cshputchar('\t');
                    685:                if (len != 1)
                    686:                        cshputchar('(');
                    687:                blkpr(p->vec);
                    688:                if (len != 1)
                    689:                        cshputchar(')');
                    690:                cshputchar('\n');
                    691:                if (p->v_right) {
                    692:                        p = p->v_right;
                    693:                        continue;
                    694:                }
                    695:                do {
                    696:                        c = p;
                    697:                        p = p->v_parent;
                    698:                } while (p->v_right == c);
                    699:                goto x;
                    700:        }
                    701: }

unix.superglobalmegacorp.com

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