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

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