# 2.11BSD#431 - /usr/src/bin/tcsh/sh.set.c

##### Functions

    adrof1            X
    dolet             X
    doset             X
    getn              X
    plist             X
    putn              X
    rleft             X
    rright            X
    set               X
    set1              X
    setNS             X
    setq              X
    shift             X
    unset             X
    unset1            X
    unsetv            X
    value1            X

##### Macros

    rleft             X
    rright            X

       1: /* $Header: /home/hyperion/mu/christos/src/sys/tcsh-6.00/RCS/sh.set.c,v 3.0 1991/07/04 21:49:28 christos Exp $ */
       2: /*
       3:  * sh.set.c: Setting and Clearing of variables
       4:  */
       5: /*-
       6:  * Copyright (c) 1980, 1991 The Regents of the University of California.
       7:  * All rights reserved.
       8:  *
       9:  * Redistribution and use in source and binary forms, with or without
      10:  * modification, are permitted provided that the following conditions
      11:  * are met:
      12:  * 1. Redistributions of source code must retain the above copyright
      13:  *    notice, this list of conditions and the following disclaimer.
      14:  * 2. Redistributions in binary form must reproduce the above copyright
      15:  *    notice, this list of conditions and the following disclaimer in the
      16:  *    documentation and/or other materials provided with the distribution.
      17:  * 3. All advertising materials mentioning features or use of this software
      18:  *    must display the following acknowledgement:
      19:  *	This product includes software developed by the University of
      20:  *	California, Berkeley and its contributors.
      21:  * 4. Neither the name of the University nor the names of its contributors
      22:  *    may be used to endorse or promote products derived from this software
      23:  *    without specific prior written permission.
      24:  *
      25:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      26:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      27:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      28:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      29:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      30:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      31:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      32:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      33:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      34:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      35:  * SUCH DAMAGE.
      36:  */
      37: #include "config.h"
      38: #if !defined(lint) && !defined(pdp11)
      39: static char *rcsid()
      40:     { return "$Id: sh.set.c,v 3.0 1991/07/04 21:49:28 christos Exp $"; }
      41: #endif
      42:
      43: #include "sh.h"
      44: #include "ed.h"
      45: #include "tw.h"
      46:
      47: extern Char HistLit;
      48: extern bool GotTermCaps;
      49:
      50: static  Char        *getinx     __P((Char *, int *));
      51: static  void         asx        __P((Char *, int, Char *));
      52: static  struct varent   *getvx      __P((Char *, int));
      53: static  Char        *xset       __P((Char *, Char ***));
      54: static  Char        *operate    __P((int, Char *, Char *));
      55: static  void         putn1      __P((int));
      56: static  struct varent   *madrof     __P((Char *, struct varent *));
      57: static  void         unsetv1    __P((struct varent *));
      58: static  void         exportpath __P((Char **));
      59: static  void         balance    __P((struct varent *, int, int));
      60:
      61: /*
      62:  * C Shell
      63:  */
      64:
      65: void
      66: doset(v)
      67:     register Char **v;
      68: {
      69:     register Char *p;
      70:     Char   *vp, op;
      71:     Char  **vecp;
      72:     bool    hadsub;
      73:     int     subscr;
      74:
      75:     v++;
      76:     p = *v++;
      77:     if (p == 0) {
      78:     prvars();
      79:     return;
      80:     }
      81:     do {
      82:     hadsub = 0;
      83:     vp = p;
      84:     if (letter(*p))
      85:         for (; alnum(*p); p++)
      86:         continue;
      87:     if (vp == p || !letter(*vp))
      88:         stderror(ERR_NAME | ERR_VARBEGIN);
      89:     if ((p - vp) > MAXVARLEN) {
      90:         stderror(ERR_NAME | ERR_VARTOOLONG);
      91:         return;
      92:     }
      93:     if (*p == '[') {
      94:         hadsub++;
      95:         p = getinx(p, &subscr);
      96:     }
      97:     if (op = *p) {
      98:         *p++ = 0;
      99:         if (*p == 0 && *v && **v == '(')
     100:         p = *v++;
     101:     }
     102:     else if (*v && eq(*v, STRequal)) {
     103:         op = '=', v++;
     104:         if (*v)
     105:         p = *v++;
     106:     }
     107:     if (op && op != '=')
     108:         stderror(ERR_NAME | ERR_SYNTAX);
     109:     if (eq(p, STRLparen)) {
     110:         register Char **e = v;
     111:
     112:         if (hadsub)
     113:         stderror(ERR_NAME | ERR_SYNTAX);
     114:         for (;;) {
     115:         if (!*e)
     116:             stderror(ERR_NAME | ERR_MISSING, ')');
     117:         if (**e == ')')
     118:             break;
     119:         e++;
     120:         }
     121:         p = *e;
     122:         *e = 0;
     123:         vecp = saveblk(v);
     124:         set1(vp, vecp, &shvhed);
     125:         *e = p;
     126:         v = e + 1;
     127:     }
     128:     else if (hadsub)
     129:         asx(vp, subscr, Strsave(p));
     130:     else
     131:         set(vp, Strsave(p));
     132:     if (eq(vp, STRpath)) {
     133:         exportpath(adrof(STRpath)->vec);
     134:         dohash();
     135:     }
     136:     else if (eq(vp, STRhstc)) {
     137:         register Char *pn = value(STRhstc);
     138:
     139:         HIST = *pn++;
     140:         HISTSUB = *pn;
     141:     }
     142:     else if (eq(vp, STRhstl)) {
     143:         HistLit = 1;
     144:     }
     145:     else if (eq(vp, STRuser)) {
     146:         Setenv(STRUSER, value(vp));
     147:         Setenv(STRLOGNAME, value(vp));
     148:     }
     149:     else if (eq(vp, STRwordchars)) {
     150:         word_chars = value(vp);
     151:     }
     152:     else if (eq(vp, STRterm)) {
     153: #ifdef DOESNT_WORK_RIGHT
     154:         register Char *cp;
     155:
     156: #endif
     157:         Setenv(STRTRM, value(vp));
     158: #ifdef DOESNT_WORK_RIGHT
     159:         cp = getenv("TERMCAP");
     160:         if (cp && (*cp != '/')) /* if TERMCAP and not a path */
     161:         Unsetenv(STRTRMCAP);
     162: #endif				/* DOESNT_WORK_RIGHT */
     163:         GotTermCaps = 0;
     164:         ed_I();     /* reset the editor */
     165:     }
     166:     else if (eq(vp, STRhome)) {
     167:         register Char *cp;
     168:
     169:         cp = Strsave(value(vp));    /* get the old value back */
     170:
     171:         /*
     172: 	     * convert to cononical pathname (possibly resolving symlinks)
     173: 	     */
     174:         cp = dcanon(cp, cp);
     175:
     176:         set(vp, Strsave(cp));   /* have to save the new val */
     177:
     178:         /* and now mirror home with HOME */
     179:         Setenv(STRHOME, cp);
     180:         /* fix directory stack for new tilde home */
     181:         dtilde();
     182:         xfree((ptr_t) cp);
     183:     }
     184:     else if (eq(vp, STRedit)) {
     185:         editing = 1;
     186:         /* PWP: add more stuff in here later */
     187:     }
     188:     else if (eq(vp, STRshlvl)) {
     189:         Setenv(STRSHLVL, value(vp));
     190:     }
     191:     else if (eq(vp, STRbKslash_quote)) {
     192:         bslash_quote = 1;
     193:     }
     194:     else if (eq(vp, STRrecognize_only_executables)) {
     195:         tw_clear_comm_list();
     196:     }
     197:     else if (eq(vp, STRwatch)) {
     198:         resetwatch();
     199:     }
     200:     } while (p = *v++);
     201: }
     202:
     203: static Char *
     204: getinx(cp, ip)
     205:     register Char *cp;
     206:     register int *ip;
     207: {
     208:     *ip = 0;
     209:     *cp++ = 0;
     210:     while (*cp && Isdigit(*cp))
     211:     *ip = *ip * 10 + *cp++ - '0';
     212:     if (*cp++ != ']')
     213:     stderror(ERR_NAME | ERR_SUBSCRIPT);
     214:     return (cp);
     215: }
     216:
     217: static void
     218: asx(vp, subscr, p)
     219:     Char   *vp;
     220:     int     subscr;
     221:     Char   *p;
     222: {
     223:     register struct varent *v = getvx(vp, subscr);
     224:
     225:     xfree((ptr_t) v->vec[subscr - 1]);
     226:     v->vec[subscr - 1] = globone(p, G_APPEND);
     227: }
     228:
     229: static struct varent *
     230: getvx(vp, subscr)
     231:     Char   *vp;
     232:     int     subscr;
     233: {
     234:     register struct varent *v = adrof(vp);
     235:
     236:     if (v == 0)
     237:     udvar(vp);
     238:     if (subscr < 1 || subscr > blklen(v->vec))
     239:     stderror(ERR_NAME | ERR_RANGE);
     240:     return (v);
     241: }
     242:
     243: void
     244: dolet(v)
     245:     Char  **v;
     246: {
     247:     register Char *p;
     248:     Char   *vp, c, op;
     249:     bool    hadsub;
     250:     int     subscr;
     251:
     252:     v++;
     253:     p = *v++;
     254:     if (p == 0) {
     255:     prvars();
     256:     return;
     257:     }
     258:     do {
     259:     hadsub = 0;
     260:     vp = p;
     261:     if (letter(*p))
     262:         for (; alnum(*p); p++)
     263:         continue;
     264:     if (vp == p || !letter(*vp))
     265:         stderror(ERR_NAME | ERR_VARBEGIN);
     266:     if ((p - vp) > MAXVARLEN)
     267:         stderror(ERR_NAME | ERR_VARTOOLONG);
     268:     if (*p == '[') {
     269:         hadsub++;
     270:         p = getinx(p, &subscr);
     271:     }
     272:     if (*p == 0 && *v)
     273:         p = *v++;
     274:     if (op = *p)
     275:         *p++ = 0;
     276:     else
     277:         stderror(ERR_NAME | ERR_ASSIGN);
     278:
     279:     /*
     280: 	 * if there is no expression after the '=' then print a "Syntax Error"
     281: 	 * message - strike
     282: 	 */
     283:     if (*p == '\0' && *v == NULL)
     284:         stderror(ERR_NAME | ERR_ASSIGN);
     285:
     286:     vp = Strsave(vp);
     287:     if (op == '=') {
     288:         c = '=';
     289:         p = xset(p, &v);
     290:     }
     291:     else {
     292:         c = *p++;
     293:         if (any("+-", c)) {
     294:         if (c != op || *p)
     295:             stderror(ERR_NAME | ERR_UNKNOWNOP);
     296:         p = Strsave(STR1);
     297:         }
     298:         else {
     299:         if (any("<>", op)) {
     300:             if (c != op)
     301:             stderror(ERR_NAME | ERR_UNKNOWNOP);
     302:             c = *p++;
     303:             stderror(ERR_NAME | ERR_SYNTAX);
     304:         }
     305:         if (c != '=')
     306:             stderror(ERR_NAME | ERR_UNKNOWNOP);
     307:         p = xset(p, &v);
     308:         }
     309:     }
     310:     if (op == '=')
     311:         if (hadsub)
     312:         asx(vp, subscr, p);
     313:         else
     314:         set(vp, p);
     315:     else if (hadsub) {
     316:         struct varent *gv = getvx(vp, subscr);
     317:
     318:         asx(vp, subscr, operate(op, gv->vec[subscr - 1], p));
     319:     }
     320:     else
     321:         set(vp, operate(op, value(vp), p));
     322:     if (eq(vp, STRpath)) {
     323:         exportpath(adrof(STRpath)->vec);
     324:         dohash();
     325:     }
     326:     xfree((ptr_t) vp);
     327:     if (c != '=')
     328:         xfree((ptr_t) p);
     329:     } while (p = *v++);
     330: }
     331:
     332: static Char *
     333: xset(cp, vp)
     334:     Char   *cp, ***vp;
     335: {
     336:     register Char *dp;
     337:
     338:     if (*cp) {
     339:     dp = Strsave(cp);
     340:     --(*vp);
     341:     xfree((ptr_t) ** vp);
     342:     **vp = dp;
     343:     }
     344:     return (putn(exp(vp)));
     345: }
     346:
     347: static Char *
     348: operate(op, vp, p)
     349:     Char    op, *vp, *p;
     350: {
     351:     Char    opr[2];
     352:     Char   *vec[5];
     353:     register Char **v = vec;
     354:     Char  **vecp = v;
     355:     register int i;
     356:
     357:     if (op != '=') {
     358:     if (*vp)
     359:         *v++ = vp;
     360:     opr[0] = op;
     361:     opr[1] = 0;
     362:     *v++ = opr;
     363:     if (op == '<' || op == '>')
     364:         *v++ = opr;
     365:     }
     366:     *v++ = p;
     367:     *v++ = 0;
     368:     i = exp(&vecp);
     369:     if (*vecp)
     370:     stderror(ERR_NAME | ERR_EXPRESSION);
     371:     return (putn(i));
     372: }
     373:
     374: static Char *putp;
     375:
     376: Char   *
     377: putn(n)
     378:     register int n;
     379: {
     380:     int     num;
     381:     static Char number[15];
     382:
     383:     putp = number;
     384:     if (n < 0) {
     385:     n = -n;
     386:     *putp++ = '-';
     387:     }
     388:     num = 2;            /* comfuse lint */
     389:     if (sizeof(int) == num && n == -32768) {
     390:     *putp++ = '3';
     391:     n = 2768;
     392: #ifdef pdp11
     393:     }
     394: #else
     395:     }
     396:     else {
     397:     num = 4;        /* comfuse lint */
     398:     if (sizeof(int) == num && n == -2147483648) {
     399:         *putp++ = '2';
     400:         n = 147483648;
     401:     }
     402:     }
     403: #endif
     404:     putn1(n);
     405:     *putp = 0;
     406:     return (Strsave(number));
     407: }
     408:
     409: static void
     410: putn1(n)
     411:     register int n;
     412: {
     413:     if (n > 9)
     414:     putn1(n / 10);
     415:     *putp++ = n % 10 + '0';
     416: }
     417:
     418: int
     419: getn(cp)
     420:     register Char *cp;
     421: {
     422:     register int n;
     423:     int     sign;
     424:
     425:     sign = 0;
     426:     if (cp[0] == '+' && cp[1])
     427:     cp++;
     428:     if (*cp == '-') {
     429:     sign++;
     430:     cp++;
     431:     if (!Isdigit(*cp))
     432:         stderror(ERR_NAME | ERR_BADNUM);
     433:     }
     434:     n = 0;
     435:     while (Isdigit(*cp))
     436:     n = n * 10 + *cp++ - '0';
     437:     if (*cp)
     438:     stderror(ERR_NAME | ERR_BADNUM);
     439:     return (sign ? -n : n);
     440: }
     441:
     442: Char   *
     443: value1(var, head)
     444:     Char   *var;
     445:     struct varent *head;
     446: {
     447:     register struct varent *vp;
     448:
     449:     vp = adrof1(var, head);
     450:     return (vp == 0 || vp->vec[0] == 0 ? STRNULL : vp->vec[0]);
     451: }
     452:
     453: static struct varent *
     454: madrof(pat, vp)
     455:     Char   *pat;
     456:     register struct varent *vp;
     457: {
     458:     register struct varent *vp1;
     459:
     460:     for (; vp; vp = vp->v_right) {
     461:     if (vp->v_left && (vp1 = madrof(pat, vp->v_left)))
     462:         return vp1;
     463:     if (Gmatch(vp->v_name, pat))
     464:         return vp;
     465:     }
     466:     return vp;
     467: }
     468:
     469: struct varent *
     470: adrof1(name, v)
     471:     register Char *name;
     472:     register struct varent *v;
     473: {
     474:     register cmp;
     475:
     476:     v = v->v_left;
     477:     while (v && ((cmp = *name - *v->v_name) || (cmp = Strcmp(name, v->v_name))))
     478:     if (cmp < 0)
     479:         v = v->v_left;
     480:     else
     481:         v = v->v_right;
     482:     return v;
     483: }
     484:
     485: /*
     486:  * The caller is responsible for putting value in a safe place
     487:  */
     488: void
     489: set(var, val)
     490:     Char   *var, *val;
     491: {
     492:     register Char **vec = (Char **) xmalloc((size_t) (2 * sizeof(Char **)));
     493:
     494:     vec[0] = val;
     495:     vec[1] = 0;
     496:     set1(var, vec, &shvhed);
     497: }
     498:
     499: void
     500: set1(var, vec, head)
     501:     Char   *var, **vec;
     502:     struct varent *head;
     503: {
     504:     register Char **oldv = vec;
     505:
     506:     gflag = 0;
     507:     tglob(oldv);
     508:     if (gflag) {
     509:     vec = globall(oldv);
     510:     if (vec == 0) {
     511:         blkfree(oldv);
     512:         stderror(ERR_NAME | ERR_NOMATCH);
     513:         return;
     514:     }
     515:     blkfree(oldv);
     516:     gargv = 0;
     517:     }
     518:     setq(var, vec, head);
     519: }
     520:
     521:
     522: void
     523: setq(name, vec, p)
     524:     Char   *name, **vec;
     525:     register struct varent *p;
     526: {
     527:     register struct varent *c;
     528:     register f;
     529:
     530:     f = 0;          /* tree hangs off the header's left link */
     531:     while (c = p->v_link[f]) {
     532:     if ((f = *name - *c->v_name) == 0 &&
     533:         (f = Strcmp(name, c->v_name)) == 0) {
     534:         blkfree(c->vec);
     535:         goto found;
     536:     }
     537:     p = c;
     538:     f = f > 0;
     539:     }
     540:     p->v_link[f] = c = (struct varent *) xmalloc((size_t)sizeof(struct varent));
     541:     c->v_name = Strsave(name);
     542:     c->v_bal = 0;
     543:     c->v_left = c->v_right = 0;
     544:     c->v_parent = p;
     545:     balance(p, f, 0);
     546: found:
     547:     trim(c->vec = vec);
     548: }
     549:
     550: void
     551: unset(v)
     552:     Char   *v[];
     553: {
     554:     register bool did_only;
     555:
     556:     did_only = adrof(STRrecognize_only_executables) != 0;
     557:     unset1(v, &shvhed);
     558:     if (adrof(STRhstc) == 0) {
     559:     HIST = '!';
     560:     HISTSUB = '^';
     561:     }
     562:     if (adrof(STRhstl) == 0)
     563:     HistLit = 0;
     564:     if (adrof(STRwordchars) == 0)
     565:     word_chars = STR_WORD_CHARS;
     566:     if (adrof(STRedit) == 0)
     567:     editing = 0;
     568:     if (adrof(STRbKslash_quote) == 0)
     569:     bslash_quote = 0;
     570:     if (did_only && adrof(STRrecognize_only_executables) == 0)
     571:     tw_clear_comm_list();
     572: }
     573:
     574: void
     575: unset1(v, head)
     576:     register Char *v[];
     577:     struct varent *head;
     578: {
     579:     register struct varent *vp;
     580:     register int cnt;
     581:
     582:     while (*++v) {
     583:     cnt = 0;
     584:     while (vp = madrof(*v, head->v_left))
     585:         unsetv1(vp), cnt++;
     586:     if (cnt == 0)
     587:         setname(short2str(*v));
     588:     }
     589: }
     590:
     591: void
     592: unsetv(var)
     593:     Char   *var;
     594: {
     595:     register struct varent *vp;
     596:
     597:     if ((vp = adrof1(var, &shvhed)) == 0)
     598:     udvar(var);
     599:     unsetv1(vp);
     600: }
     601:
     602: static void
     603: unsetv1(p)
     604:     register struct varent *p;
     605: {
     606:     register struct varent *c, *pp;
     607:     register f;
     608:
     609:     /*
     610:      * Free associated memory first to avoid complications.
     611:      */
     612:     blkfree(p->vec);
     613:     xfree((ptr_t) p->v_name);
     614:     /*
     615:      * If p is missing one child, then we can move the other into where p is.
     616:      * Otherwise, we find the predecessor of p, which is guaranteed to have no
     617:      * right child, copy it into p, and move it's left child into it.
     618:      */
     619:     if (p->v_right == 0)
     620:     c = p->v_left;
     621:     else if (p->v_left == 0)
     622:     c = p->v_right;
     623:     else {
     624:     for (c = p->v_left; c->v_right; c = c->v_right);
     625:     p->v_name = c->v_name;
     626:     p->vec = c->vec;
     627:     p = c;
     628:     c = p->v_left;
     629:     }
     630:     /*
     631:      * Move c into where p is.
     632:      */
     633:     pp = p->v_parent;
     634:     f = pp->v_right == p;
     635:     if (pp->v_link[f] = c)
     636:     c->v_parent = pp;
     637:     /*
     638:      * Free the deleted node, and rebalance.
     639:      */
     640:     xfree((ptr_t) p);
     641:     balance(pp, f, 1);
     642: }
     643:
     644: void
     645: setNS(cp)
     646:     Char   *cp;
     647: {
     648:     set(cp, Strsave(STRNULL));
     649: }
     650:
     651: void
     652: shift(v)
     653:     register Char **v;
     654: {
     655:     register struct varent *argv;
     656:     register Char *name;
     657:
     658:     v++;
     659:     name = *v;
     660:     if (name == 0)
     661:     name = STRargv;
     662:     else
     663:     (void) strip(name);
     664:     argv = adrof(name);
     665:     if (argv == 0)
     666:     udvar(name);
     667:     if (argv->vec[0] == 0)
     668:     stderror(ERR_NAME | ERR_NOMORE);
     669:     lshift(argv->vec, 1);
     670: }
     671:
     672: static void
     673: exportpath(val)
     674:     Char  **val;
     675: {
     676:     Char    exppath[BUFSIZ];
     677:
     678:     exppath[0] = 0;
     679:     if (val)
     680:     while (*val) {
     681:         if (Strlen(*val) + Strlen(exppath) + 2 > BUFSIZ) {
     682:         xprintf("Warning: ridiculously long PATH truncated\n");
     683:         break;
     684:         }
     685:         (void) Strcat(exppath, *val++);
     686:         if (*val == 0 || eq(*val, STRRparen))
     687:         break;
     688:         (void) Strcat(exppath, STRcolon);
     689:     }
     690:     Setenv(STRPATH, exppath);
     691: }
     692:
     693: #ifndef lint
     694:  /*
     695:   * Lint thinks these have null effect
     696:   */
     697:  /* macros to do single rotations on node p */
     698: #define rright(p) (\
     699:     t = (p)->v_left,\
     700:     (t)->v_parent = (p)->v_parent,\
     701:     ((p)->v_left = t->v_right) ? (t->v_right->v_parent = (p)) : 0,\
     702:     (t->v_right = (p))->v_parent = t,\
     703:     (p) = t)
     704: #define rleft(p) (\
     705:     t = (p)->v_right,\
     706:     (t)->v_parent = (p)->v_parent,\
     707:     ((p)->v_right = t->v_left) ? (t->v_left->v_parent = (p)) : 0,\
     708:     (t->v_left = (p))->v_parent = t,\
     709:     (p) = t)
     710: #else
     711: struct varent *
     712: rleft(p)
     713:     struct varent *p;
     714: {
     715:     return (p);
     716: }
     717: struct varent *
     718: rright(p)
     719:     struct varent *p;
     720: {
     721:     return (p);
     722: }
     723:
     724: #endif				/* ! lint */
     725:
     726:
     727: /*
     728:  * Rebalance a tree, starting at p and up.
     729:  * F == 0 means we've come from p's left child.
     730:  * D == 1 means we've just done a delete, otherwise an insert.
     731:  */
     732: static void
     733: balance(p, f, d)
     734:     register struct varent *p;
     735:     register int f, d;
     736: {
     737:     register struct varent *pp;
     738:
     739: #ifndef lint
     740:     register struct varent *t;  /* used by the rotate macros */
     741:
     742: #endif
     743:     register ff;
     744:
     745:     /*
     746:      * Ok, from here on, p is the node we're operating on; pp is it's parent; f
     747:      * is the branch of p from which we have come; ff is the branch of pp which
     748:      * is p.
     749:      */
     750:     for (; pp = p->v_parent; p = pp, f = ff) {
     751:     ff = pp->v_right == p;
     752:     if (f ^ d) {        /* right heavy */
     753:         switch (p->v_bal) {
     754:         case -1:        /* was left heavy */
     755:         p->v_bal = 0;
     756:         break;
     757:         case 0:     /* was balanced */
     758:         p->v_bal = 1;
     759:         break;
     760:         case 1:     /* was already right heavy */
     761:         switch (p->v_right->v_bal) {
     762:         case 1: /* sigle rotate */
     763:             pp->v_link[ff] = rleft(p);
     764:             p->v_left->v_bal = 0;
     765:             p->v_bal = 0;
     766:             break;
     767:         case 0: /* single rotate */
     768:             pp->v_link[ff] = rleft(p);
     769:             p->v_left->v_bal = 1;
     770:             p->v_bal = -1;
     771:             break;
     772:         case -1:    /* double rotate */
     773:             (void) rright(p->v_right);
     774:             pp->v_link[ff] = rleft(p);
     775:             p->v_left->v_bal =
     776:             p->v_bal < 1 ? 0 : -1;
     777:             p->v_right->v_bal =
     778:             p->v_bal > -1 ? 0 : 1;
     779:             p->v_bal = 0;
     780:             break;
     781:         }
     782:         break;
     783:         }
     784:     }
     785:     else {          /* left heavy */
     786:         switch (p->v_bal) {
     787:         case 1:     /* was right heavy */
     788:         p->v_bal = 0;
     789:         break;
     790:         case 0:     /* was balanced */
     791:         p->v_bal = -1;
     792:         break;
     793:         case -1:        /* was already left heavy */
     794:         switch (p->v_left->v_bal) {
     795:         case -1:    /* single rotate */
     796:             pp->v_link[ff] = rright(p);
     797:             p->v_right->v_bal = 0;
     798:             p->v_bal = 0;
     799:             break;
     800:         case 0: /* signle rotate */
     801:             pp->v_link[ff] = rright(p);
     802:             p->v_right->v_bal = -1;
     803:             p->v_bal = 1;
     804:             break;
     805:         case 1: /* double rotate */
     806:             (void) rleft(p->v_left);
     807:             pp->v_link[ff] = rright(p);
     808:             p->v_left->v_bal =
     809:             p->v_bal < 1 ? 0 : -1;
     810:             p->v_right->v_bal =
     811:             p->v_bal > -1 ? 0 : 1;
     812:             p->v_bal = 0;
     813:             break;
     814:         }
     815:         break;
     816:         }
     817:     }
     818:     /*
     819: 	 * If from insert, then we terminate when p is balanced. If from
     820: 	 * delete, then we terminate when p is unbalanced.
     821: 	 */
     822:     if ((p->v_bal == 0) ^ d)
     823:         break;
     824:     }
     825: }
     826:
     827: void
     828: plist(p)
     829:     register struct varent *p;
     830: {
     831:     register struct varent *c;
     832:     register len;
     833:
     834:     if (setintr)
     835: #ifdef BSDSIGS
     836:     (void) sigsetmask(sigblock((sigmask_t) 0) & ~sigmask(SIGINT));
     837: #else               /* BSDSIGS */
     838:     (void) sigrelse(SIGINT);
     839: #endif				/* BSDSIGS */
     840:
     841:     for (;;) {
     842:     while (p->v_left)
     843:         p = p->v_left;
     844: x:
     845:     if (p->v_parent == 0)   /* is it the header? */
     846:         return;
     847:     len = blklen(p->vec);
     848:     xprintf(short2str(p->v_name));
     849:     xputchar('\t');
     850:     if (len != 1)
     851:         xputchar('(');
     852:     blkpr(p->vec);
     853:     if (len != 1)
     854:         xputchar(')');
     855:     xputchar('\n');
     856:     if (p->v_right) {
     857:         p = p->v_right;
     858:         continue;
     859:     }
     860:     do {
     861:         c = p;
     862:         p = p->v_parent;
     863:     } while (p->v_right == c);
     864:     goto x;
     865:     }
     866: }

#### Defined functions

adrof1 defined in line 469; used 15 times

- in line 449, 597
- in /usr/src/bin/tcsh/sh.exec.c line 349, 617
- in /usr/src/bin/tcsh/sh.func.c line 224
- in /usr/src/bin/tcsh/sh.h line 633-635(2)
- in /usr/src/bin/tcsh/sh.parse.c line 162
- in /usr/src/bin/tcsh/sh.set.c line 449, 597
- in /usr/src/bin/tcsh/tc.func.c line 380, 536, 571, 608
- in /usr/src/bin/tcsh/tw.help.c line 88

asx defined in line 217; used 3 times

- in line 129, 312, 318

balance defined in line 732; used 2 times

- in line 545, 641

dolet defined in line 243; used 1 times

- in /usr/src/bin/tcsh/sh.init.c line 52

doset defined in line 65; used 1 times

- in /usr/src/bin/tcsh/sh.init.c line 129

exportpath defined in line 672; used 2 times

- in line 133, 323

getinx defined in line 203; used 2 times

- in line 95, 270

getn defined in line 418; used 11 times

- in /usr/src/bin/tcsh/sh.dir.c line 616
- in /usr/src/bin/tcsh/sh.exp.c line 680
- in /usr/src/bin/tcsh/sh.func.c line 578
- in /usr/src/bin/tcsh/sh.hist.c line 134, 164-166(2)
- in /usr/src/bin/tcsh/sh.sem.c line 144, 571
- in /usr/src/bin/tcsh/sh.time.c line 154
- in /usr/src/bin/tcsh/tc.func.c line 612
- in /usr/src/bin/tcsh/tc.who.c line 186

