GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/mg/main.c Lines: 0 111 0.0 %
Date: 2016-12-06 Branches: 0 71 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: main.c,v 1.83 2016/07/14 08:31:18 semarie Exp $	*/
2
3
/* This file is in the public domain. */
4
5
/*
6
 *	Mainline.
7
 */
8
9
#include <sys/queue.h>
10
#include <err.h>
11
#include <limits.h>
12
#include <locale.h>
13
#include <signal.h>
14
#include <stdio.h>
15
#include <stdlib.h>
16
#include <string.h>
17
#include <unistd.h>
18
19
#include "def.h"
20
#include "kbd.h"
21
#include "funmap.h"
22
#include "macro.h"
23
24
int		 thisflag;			/* flags, this command	*/
25
int		 lastflag;			/* flags, last command	*/
26
int		 curgoal;			/* goal column		*/
27
int		 startrow;			/* row to start		*/
28
int		 doaudiblebell;			/* audible bell toggle	*/
29
int		 dovisiblebell;			/* visible bell toggle	*/
30
int		 dblspace;			/* sentence end #spaces	*/
31
struct buffer	*curbp;				/* current buffer	*/
32
struct buffer	*bheadp;			/* BUFFER list head	*/
33
struct mgwin	*curwp;				/* current window	*/
34
struct mgwin	*wheadp;			/* MGWIN listhead	*/
35
char		 pat[NPAT];			/* pattern		*/
36
37
static void	 edinit(struct buffer *);
38
static __dead void usage(void);
39
40
extern char	*__progname;
41
extern void     closetags(void);
42
43
static __dead void
44
usage()
45
{
46
	fprintf(stderr, "usage: %s [-nR] [-f mode] [+number] [file ...]\n",
47
	    __progname);
48
	exit(1);
49
}
50
51
int
52
main(int argc, char **argv)
53
{
54
	char		*cp, *init_fcn_name = NULL;
55
	PF		 init_fcn = NULL;
56
	int	 	 o, i, nfiles;
57
	int	  	 nobackups = 0, bro = 0;
58
	struct buffer	*bp = NULL;
59
60
	if (pledge("stdio rpath wpath cpath fattr chown getpw tty proc exec",
61
	    NULL) == -1)
62
		err(1, "pledge");
63
64
	while ((o = getopt(argc, argv, "nRf:")) != -1)
65
		switch (o) {
66
		case 'R':
67
			bro = 1;
68
			break;
69
		case 'n':
70
			nobackups = 1;
71
			break;
72
		case 'f':
73
			if (init_fcn_name != NULL)
74
				errx(1, "cannot specify more than one "
75
				    "initial function");
76
			init_fcn_name = optarg;
77
			break;
78
		default:
79
			usage();
80
		}
81
	argc -= optind;
82
	argv += optind;
83
84
	setlocale(LC_CTYPE, "");
85
86
	maps_init();		/* Keymaps and modes.		*/
87
	funmap_init();		/* Functions.			*/
88
89
	/*
90
	 * This is where we initialize standalone extensions that should
91
	 * be loaded dynamically sometime in the future.
92
	 */
93
	{
94
		extern void grep_init(void);
95
		extern void theo_init(void);
96
		extern void cmode_init(void);
97
		extern void dired_init(void);
98
99
		dired_init();
100
		grep_init();
101
		theo_init();
102
		cmode_init();
103
	}
104
105
	if (init_fcn_name &&
106
	    (init_fcn = name_function(init_fcn_name)) == NULL)
107
		errx(1, "Unknown function `%s'", init_fcn_name);
108
109
	vtinit();		/* Virtual terminal.		*/
110
	dirinit();		/* Get current directory.	*/
111
	edinit(bp);		/* Buffers, windows.		*/
112
	ttykeymapinit();	/* Symbols, bindings.		*/
113
	bellinit();		/* Audible and visible bell.	*/
114
	dblspace = 1;		/* two spaces for sentence end. */
115
116
	/*
117
	 * doing update() before reading files causes the error messages from
118
	 * the file I/O show up on the screen.	(and also an extra display of
119
	 * the mode line if there are files specified on the command line.)
120
	 */
121
	update(CMODE);
122
123
	/* user startup file. */
124
	if ((cp = startupfile(NULL)) != NULL)
125
		(void)load(cp);
126
127
	/*
128
	 * Now ensure any default buffer modes from the startup file are
129
	 * given to any files opened when parsing the startup file.
130
	 * Note *scratch* will also be updated.
131
	 */
132
	for (bp = bheadp; bp != NULL; bp = bp->b_bufp) {
133
		bp->b_flag = defb_flag;
134
		for (i = 0; i <= defb_nmodes; i++) {
135
                	bp->b_modes[i] = defb_modes[i];
136
        	}
137
	}
138
139
	/* Force FFOTHARG=1 so that this mode is enabled, not simply toggled */
140
	if (init_fcn)
141
		init_fcn(FFOTHARG, 1);
142
143
	if (nobackups)
144
		makebkfile(FFARG, 0);
145
146
	for (nfiles = 0, i = 0; i < argc; i++) {
147
		if (argv[i][0] == '+' && strlen(argv[i]) >= 2) {
148
			long long lval;
149
			const char *errstr;
150
151
			lval = strtonum(&argv[i][1], INT_MIN, INT_MAX, &errstr);
152
			if (argv[i][1] == '\0' || errstr != NULL)
153
				goto notnum;
154
			startrow = lval;
155
		} else {
156
notnum:
157
			cp = adjustname(argv[i], FALSE);
158
			if (cp != NULL) {
159
				if (nfiles == 1)
160
					splitwind(0, 1);
161
162
				if (fisdir(cp) == TRUE) {
163
					(void)do_dired(cp);
164
					continue;
165
				}
166
				if ((curbp = findbuffer(cp)) == NULL) {
167
					vttidy();
168
					errx(1, "Can't find current buffer!");
169
				}
170
				(void)showbuffer(curbp, curwp, 0);
171
				if (readin(cp) != TRUE)
172
					killbuffer(curbp);
173
				else {
174
					/* Ensure enabled, not just toggled */
175
					if (init_fcn_name)
176
						init_fcn(FFOTHARG, 1);
177
					nfiles++;
178
				}
179
				if (bro)
180
					curbp->b_flag |= BFREADONLY;
181
			}
182
		}
183
	}
184
185
	if (nfiles > 2)
186
		listbuffers(0, 1);
187
188
	/* fake last flags */
189
	thisflag = 0;
190
	for (;;) {
191
		if (epresf == KCLEAR)
192
			eerase();
193
		if (epresf == TRUE)
194
			epresf = KCLEAR;
195
		if (winch_flag) {
196
			do_redraw(0, 0, TRUE);
197
			winch_flag = 0;
198
		}
199
		update(CMODE);
200
		lastflag = thisflag;
201
		thisflag = 0;
202
203
		switch (doin()) {
204
		case TRUE:
205
			break;
206
		case ABORT:
207
			ewprintf("Quit");
208
			/* FALLTHRU */
209
		case FALSE:
210
		default:
211
			macrodef = FALSE;
212
		}
213
	}
214
}
215
216
/*
217
 * Initialize default buffer and window. Default buffer is called *scratch*.
218
 */
