sh.dol.c

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

C
768
字号
		 */		dolmod = 'q';		dolmcnt = 10000;		setDolp(wbuf);		goto eatbrac;	case DEOF:	case '\n':		goto syntax;	case '*':		(void) strcpy(name, "argv");		vp = adrof("argv");		subscr = -1;			/* Prevent eating [...] */		break;	default:		np = name;		if (digit(c)) {			if (dimen)				goto syntax;	/* No $#1, e.g. */			subscr = 0;			do {				subscr = subscr * 10 + c - '0';				c = DgetC(0);			} while (digit(c));			unDredc(c);			if (subscr < 0)				goto oob;			if (subscr == 0) {				if (bitset) {					dolp = file ? "1" : "0";					goto eatbrac;				}				if (file == 0)					error("No file for $0");				setDolp(file);				goto eatbrac;			}			if (bitset)				goto syntax;			vp = adrof("argv");			if (vp == 0) {				vp = &nulargv;				goto eatmod;			}			break;		}		/* GT01: must start with an alphabetic */		if (!letter(c))			goto syntax;		for (;;) {			*np++ = c;			c = DgetC(0);			if (!alnum(c))				break;			if (np >= &name[sizeof name - 2])syntax:				error("Variable syntax");		}		*np++ = 0;		unDredc(c);		vp = adrof(name);	}	if (bitset) {		dolp = (vp || getenv(name)) ? "1" : "0";		goto eatbrac;	}	if (vp == 0) {		np = getenv(name);		if (np) {			addla(np);			goto eatbrac;		}		udvar(name);		/*NOTREACHED*/	}	c = DgetC(0);	upb = blklen(vp->vec);	if (dimen == 0 && subscr == 0 && c == '[') {		np = name;		for (;;) {			c = DgetC(DODOL);	/* Allow $ expand within [ ] */			if (c == ']')				break;			if (c == '\n' || c == DEOF)				goto syntax;			if (np >= &name[sizeof name - 2])				goto syntax;			*np++ = c;		}		*np = 0, np = name;		if (dolp || dolcnt)		/* $ exp must end before ] */			goto syntax;		if (!*np)			goto syntax;		if (digit(*np)) {			register int i = 0;			while (digit(*np))				i = i * 10 + *np++ - '0';			if ((i < 0 || i > upb) && !any(*np, "-*")) {oob:				setname(vp->v_name);				error("Subscript out of range");			}			lwb = i;			if (!*np)				upb = lwb, np = "*";		}		if (*np == '*')			np++;		else if (*np != '-')			goto syntax;		else {			register int i = upb;			np++;			if (digit(*np)) {				i = 0;				while (digit(*np))					i = i * 10 + *np++ - '0';				if (i < 0 || i > upb)					goto oob;			}			if (i < lwb)				upb = lwb - 1;			else				upb = i;		}		if (lwb == 0) {			if (upb != 0)				goto oob;			upb = -1;		}		if (*np)			goto syntax;	} else {		if (subscr > 0)			if (subscr > upb)				lwb = 1, upb = 0;			else				lwb = upb = subscr;		unDredc(c);	}	if (dimen) {		char *cp = putn(upb - lwb + 1);		addla(cp);		xfree(cp);	} else {eatmod:		c = DgetC(0);		if (c == ':') {			c = DgetC(0), dolmcnt = 1;			if (c == 'g')				c = DgetC(0), dolmcnt = 10000;			if (!any(c, "htrqxe"))				error("Bad : mod in $");			dolmod = c;			if (c == 'q')				dolmcnt = 10000;		} else			unDredc(c);		dolnxt = &vp->vec[lwb - 1];		dolcnt = upb - lwb + 1;	}eatbrac:	if (sc == '{') {		c = Dredc();		if (c != '}')			goto syntax;	}}setDolp(cp)	register char *cp;{	register char *dp;	if (dolmod == 0 || dolmcnt == 0) {		dolp = cp;		return;	}	dp = domod(cp, dolmod);	if (dp) {		dolmcnt--;		addla(dp);		xfree(dp);	} else		addla(cp);	dolp = "";}unDredc(c)	int c;{	Dpeekrd = c;}Dredc(){	register int c;	if (c = Dpeekrd) {		Dpeekrd = 0;		return (c);	}	if (Dcp && (c = *Dcp++)) {		if ((c  & TRIM) == QUOTECHAR)			c = (*Dcp++ & TRIM) | QUOTE;		return (c&(QUOTE|TRIM));	}	if (*Dvp == 0) {		Dcp = 0;		return (DEOF);	}	Dcp = *Dvp++;	return (' ');}Dtestq(c)	register int c;{	if (any(c, "\\'\"`"))		gflag = 1;}/* * Form a shell temporary file (in unit 0) from the words * of the shell input up to a line the same as "term". * Unit 0 should have been closed before this call. */heredoc(term)	char *term;{	register int c;	char *Dv[2];	char obuf[BUFSIZ], lbuf[BUFSIZ], mbuf[BUFSIZ];	int ocnt, lcnt, mcnt;	register char *lbp, *obp, *mbp;	char **vp;	bool quoted;	if (creat(shtemp, 0600) < 0)		Perror(shtemp);	(void) close(0);	if (open(shtemp, 2) < 0) {		int oerrno = errno;		(void) unlink(shtemp);		errno = oerrno;		Perror(shtemp);	}	(void) unlink(shtemp);			/* 0 0 inode! */	Dv[0] = term; Dv[1] = NOSTR; gflag = 0;	trim(Dv); rscan(Dv, Dtestq); quoted = gflag;	ocnt = BUFSIZ; obp = obuf;	for (;;) {		/*		 * Read up a line		 */		lbp = lbuf; lcnt = BUFSIZ - 4;		for (;;) {			c = readc(1);		/* 1 -> Want EOF returns */			if (c == (-1)) {	/* ARG - compare correctly */				setname(term);				bferr("<< terminator not found");			}			if (c == '\n')				break;			if (c &= TRIM) {				*lbp++ = c;				if (--lcnt < 0) {					setname("<<");					error("Line overflow");				} 			}		}		*lbp = 0;		/*		 * Compare to terminator -- before expansion		 */		if (eq(lbuf, term)) {			(void) write(0, obuf, BUFSIZ - ocnt);			(void) lseek(0, (off_t)0, 0);			return;		}		/*		 * If term was quoted or -n just pass it on		 */		if (quoted || noexec) {			*lbp++ = '\n'; *lbp = 0;			for (lbp = lbuf; c = *lbp++;) {				*obp++ = c;				if (--ocnt == 0) {					(void) write(0, obuf, BUFSIZ);					obp = obuf; ocnt = BUFSIZ;				}			}			continue;		}		/*		 * Term wasn't quoted so variable and then command		 * expand the input line		 */		Dcp = lbuf; Dvp = Dv + 1; mbp = mbuf; mcnt = BUFSIZ - 4;		for (;;) {			c = DgetC(DODOL);			if (c == DEOF)				break;			if ((c &= TRIM) == 0)				continue;			/* \ quotes \ $ ` here */			if (c =='\\') {				c = DgetC(0);				if (!any(c, "$\\`"))					unDgetC(c | QUOTE), c = '\\';				else					*mbp++ = QUOTECHAR, c |= QUOTE;	/* 003 - GAG */			}			*mbp++ = c & TRIM;	/* 003 - GAG */			if (--mcnt == 0) {				setname("<<");				bferr("Line overflow");			}		}		*mbp = 0;	/* 003 - GAG */		/*		 * If any ` in line do command substitution		 */		for (mbp = mbuf; *mbp; mbp++) {			if ((*mbp & TRIM) == QUOTECHAR)				mbp++;			else if (any(*mbp, "`")) {				/*				 * 1 arg to dobackp causes substitution to be literal.				 * Words are broken only at newlines so that all blanks				 * and tabs are preserved.  Blank lines (null words)				 * are not discarded.				 */				vp = dobackp(mbuf, 1);				break;			}		}		if (!*mbp) {	/* no ` in string; mbp points to NULL */			mbp = mbuf;			/* Setup trivial vector similar to return of dobackp */			Dv[0] = mbp, Dv[1] = NOSTR, vp = Dv;		}		/*		 * Resurrect the words from the command substitution		 * each separated by a newline.  Note that the last		 * newline of a command substitution will have been		 * discarded, but we put a newline after the last word		 * because this represents the newline after the last		 * input line!		 */		trim (vp);	/* 003 - GAG */		for (; *vp; vp++) {			for (mbp = *vp; *mbp; mbp++) {				*obp++ = *mbp & TRIM;				if (--ocnt == 0) {					(void) write(0, obuf, BUFSIZ);					obp = obuf; ocnt = BUFSIZ;				}			}			*obp++ = '\n';			if (--ocnt == 0) {				(void) write(0, obuf, BUFSIZ);				obp = obuf; ocnt = BUFSIZ;			}		}		if (pargv)			blkfree(pargv), pargv = 0;	}}

⌨️ 快捷键说明

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