⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 set.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
    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 + -