[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.87

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