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

📄 main.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * Copyright (c) 1992, 1993, 1994 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char copyright[] ="@(#) Copyright (c) 1992, 1993\n\	The Regents of the University of California.  All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)main.c	8.80 (Berkeley) 4/15/94";#endif /* not lint */#include <sys/param.h>#include <sys/queue.h>#include <sys/stat.h>#include <sys/time.h>#include <bitstring.h>#include <ctype.h>#include <err.h>#include <errno.h>#include <fcntl.h>#include <limits.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <termios.h>#include <unistd.h>#ifdef __STDC__#include <stdarg.h>#else#include <varargs.h>#endif#include "compat.h"#include <db.h>#include <regex.h>#include <pathnames.h>#include "vi.h"#include "excmd.h"#include "tag.h"enum rc { NOEXIST, NOPERM, OK };static enum rc	 exrc_isok __P((SCR *, struct stat *, char *, int));static void	 gs_end __P((GS *));static GS	*gs_init __P((void));static void	 h_hup __P((int));static void	 h_term __P((int));static void	 h_winch __P((int));static void	 obsolete __P((char *[]));static void	 usage __P((int));GS *__global_list;			/* GLOBAL: List of screens. */intmain(argc, argv)	int argc;	char *argv[];{	extern int optind;	extern char *optarg;	static int reenter;		/* STATIC: Re-entrancy check. */	struct sigaction act;	struct stat hsb, lsb;	GS *gp;	FREF *frp;	SCR *sp;	u_int flags, saved_vi_mode;	int ch, eval, flagchk, readonly, silent, snapshot;	char *excmdarg, *myname, *p, *rec_f, *tag_f, *trace_f, *wsizearg;	char path[MAXPATHLEN];	/* Stop if indirecting through a NULL pointer. */	if (reenter++)		abort();	/* Set screen type and mode based on the program name. */	readonly = 0;	if ((myname = strrchr(*argv, '/')) == NULL)		myname = *argv;	else		++myname;	if (!strcmp(myname, "ex") || !strcmp(myname, "nex"))		LF_INIT(S_EX);	else {		/* View is readonly. */		if (!strcmp(myname, "view"))			readonly = 1;		LF_INIT(S_VI_CURSES);	}	saved_vi_mode = S_VI_CURSES;	/* Convert old-style arguments into new-style ones. */	obsolete(argv);	/* Parse the arguments. */	flagchk = '\0';	excmdarg = rec_f = tag_f = trace_f = wsizearg = NULL;	silent = 0;	snapshot = 1;	while ((ch = getopt(argc, argv, "c:eFlRr:sT:t:vw:x:")) != EOF)		switch (ch) {		case 'c':		/* Run the command. */			excmdarg = optarg;			break;		case 'e':		/* Ex mode. */			LF_CLR(S_SCREENS);			LF_SET(S_EX);			break;		case 'F':		/* No snapshot. */			snapshot = 0;			break;		case 'l':			if (flagchk != '\0' && flagchk != 'l')				errx(1,				    "only one of -%c and -l may be specified.",				    flagchk);			flagchk = 'l';			break;		case 'R':		/* Readonly. */			readonly = 1;			break;		case 'r':		/* Recover. */			if (flagchk == 'r')				errx(1,				    "only one recovery file may be specified.");			if (flagchk != '\0')				errx(1,				    "only one of -%c and -r may be specified.",				    flagchk);			flagchk = 'r';			rec_f = optarg;			break;		case 's':			silent = 1;			break;		case 'T':		/* Trace. */			trace_f = optarg;			break;		case 't':		/* Tag. */			if (flagchk == 't')				errx(1,				    "only one tag file may be specified.");			if (flagchk != '\0')				errx(1,				    "only one of -%c and -t may be specified.",				    flagchk);			flagchk = 't';			tag_f = optarg;			break;		case 'v':		/* Vi mode. */			LF_CLR(S_SCREENS);			LF_SET(S_VI_CURSES);			break;		case 'w':			wsizearg = optarg;			break;		case 'x':			if (!strcmp(optarg, "aw")) {				LF_CLR(S_SCREENS);				LF_SET(S_VI_XAW);				saved_vi_mode = S_VI_XAW;				break;			}			/* FALLTHROUGH */		case '?':		default:			usage(LF_ISSET(S_EX));		}	argc -= optind;	argv += optind;	/* Silent is only applicable to ex. */	if (silent && !LF_ISSET(S_EX))		errx(1, "-s only applicable to ex.");	/* Build and initialize the GS structure. */	__global_list = gp = gs_init();	/*	 * If not reading from a terminal, it's like -s was specified.	 * Vi always reads from the terminal, so fail if it's not a	 * terminal.	 */	if (!F_ISSET(gp, G_STDIN_TTY)) {		silent = 1;		if (!LF_ISSET(S_EX)) {			msgq(NULL, M_ERR,			    "Vi's standard input must be a terminal.");			goto err;		}	}	/*	 * Build and initialize the first/current screen.  This is a bit	 * tricky.  If an error is returned, we may or may not have a	 * screen structure.  If we have a screen structure, put it on a	 * display queue so that the error messages get displayed.	 */	if (screen_init(NULL, &sp, flags)) {		if (sp != NULL)			CIRCLEQ_INSERT_HEAD(&__global_list->dq, sp, q);		goto err;	}	sp->saved_vi_mode = saved_vi_mode;	CIRCLEQ_INSERT_HEAD(&__global_list->dq, sp, q);	if (trace_f != NULL) {#ifdef DEBUG		if ((gp->tracefp = fopen(optarg, "w")) == NULL)			err(1, "%s", optarg);		(void)fprintf(gp->tracefp, "\n===\ntrace: open %s\n", optarg);#else		msgq(sp, M_ERR, "-T support not compiled into this version.");#endif	}	if (set_window_size(sp, 0, 0))	/* Set the window size. */		goto err;	if (opts_init(sp))		/* Options initialization. */		goto err;	if (readonly)			/* Global read-only bit. */		O_SET(sp, O_READONLY);	if (silent) {			/* Ex batch mode. */		O_CLR(sp, O_AUTOPRINT);		O_CLR(sp, O_PROMPT);		O_CLR(sp, O_VERBOSE);		O_CLR(sp, O_WARN);		F_SET(sp, S_EXSILENT);	}	if (wsizearg != NULL) {		ARGS *av[2], a, b;		errno = 0;		if (strtol(optarg, &p, 10) < 0 || errno || *p)			errx(1, "illegal window size -- %s", optarg);		(void)snprintf(path, sizeof(path), "window=%s", optarg);		a.bp = (CHAR_T *)path;		a.len = strlen(path);		b.bp = NULL;		b.len = 0;		av[0] = &a;		av[1] = &b;		if (opts_set(sp, av))			 msgq(sp, M_ERR,			     "Unable to set command line window size option.");	}	/* Keymaps, special keys, must follow option initializations. */	if (term_init(sp))		goto err;#ifdef	DIGRAPHS	if (digraph_init(sp))		/* Digraph initialization. */		goto err;#endif	/*	 * Source the system, environment, $HOME and local .exrc values.	 * Vi historically didn't check $HOME/.exrc if the environment	 * variable EXINIT was set.  This is all done before the file is	 * read in, because things in the .exrc information can set, for	 * example, the recovery directory.	 *	 * !!!	 * While nvi can handle any of the options settings of historic vi,	 * the converse is not true.  Since users are going to have to have	 * files and environmental variables that work with both, we use nvi	 * versions of both the $HOME and local startup files if they exist,	 * otherwise the historic ones.	 *	 * !!!	 * For a discussion of permissions and when what .exrc files are	 * read, see the the comment above the exrc_isok() function below.	 *	 * !!!	 * If the user started the historic of vi in $HOME, vi read the user's	 * .exrc file twice, as $HOME/.exrc and as ./.exrc.  We avoid this, as	 * it's going to make some commands behave oddly, and I can't imagine	 * anyone depending on it.	 */	if (!silent) {		switch (exrc_isok(sp, &hsb, _PATH_SYSEXRC, 1)) {		case NOEXIST:		case NOPERM:			break;		case OK:			(void)ex_cfile(sp, NULL, _PATH_SYSEXRC);			break;		}		if ((p = getenv("NEXINIT")) != NULL ||		    (p = getenv("EXINIT")) != NULL)			if ((p = strdup(p)) == NULL) {				msgq(sp, M_SYSERR, NULL);				goto err;			} else {				F_SET(sp, S_VLITONLY);				(void)ex_icmd(sp, NULL, p, strlen(p));				F_CLR(sp, S_VLITONLY);				free(p);			}		else if ((p = getenv("HOME")) != NULL && *p) {			(void)snprintf(path,			    sizeof(path), "%s/%s", p, _PATH_NEXRC);			switch (exrc_isok(sp, &hsb, path, 0)) {			case NOEXIST:				(void)snprintf(path,				    sizeof(path), "%s/%s", p, _PATH_EXRC);				if (exrc_isok(sp, &hsb, path, 0) == OK)					(void)ex_cfile(sp, NULL, path);				break;			case NOPERM:				break;			case OK:				(void)ex_cfile(sp, NULL, path);				break;			}		}		if (O_ISSET(sp, O_EXRC))			switch (exrc_isok(sp, &lsb, _PATH_NEXRC, 0)) {			case NOEXIST:				if (exrc_isok(sp, &lsb, _PATH_EXRC, 0) == OK &&				    (lsb.st_dev != hsb.st_dev ||				    lsb.st_ino != hsb.st_ino))					(void)ex_cfile(sp, NULL, _PATH_EXRC);				break;			case NOPERM:				break;			case OK:				if (lsb.st_dev != hsb.st_dev ||				    lsb.st_ino != hsb.st_ino)					(void)ex_cfile(sp, NULL, _PATH_NEXRC);				break;			}	}	/* List recovery files if -l specified. */	if (flagchk == 'l')		exit(rcv_list(sp));	/* Set the file snapshot flag. */	if (snapshot)		F_SET(gp, G_SNAPSHOT);	/* Use a tag file or recovery file if specified. */	if (tag_f != NULL && ex_tagfirst(sp, tag_f))		goto err;	else if (rec_f != NULL && rcv_read(sp, rec_f))		goto err;	/* Append any remaining arguments as file names. */	if (*argv != NULL)		for (; *argv != NULL; ++argv)			if (file_add(sp, NULL, *argv, 0) == NULL)				goto err;	/*	 * If no recovery or tag file, get an EXF structure.	 * If no argv file, use a temporary file.	 */	if (tag_f == NULL && rec_f == NULL) {		if ((frp = file_first(sp)) == NULL &&		    (frp = file_add(sp, NULL, NULL, 1)) == NULL)			goto err;		if (file_init(sp, frp, NULL, 0))

⌨️ 快捷键说明

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