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