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