getvx defined in line 229; used 2 times

- in line 223, 316

madrof defined in line 453; used 2 times

- in line 461, 584

operate defined in line 347; used 2 times

- in line 318-321(2)

plist defined in line 827; used 11 times

- in /usr/src/bin/tcsh/sh.func.c line 209, 222
- in /usr/src/bin/tcsh/tc.func.c line 905-906(2), 915-921(3), 929, 973, 981, 1159

putn defined in line 376; used 16 times

- in line 344, 371
- in /usr/src/bin/tcsh/sh.c line 407
- in /usr/src/bin/tcsh/sh.dol.c line 585
- in /usr/src/bin/tcsh/sh.exp.c line 296, 326, 363, 410, 433, 443, 454, 488, 586
- in /usr/src/bin/tcsh/sh.func.c line 416
- in /usr/src/bin/tcsh/sh.lex.c line 1195
- in /usr/src/bin/tcsh/sh.proc.c line 616

putn1 defined in line 409; used 2 times

- in line 404, 414

rcsid defined in line 39; never used
rleft defined in line 711; never used
rright defined in line 717; never used
set defined in line 488; used 32 times

- in line 131, 176, 314, 321, 648
- in /usr/src/bin/tcsh/sh.err.c line 466
- in /usr/src/bin/tcsh/sh.exp.c line 603
- in /usr/src/bin/tcsh/sh.func.c line 416, 562
- in /usr/src/bin/tcsh/sh.proc.c line 616
- in /usr/src/bin/tcsh/sh.sem.c line 129
- in /usr/src/bin/tcsh/sh.set.c line 131, 176, 314, 321, 648
- in /usr/src/bin/tcsh/tc.func.c line 481
- in /usr/src/bin/tcsh/tc.sig.c line 302-313(4), 335-343(3), 350-352(2), 374-382(4)
- in /usr/src/bin/tcsh/tc.vers.c line 394-396(2)