219
static void
220
edinit(struct buffer *bp)
221
{
222
	struct mgwin	*wp;
223
224
	bheadp = NULL;
225
	bp = bfind("*scratch*", TRUE);		/* Text buffer.          */
226
	if (bp == NULL)
227
		panic("edinit");
228
229
	wp = new_window(bp);
230
	if (wp == NULL)
231
		panic("edinit: Out of memory");
232
233
	curbp = bp;				/* Current buffer.	 */
234
	wheadp = wp;
235
	curwp = wp;
236
	wp->w_wndp = NULL;			/* Initialize window.	 */
237
	wp->w_linep = wp->w_dotp = bp->b_headp;
238
	wp->w_ntrows = nrow - 2;		/* 2 = mode, echo.	 */
239
	wp->w_rflag = WFMODE | WFFULL;		/* Full.		 */
240
}
241
242
/*
243
 * Quit command.  If an argument, always quit.  Otherwise confirm if a buffer
244
 * has been changed and not written out.  Normally bound to "C-X C-C".
245
 */
246
/* ARGSUSED */
247
int
248
quit(int f, int n)
249
{
250
	int	 s;
251
252
	if ((s = anycb(FALSE)) == ABORT)
253
		return (ABORT);
254
	if (s == FIOERR || s == UERROR)
255
		return (FALSE);
256
	if (s == FALSE
257
	    || eyesno("Modified buffers exist; really exit") == TRUE) {
258
		vttidy();
259
		closetags();
260
		exit(0);
261
	}
262
	return (TRUE);
263
}
264
265
/*
266
 * User abort.  Should be called by any input routine that sees a C-g to abort
267
 * whatever C-g is aborting these days. Currently does nothing.
268
 */
269
/* ARGSUSED */
270
int
271
ctrlg(int f, int n)
272
{
273
	return (ABORT);
274
}