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

📄 cmd2.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* cmd2.c *//* Author: *	Steve Kirkendall *	14407 SW Teal Blvd. #C *	Beaverton, OR 97005 *	kirkenda@cs.pdx.edu *//* This file contains some of the commands - mostly ones that change text */#include "config.h"#include "ctype.h"#include "vi.h"#include "regexp.h"#if TOS# include <stat.h>#else# if OSK#  include "osk.h"# else#  if AMIGA#   include "amistat.h"#  else#   include <sys/stat.h>#  endif# endif#endif/*ARGSUSED*/void cmd_substitute(frommark, tomark, cmd, bang, extra)	MARK	frommark;	MARK	tomark;	CMD	cmd;	int	bang;	char	*extra;	/* rest of the command line */{	char	*line;	/* a line from the file */	regexp	*re;	/* the compiled search expression */	char	*subst;	/* the substitution string */	char	*opt;	/* substitution options */	long	l;	/* a line number */	char	*s, *d;	/* used during subtitutions */	char	*conf;	/* used during confirmation */	long	chline;	/* # of lines changed */	long	chsub;	/* # of substitutions made */	static	optp;	/* boolean option: print when done? */	static	optg;	/* boolean option: substitute globally in line? */	static	optc;	/* boolean option: confirm before subst? */#ifndef CRUNCH	long	oldnlines;#endif	/* for now, assume this will fail */	rptlines = -1L;	if (cmd == CMD_SUBAGAIN)	{#ifndef NO_MAGIC		if (*o_magic)			subst = "~";		else#endif		subst = "\\~";		re = regcomp("");		/* if visual "&", then turn off the "p" and "c" options */		if (bang)		{			optp = optc = FALSE;		}	}	else /* CMD_SUBSTITUTE */	{		/* make sure we got a search pattern */		if (*extra != '/' && *extra != '?')		{			msg("Usage: s/regular expression/new text/");			return;		}		/* parse & compile the search pattern */		subst = parseptrn(extra);		re = regcomp(extra + 1);	}	/* abort if RE error -- error message already given by regcomp() */	if (!re)	{		return;	}	if (cmd == CMD_SUBSTITUTE)	{		/* parse the substitution string & find the option string */		for (opt = subst; *opt && *opt != *extra; opt++)		{			if (*opt == '\\' && opt[1])			{				opt++;			}		}		if (*opt)		{			*opt++ = '\0';		}		/* analyse the option string */		if (!*o_edcompatible)		{			optp = optg = optc = FALSE;		}		while (*opt)		{			switch (*opt++)			{			  case 'p':	optp = !optp;	break;			  case 'g':	optg = !optg;	break;			  case 'c':	optc = !optc;	break;			  case ' ':			  case '\t':			break;			  default:				msg("Subst options are p, c, and g -- not %c", opt[-1]);				return;			}		}	}	/* if "c" or "p" flag was given, and we're in visual mode, then NEWLINE */	if ((optc || optp) && mode == MODE_VI)	{		addch('\n');		exrefresh();	}	ChangeText	{		/* reset the change counters */		chline = chsub = 0L;		/* for each selected line */		for (l = markline(frommark); l <= markline(tomark); l++)		{			/* fetch the line */			line = fetchline(l);			/* if it contains the search pattern... */			if (regexec(re, line, TRUE))			{				/* increment the line change counter */				chline++;				/* initialize the pointers */				s = line;				d = tmpblk.c;				/* do once or globally ... */				do				{#ifndef CRUNCH					/* confirm, if necessary */					if (optc)					{						for (conf = line; conf < re->startp[0]; conf++)							addch(*conf);						standout();						for ( ; conf < re->endp[0]; conf++)							addch(*conf);						standend();						for (; *conf; conf++)							addch(*conf);						addch('\n');						exrefresh();						if (getkey(0) != 'y')						{							/* copy accross the original chars */							while (s < re->endp[0])								*d++ = *s++;							/* skip to next match on this line, if any */							goto Continue;						}					}#endif /* not CRUNCH */					/* increment the substitution change counter */					chsub++;					/* copy stuff from before the match */					while (s < re->startp[0])					{						*d++ = *s++;					}					/* substitute for the matched part */					regsub(re, subst, d);					s = re->endp[0];					d += strlen(d);Continue:					/* if this regexp could conceivably match					 * a zero-length string, then require at					 * least 1 unmatched character between					 * matches.					 */					if (re->minlen == 0)					{						if (!*s)							break;						*d++ = *s++;					}				} while (optg && regexec(re, s, FALSE));				/* copy stuff from after the match */				while (*d++ = *s++)	/* yes, ASSIGNMENT! */				{				}#ifndef CRUNCH				/* NOTE: since the substitution text is allowed to have ^Ms which are				 * translated into newlines, it is possible that the number of lines				 * in the file will increase after each line has been substituted.				 * we need to adjust for this.				 */				oldnlines = nlines;#endif				/* replace the old version of the line with the new */				d[-1] = '\n';				d[0] = '\0';				change(MARK_AT_LINE(l), MARK_AT_LINE(l + 1), tmpblk.c);#ifndef CRUNCH				l += nlines - oldnlines;				tomark += MARK_AT_LINE(nlines - oldnlines);#endif				/* if supposed to print it, do so */				if (optp)				{					addstr(tmpblk.c);					exrefresh();				}				/* move the cursor to that line */				cursor = MARK_AT_LINE(l);			}		}	}	/* free the regexp */	free(re);	/* if done from within a ":g" command, then finish silently */	if (doingglobal)	{		rptlines = chline;		rptlabel = "changed";		return;	}	/* Reporting */	if (chsub == 0)	{		msg("Substitution failed");	}	else if (chline >= *o_report)	{		msg("%ld substitutions on %ld lines", chsub, chline);	}	rptlines = 0L;}/*ARGSUSED*/void cmd_delete(frommark, tomark, cmd, bang, extra)	MARK	frommark;	MARK	tomark;	CMD	cmd;	int	bang;	char	*extra;{	MARK	curs2;	/* an altered form of the cursor */	/* choose your cut buffer */	if (*extra == '"')	{		extra++;	}	if (*extra)	{		cutname(*extra);	}	/* make sure we're talking about whole lines here */	frommark = frommark & ~(BLKSIZE - 1);	tomark = (tomark & ~(BLKSIZE - 1)) + BLKSIZE;	/* yank the lines */	cut(frommark, tomark);	/* if CMD_DELETE then delete the lines */	if (cmd != CMD_YANK)	{		curs2 = cursor;		ChangeText		{			/* delete the lines */			delete(frommark, tomark);		}		if (curs2 > tomark)		{			cursor = curs2 - tomark + frommark;		}		else if (curs2 > frommark)		{			cursor = frommark;		}	}}/*ARGSUSED*/void cmd_append(frommark, tomark, cmd, bang, extra)	MARK	frommark;	MARK	tomark;	CMD	cmd;	int	bang;	char	*extra;{	long	l;	/* line counter */#ifndef CRUNCH	/* if '!' then toggle auto-indent */	if (bang)	{		*o_autoindent = !*o_autoindent;	}#endif	ChangeText	{		/* if we're doing a change, delete the old version */		if (cmd == CMD_CHANGE)		{			/* delete 'em */			cmd_delete(frommark, tomark, cmd, bang, extra);		}		/* new lines start at the frommark line, or after it */		l = markline(frommark);		if (cmd == CMD_APPEND)		{ 			l++;		}		/* get lines until no more lines, or "." line, and insert them */		while (vgets('\0', tmpblk.c, BLKSIZE) >= 0)		{			addch('\n');			if (!strcmp(tmpblk.c, "."))			{				break;			}			strcat(tmpblk.c, "\n");			add(MARK_AT_LINE(l), tmpblk.c);			l++;		}	}	/* on the odd chance that we're calling this from vi mode ... */	redraw(MARK_UNSET, FALSE);}/*ARGSUSED*/void cmd_put(frommark, tomark, cmd, bang, extra)	MARK	frommark;	MARK	tomark;	CMD	cmd;	int	bang;	char	*extra;{	/* choose your cut buffer */	if (*extra == '"')	{		extra++;	}	if (*extra)	{		cutname(*extra);	}	/* paste it */	ChangeText	{		cursor = paste(frommark, TRUE, FALSE);	}}/*ARGSUSED*/void cmd_join(frommark, tomark, cmd, bang, extra)	MARK	frommark;	MARK	tomark;	CMD	cmd;	int	bang;	char	*extra;{	long	l;	char	*scan;	int	len;	/* length of the new line */	/* if only one line is specified, assume the following one joins too */	if (markline(frommark) == nlines)	{		msg("Nothing to join with this line");		return;	}	if (markline(frommark) == markline(tomark))	{		tomark += BLKSIZE;	}	/* get the first line */	l = markline(frommark);	strcpy(tmpblk.c, fetchline(l));	len = strlen(tmpblk.c);	/* build the longer line */	while (++l <= markline(tomark))	{		/* get the next line */		scan = fetchline(l);		/* remove any leading whitespace */		while (*scan == '\t' || *scan == ' ')		{			scan++;		}		/* see if the line will fit */		if (strlen(scan) + len + 3 > BLKSIZE)		{			msg("Can't join -- the resulting line would be too long");			return;		}		/* catenate it, with a space (or two) in between */		if (!bang)		{			if (len >= 1)			{				if (tmpblk.c[len - 1] == '.'				 || tmpblk.c[len - 1] == '?'				 || tmpblk.c[len - 1] == '!')				{					 tmpblk.c[len++] = ' ';				}				tmpblk.c[len++] = ' ';			}		}		strcpy(tmpblk.c + len, scan);		len += strlen(scan);	}

⌨️ 快捷键说明

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