⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 re.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	case AT_BOW:		if (linep != locrater && ismword(*linep)		&& (linep == REbolp || !ismword(linep[-1])))			continue;		return NO;	case AT_EOW:		if (linep != locrater && (*linep == '\0' || !ismword(*linep)) &&		    (linep != REbolp && ismword(linep[-1])))			continue;		return NO;	case ONE_OF:	case NONE_OF:		if (member(comp_ptr, *linep++, comp_ptr[-1] == ONE_OF)) {			comp_ptr += SETSIZE;			continue;		}		return NO;	case OPENP:		pstrtlst[*comp_ptr++] = linep;		continue;	case CLOSEP:		pendlst[*comp_ptr++] = linep;		continue;	case BACKREF:		if (pstrtlst[n = *comp_ptr++] == NULL) {			s_mess("\\%d was not specified.", n + 1);		} else if (backref(n, linep)) {			linep += pendlst[n] - pstrtlst[n];			continue;		}		return NO;	case CURLYB:	    {		int	wcnt;		bool	any;		wcnt = *comp_ptr++;		any = NO;		while (--wcnt >= 0) {			if (!any)				any = REmatch(linep, comp_ptr + 1);			comp_ptr += *comp_ptr;		}		if (!any)			return NO;		linep = loc2;		continue;	    }	case ANYC | STAR:		first_p = linep;		do ; while (*linep++);		goto star;	case NORMC | STAR:		first_p = linep;		do ; while (*comp_ptr == *linep++);		comp_ptr += 1;		goto star;	case CINDC | STAR:		first_p = linep;		do ; while (cind_cmp(*comp_ptr, *linep++));		comp_ptr += 1;		goto star;	case ONE_OF | STAR:	case NONE_OF | STAR:		first_p = linep;		do ; while (member(comp_ptr, *linep++, comp_ptr[-1] == (ONE_OF | STAR)));		comp_ptr += SETSIZE;		/* fall through */star:		/* linep points *after* first unmatched char.		 * first_p points at where starred element started matching.		 */		while (--linep > first_p) {			if ((*comp_ptr != NORMC || *linep == comp_ptr[2]) &&			    REmatch(linep, comp_ptr))				return YES;		}		continue;	case BACKREF | STAR:		first_p = linep;		n = *comp_ptr++;		while (backref(n, linep))			linep += pendlst[n] - pstrtlst[n];		while (linep > first_p) {			if (REmatch(linep, comp_ptr))				return YES;			linep -= pendlst[n] - pstrtlst[n];		}		continue;	default:		complain("RE error match (%d).", comp_ptr[-1]);	}	/* NOTREACHED */}private voidREreset(){	register int	i;	for (i = 0; i < NPAR; i++)		pstrtlst[i] = pendlst[i] = NULL;}/* Index LINE at OFFSET.  If lbuf_okay is nonzero it's okay to use linebuf   if LINE is the current line.  This should save lots of time in things   like paren matching in LISP mode.  Saves all that copying from linebuf   to a local buffer.  substitute() is the guy who calls re_lindex with   lbuf_okay as NO, since the substitution gets placed in linebuf ...   doesn't work too well when the source and destination strings are the   same.  I hate all these arguments!   This code is cumbersome, repetetive for reasons of efficiency.  Fast   search is a must as far as I am concerned. */boolre_lindex(line, offset, dir, re_blk, lbuf_okay, crater)Line	*line;int	offset;int	dir;struct RE_block	*re_blk;int	lbuf_okay;int	crater;	/* offset of previous substitute (or -1) */{	register char	*p;	register int	firstc = re_blk->r_firstc;	register int	anchored = re_blk->r_anchored;	char		**alts = re_blk->r_alternates;	REreset();	if (lbuf_okay) {		REbolp = lbptr(line);		if (offset == -1)			offset = strlen(REbolp);	/* arg! */	} else {		REbolp = ltobuf(line, re_blk->r_lbuf);		if (offset == -1) {	/* Reverse search, find end of line. */			offset = Jr_Len;	/* Just Read Len. */		}	}	if (anchored == YES) {		if (dir == FORWARD) {			if (offset != 0 || crater != -1)				return NO;		} else {			offset = 0;		}	}	p = REbolp + offset;	locrater = REbolp + crater;	if (firstc != '\0') {		char	*first_alt = *alts;		if (dir == FORWARD) {			while (CharUpcase(*p) != firstc || !REmatch(p, first_alt))				if (*p++ == '\0')					return NO;		} else {			while (CharUpcase(*p) != firstc || !REmatch(p, first_alt))				if (--p < REbolp)					return NO;		}	} else {		for (;;) {			register char	**altp = alts;			while (*altp != NULL)				if (REmatch(p, *altp++))					goto success;			if (anchored ||			    (dir == FORWARD ? *p++ == '\0' : --p < REbolp))				return NO;		}success:;	}	loc1 = p;	REbom = loc1 - REbolp;	return YES;}bool	okay_wrap = NO;	/* Do a wrap search ... not when we're			   parsing errors ... */Bufpos *dosearch(pattern, dir, re)char	*pattern;int	dir;bool	re;{	Bufpos	*pos;	struct RE_block	re_blk;		/* global re-compiled buffer */	if (bobp() && eobp())	/* Can't match!  There's no buffer. */		return NULL;	REcompile(pattern, re, &re_blk);	pos = docompiled(dir, &re_blk);	return pos;}Bufpos *docompiled(dir, re_blk)int dir;register struct RE_block	*re_blk;{	static Bufpos	ret;	register Line	*lp;	register int	offset;	int	we_wrapped = NO;	lsave();	/* Search now lsave()'s so it doesn't make any assumptions on	   whether the the contents of curline/curchar are in linebuf.	   Nowhere does search write all over linebuf.  However, we have to	   be careful about what calls we make here, because many of them	   assume (and rightly so) that curline is in linebuf. */	lp = curline;	offset = curchar;	if (dir == BACKWARD) {		if (bobp()) {			if (okay_wrap && WrapScan)				goto doit;			return NULL;		}		/* here we simulate BackChar() */		if (bolp()) {			lp = lp->l_prev;			offset = length(lp);		} else {			offset -= 1;		}	} else if (dir==FORWARD && lbptr(lp)[offset]=='\0' && !lastp(lp)) {		lp = lp->l_next;		offset = 0;	}	do {		if (re_lindex(lp, offset, dir, re_blk, YES, -1))			break;doit:		lp = (dir == FORWARD) ? lp->l_next : lp->l_prev;		if (lp == NULL) {			if (okay_wrap && WrapScan) {				lp = (dir == FORWARD) ?				     curbuf->b_first : curbuf->b_last;				we_wrapped = YES;			} else				 break;		}		if (dir == FORWARD)			offset = 0;		else			offset = -1;	/* signals re_lindex ... */	} while (lp != curline);	if (lp == curline && we_wrapped)		lp = NULL;	if (lp == NULL)		return NULL;	ret.p_line = lp;	ret.p_char = (dir == FORWARD) ? REeom : REbom;	return &ret;}private char *insert(off, endp, which)char	*off,	*endp;int which;{	register char	*pp;	register int	n;	n = pendlst[which] - pstrtlst[which];	pp = pstrtlst[which];	while (--n >= 0) {		*off++ = *pp++;		if (off >= endp)			len_error(ERROR);	}	return off;}/* Perform the substitution.  If DELP is nonzero the matched string is   deleted, i.e., the substitution string is not inserted. */voidre_dosub(re_blk, tobuf, delp)struct RE_block	*re_blk;char	*tobuf;int delp;{	register char	*tp,			*rp;	char	*endp;	tp = tobuf;	endp = tp + LBSIZE;	rp = re_blk->r_lbuf;	while (rp < loc1)		*tp++ = *rp++;	if (!delp) {		register int	c;		rp = rep_str;		while ((c = *rp++) != '\0') {			if (c == '\\') {				c = *rp++;				if (c >= '0' && c < re_blk->r_nparens + '0') {					tp = insert(tp, endp, c - '0');					continue;				}				if (c == '\0') {					*tp++ = '\\';					rp--;   /* be sure to hit again */				}			}			*tp++ = c;			if (tp >= endp)				len_error(ERROR);		}	}	rp = loc2;	REdelta = -REeom;	REeom = tp - tobuf;	REdelta += REeom;	if (loc1==rp && *rp!='\0') {		/* Skip an extra character if the matched text was a null		 * string, but don't skip over the end of line.  This is to		 * prevent an infinite number of replacements in the same		 * position, e.g., replace "^" with "".		 */		REeom += 1;	}	loc2 = re_blk->r_lbuf + REeom;	while ((*tp++ = *rp++) != '\0')		if (tp >= endp)			len_error(ERROR);}voidputmatch(which, buf, size)int which;char	*buf;size_t size;{	*(insert(buf, buf + size, which)) = '\0';}voidsetsearch(str)char	*str;{	strcpy(searchstr, str);}char *getsearch(){	return searchstr;}voidRErecur(){	char	repbuf[sizeof rep_str];	Mark	*m = MakeMark(curline, REbom, M_FLOATER);	message("Type C-X C-C to continue with query replace.");	byte_copy(rep_str, repbuf, sizeof rep_str);	Recur();	byte_copy(repbuf, rep_str, sizeof rep_str);	if (!is_an_arg())		ToMark(m);	DelMark(m);}voidForSearch(){	search(FORWARD, UseRE, YES);}voidRevSearch(){	search(BACKWARD, UseRE, YES);}voidFSrchND(){	search(FORWARD, UseRE, NO);}voidRSrchND(){	search(BACKWARD, UseRE, NO);}private voidsearch(dir, re, setdefault)int	dir;bool	re,	setdefault;{	Bufpos	*newdot;	char	*s;	s = ask(searchstr, ProcFmt);	if (setdefault)		setsearch(s);	okay_wrap = YES;	newdot = dosearch(s, dir, re);	okay_wrap = NO;	if (newdot == NULL) {		if (WrapScan)			complain("No \"%s\" in buffer.", s);		else			complain("No \"%s\" found to %s.", s,				 (dir == FORWARD) ? "bottom" : "top");	}	PushPntp(newdot->p_line);	SetDot(newdot);}/* Do we match PATTERN at OFFSET in BUF? */boolLookingAt(pattern, buf, offset)char	*pattern,	*buf;int offset;{	struct RE_block	re_blk;	char	**alt = re_blk.r_alternates;	REcompile(pattern, YES, &re_blk);	REreset();	locrater = NULL;	REbolp = buf;	while (*alt)		if (REmatch(buf + offset, *alt++))			return YES;	return NO;}boollook_at(expr)char	*expr;{	struct RE_block	re_blk;	REcompile(expr, NO, &re_blk);	REreset();	locrater = NULL;	REbolp = linebuf;	if (REmatch(linebuf + curchar, re_blk.r_alternates[0]))		return YES;	return NO;}

⌨️ 快捷键说明

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