Annotation of src/usr.bin/mg/main.c, Revision 1.29
1.29 ! vincent 1: /* $OpenBSD: main.c,v 1.28 2004/01/27 23:43:37 vincent Exp $ */
1.6 niklas 2:
1.1 deraadt 3: /*
1.5 millert 4: * Mainline.
1.1 deraadt 5: */
1.5 millert 6:
1.1 deraadt 7: #include "def.h"
1.12 art 8: #include "kbd.h"
1.11 art 9: #include "funmap.h"
1.5 millert 10:
1.1 deraadt 11: #ifndef NO_MACRO
12: #include "macro.h"
1.5 millert 13: #endif /* NO_MACRO */
1.1 deraadt 14:
1.24 vincent 15: #include <err.h>
16:
1.5 millert 17: int thisflag; /* flags, this command */
18: int lastflag; /* flags, last command */
19: int curgoal; /* goal column */
1.23 deraadt 20: int startrow; /* row to start */
1.5 millert 21: BUFFER *curbp; /* current buffer */
1.29 ! vincent 22: BUFFER *bheadp; /* BUFFER list head */
1.5 millert 23: MGWIN *curwp; /* current window */
1.8 art 24: MGWIN *wheadp; /* MGWIN listhead */
1.5 millert 25: char pat[NPAT]; /* pattern */
1.1 deraadt 26:
1.24 vincent 27: static void edinit(PF);
1.1 deraadt 28:
1.2 deraadt 29: int
1.19 vincent 30: main(int argc, char **argv)
1.1 deraadt 31: {
1.24 vincent 32: char *cp, *init_fcn_name = NULL;
33: PF init_fcn = NULL;
1.27 vincent 34: int o, i, nfiles;
1.24 vincent 35:
36: while ((o = getopt(argc, argv, "f:")) != -1)
37: switch (o) {
38: case 'f':
39: if (init_fcn_name != NULL)
40: errx(1, "cannot specify more than one "
41: "initial function");
42: init_fcn_name = optarg;
43: break;
44: default:
45: errx(1, "usage: mg [-f <mode>] [files...]");
46: }
47: argc -= optind;
48: argv += optind;
1.1 deraadt 49:
1.12 art 50: maps_init(); /* Keymaps and modes. */
1.11 art 51: funmap_init(); /* Functions. */
1.19 vincent 52:
1.13 art 53: /*
54: * This is where we initialize standalone extensions that should
55: * be loaded dynamically sometime in the future.
56: */
57: {
58: extern void grep_init(void);
1.14 art 59: extern void theo_init(void);
1.13 art 60:
61: grep_init();
1.14 art 62: theo_init();
1.24 vincent 63: mail_init();
1.13 art 64: }
1.5 millert 65:
1.24 vincent 66: if (init_fcn_name &&
67: (init_fcn = name_function(init_fcn_name)) == NULL)
68: errx(1, "Unknown function `%s'", init_fcn_name);
69:
70: vtinit(); /* Virtual terminal. */
71: #ifndef NO_DIR
72: dirinit(); /* Get current directory. */
73: #endif /* !NO_DIR */
74: edinit(init_fcn); /* Buffers, windows. */
75: ttykeymapinit(); /* Symbols, bindings. */
76:
1.4 millert 77: /*
78: * doing update() before reading files causes the error messages from
79: * the file I/O show up on the screen. (and also an extra display of
80: * the mode line if there are files specified on the command line.)
1.1 deraadt 81: */
82: update();
1.5 millert 83:
84: #ifndef NO_STARTUP
85: /* user startup file */
1.8 art 86: if ((cp = startupfile(NULL)) != NULL)
1.7 art 87: (void)load(cp);
1.5 millert 88: #endif /* !NO_STARTUP */
1.27 vincent 89:
90: for (nfiles = 0, i = 0; i < argc; i++) {
91: if (argv[i][0] == '+' && strlen(argv[i]) >= 2) {
1.23 deraadt 92: long lval;
93: char *ep;
94:
95: errno = 0;
1.27 vincent 96: lval = strtoul(&argv[i][1], &ep, 10);
97: if (argv[i][1] == '\0' || *ep != '\0')
1.23 deraadt 98: goto notnum;
99: if ((errno == ERANGE &&
100: (lval == LONG_MAX || lval == LONG_MIN)) ||
101: (lval > INT_MAX || lval < INT_MIN))
102: goto notnum;
103: startrow = (int)lval;
1.24 vincent 104: } else {
1.23 deraadt 105: notnum:
1.27 vincent 106: cp = adjustname(argv[i]);
1.24 vincent 107: if (cp != NULL) {
1.29 ! vincent 108: if (nfiles == 1) {
1.27 vincent 109: splitwind(0, 1);
1.29 ! vincent 110: }
1.24 vincent 111: curbp = findbuffer(cp);
112: (void)showbuffer(curbp, curwp, 0);
113: (void)readin(cp);
114: if (init_fcn_name)
1.25 vincent 115: init_fcn(0, 1);
1.27 vincent 116: nfiles++;
1.24 vincent 117: }
1.22 vincent 118: }
1.1 deraadt 119: }
1.29 ! vincent 120:
! 121: if (nfiles > 2)
! 122: listbuffers(0, 1);
1.5 millert 123:
124: /* fake last flags */
125: thisflag = 0;
1.4 millert 126: for (;;) {
1.1 deraadt 127: #ifndef NO_DPROMPT
1.4 millert 128: if (epresf == KPROMPT)
129: eerase();
1.5 millert 130: #endif /* !NO_DPROMPT */
1.17 deraadt 131: if (winch_flag) {
132: refresh(0, 0);
133: winch_flag = 0;
134: }
1.4 millert 135: update();
136: lastflag = thisflag;
137: thisflag = 0;
1.5 millert 138:
1.4 millert 139: switch (doin()) {
140: case TRUE:
141: break;
1.1 deraadt 142: case ABORT:
1.5 millert 143: ewprintf("Quit");
144: /* and fall through */
1.1 deraadt 145: case FALSE:
146: default:
1.4 millert 147: ttbeep();
1.1 deraadt 148: #ifndef NO_MACRO
1.4 millert 149: macrodef = FALSE;
1.5 millert 150: #endif /* !NO_MACRO */
1.4 millert 151: }
1.1 deraadt 152: }
153: }
154:
155: /*
156: * Initialize default buffer and window.
157: */
1.7 art 158: static void
1.24 vincent 159: edinit(PF init_fcn)
1.4 millert 160: {
1.5 millert 161: BUFFER *bp;
162: MGWIN *wp;
1.1 deraadt 163:
164: bheadp = NULL;
1.5 millert 165: bp = bfind("*scratch*", TRUE); /* Text buffer. */
1.26 vincent 166: wp = new_window(bp);
1.21 vincent 167: if (wp == NULL)
168: panic("Out of memory");
1.4 millert 169: if (bp == NULL || wp == NULL)
170: panic("edinit");
1.5 millert 171: curbp = bp; /* Current ones. */
1.1 deraadt 172: wheadp = wp;
1.4 millert 173: curwp = wp;
1.5 millert 174: wp->w_wndp = NULL; /* Initialize window. */
1.1 deraadt 175: wp->w_linep = wp->w_dotp = bp->b_linep;
1.28 vincent 176: wp->w_ntrows = nrow - 2; /* 2 = mode, echo. */
177: wp->w_flag = WFMODE | WFHARD; /* Full. */
1.24 vincent 178:
179: if (init_fcn)
1.25 vincent 180: init_fcn(0, 1);
1.1 deraadt 181: }
182:
183: /*
1.5 millert 184: * Quit command. If an argument, always quit. Otherwise confirm if a buffer
185: * has been changed and not written out. Normally bound to "C-X C-C".
1.1 deraadt 186: */
1.4 millert 187: /* ARGSUSED */
1.5 millert 188: int
1.20 vincent 189: quit(int f, int n)
1.1 deraadt 190: {
1.5 millert 191: int s;
1.1 deraadt 192:
1.4 millert 193: if ((s = anycb(FALSE)) == ABORT)
194: return ABORT;
1.1 deraadt 195: if (s == FALSE
1.4 millert 196: || eyesno("Some modified buffers exist, really exit") == TRUE) {
1.1 deraadt 197: vttidy();
1.5 millert 198: #ifdef SYSCLEANUP
1.4 millert 199: SYSCLEANUP;
1.5 millert 200: #endif /* SYSCLEANUP */
1.1 deraadt 201: exit(GOOD);
202: }
203: return TRUE;
204: }
205:
206: /*
1.10 mickey 207: * User abort. Should be called by any input routine that sees a C-g to abort
1.5 millert 208: * whatever C-g is aborting these days. Currently does nothing.
1.1 deraadt 209: */
1.4 millert 210: /* ARGSUSED */
211: int
1.20 vincent 212: ctrlg(int f, int n)
1.1 deraadt 213: {
1.24 vincent 214: return (ABORT);
1.1 deraadt 215: }