/*
 * sh.set.c: "Gospodarka zmiennymi "
 */
[...]

/* wybralem co ciekawsze i autonomicznie napisane funkcje */






static struct varent * /*szuka wezla w drzewie AVT odpowiadajacego wzorcowi pat */
madrof(pat, vp)
    Char   *pat;
    register struct varent *vp;
{
    register struct varent *vp1;

    for (vp = vp->v_left; vp; vp = vp->v_right) {
        if (vp->v_left && (vp1 = madrof(pat, vp)) != NULL)
            return vp1;
        if (Gmatch(vp->v_name, pat))
            return vp;
    }
    return vp;
}




struct varent *         /* szuka w drzewie AVT wezla ktory w polu w_name ma wartosc
                           nazwa */
adrof1(name, v)
    register Char *name;
    register struct varent *v;
{
    int cmp;

    v = v->v_left;
    while (v && ((cmp = *name - *v->v_name) != 0 || 
                 (cmp = Strcmp(name, v->v_name)) != 0))
        if (cmp < 0)
            v = v->v_left;
        else
            v = v->v_right;
    return v;
}





#ifndef lint
 /*
  * 
  */
 /* makra do robienia pojedynczej rotacji na wezle  p */
# define rright(p) (\
        t = (p)->v_left,\
        (t)->v_parent = (p)->v_parent,\
        (((p)->v_left = t->v_right) != NULL) ?\
            (t->v_right->v_parent = (p)) : 0,\
        (t->v_right = (p))->v_parent = t,\
        (p) = t)
# define rleft(p) (\
        t = (p)->v_right,\
        ((t)->v_parent = (p)->v_parent,\
        ((p)->v_right = t->v_left) != NULL) ? \
                (t->v_left->v_parent = (p)) : 0,\
        (t->v_left = (p))->v_parent = t,\
        (p) = t)
#else
static struct varent *
rleft(p)
    struct varent *p;
{
    return (p);
}
static struct varent *
rright(p)
    struct varent *p;
{
    return (p);
}

#endif /* ! lint */





/*
 * "Wybalansuj drzewo AVT"
 * F == 0  znaczy ,ze przyszlismy od lewego dziecka p
 * D == 1 zrobilismy kasowanie w p.p. wlozenie .
 */
static void
balance(p, f, d)
    register struct varent *p;
    register int f, d;
{
    register struct varent *pp;

#ifndef lint
    register struct varent *t;  
#endif /* !lint */
    register int ff;
#ifdef lint
    ff = 0;     
#endif

    /*
     * p jest wierzchilkiem od ktorego przyszlismy i na ktorym operujemy
     * pp jest jego ojcem ,f jest galezia od ktorej przyszlismy ff to galaz 
     * pp na ktorej jest p
     */
    for (; (pp = p->v_parent) != 0; p = pp, f = ff) {
        ff = pp->v_right == p;
        if (f ^ d) {            /* prawy ciezszy */
            switch (p->v_bal) {
            case -1:            /* byl lewy ciezszy */
                p->v_bal = 0;
                break;
            case 0:             /* wybalansowano */
                p->v_bal = 1;
                break;
            case 1:             /* byl juz prawy ciezszy */
                switch (p->v_right->v_bal) {
                case 1: /* sigle rotate */
                    pp->v_link[ff] = rleft(p);
                    p->v_left->v_bal = 0;
                    p->v_bal = 0;
                    break;
                case 0: /* jedno przejscie  */
                    pp->v_link[ff] = rleft(p);
                    p->v_left->v_bal = 1;
                    p->v_bal = -1;
                    break;
                case -1:        /* dwa przejscia */
                    (void) rright(p->v_right);
                    pp->v_link[ff] = rleft(p);
                    p->v_left->v_bal =
                        p->v_bal < 1 ? 0 : -1;
                    p->v_right->v_bal =
                        p->v_bal > -1 ? 0 : 1;
                    p->v_bal = 0;
                    break;
                default:
                    break;
                }
                break;
            default:
                break;
            }
        }
        else {                  /* lewy ciezszy */
            switch (p->v_bal) {
            case 1:             /* byl prawy ciezszy */
                p->v_bal = 0;
                break;
            case 0:             /* zostalo wybalansowane */
                p->v_bal = -1;
                break;
            case -1:            /* byl juz lewy ciezszy */
                switch (p->v_left->v_bal) {
                case -1:        /* jedno przejscie  */
                    pp->v_link[ff] = rright(p);
                    p->v_right->v_bal = 0;
                    p->v_bal = 0;
                    break;
                case 0: /* jedno przejscie  */
                    pp->v_link[ff] = rright(p);
                    p->v_right->v_bal = -1;
                    p->v_bal = 1;
                    break;
                case 1: /* dwa przejscia */
                    (void) rleft(p->v_left);
                    pp->v_link[ff] = rright(p);
                    p->v_left->v_bal =
                        p->v_bal < 1 ? 0 : -1;
                    p->v_right->v_bal =
                        p->v_bal > -1 ? 0 : 1;
                    p->v_bal = 0;
                    break;
                default:
                    break;
                }
                break;
            default:
                break;
            }
        }
        /*
         * jesli ze strony wlozenia jestesmy wtedy konczymy z p 
         * wybalansowanym ,w p.p. nie 
         */
        if ((p->v_bal == 0) ^ d)
            break;
    }
}

[....]