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