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 = ¶ml; 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(¶ml); t = syntax(paraml.next, ¶ml, 0); if (err) error(err); execute(t, -1); freelex(¶ml), 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 + -
显示快捷键?