sh.dol.c

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

C
768
字号
#ifndef lintstatic char *sccsid = "@(#)sh.dol.c	4.1  (ULTRIX)        7/17/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.dol.c,v 1.3 86/07/11 10:29:59 dce Exp $ */#include "sh.h"/* * C shell * * Modification History * * 003 - Gary A. Gaudet - Wed Jan 31 13:09:35 EST 1990 *	Fixed escape of command substitution and variable expansion *	in heredoc rediction. * * 002 - Gary A. Gaudet - Thu Dec 28 17:43:59 EST 1989 *	Added (castings). & TRIMming. * * 01 Sat Aug 13 15:28:57 EDT 1988, Gary A. Gaudet *	merging mips & ultrix for 8 bit clean and bug fixes *//* * These routines perform variable substitution and quoting via ' and ". * To this point these constructs have been preserved in the divided * input words.  Here we expand variables and turn quoting via ' and " into * QUOTE bits on characters (which prevent further interpretation). * If the `:q' modifier was applied during history expansion, then * some QUOTEing may have occurred already, so we dont "trim()" here. */int	Dpeekc, Dpeekrd;		/* Peeks for DgetC and Dreadc */char	*Dcp, **Dvp;			/* Input vector for Dreadc */#define	DEOF	-1#define	unDgetC(c)	Dpeekc = c#define QUOTES		(_Q|_Q1|_ESC)	/* \ ' " ` *//* * The following variables give the information about the current * $ expansion, recording the current word position, the remaining * words within this expansion, the count of remaining words, and the * information about any : modifier which is being applied. */char	*dolp;			/* Remaining chars from this word */char	**dolnxt;		/* Further words */int	dolcnt;			/* Count of further words */char	dolmod;			/* : modifier character */int	dolmcnt;		/* :gx -> 10000, else 1 *//* * Fix up the $ expansions and quotations in the * argument list to command t. */Dfix(t)	register struct command *t;{	register char **pp;	register char *p;	if (noexec)		return;	/* Note that t_dcom isn't trimmed thus !...:q's aren't lost */	for (pp = t->t_dcom; p = *pp++;)		while (*p)			if (cmap(*p++, _DOL|QUOTES)) {	/* $, \, ', ", ` */				Dfix2(t->t_dcom);	/* found one */				blkfree(t->t_dcom);				t->t_dcom = gargv;				gargv = 0;				return;			}}/* * $ substitute one word, for i/o redirection */char *Dfix1(cp)	register char *cp;{	char *Dv[2];	if (noexec)		return (0);	Dv[0] = cp; Dv[1] = NOSTR;	Dfix2(Dv);	if (gargc != 1) {		setname(cp);		bferr("Ambiguous");	}	cp = savestr(gargv[0]);	blkfree(gargv), gargv = 0;	return (cp);}/* * Subroutine to do actual fixing after state initialization. */Dfix2(v)	char **v;{	char *agargv[GAVSIZ];	ginit(agargv);			/* Initialize glob's area pointers */	Dvp = v; Dcp = "";		/* Setup input vector for Dreadc */	unDgetC(0); unDredc(0);		/* Clear out any old peeks (at error) */	dolp = 0; dolcnt = 0;		/* Clear out residual $ expands (...) */	while (Dword())		continue;	gargv = copyblk(gargv);}/* * Get a word.  This routine is analogous to the routine * word() in sh.lex.c for the main lexical input.  One difference * here is that we don't get a newline to terminate our expansion. * Rather, DgetC will return a DEOF when we hit the end-of-input. */Dword(){	register int c, c1;	char wbuf[BUFSIZ*2];	register char *wp = wbuf;	register int i = BUFSIZ*2 - 4*2;	register bool dolflg;	bool sofar = 0;loop:	c = DgetC(DODOL);	switch (c) {	case DEOF:deof:		if (sofar == 0)			return (0);		/* finish this word and catch the code above the next time */		unDredc(c);		/* fall into ... */	case '\n':		*wp = 0;		goto ret;	case ' ':	case '\t':		goto loop;	case '`':		/* We preserve ` quotations which are done yet later */		*wp++ = c, --i;	case '\'':	case '"':		/*		 * Note that DgetC never returns a QUOTES character		 * from an expansion, so only true input quotes will		 * get us here or out.		 */		c1 = c;		dolflg = c1 == '"' ? DODOL : 0;		for (;;) {			c = DgetC(dolflg);			if (c == c1)				break;			if (c == '\n' || c == DEOF)				error("Unmatched %c", c1);			if ((c & (QUOTE|TRIM)) == ('\n' | QUOTE)) 				/*				 * backout the previous character and its				 * QUOTECHAR				 */				wp -= 2, i +=2;			if (--i <= 0)				goto toochars;			switch (c1) {			case '"':				/*				 * Leave any `s alone for later.				 * Other chars are all quoted, thus `...`				 * can tell it was within "...".				 */				if (c != '`') {					*wp++ = QUOTECHAR;					i--;				}				*wp++ = c;				break;			case '\'':				/* Prevent all further interpretation */				*wp++ = (char) QUOTECHAR;	/* 002 - GAG */				i--;				*wp++ = c;				break;			case '`':				/* Leave all text alone for later */				*wp++ = c;				break;			}		}		if (c1 == '`')			*wp++ = '`', --i;		goto pack;		/* continue the word */	case '\\':		c = DgetC(0);		/* No $ subst! */		if (c == '\n' || c == DEOF)			goto loop;		c |= QUOTE;		break;	}	unDgetC(c);pack:	sofar = 1;	/* pack up more characters in this word */	for (;;) {		c = DgetC(DODOL);		if (c == '\\') {			c = DgetC(0);			if (c == DEOF)				goto deof;			if (c == '\n')				c = ' ';			else				c |= QUOTE;		}		if (c == DEOF)			goto deof;		if (any(c," \t\n'\"`")) {		/* sp \t\n'"` */			unDgetC(c);			if (any(c, "\\'\"`"))				goto loop;			*wp++ = 0;			goto ret;		}		if (--i <= 0)toochars:			error("Word too long");		if (c & QUOTE) {			*(unsigned char *)wp++ = QUOTECHAR;	/* 002 - GAG */			i--;		}		*wp++ = c & TRIM;	/* 002 - GAG */	}ret:	Gcat("", wbuf);	return (1);}/* * Get a character, performing $ substitution unless flag is 0. * Any QUOTES character which is returned from a $ expansion is * QUOTEd so that it will not be recognized above. */DgetC(flag)	register int flag;{	register int c;top:	if (c = Dpeekc) {		Dpeekc = 0;		return (c);	}	if (lap) {		if (((c = *lap++) & TRIM) == QUOTECHAR)			c = (*lap++ & TRIM) | QUOTE; /* GAG - fix "set a=$<" */		if (c == 0) {			lap = 0;			goto top;		}quotspec:		if (any(c, "\\'\"`"))			return (c | QUOTE);		return (c);	}	if (dolp) {		if (((c = *dolp++) & TRIM) == QUOTECHAR)			c = (*dolp++ & TRIM) | QUOTE; /* GAG - fix "set a=$<" */		if (c & (QUOTE|TRIM))			goto quotspec;		if (dolcnt > 0) {			setDolp(*dolnxt++);			--dolcnt;			return (' ');		}		dolp = 0;	}	if (dolcnt > 0) {		setDolp(*dolnxt++);		--dolcnt;		goto top;	}	c = Dredc();	if (c == '$' && flag) {		Dgetdol();		goto top;	}	return (c);}char	*nulvec[] = { 0 };struct	varent nulargv = { nulvec, "argv", 0 };/* * Handle the multitudinous $ expansion forms. * Ugh. */Dgetdol(){	register char *np;	register struct varent *vp;	char name[20];	int c, sc;	int subscr = 0, lwb = 1, upb = 0;	bool dimen = 0, bitset = 0;	char wbuf[BUFSIZ];	dolmod = dolmcnt = 0;	c = sc = DgetC(0);	if (c == '{')		c = DgetC(0);		/* sc is { to take } later */	if ((c & TRIM) == '#')		dimen++, c = DgetC(0);		/* $# takes dimension */	else if (c == '?')		bitset++, c = DgetC(0);		/* $? tests existence */	switch (c) {		case '$':		if (dimen || bitset)			goto syntax;		/* No $?$, $#$ */		setDolp(doldol);		goto eatbrac;	case '<'|QUOTE:		if (dimen || bitset)			goto syntax;		/* No $?<, $#< */		for (np = wbuf; read(OLDSTD, np, 1) == 1; np++) {			if (np >= &wbuf[BUFSIZ-1])				error("$< line too long");			if (*np <= 0 || *np == '\n')				break;		}		*np = 0;		/*		 * KLUDGE: dolmod is set here because it will		 * cause setDolp to call domod and thus to copy wbuf.		 * Otherwise setDolp would use it directly. If we saved		 * it ourselves, no one would know when to free it.		 * The actual function of the 'q' causes filename		 * expansion not to be done on the interpolated value.

⌨️ 快捷键说明

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