sh.lex.c

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

C
1,440
字号
				if (c != delim /* && c != '~' */)					*cp++ = '\\';			}			*cp++ = c;		}		*cp++ = 0;		break;	default:		if (c == '\n')			unreadc(c);		seterrc("Bad ! modifier: ", (char) c);		goto ret;	}	(void) strcpy(slhs, lhsb);	if (exclc)		en = dosub(sc, en, global);ret:	return (en);}struct wordent *dosub(sc, en, global)	int sc;	struct wordent *en;	bool global;{	struct wordent lex;	bool didsub = 0;	struct wordent *hp = &lex;	register struct wordent *wdp;	register int i = exclc;	wdp = hp;	while (--i >= 0) {		register struct wordent *new = (struct wordent *) calloc(1, sizeof *wdp);		new->prev = wdp;		new->next = hp;		wdp->next = new;		wdp = new;		en = en->next;		wdp->word = global || didsub == 0 ?		    subword(en->word, sc, &didsub) : savestr(en->word);	}	if (didsub == 0)		seterr("Modifier failed");	hp->prev = wdp;	return (&enthist(-1000, &lex, 0)->Hlex);}char *subword(cp, type, adid)	char *cp;	int type;	bool *adid;{	char wbuf[BUFSIZ];	register char *wp, *mp, *np;	register int i;	switch (type) {	case 'r':	case 'e':	case 'h':	case 't':	case 'q':	case 'x':		wp = domod(cp, type);		if (wp == 0)			return (savestr(cp));		*adid = 1;		return (wp);	default:		wp = wbuf;		i = BUFSIZ - 4;		for (mp = cp; *mp; mp++)			if (matchs(mp, lhsb)) {				for (np = cp; np < mp;)					*wp++ = *np++, --i;				for (np = rhsb; *np; np++) switch (*np) {				case '\\':					if (np[1] == '&')						np++;					/* fall into ... */				default:					if (--i < 0)						goto ovflo;					*wp++ = *np;					continue;				case '&':					i -= strlen(lhsb);					if (i < 0)						goto ovflo;					*wp = 0;					(void) strcat(wp, lhsb);					wp = strend(wp);					continue;				}				mp += strlen(lhsb);				i -= strlen(mp);				if (i < 0) {ovflo:					seterr("Subst buf ovflo");					return ("");				}				*wp = 0;				(void) strcat(wp, mp);				*adid = 1;				return (savestr(wbuf));			}		return (savestr(cp));	}}char *domod(cp, type)	char *cp;	int type;{	char wbuf[BUFSIZ];	register char *wp, *xp;	register int c;	switch (type) {	case 'x':	case 'q':		for (xp = wbuf; c = *cp++; ) {			if ((c != ' ' && c != '\t') || type == 'q')				*xp++ = QUOTECHAR;			*xp++ = c;		}		*xp = '\0';		return (savestr(wbuf));	case 'h':	case 't':		if (!any('/', cp))			return (type == 't' ? savestr(cp) : 0);		wp = strend(cp);		while (*--wp != '/')			continue;		if (type == 'h')			xp = savestr(cp), xp[wp - cp] = 0;		else			xp = savestr(wp + 1);		return (xp);	case 'e':	case 'r':		wp = strend(cp);		for (wp--; wp >= cp && *wp != '/'; wp--)			if (*wp == '.') {				if (type == 'e')					xp = savestr(wp + 1);				else					xp = savestr(cp), xp[wp - cp] = 0;				return (xp);			}		return (savestr(type == 'e' ? "" : cp));	}	return (0);}matchs(str, pat)	register char *str, *pat;{	while (*str && *pat && *str == *pat)		str++, pat++;	return (*pat == 0);}getsel(al, ar, dol)	register int *al, *ar;	int dol;{	register int c = getC(0);	register int i;	bool first = *al < 0;	switch (c) {	case '%':		if (quesarg == -1)			goto bad;		if (*al < 0)			*al = quesarg;		*ar = quesarg;		break;	case '-':		if (*al < 0) {			*al = 0;			*ar = dol - 1;			unreadc(c);		}		return (1);	case '^':		if (*al < 0)			*al = 1;		*ar = 1;		break;	case '$':		if (*al < 0)			*al = dol;		*ar = dol;		break;	case '*':		if (*al < 0)			*al = 1;		*ar = dol;		if (*ar < *al) {			*ar = 0;			*al = 1;			return (1);		}		break;	default:		if (digit(c)) {			i = 0;			while (digit(c)) {				i = i * 10 + c - '0';				c = getC(0);			}			if (i < 0)				i = dol + 1;			if (*al < 0)				*al = i;			*ar = i;		} else			if (*al < 0)				*al = 0, *ar = dol;			else				*ar = dol - 1;		unreadc(c);		break;	}	if (first) {		c = getC(0);		unreadc(c);		if (any(c, "-$*"))			return (1);	}	if (*al > *ar || *ar > dol) {bad:		seterr("Bad ! arg selector");		return (0);	}	return (1);}struct wordent *gethent(sc)	int sc;{	register struct Hist *hp;	register char *np;	register int c;	int event;	bool back = 0;	c = sc == HISTSUB ? HIST : getC(0);	if (c == HIST) {		if (alhistp)			return (alhistp);		event = eventno;		goto skip;	}	switch (c) {	case ':':	case '^':	case '$':	case '*':	case '%':		ungetC(c);		if (lastev == eventno && alhistp)			return (alhistp);		event = lastev;		break;	case '-':		back = 1;		c = getC(0);		goto number;	case '#':			/* !# is command being typed in (mrh) */		return(&paraml);	default:		if (any(c, "(=~")) {			unreadc(c);			ungetC(HIST);			return (0);		}		if (digit(c))			goto number;		np = lhsb;		while (!any(c, ": \t\\\n}")) {			if (np < &lhsb[sizeof lhsb - 2])				*np++ = c;			c = getC(0);		}		unreadc(c);		if (np == lhsb) {			ungetC(HIST);			return (0);		}		*np++ = 0;		hp = findev(lhsb, 0);		if (hp)			lastev = hp->Hnum;		return (&hp->Hlex);	case '?':		np = lhsb;		for (;;) {			c = getC(0);			if (c == '\n') {				unreadc(c);				break;			}			if (c == '?')				break;			if (np < &lhsb[sizeof lhsb - 2])				*np++ = c;		}		if (np == lhsb) {			if (lhsb[0] == 0) {				seterr("No prev search");				return (0);			}		} else			*np++ = 0;		hp = findev(lhsb, 1);		if (hp)			lastev = hp->Hnum;		return (&hp->Hlex);	number:		event = 0;		while (digit(c)) {			event = event * 10 + c - '0';			c = getC(0);		}		if (back)			event = eventno + (alhistp == 0) - (event ? event : 0);		unreadc(c);		break;	}skip:	for (hp = Histlist.Hnext; hp; hp = hp->Hnext)		if (hp->Hnum == event) {			hp->Href = eventno;			lastev = hp->Hnum;			return (&hp->Hlex);		}	np = putn(event);	noev(np);	return (0);}struct Hist *findev(cp, anyarg)	char *cp;	bool anyarg;{	register struct Hist *hp;	for (hp = Histlist.Hnext; hp; hp = hp->Hnext) {		char *dp;		register char *p, *q;		register struct wordent *lp = hp->Hlex.next;		int argno = 0;		if (lp->word[0] == '\n')			continue;		if (!anyarg) {			p = cp;			q = lp->word;			do				if (!*p)					return (hp);			while (*p++ == *q++);			continue;		}		do {			for (dp = lp->word; *dp; dp++) {				p = cp;				q = dp;				do					if (!*p) {						quesarg = argno;						return (hp);					}				while (*p++ == *q++);			}			lp = lp->next;			argno++;		} while (lp->word[0] != '\n');	}	noev(cp);	return (0);}noev(cp)	char *cp;{	seterr2(cp, ": Event not found");}setexclp(cp)	register char *cp;{	if (cp && cp[0] == '\n')		return;	exclp = cp;}unreadc(c)	unsigned char c;{	peekread = c;}readc(wanteof)	bool wanteof;{	register int c;	static sincereal;	if (c = peekread) {		peekread = 0;		return (c);	}top:	if (alvecp) {		if (c = *alvecp++)			return (c);		if (*alvec) {			alvecp = *alvec++;			return (' ');		}	}	if (alvec) {		if (alvecp = *alvec) {			alvec++;			goto top;		}		/* Infinite source! */		return ('\n');	}	if (evalp) {		if (c = *evalp++)			return (c);		if (*evalvec) {			evalp = *evalvec++;			return (' ');		}		evalp = 0;	}	if (evalvec) {		if (evalvec == (char **)1) {			doneinp = 1;			reset();		}		if (evalp = *evalvec) {			evalvec++;			goto top;		}		evalvec = (char **)1;		return ('\n');	}	do {		if (arginp == (char *) 1 || onelflg == 1) {			if (wanteof)				return (-1);			exitstat();		}		if (arginp) {			if ((c = *arginp++) == 0) {				arginp = (char *) 1;				return ('\n');			}			return (c);		}reread:		c = bgetc();		if (c == -1) {			struct sgttyb tty;			if (wanteof)				return (-1);			/* was isatty but raw with ignoreeof yields problems */			if (ioctl(SHIN, TIOCGETP, (char *)&tty) == 0 &&			    (tty.sg_flags & RAW) == 0) {				/* was 'short' for FILEC */				int ctpgrp;				if (++sincereal > 25)					goto oops;				if (tpgrp != -1 &&				    ioctl(FSHTTY, TIOCGPGRP, (char *)&ctpgrp) == 0 &&				    tpgrp != ctpgrp) {					(void) ioctl(FSHTTY, TIOCSPGRP,						(char *)&tpgrp);					(void) killpg(ctpgrp, SIGHUP);csh_printf("Reset tty pgrp from %d to %d\n", ctpgrp, tpgrp); /* 005 RNF */					goto reread;				}				if (adrof("ignoreeof")) {					if (loginsh)						csh_printf("\nUse \"logout\" to logout.\n"); /* 005 RNF */					else						csh_printf("\nUse \"exit\" to leave csh.\n"); /* 005 RNF */					reset();				}				if (chkstop == 0)					panystop(1);			} else {	/* 002 - GAG */				/*Perror ("ioctl");*/			}oops:			doneinp = 1;			reset();		}		sincereal = 0;		if (c == '\n' && onelflg)			onelflg--;	} while (c == 0);	return (c);}bgetc(){	register int buf, off, c;	register int roomleft;#ifdef TENEX	register int numleft = 0;	char ttyline[BUFSIZ];#endif#ifdef TELL	if (cantell) {		if (fseekp < fbobp || fseekp > feobp) {			fbobp = feobp = fseekp;			(void) lseek(SHIN, fseekp, 0);		}		if (fseekp == feobp) {			fbobp = feobp;			do				c = read(SHIN, fbuf[0], BUFSIZ);			while (c < 0 && errno == EINTR);			if (c <= 0)				return (-1);			feobp += c;		}		c = fbuf[0][fseekp - fbobp];		fseekp++;		return (c & TRIM);	}#endifagain:	buf = (int) fseekp / BUFSIZ;	if (buf >= fblocks) {		register char **nfbuf =			(char **) calloc((unsigned) (fblocks + 2),				sizeof (char **));		if (fbuf) {			(void) blkcpy(nfbuf, fbuf);			xfree((char *)fbuf);		}		fbuf = nfbuf;		fbuf[fblocks] = calloc(BUFSIZ, sizeof (char));		fblocks++;		goto again;	}	if (fseekp >= feobp) {		buf = (int) feobp / BUFSIZ;		off = (int) feobp % BUFSIZ;		roomleft = BUFSIZ - off;		for (;;) {			/* break out: see below */#ifdef TENEX			if (intty)		/* then use tenex routine */			{				c = numleft ? numleft : tenex(ttyline, BUFSIZ);				if (c > roomleft) /* No room in this buffer? */				{					/* start with fresh buffer */					feobp = fseekp = fblocks * BUFSIZ;					numleft = c;					goto again;				}				if (c > 0)					copy (fbuf[buf] + off, ttyline, c);				numleft = 0;			}			else				c = read(SHIN, fbuf[buf] + off, roomleft);			if ((c >= 0) || (errno != EINTR))				break;#else not tenex			c = read(SHIN, fbuf[buf] + off, BUFSIZ - off);			if (c >= 0)				break;			if (errno == EWOULDBLOCK) {				int off = 0;				(void) ioctl(SHIN, FIONBIO, (char *)&off);			} else if (errno != EINTR)				break;#endif		} /* end "for (;;)" */		if (c <= 0)			return (-1);		feobp += c;#ifdef TENEX		if (!intty)#endif		    goto again;	}	c = fbuf[buf][(int) fseekp % BUFSIZ];	fseekp++;	return (c);}bfree(){	register int sb, i;#ifdef TELL	if (cantell)		return;#endif	if (whyles)		return;	sb = (int) (fseekp - 1) / BUFSIZ;	if (sb > 0) {		for (i = 0; i < sb; i++)			xfree(fbuf[i]);		(void) blkcpy(fbuf, &fbuf[sb]);		fseekp -= BUFSIZ * sb;		feobp -= BUFSIZ * sb;		fblocks -= sb;	}}bseek(l)	off_t l;{	register struct whyle *wp;	fseekp = l;#ifdef TELL	if (!cantell) {#endif		if (!whyles)			return;		for (wp = whyles; wp->w_next; wp = wp->w_next)			continue;		if (wp->w_start > l)			l = wp->w_start;#ifdef TELL	}#endif}/* any similarity to bell telephone is purely accidental */#ifndef btelloff_tbtell(){	return (fseekp);}#endifbtoeof(){	(void) lseek(SHIN, (off_t)0, 2);	fseekp = feobp;	wfree();	bfree();}#ifdef TELLsettell(){	cantell = 0;	if (arginp || onelflg || intty)		return;	if (lseek(SHIN, (off_t)0, 1) < 0 || errno == ESPIPE)		return;	fbuf = (char **) calloc(2, sizeof (char **));	fblocks = 1;	fbuf[0] = calloc(BUFSIZ, sizeof (char));	fseekp = fbobp = feobp = lseek(SHIN, (off_t)0, 1);	cantell = 1;}#endif

⌨️ 快捷键说明

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