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