set1 defined in line 499; used 5 times

- in line 124, 496
- in /usr/src/bin/tcsh/sh.func.c line 233
- in /usr/src/bin/tcsh/sh.set.c line 124, 496

setNS defined in line 644; never used
setq defined in line 522; used 4 times

- in line 518
- in /usr/src/bin/tcsh/sh.dir.c line 149
- in /usr/src/bin/tcsh/sh.set.c line 518
- in /usr/src/bin/tcsh/tc.func.c line 1209

shift defined in line 651; used 1 times

- in /usr/src/bin/tcsh/sh.init.c line 141

unset defined in line 550; used 1 times

- in /usr/src/bin/tcsh/sh.init.c line 155

unset1 defined in line 574; used 3 times

- in line 557
- in /usr/src/bin/tcsh/sh.func.c line 242
- in /usr/src/bin/tcsh/sh.set.c line 557

unsetv defined in line 591; used 1 times

- in /usr/src/bin/tcsh/sh.proc.c line 306

unsetv1 defined in line 602; used 2 times

- in line 585, 599

value1 defined in line 442; used 1 times

- in /usr/src/bin/tcsh/sh.h line 636

xset defined in line 332; used 2 times

- in line 289, 307

#### Defined variables

putp defined in line 374; used 6 times

- in line 383-390(3), 399, 405, 415

#### Defined macros

rleft defined in line 704; used 4 times

- in line 763-768(2), 774, 806

rright defined in line 698; used 4 times

- in line 773, 796-801(2), 807

Last modified: 1991-08-20 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1942 |