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

📄 prim.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Jump to a specified position in the file. */jump_loc(pos)	off_t pos;{	register int nline;	off_t tpos;	if ((nline = onscreen(pos)) >= 0) {		/*		 * The line is currently displayed.  		 * Just scroll there.		 */		forw(nline, position(BOTTOM_PLUS_ONE), 0);		return;	}	/*	 * Line is not on screen.	 * Seek to the desired location.	 */	if (ch_seek(pos)) {		error("Cannot seek to that position");		return;	}	/*	 * See if the desired line is BEFORE the currently displayed screen.	 * If so, then move forward far enough so the line we're on will be	 * at the bottom of the screen, in order to be able to call back()	 * to make the screen scroll backwards & put the line at the top of	 * the screen.	 * {{ This seems inefficient, but it's not so bad,	 *    since we can never move forward more than a	 *    screenful before we stop to redraw the screen. }}	 */	tpos = position(TOP);	if (tpos != NULL_POSITION && pos < tpos) {		off_t npos = pos;		/*		 * Note that we can't forw_line() past tpos here,		 * so there should be no EOI at this stage.		 */		for (nline = 0;  npos < tpos && nline < sc_height - 1;  nline++)			npos = forw_line(npos);		if (npos < tpos) {			/*			 * More than a screenful back.			 */			lastmark();			clear();			pos_clear();			add_back_pos(npos);		}		/*		 * Note that back() will repaint() if nline > back_scroll.		 */		back(nline, npos, 0);		return;	}	/*	 * Remember where we were; clear and paint the screen.	 */	lastmark();	prepaint(pos);}/* * The table of marks. * A mark is simply a position in the file. */#define	NMARKS		(27)		/* 26 for a-z plus one for quote */#define	LASTMARK	(NMARKS-1)	/* For quote */static off_t marks[NMARKS];/* * Initialize the mark table to show no marks are set. */init_mark(){	int i;	for (i = 0;  i < NMARKS;  i++)		marks[i] = NULL_POSITION;}/* * See if a mark letter is valid (between a and z). */	static intbadmark(c)	int c;{	if (c < 'a' || c > 'z')	{		error("Choose a letter between 'a' and 'z'");		return (1);	}	return (0);}/* * Set a mark. */setmark(c)	int c;{	if (badmark(c))		return;	marks[c-'a'] = position(TOP);}lastmark(){	marks[LASTMARK] = position(TOP);}/* * Go to a previously set mark. */gomark(c)	int c;{	off_t pos;	if (c == '\'') {		pos = marks[LASTMARK];		if (pos == NULL_POSITION)			pos = 0;	}	else {		if (badmark(c))			return;		pos = marks[c-'a'];		if (pos == NULL_POSITION) {			error("mark not set");			return;		}	}	jump_loc(pos);}/* * Get the backwards scroll limit. * Must call this function instead of just using the value of * back_scroll, because the default case depends on sc_height and * top_scroll, as well as back_scroll. */get_back_scroll(){	if (back_scroll >= 0)		return (back_scroll);	if (top_scroll)		return (sc_height - 2);	return (sc_height - 1);}/* * Search for the n-th occurence of a specified pattern,  * either forward or backward. */search(search_forward, pattern, n, wantmatch)	register int search_forward;	register char *pattern;	register int n;	int wantmatch;{	off_t pos, linepos;	register char *p;	register char *q;	int linenum;	int linematch;#ifdef RECOMP	char *re_comp();	char *errmsg;#else#ifdef REGCMP	char *regcmp();	static char *cpattern = NULL;#else	static char lpbuf[100];	static char *last_pattern = NULL;	char *strcpy();#endif#endif	/*	 * For a caseless search, convert any uppercase in the pattern to	 * lowercase.	 */	if (caseless && pattern != NULL)		for (p = pattern;  *p;  p++)			if (isupper(*p))				*p = tolower(*p);#ifdef RECOMP	/*	 * (re_comp handles a null pattern internally, 	 *  so there is no need to check for a null pattern here.)	 */	if ((errmsg = re_comp(pattern)) != NULL)	{		error(errmsg);		return(0);	}#else#ifdef REGCMP	if (pattern == NULL || *pattern == '\0')	{		/*		 * A null pattern means use the previous pattern.		 * The compiled previous pattern is in cpattern, so just use it.		 */		if (cpattern == NULL)		{			error("No previous regular expression");			return(0);		}	} else	{		/*		 * Otherwise compile the given pattern.		 */		char *s;		if ((s = regcmp(pattern, 0)) == NULL)		{			error("Invalid pattern");			return(0);		}		if (cpattern != NULL)			free(cpattern);		cpattern = s;	}#else	if (pattern == NULL || *pattern == '\0')	{		/*		 * Null pattern means use the previous pattern.		 */		if (last_pattern == NULL)		{			error("No previous regular expression");			return(0);		}		pattern = last_pattern;	} else	{		(void)strcpy(lpbuf, pattern);		last_pattern = lpbuf;	}#endif#endif	/*	 * Figure out where to start the search.	 */	if (position(TOP) == NULL_POSITION) {		/*		 * Nothing is currently displayed.  Start at the beginning		 * of the file.  (This case is mainly for searches from the		 * command line.		 */		pos = (off_t)0;	} else if (!search_forward) {		/*		 * Backward search: start just before the top line		 * displayed on the screen.		 */		pos = position(TOP);	} else {		/*		 * Start at the second screen line displayed on the screen.		 */		pos = position(TOP_PLUS_ONE);	}	if (pos == NULL_POSITION)	{		/*		 * Can't find anyplace to start searching from.		 */		error("Nothing to search");		return(0);	}	linenum = find_linenum(pos);	for (;;)	{		/*		 * Get lines until we find a matching one or 		 * until we hit end-of-file (or beginning-of-file 		 * if we're going backwards).		 */		if (sigs)			/*			 * A signal aborts the search.			 */			return(0);		if (search_forward)		{			/*			 * Read the next line, and save the 			 * starting position of that line in linepos.			 */			linepos = pos;			pos = forw_raw_line(pos);			if (linenum != 0)				linenum++;		} else		{			/*			 * Read the previous line and save the			 * starting position of that line in linepos.			 */			pos = back_raw_line(pos);			linepos = pos;			if (linenum != 0)				linenum--;		}		if (pos == NULL_POSITION)		{			/*			 * We hit EOF/BOF without a match.			 */			error("Pattern not found");			return(0);		}		/*		 * If we're using line numbers, we might as well		 * remember the information we have now (the position		 * and line number of the current line).		 */		if (linenums)			add_lnum(linenum, pos);		/*		 * If this is a caseless search, convert uppercase in the		 * input line to lowercase.		 */		if (caseless)			for (p = q = line;  *p;  p++, q++)				*q = isupper(*p) ? tolower(*p) : *p;		/*		 * Remove any backspaces along with the preceeding char.		 * This allows us to match text which is underlined or		 * overstruck.		 */		for (p = q = line;  *p;  p++, q++)			if (q > line && *p == '\b')				/* Delete BS and preceeding char. */				q -= 2;			else				/* Otherwise, just copy. */				*q = *p;		/*		 * Test the next line to see if we have a match.		 * This is done in a variety of ways, depending		 * on what pattern matching functions are available.		 */#ifdef REGCMP		linematch = (regex(cpattern, line) != NULL);#else#ifdef RECOMP		linematch = (re_exec(line) == 1);#else		linematch = match(pattern, line);#endif#endif		/*		 * We are successful if wantmatch and linematch are		 * both true (want a match and got it),		 * or both false (want a non-match and got it).		 */		if (((wantmatch && linematch) || (!wantmatch && !linematch)) &&		      --n <= 0)			/*			 * Found the line.			 */			break;	}	jump_loc(linepos);	return(1);}#if !defined(REGCMP) && !defined(RECOMP)/* * We have neither regcmp() nor re_comp(). * We use this function to do simple pattern matching. * It supports no metacharacters like *, etc. */staticmatch(pattern, buf)	char *pattern, *buf;{	register char *pp, *lp;	for ( ;  *buf != '\0';  buf++)	{		for (pp = pattern, lp = buf;  *pp == *lp;  pp++, lp++)			if (*pp == '\0' || *lp == '\0')				break;		if (*pp == '\0')			return (1);	}	return (0);}#endif

⌨️ 快捷键说明

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