sh.exp.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 635 行

C
635
字号
#ifndef lintstatic char *sccsid = "@(#)sh.exp.c	4.2  (ULTRIX)        8/13/90";#endif/************************************************************************ *                                                                      * *                      Copyright (c) 1988 by                           * *              Digital Equipment Corporation, Maynard, MA              * *                      All rights reserved.                            * *                                                                      * *   This software is furnished under a license and may be used and     * *   copied  only  in accordance with the terms of such license and     * *   with the  inclusion  of  the  above  copyright  notice.   This     * *   software  or  any  other copies thereof may not be provided or     * *   otherwise made available to any other person.  No title to and     * *   ownership of the software is hereby transferred.                   * *                                                                      * *   The information in this software is subject to change  without     * *   notice  and should not be construed as a commitment by Digital     * *   Equipment Corporation.                                             * *                                                                      * *   Digital assumes no responsibility for the use  or  reliability     * *   of its software on equipment which is not supplied by Digital.     * *                                                                      * ************************************************************************//* ------------------------------------------------------------------ *//* | Copyright Unpublished, MIPS Computer Systems, Inc.  All Rights | *//* | Reserved.  This software contains proprietary and confidential | *//* | information of MIPS and its suppliers.  Use, disclosure or     | *//* | reproduction is prohibited without the prior express written   | *//* | consent of MIPS.                                               | *//* ------------------------------------------------------------------ *//* $Header: sh.exp.c,v 1.4 87/04/15 08:56:53 dce Exp $ */#include "sh.h"/* * C shell * * Modification History * * 001 - Bob Fontaine - Fri Jun 22 09:53:01 EDT 1990 *	 changed call to csh internal printf routine to csh_printf to avoid *	 confusion with stdio printf. */#define IGNORE	1	/* in ignore, it means to ignore value, just parse */#define NOGLOB	2	/* in ignore, it means not to globone */#define	ADDOP	1#define	MULOP	2#define	EQOP	4#define	RELOP	8#define	RESTOP	16#define	ANYOP	31#define	EQEQ	1#define	GTR	2#define	LSS	4#define	NOTEQ	6#define EQMATCH 7#define NOTEQMATCH 8exp(vp)	register char ***vp;{	return (exp0(vp, 0));}exp0(vp, ignore)	register char ***vp;	bool ignore;{	register int p1 = exp1(vp, ignore);	#ifdef EDEBUG	etraci("exp0 p1", p1, vp);#endif	if (**vp && eq(**vp, "||")) {		register int p2;		(*vp)++;		p2 = exp0(vp, (ignore&IGNORE) || p1);#ifdef EDEBUG		etraci("exp0 p2", p2, vp);#endif		return (p1 || p2);	}	return (p1);}exp1(vp, ignore)	register char ***vp;{	register int p1 = exp2(vp, ignore);#ifdef EDEBUG	etraci("exp1 p1", p1, vp);#endif	if (**vp && eq(**vp, "&&")) {		register int p2;		(*vp)++;		p2 = exp1(vp, (ignore&IGNORE) || !p1);#ifdef EDEBUG		etraci("exp1 p2", p2, vp);#endif		return (p1 && p2);	}	return (p1);}exp2(vp, ignore)	register char ***vp;	bool ignore;{	register int p1 = exp2a(vp, ignore);#ifdef EDEBUG	etraci("exp3 p1", p1, vp);#endif	if (**vp && eq(**vp, "|")) {		register int p2;		(*vp)++;		p2 = exp2(vp, ignore);#ifdef EDEBUG		etraci("exp3 p2", p2, vp);#endif		return (p1 | p2);	}	return (p1);}exp2a(vp, ignore)	register char ***vp;	bool ignore;{	register int p1 = exp2b(vp, ignore);#ifdef EDEBUG	etraci("exp2a p1", p1, vp);#endif	if (**vp && eq(**vp, "^")) {		register int p2;		(*vp)++;		p2 = exp2a(vp, ignore);#ifdef EDEBUG		etraci("exp2a p2", p2, vp);#endif		return (p1 ^ p2);	}	return (p1);}exp2b(vp, ignore)	register char ***vp;	bool ignore;{	register int p1 = exp2c(vp, ignore);#ifdef EDEBUG	etraci("exp2b p1", p1, vp);#endif	if (**vp && eq(**vp, "&")) {		register int p2;		(*vp)++;		p2 = exp2b(vp, ignore);#ifdef EDEBUG		etraci("exp2b p2", p2, vp);#endif		return (p1 & p2);	}	return (p1);}exp2c(vp, ignore)	register char ***vp;	bool ignore;{	register char *p1 = exp3(vp, ignore);	register char *p2;	register int i;#ifdef EDEBUG	etracc("exp2c p1", p1, vp);#endif	if (i = isa(**vp, EQOP)) {		(*vp)++;		if (i == EQMATCH || i == NOTEQMATCH)			ignore |= NOGLOB;		p2 = exp3(vp, ignore);#ifdef EDEBUG		etracc("exp2c p2", p2, vp);#endif		if (!(ignore&IGNORE)) switch (i) {		case EQEQ:			i = eq(p1, p2);			break;		case NOTEQ:			i = !eq(p1, p2);			break;		case EQMATCH:			i = Gmatch(p1, p2);			break;		case NOTEQMATCH:			i = !Gmatch(p1, p2);			break;		}		xfree(p1), xfree(p2);		return (i);	}	i = egetn(p1);	xfree(p1);	return (i);}char *exp3(vp, ignore)	register char ***vp;	bool ignore;{	register char *p1, *p2;	register int i;	p1 = exp3a(vp, ignore);#ifdef EDEBUG	etracc("exp3 p1", p1, vp);#endif	if (i = isa(**vp, RELOP)) {		(*vp)++;		if (**vp && eq(**vp, "="))			i |= 1, (*vp)++;		p2 = exp3(vp, ignore);#ifdef EDEBUG		etracc("exp3 p2", p2, vp);#endif		if (!(ignore&IGNORE)) switch (i) {		case GTR:			i = egetn(p1) > egetn(p2);			break;		case GTR|1:			i = egetn(p1) >= egetn(p2);			break;		case LSS:			i = egetn(p1) < egetn(p2);			break;		case LSS|1:			i = egetn(p1) <= egetn(p2);			break;		}		xfree(p1), xfree(p2);		return (putn(i));	}	return (p1);}char *exp3a(vp, ignore)	register char ***vp;	bool ignore;{	register char *p1, *p2, *op;	register int i;	p1 = exp4(vp, ignore);#ifdef EDEBUG	etracc("exp3a p1", p1, vp);#endif	op = **vp;	if (op && any(op[0], "<>") && op[0] == op[1]) {		(*vp)++;		p2 = exp3a(vp, ignore);#ifdef EDEBUG		etracc("exp3a p2", p2, vp);#endif		if (op[0] == '<')			i = egetn(p1) << egetn(p2);		else			i = egetn(p1) >> egetn(p2);		xfree(p1), xfree(p2);		return (putn(i));	}	return (p1);}char *exp4(vp, ignore)	register char ***vp;	bool ignore;{	register char *p1, *p2;	register int i = 0;	p1 = exp5(vp, ignore);#ifdef EDEBUG	etracc("exp4 p1", p1, vp);#endif	if (isa(**vp, ADDOP)) {		register char *op = *(*vp)++;		p2 = exp4(vp, ignore);#ifdef EDEBUG		etracc("exp4 p2", p2, vp);#endif		if (!(ignore&IGNORE)) switch (op[0]) {		case '+':			i = egetn(p1) + egetn(p2);			break;		case '-':			i = egetn(p1) - egetn(p2);			break;		}		xfree(p1), xfree(p2);		return (putn(i));	}	return (p1);}char *exp5(vp, ignore)	register char ***vp;	bool ignore;{	register char *p1, *p2;	register int i = 0;	p1 = exp6(vp, ignore);#ifdef EDEBUG	etracc("exp5 p1", p1, vp);#endif	if (isa(**vp, MULOP)) {		register char *op = *(*vp)++;		p2 = exp5(vp, ignore);#ifdef EDEBUG		etracc("exp5 p2", p2, vp);#endif		if (!(ignore&IGNORE)) switch (op[0]) {		case '*':			i = egetn(p1) * egetn(p2);			break;		case '/':			i = egetn(p2);			if (i == 0)				error("Divide by 0");			i = egetn(p1) / i;			break;		case '%':			i = egetn(p2);			if (i == 0)				error("Mod by 0");			i = egetn(p1) % i;			break;		}		xfree(p1), xfree(p2);		return (putn(i));	}	return (p1);}char *exp6(vp, ignore)	register char ***vp;{	int ccode, i;	register char *cp, *dp, *ep;	if (**vp == 0)		bferr("Expression syntax");	if (eq(**vp, "!")) {		(*vp)++;		cp = exp6(vp, ignore);#ifdef EDEBUG		etracc("exp6 ! cp", cp, vp);#endif		i = egetn(cp);		xfree(cp);		return (putn(!i));	}	if (eq(**vp, "~")) {		(*vp)++;		cp = exp6(vp, ignore);#ifdef EDEBUG		etracc("exp6 ~ cp", cp, vp);#endif		i = egetn(cp);		xfree(cp);		return (putn(~i));	}	if (eq(**vp, "(")) {		(*vp)++;		ccode = exp0(vp, ignore);#ifdef EDEBUG		etraci("exp6 () ccode", ccode, vp);#endif		if (*vp == 0 || **vp == 0 || ***vp != ')')			bferr("Expression syntax");		(*vp)++;		return (putn(ccode));	}	if (eq(**vp, "{")) {		register char **v;		struct command faket;		char *fakecom[2];		faket.t_dtyp = TCOM;		faket.t_dflg = 0;		faket.t_dcar = faket.t_dcdr = faket.t_dspr = (struct command *)0;		faket.t_dcom = fakecom;		fakecom[0] = "{ ... }";		fakecom[1] = NOSTR;		(*vp)++;		v = *vp;		for (;;) {			if (!**vp)				bferr("Missing }");			if (eq(*(*vp)++, "}"))				break;		}		if (ignore&IGNORE)			return ("");		psavejob();		if (pfork(&faket, -1) == 0) {			*--(*vp) = 0;			evalav(v);			exitstat();		}		pwait();		prestjob();#ifdef EDEBUG		etraci("exp6 {} status", egetn(value("status")), vp);#endif		return (putn(egetn(value("status")) == 0));	}	if (isa(**vp, ANYOP))		return ("");	cp = *(*vp)++;	if (*cp == '-' && any(cp[1], "erwxfdzo")) {		struct stat stb;/* * The check used to be for ANYOP, but that isn't correct since it caused * the expression ( -d / ) to say 'Missing file name'. RESTOP is somewhat * better, but not perfect. This -[rwxd...] stuff is for the birds anyway. * We should be using Lisp syntax, functions like isdir(name), or something * equally clear instead of all of this ambiuous junk. */		if (isa(**vp, RESTOP))			bferr("Missing file name");		dp = *(*vp)++;		if (ignore&IGNORE)			return ("");		ep = globone(dp);		switch (cp[1]) {		case 'r':			i = !access(ep, 4);			break;		case 'w':			i = !access(ep, 2);			break;		case 'x':			i = !access(ep, 1);			break;		default:			if (stat(ep, &stb)) {				xfree(ep);				return ("0");			}			switch (cp[1]) {			case 'f':				i = (stb.st_mode & S_IFMT) == S_IFREG;				break;			case 'd':				i = (stb.st_mode & S_IFMT) == S_IFDIR;				break;			case 'z':				i = stb.st_size == 0;				break;			case 'e':				i = 1;				break;			case 'o':				i = stb.st_uid == uid;				break;			}		}#ifdef EDEBUG		etraci("exp6 -? i", i, vp);#endif		xfree(ep);		return (putn(i));	}#ifdef EDEBUG	etracc("exp6 default", cp, vp);#endif	return (ignore&NOGLOB ? savestr(cp) : globone(cp));}evalav(v)	register char **v;{	struct wordent paraml;	register struct wordent *hp = &paraml;	struct command *t;	register struct wordent *wdp = hp;		set("status", "0");	hp->prev = hp->next = hp;	hp->word = "";	while (*v) {		register struct wordent *new = (struct wordent *) calloc(1, sizeof *wdp);		new->prev = wdp;		new->next = hp;		wdp->next = new;		wdp = new;		wdp->word = savestr(*v++);	}	hp->prev = wdp;	alias(&paraml);	t = syntax(paraml.next, &paraml, 0);	if (err)		error(err);	execute(t, -1);	freelex(&paraml), freesyn(t);}isa(cp, what)	register char *cp;	register int what;{	if (cp == 0)		return ((what & RESTOP) != 0);	if (cp[1] == 0) {		if (what & ADDOP && (*cp == '+' || *cp == '-'))			return (1);		if (what & MULOP && (*cp == '*' || *cp == '/' || *cp == '%'))			return (1);		if (what & RESTOP && (*cp == '(' || *cp == ')' || *cp == '!' ||				      *cp == '~' || *cp == '^' || *cp == '"'))			return (1);	} else if (cp[2] == 0) {		if (what & RESTOP) {			if (cp[0] == '|' && cp[1] == '&')				return (1);			if (cp[0] == '<' && cp[1] == '<')				return (1);			if (cp[0] == '>' && cp[1] == '>')				return (1);		}		if (what & EQOP) {			if (cp[0] == '=') {				if (cp[1] == '=')					return (EQEQ);				if (cp[1] == '~')					return (EQMATCH);			} else if (cp[0] == '!') {				if (cp[1] == '=')					return (NOTEQ);				if (cp[1] == '~')					return (NOTEQMATCH);			}		}	}	if (what & RELOP) {		if (*cp == '<')			return (LSS);		if (*cp == '>')			return (GTR);	}	return (0);}egetn(cp)	register char *cp;{	if (*cp && *cp != '-' && !digit(*cp))		bferr("Expression syntax");	return (getn(cp));}/* Phew! */#ifdef EDEBUGetraci(str, i, vp)	char *str;	int i;	char ***vp;{	csh_printf("%s=%d\t", str, i);		/*  001 RNF  */	blkpr(*vp);	csh_printf("\n");			/*  001 RNF  */}etracc(str, cp, vp)	char *str, *cp;	char ***vp;{	csh_printf("%s=%s\t", str, cp);		/*  001 RNF  */	blkpr(*vp);	csh_printf("\n");			/*  001 RNF  */}#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?