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

📄 ex.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ex.c *//* Author: *	Steve Kirkendall *	14407 SW Teal Blvd. #C *	Beaverton, OR 97005 *	kirkenda@cs.pdx.edu *//* This file contains the code for reading ex commands. */#include "config.h"#include "ctype.h"#include "vi.h"/* This data type is used to describe the possible argument combinations */typedef short ARGT;#define FROM	1		/* allow a linespec */#define	TO	2		/* allow a second linespec */#define BANG	4		/* allow a ! after the command name */#define EXTRA	8		/* allow extra args after command name */#define XFILE	16		/* expand wildcards in extra part */#define NOSPC	32		/* no spaces allowed in the extra part */#define	DFLALL	64		/* default file range is 1,$ */#define DFLNONE	128		/* no default file range */#define NODFL	256		/* do not default to the current file name */#define EXRCOK	512		/* can be in a .exrc file */#define NL	1024		/* if mode!=MODE_EX, then write a newline first */#define PLUS	2048		/* allow a line number, as in ":e +32 foo" */#define ZERO	4096		/* allow 0 to be given as a line number */#define NOBAR	8192		/* treat following '|' chars as normal */#define FILES	(XFILE + EXTRA)	/* multiple extra files allowed */#define WORD1	(EXTRA + NOSPC)	/* one extra word allowed */#define FILE1	(FILES + NOSPC)	/* 1 file allowed, defaults to current file */#define NAMEDF	(FILE1 + NODFL)	/* 1 file allowed, defaults to "" */#define NAMEDFS	(FILES + NODFL)	/* multiple files allowed, default is "" */#define RANGE	(FROM + TO)	/* range of linespecs allowed */#define NONE	0		/* no args allowed at all *//* This array maps ex command names to command codes. The order in which * command names are listed below is significant -- ambiguous abbreviations * are always resolved to be the first possible match.  (e.g. "r" is taken * to mean "read", not "rewind", because "read" comes before "rewind") */static struct{	char	*name;	/* name of the command */	CMD	code;	/* enum code of the command */	void	(*fn)();/* function which executes the command */	ARGT	argt;	/* command line arguments permitted/needed/used */}	cmdnames[] ={   /*	cmd name	cmd code	function	arguments */	{"append",	CMD_APPEND,	cmd_append,	FROM+ZERO+BANG	},#ifdef DEBUG	{"bug",		CMD_DEBUG,	cmd_debug,	RANGE+BANG+EXTRA+NL},#endif	{"change",	CMD_CHANGE,	cmd_append,	RANGE+BANG	},	{"delete",	CMD_DELETE,	cmd_delete,	RANGE+WORD1	},	{"edit",	CMD_EDIT,	cmd_edit,	BANG+FILE1+PLUS	},	{"file",	CMD_FILE,	cmd_file,	NAMEDF		},	{"global",	CMD_GLOBAL,	cmd_global,	RANGE+BANG+EXTRA+DFLALL+NOBAR},	{"insert",	CMD_INSERT,	cmd_append,	FROM+BANG	},	{"join",	CMD_INSERT,	cmd_join,	RANGE+BANG	},	{"k",		CMD_MARK,	cmd_mark,	FROM+WORD1	},	{"list",	CMD_LIST,	cmd_print,	RANGE+NL	},	{"move",	CMD_MOVE,	cmd_move,	RANGE+EXTRA	},	{"next",	CMD_NEXT,	cmd_next,	BANG+NAMEDFS	},	{"Next",	CMD_PREVIOUS,	cmd_next,	BANG		},	{"print",	CMD_PRINT,	cmd_print,	RANGE+NL	},	{"quit",	CMD_QUIT,	cmd_xit,	BANG		},	{"read",	CMD_READ,	cmd_read,	FROM+ZERO+NAMEDF},	{"substitute",	CMD_SUBSTITUTE,	cmd_substitute,	RANGE+EXTRA	},	{"to",		CMD_COPY,	cmd_move,	RANGE+EXTRA	},	{"undo",	CMD_UNDO,	cmd_undo,	NONE		},	{"vglobal",	CMD_VGLOBAL,	cmd_global,	RANGE+EXTRA+DFLALL+NOBAR},	{"write",	CMD_WRITE,	cmd_write,	RANGE+BANG+FILE1+DFLALL},	{"xit",		CMD_XIT,	cmd_xit,	BANG+NL		},	{"yank",	CMD_YANK,	cmd_delete,	RANGE+WORD1	},	{"!",		CMD_BANG,	cmd_shell,	EXRCOK+RANGE+NAMEDFS+DFLNONE+NL+NOBAR},	{"#",		CMD_NUMBER,	cmd_print,	RANGE+NL	},	{"<",		CMD_SHIFTL,	cmd_shift,	RANGE		},	{">",		CMD_SHIFTR,	cmd_shift,	RANGE		},	{"=",		CMD_EQUAL,	cmd_file,	RANGE		},	{"&",		CMD_SUBAGAIN,	cmd_substitute,	RANGE		},#ifndef NO_AT	{"@",		CMD_AT,		cmd_at,		EXTRA		},#endif#ifndef NO_ABBR	{"abbreviate",	CMD_ABBR,	cmd_map,	EXRCOK+BANG+EXTRA},#endif	{"args",	CMD_ARGS,	cmd_args,	EXRCOK+NAMEDFS	},#ifndef NO_ERRLIST	{"cc",		CMD_CC,		cmd_make,	BANG+FILES	},#endif	{"cd",		CMD_CD,		cmd_cd,		EXRCOK+BANG+NAMEDF},	{"copy",	CMD_COPY,	cmd_move,	RANGE+EXTRA	},#ifndef NO_DIGRAPH	{"digraph",	CMD_DIGRAPH,	cmd_digraph,	EXRCOK+BANG+EXTRA},#endif#ifndef NO_ERRLIST	{"errlist",	CMD_ERRLIST,	cmd_errlist,	BANG+NAMEDF	},#endif	{"ex",		CMD_EDIT,	cmd_edit,	BANG+FILE1	},	{"mark",	CMD_MARK,	cmd_mark,	FROM+WORD1	},#ifndef NO_MKEXRC	{"mkexrc",	CMD_MKEXRC,	cmd_mkexrc,	NAMEDF		},#endif	{"number",	CMD_NUMBER,	cmd_print,	RANGE+NL	},	{"put",		CMD_PUT,	cmd_put,	FROM+ZERO+WORD1	},	{"set",		CMD_SET,	cmd_set,	EXRCOK+EXTRA	},	{"shell",	CMD_SHELL,	cmd_shell,	NL		},	{"source",	CMD_SOURCE,	cmd_source,	EXRCOK+NAMEDF	},#ifdef SIGTSTP	{"stop",	CMD_STOP,	cmd_suspend,	NONE		},#endif	{"tag",		CMD_TAG,	cmd_tag,	BANG+WORD1	},	{"version",	CMD_VERSION,	cmd_version,	EXRCOK+NONE	},	{"visual",	CMD_VISUAL,	cmd_edit,	BANG+NAMEDF	},	{"wq",		CMD_WQUIT,	cmd_xit,	NL		},#ifdef DEBUG	{"debug",	CMD_DEBUG,	cmd_debug,	RANGE+BANG+EXTRA+NL},	{"validate",	CMD_VALIDATE,	cmd_validate,	BANG+NL		},#endif	{"chdir",	CMD_CD,		cmd_cd,		EXRCOK+BANG+NAMEDF},#ifndef NO_COLOR	{"color",	CMD_COLOR,	cmd_color,	EXRCOK+EXTRA	},#endif#ifndef NO_ERRLIST	{"make",	CMD_MAKE,	cmd_make,	BANG+NAMEDFS	},#endif	{"map",		CMD_MAP,	cmd_map,	EXRCOK+BANG+EXTRA},	{"previous",	CMD_PREVIOUS,	cmd_next,	BANG		},	{"rewind",	CMD_REWIND,	cmd_next,	BANG		},#ifdef SIGTSTP	{"suspend",	CMD_SUSPEND,	cmd_suspend,	NONE		},#endif	{"unmap",	CMD_UNMAP,	cmd_map,	EXRCOK+BANG+EXTRA},#ifndef NO_ABBR	{"unabbreviate",CMD_UNABBR,	cmd_map,	EXRCOK+WORD1	},#endif	{(char *)0}};/* This function parses a search pattern - given a pointer to a / or ?, * it replaces the ending / or ? with a \0, and returns a pointer to the * stuff that came after the pattern. */char	*parseptrn(ptrn)	REG char	*ptrn;{	REG char 	*scan;	for (scan = ptrn + 1;	     *scan && *scan != *ptrn;	     scan++)	{		/* allow backslashed versions of / and ? in the pattern */		if (*scan == '\\' && scan[1] != '\0')		{			scan++;		}	}	if (*scan)	{		*scan++ = '\0';	}	return scan;}/* This function parses a line specifier for ex commands */char *linespec(s, markptr)	REG char	*s;		/* start of the line specifier */	MARK		*markptr;	/* where to store the mark's value */{	long		num;	REG char	*t;	/* parse each ;-delimited clause of this linespec */	do	{		/* skip an initial ';', if any */		if (*s == ';')		{			s++;		}		/* skip leading spaces */		while (isspace(*s))		{			s++;		}		/* dot means current position */		if (*s == '.')		{			s++;			*markptr = cursor;		}		/* '$' means the last line */		else if (*s == '$')		{			s++;			*markptr = MARK_LAST;		}		/* digit means an absolute line number */		else if (isdigit(*s))		{			for (num = 0; isdigit(*s); s++)			{				num = num * 10 + *s - '0';			}			*markptr = MARK_AT_LINE(num);		}		/* appostrophe means go to a set mark */		else if (*s == '\'')		{			s++;			*markptr = m_tomark(cursor, 1L, (int)*s);			s++;		}		/* slash means do a search */		else if (*s == '/' || *s == '?')		{			/* put a '\0' at the end of the search pattern */			t = parseptrn(s);			/* search for the pattern */			*markptr &= ~(BLKSIZE - 1);			if (*s == '/')			{				pfetch(markline(*markptr));				if (plen > 0)					*markptr += plen - 1;				*markptr = m_fsrch(*markptr, s);			}			else			{				*markptr = m_bsrch(*markptr, s);			}			/* adjust command string pointer */			s = t;		}		/* if linespec was faulty, quit now */		if (!*markptr)		{			return s;		}		/* maybe add an offset */		t = s;		if (*t == '-' || *t == '+')		{			s++;			for (num = 0; isdigit(*s); s++)			{				num = num * 10 + *s - '0';			}			if (num == 0)			{				num = 1;			}			*markptr = m_updnto(*markptr, num, *t);		}	} while (*s == ';' || *s == '+' || *s == '-');	/* protect against invalid line numbers */	num = markline(*markptr);	if (num < 1L || num > nlines)	{		msg("Invalid line number -- must be from 1 to %ld", nlines);		*markptr = MARK_UNSET;	}	return s;}/* This function reads an ex command and executes it. */void ex(){	char		cmdbuf[150];	REG int		cmdlen;	static long	oldline;	significant = FALSE;	oldline = markline(cursor);	while (mode == MODE_EX)	{		/* read a line */#ifdef CRUNCH		cmdlen = vgets(':', cmdbuf, sizeof(cmdbuf));#else		cmdlen = vgets(*o_prompt ? ':' : '\0', cmdbuf, sizeof(cmdbuf));#endif		if (cmdlen < 0)		{			return;		}		/* if empty line, assume ".+1" */		if (cmdlen == 0)		{			strcpy(cmdbuf, ".+1");			qaddch('\r');			clrtoeol();		}		else		{			addch('\n');		}		refresh();		/* parse & execute the command */		doexcmd(cmdbuf);		/* handle autoprint */		if (significant || markline(cursor) != oldline)		{			significant = FALSE;			oldline = markline(cursor);			if (*o_autoprint && mode == MODE_EX)			{				cmd_print(cursor, cursor, CMD_PRINT, FALSE, "");			}		}	}}void doexcmd(cmdbuf)	char		*cmdbuf;	/* string containing an ex command */{	REG char	*scan;		/* used to scan thru cmdbuf */	MARK		frommark;	/* first linespec */	MARK		tomark;		/* second linespec */	REG int		cmdlen;		/* length of the command name given */	CMD		cmd;		/* what command is this? */	ARGT		argt;		/* argument types for this command */	short		forceit;	/* bang version of a command? */	REG int		cmdidx;		/* index of command */	REG char	*build;		/* used while copying filenames */	int		iswild;		/* boolean: filenames use wildcards? */	int		isdfl;		/* using default line ranges? */	int		didsub;		/* did we substitute file names for % or # */	/* ex commands can't be undone via the shift-U command */	U_line = 0L;	/* permit extra colons at the start of the line */	for (; *cmdbuf == ':'; cmdbuf++)

⌨️ 快捷键说明

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