[BACK]Return to main.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mg

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: }