📄 set.c
字号:
Char *var; struct varent *head;{ register struct varent *vp; vp = adrof1(var, head); return (vp == 0 || vp->vec[0] == 0 ? STRNULL : vp->vec[0]);}static struct varent *madrof(pat, vp) Char *pat; register struct varent *vp;{ register struct varent *vp1; for (; vp; vp = vp->v_right) { if (vp->v_left && (vp1 = madrof(pat, vp->v_left))) return vp1; if (Gmatch(vp->v_name, pat)) return vp; } return vp;}struct varent *adrof1(name, v) register Char *name; register struct varent *v;{ register cmp; v = v->v_left; while (v && ((cmp = *name - *v->v_name) || (cmp = Strcmp(name, v->v_name)))) if (cmp < 0) v = v->v_left; else v = v->v_right; return v;}/* * The caller is responsible for putting value in a safe place */voidset(var, val) Char *var, *val;{ register Char **vec = (Char **) xmalloc((size_t) (2 * sizeof(Char **))); vec[0] = val; vec[1] = 0; set1(var, vec, &shvhed);}voidset1(var, vec, head) Char *var, **vec; struct varent *head;{ register Char **oldv = vec; gflag = 0; tglob(oldv); if (gflag) { vec = globall(oldv); if (vec == 0) { blkfree(oldv); stderror(ERR_NAME | ERR_NOMATCH); return; } blkfree(oldv); gargv = 0; } setq(var, vec, head);}voidsetq(name, vec, p) Char *name, **vec; register struct varent *p;{ register struct varent *c; register f; f = 0; /* tree hangs off the header's left link */ while ((c = p->v_link[f]) != NULL) { if ((f = *name - *c->v_name) == 0 && (f = Strcmp(name, c->v_name)) == 0) { blkfree(c->vec); goto found; } p = c; f = f > 0; } p->v_link[f] = c = (struct varent *) xmalloc((size_t) sizeof(struct varent)); c->v_name = Strsave(name); c->v_bal = 0; c->v_left = c->v_right = 0; c->v_parent = p; balance(p, f, 0);found: trim(c->vec = vec);}void/*ARGSUSED*/unset(v, t) Char **v; struct command *t;{ unset1(v, &shvhed);#ifdef FILEC if (adrof(STRfilec) == 0) filec = 0;#endif if (adrof(STRhistchars) == 0) { HIST = '!'; HISTSUB = '^'; } if (adrof(STRwordchars) == 0) word_chars = STR_WORD_CHARS;}voidunset1(v, head) register Char *v[]; struct varent *head;{ register struct varent *vp; register int cnt; while (*++v) { cnt = 0; while ((vp = madrof(*v, head->v_left)) != NULL) unsetv1(vp), cnt++; if (cnt == 0) setname(vis_str(*v)); }}voidunsetv(var) Char *var;{ register struct varent *vp; if ((vp = adrof1(var, &shvhed)) == 0) udvar(var); unsetv1(vp);}static voidunsetv1(p) register struct varent *p;{ register struct varent *c, *pp; register f; /* * Free associated memory first to avoid complications. */ blkfree(p->vec); xfree((ptr_t) p->v_name); /* * If p is missing one child, then we can move the other into where p is. * Otherwise, we find the predecessor of p, which is guaranteed to have no * right child, copy it into p, and move it's left child into it. */ if (p->v_right == 0) c = p->v_left; else if (p->v_left == 0) c = p->v_right; else { for (c = p->v_left; c->v_right; c = c->v_right) continue; p->v_name = c->v_name; p->vec = c->vec; p = c; c = p->v_left; } /* * Move c into where p is. */ pp = p->v_parent; f = pp->v_right == p; if ((pp->v_link[f] = c) != NULL) c->v_parent = pp; /* * Free the deleted node, and rebalance. */ xfree((ptr_t) p); balance(pp, f, 1);}voidsetNS(cp) Char *cp;{ set(cp, Strsave(STRNULL));}void/*ARGSUSED*/shift(v, t) Char **v; struct command *t;{ register struct varent *argv; register Char *name; v++; name = *v; if (name == 0) name = STRargv; else (void) strip(name); argv = adrof(name); if (argv == 0) udvar(name); if (argv->vec[0] == 0) stderror(ERR_NAME | ERR_NOMORE); lshift(argv->vec, 1);}static voidexportpath(val) Char **val;{ Char exppath[BUFSIZ]; exppath[0] = 0; if (val) while (*val) { if (Strlen(*val) + Strlen(exppath) + 2 > BUFSIZ) { (void) fprintf(csherr, "Warning: ridiculously long PATH truncated\n"); break; } if ((**val != '/' || **val == '\0') && (euid == 0 || uid == 0)) (void) fprintf(csherr, "Warning: exported path contains relative components.\n"); (void) Strcat(exppath, *val++); if (*val == 0 || eq(*val, STRRparen)) break; (void) Strcat(exppath, STRcolon); } Setenv(STRPATH, exppath);}#ifndef lint /* * Lint thinks these have null effect */ /* macros to do single rotations on node p */#define rright(p) (\ t = (p)->v_left,\ (t)->v_parent = (p)->v_parent,\ ((p)->v_left = t->v_right) ? (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) ? (t->v_left->v_parent = (p)) : 0,\ (t->v_left = (p))->v_parent = t,\ (p) = t)#elsestruct varent *rleft(p) struct varent *p;{ return (p);}struct varent *rright(p) struct varent *p;{ return (p);}#endif /* ! lint *//* * Rebalance a tree, starting at p and up. * F == 0 means we've come from p's left child. * D == 1 means we've just done a delete, otherwise an insert. */static voidbalance(p, f, d) register struct varent *p; register int f, d;{ register struct varent *pp;#ifndef lint register struct varent *t; /* used by the rotate macros */#endif register ff; /* * Ok, from here on, p is the node we're operating on; pp is it's parent; f * is the branch of p from which we have come; ff is the branch of pp which * is p. */ for (; (pp = p->v_parent) != NULL; p = pp, f = ff) { ff = pp->v_right == p; if (f ^ d) { /* right heavy */ switch (p->v_bal) { case -1: /* was left heavy */ p->v_bal = 0; break; case 0: /* was balanced */ p->v_bal = 1; break; case 1: /* was already right heavy */ 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: /* single rotate */ pp->v_link[ff] = rleft(p); p->v_left->v_bal = 1; p->v_bal = -1; break; case -1: /* double rotate */ (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; } break; } } else { /* left heavy */ switch (p->v_bal) { case 1: /* was right heavy */ p->v_bal = 0; break; case 0: /* was balanced */ p->v_bal = -1; break; case -1: /* was already left heavy */ switch (p->v_left->v_bal) { case -1: /* single rotate */ pp->v_link[ff] = rright(p); p->v_right->v_bal = 0; p->v_bal = 0; break; case 0: /* signle rotate */ pp->v_link[ff] = rright(p); p->v_right->v_bal = -1; p->v_bal = 1; break; case 1: /* double rotate */ (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; } break; } } /* * If from insert, then we terminate when p is balanced. If from * delete, then we terminate when p is unbalanced. */ if ((p->v_bal == 0) ^ d) break; }}voidplist(p) register struct varent *p;{ register struct varent *c; register len; if (setintr) (void) sigsetmask(sigblock((sigset_t) 0) & ~sigmask(SIGINT)); for (;;) { while (p->v_left) p = p->v_left;x: if (p->v_parent == 0) /* is it the header? */ return; len = blklen(p->vec); (void) fprintf(cshout, "%s\t", short2str(p->v_name)); if (len != 1) (void) fputc('(', cshout); blkpr(cshout, p->vec); if (len != 1) (void) fputc(')', cshout); (void) fputc('\n', cshout); if (p->v_right) { p = p->v_right; continue; } do { c = p; p = p->v_parent; } while (p->v_right == c); goto x; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -