Annotation of coherent/g/usr/bin/vi/main.c, revision 1.1.1.1

1.1       root        1: /* main.c */
                      2: 
                      3: /* Author:
                      4:  *     Steve Kirkendall
                      5:  *     14407 SW Teal Blvd. #C
                      6:  *     Beaverton, OR 97005
                      7:  *     [email protected]
                      8:  */
                      9: 
                     10: 
                     11: /* This file contains the main() function of vi */
                     12: 
                     13: /* HACK! bcc needs to disable use of precompiled headers for this file,
                     14:    or else command line args will not be passed to elvis */
                     15: #if __BORLANDC__
                     16: #include "borland.h"
                     17: #endif
                     18: 
                     19: #include "config.h"
                     20: #include <setjmp.h>
                     21: #include "vi.h"
                     22: 
                     23: extern         trapint(); /* defined below */
                     24: extern char    *getenv();
                     25: jmp_buf                jmpenv;
                     26: 
                     27: #ifndef NO_DIGRAPH
                     28: static init_digraphs();
                     29: #endif
                     30: 
                     31: /*---------------------------------------------------------------------*/
                     32: 
                     33: #if AMIGA
                     34: # include "amiwild.c"
                     35: main (argc, argv)
                     36: #else
                     37: # if VMS
                     38: #  include "vmswild.c"
                     39: main (argc, argv)
                     40: # else
                     41: void main(argc, argv)
                     42: # endif
                     43: #endif
                     44:        int     argc;
                     45:        char    *argv[];
                     46: {
                     47:        int     i;
                     48:        char    *cmd = (char *)0;
                     49:        char    *err = (char *)0;
                     50:        char    *str;
                     51:        char    *tag = (char *)0;
                     52: 
                     53:        /* set mode to MODE_VI or MODE_EX depending on program name */
                     54:        switch (argv[0][strlen(argv[0]) - 1])
                     55:        {
                     56:          case 'x':                     /* "ex" */
                     57:                mode = MODE_EX;
                     58:                break;
                     59: 
                     60:          case 'w':                     /* "view" */
                     61:                mode = MODE_VI;
                     62:                *o_readonly = TRUE;
                     63:                break;
                     64: #ifndef NO_EXTENSIONS
                     65:          case 't':                     /* "edit" or "input" */
                     66:                mode = MODE_VI;
                     67:                *o_inputmode = TRUE;
                     68:                break;
                     69: #endif
                     70:          default:                      /* "vi" or "elvis" */
                     71:                mode = MODE_VI;
                     72:        }
                     73: 
                     74: #ifndef DEBUG
                     75: # ifdef        SIGQUIT
                     76:        /* normally, we ignore SIGQUIT.  SIGINT is trapped later */
                     77:        signal(SIGQUIT, SIG_IGN);
                     78: # endif
                     79: #endif
                     80: 
                     81:        /* temporarily ignore SIGINT */
                     82:        signal(SIGINT, SIG_IGN);
                     83: 
                     84:        /* start curses */
                     85:        initscr();
                     86:        cbreak();
                     87:        noecho();
                     88:        scrollok(stdscr, TRUE);
                     89: 
                     90:        /* arrange for deadly signals to be caught */
                     91: # ifdef SIGHUP
                     92:        signal(SIGHUP, (void(*)()) deathtrap);
                     93: # endif
                     94: # ifndef DEBUG
                     95: #  ifdef SIGILL
                     96:        signal(SIGILL, (void(*)()) deathtrap);
                     97: #  endif
                     98: #  ifdef SIGBUS
                     99:        signal(SIGBUS, (void(*)()) deathtrap);
                    100: #  endif
                    101: #  ifdef SIGSEGV
                    102:        signal(SIGSEGV, (void(*)()) deathtrap);
                    103: #  endif
                    104: #  ifdef SIGSYS
                    105:        signal(SIGSYS, (void(*)()) deathtrap);
                    106: #  endif
                    107: # endif /* !DEBUG */
                    108: # ifdef SIGPIPE
                    109:        signal(SIGPIPE, (void(*)()) deathtrap);
                    110: # endif
                    111: # ifdef SIGTERM
                    112:        signal(SIGTERM, (void(*)()) deathtrap);
                    113: # endif
                    114: # ifdef SIGUSR1
                    115:        signal(SIGUSR1, (void(*)()) deathtrap);
                    116: # endif
                    117: # ifdef SIGUSR2
                    118:        signal(SIGUSR2, (void(*)()) deathtrap);
                    119: # endif
                    120: 
                    121:        /* initialize the options - must be done after initscr(), so that
                    122:         * we can alter LINES and COLS if necessary.
                    123:         */
                    124:        initopts();
                    125: 
                    126:        /* map the arrow keys.  The KU,KD,KL,and KR variables correspond to
                    127:         * the :ku=: (etc.) termcap capabilities.  The variables are defined
                    128:         * as part of the curses package.
                    129:         */
                    130:        if (has_KU) mapkey(has_KU, "k",    WHEN_VICMD|WHEN_INMV, "<Up>");
                    131:        if (has_KD) mapkey(has_KD, "j",    WHEN_VICMD|WHEN_INMV, "<Down>");
                    132:        if (has_KL) mapkey(has_KL, "h",    WHEN_VICMD|WHEN_INMV, "<Left>");
                    133:        if (has_KR) mapkey(has_KR, "l",    WHEN_VICMD|WHEN_INMV, "<Right>");
                    134:        if (has_HM) mapkey(has_HM, "^",    WHEN_VICMD|WHEN_INMV, "<Home>");
                    135:        if (has_EN) mapkey(has_EN, "$",    WHEN_VICMD|WHEN_INMV, "<End>");
                    136:        if (has_PU) mapkey(has_PU, "\002", WHEN_VICMD|WHEN_INMV, "<PageUp>");
                    137:        if (has_PD) mapkey(has_PD, "\006", WHEN_VICMD|WHEN_INMV, "<PageDn>");
                    138:        if (has_KI) mapkey(has_KI, "i",    WHEN_VICMD|WHEN_INMV, "<Insert>");
                    139: #if MSDOS
                    140: # if RAINBOW
                    141:        if (!strcmp("rainbow", o_term))
                    142:        {
                    143:                mapkey("\033[1~",  "/",         WHEN_VICMD,             "<Find>");
                    144:                mapkey("\033[3~",  "x",         WHEN_VICMD|WHEN_INMV,   "<Remove>");
                    145:                mapkey("\033[4~",  "v",         WHEN_VICMD|WHEN_INMV,   "<Select>");
                    146:                mapkey("\033[17~", ":sh\n",     WHEN_VICMD,             "<Intrpt>");
                    147:                mapkey("\033[19~", ":q\n",      WHEN_VICMD,             "<Cancel>");
                    148:                mapkey("\033[21~", "ZZ",        WHEN_VICMD,             "<Exit>");
                    149:                mapkey("\033[26~", "V",         WHEN_VICMD|WHEN_INMV,   "<AddlOp>");
                    150:                mapkey("\033[28~", "\\",        WHEN_VICMD|WHEN_INMV,   "<Help>");
                    151:                mapkey("\033[29~", "K",         WHEN_VICMD|WHEN_INMV,   "<Do>");
                    152:        }
                    153:        else
                    154: # endif /* RAINBOW */
                    155:        {
                    156:                mapkey("#S", "x", WHEN_VICMD|WHEN_INMV, "<Delete>");
                    157:                mapkey("#s", "B", WHEN_VICMD|WHEN_INMV, "^<Left>");
                    158:                mapkey("#t", "W", WHEN_VICMD|WHEN_INMV, "^<Right>");
                    159:        }
                    160: #else /* not MSDOS */
                    161: # if COHERENT
                    162:        mapkey("\033[P", "x", WHEN_VICMD|WHEN_INMV, "<Del>");
                    163: # else
                    164: #if AMIGA
                    165:        mapkey("\233?~", "\\",  WHEN_VICMD|WHEN_INMV,   "<Help>");
                    166: #endif
                    167: 
                    168:        if (ERASEKEY != '\177')
                    169:        {
                    170:                mapkey("\177", "x", WHEN_VICMD|WHEN_INMV, "<Del>");
                    171:        }
                    172: # endif
                    173: #endif
                    174: 
                    175: #ifndef NO_DIGRAPH
                    176:        init_digraphs();
                    177: #endif /* NO_DIGRAPH */
                    178: 
                    179:        /* process any flags */
                    180:        for (i = 1; i < argc && *argv[i] == '-'; i++)
                    181:        {
                    182:                switch (argv[i][1])
                    183:                {
                    184:                  case 'R':     /* readonly */
                    185:                        *o_readonly = TRUE;
                    186:                        break;
                    187: 
                    188:                  case 'L':
                    189:                  case 'r':     /* recover */
                    190:                        msg("Use the `elvrec` program to recover lost files");
                    191:                        endmsgs();
                    192:                        refresh();
                    193:                        endwin();
                    194:                        exit(0);
                    195:                        break;
                    196: 
                    197:                  case 't':     /* tag */
                    198:                        if (argv[i][2])
                    199:                        {
                    200:                                tag = argv[i] + 2;
                    201:                        }
                    202:                        else
                    203:                        {
                    204:                                tag = argv[++i];
                    205:                        }
                    206:                        break;
                    207: 
                    208:                  case 'v':     /* vi mode */
                    209:                        mode = MODE_VI;
                    210:                        break;
                    211: 
                    212:                  case 'e':     /* ex mode */
                    213:                        mode = MODE_EX;
                    214:                        break;
                    215: #ifndef NO_EXTENSIONS
                    216:                  case 'i':     /* input mode */
                    217:                        *o_inputmode = TRUE;
                    218:                        break;
                    219: #endif
                    220: #ifndef NO_ERRLIST
                    221:                  case 'm':     /* use "errlist" as the errlist */
                    222:                        if (argv[i][2])
                    223:                        {
                    224:                                err = argv[i] + 2;
                    225:                        }
                    226:                        else if (i + 1 < argc)
                    227:                        {
                    228:                                err = argv[++i];
                    229:                        }
                    230:                        else
                    231:                        {
                    232:                                err = "";
                    233:                        }
                    234:                        break;
                    235: #endif
                    236: #ifndef CRUNCH
                    237:                 case 'c':      /* run the following command, later */
                    238:                        if (argv[i][2])
                    239:                        {
                    240:                                cmd = argv[i] + 2;
                    241:                        }
                    242:                        else
                    243:                        {
                    244:                                cmd = argv[++i];
                    245:                        }
                    246:                        break;
                    247: 
                    248:                  case 'w':     /* set the window size */
                    249:                        if (argv[i][2])
                    250:                        {
                    251:                                *o_window = atoi(argv[i] + 2);
                    252:                                wset = TRUE;
                    253:                        }
                    254:                        else
                    255:                        {
                    256:                                *o_window = atoi(argv[++i]);
                    257:                                wset = TRUE;
                    258:                        }
                    259:                        break;
                    260: #endif
                    261:                  default:
                    262:                        msg("Ignoring unknown flag \"%s\"", argv[i]);
                    263:                }
                    264:        }
                    265: 
                    266:        /* if we were given an initial ex command, save it... */
                    267:        if (i < argc && *argv[i] == '+')
                    268:        {
                    269:                if (argv[i][1])
                    270:                {
                    271:                        cmd = argv[i++] + 1;
                    272:                }
                    273:                else
                    274:                {
                    275:                        cmd = "$"; /* "vi + file" means start at EOF */
                    276:                        i++;
                    277:                }
                    278:        }
                    279: 
                    280:        /* the remaining args are file names. */
                    281:        if (i < argc)
                    282:        {
                    283:                strcpy(args, argv[i]);
                    284:                while (++i < argc && strlen(args) + 1 + strlen(argv[i]) < sizeof args)
                    285:                {
                    286:                        strcat(args, " ");
                    287:                        strcat(args, argv[i]);
                    288:                }
                    289: #if MSDOS || TOS
                    290:                /* expand wildcard characters, if necessary */
                    291:                if (strchr(args, '*') || strchr(args, '?'))
                    292:                {
                    293:                        strcpy(args, wildcard(args));
                    294:                }
                    295: #endif
                    296:                strcpy(tmpblk.c, args);
                    297:                cmd_args(MARK_UNSET, MARK_UNSET, CMD_ARGS, TRUE, tmpblk.c);
                    298:        }
                    299:        else
                    300:        {
                    301:                /* empty args list */
                    302:                args[0] = '\0';
                    303:                nargs = 1;
                    304:                argno = -1;
                    305:        }
                    306: 
                    307:        /* perform the .exrc files and EXINIT environment variable */
                    308: #ifdef SYSEXRC
                    309:        doexrc(SYSEXRC);
                    310: #endif
                    311: #ifdef HMEXRC
                    312:        str = getenv("HOME");
                    313:        if (str && *str)
                    314:        {
                    315:                strcpy(tmpblk.c, str);
                    316:                str = tmpblk.c + strlen(tmpblk.c);
                    317: #if !VMS
                    318: # if AMIGA     /* Don't SLASH a device. "Elvis:.exrc" */
                    319:                if (str[-1] != COLON && str[-1] != SLASH)
                    320: # else
                    321:                if (str[-1] != SLASH)
                    322: # endif
                    323:                {
                    324:                        *str++ = SLASH;
                    325:                }
                    326: #endif
                    327:                strcpy(str, HMEXRC);
                    328:                doexrc(tmpblk.c);
                    329:        }
                    330: #endif
                    331: #ifndef CRUNCH
                    332:        if (*o_exrc)
                    333: #endif
                    334:        {
                    335:                doexrc(EXRC);
                    336:        }
                    337: #ifdef EXINIT
                    338:        str = getenv(EXINIT);
                    339:        if (str)
                    340:        {
                    341:                exstring(str, strlen(str), ctrl('V'));
                    342:        }
                    343: #endif
                    344: 
                    345:        /* search for a tag (or an error) now, if desired */
                    346:        blkinit();
                    347:        if (tag)
                    348:        {
                    349:                cmd_tag(MARK_FIRST, MARK_FIRST, CMD_TAG, 0, tag);
                    350:        }
                    351: #ifndef NO_ERRLIST
                    352:        else if (err)
                    353:        {
                    354:                cmd_errlist(MARK_FIRST, MARK_FIRST, CMD_ERRLIST, 0, err);
                    355:        }
                    356: #endif
                    357: 
                    358:        /* if no tag/err, or tag failed, then start with first arg */
                    359:        if (tmpfd < 0)
                    360:        {
                    361:                /* start with first arg */
                    362:                cmd_next(MARK_UNSET, MARK_UNSET, CMD_NEXT, FALSE, "");
                    363: 
                    364:                /* pretend to do something, just to force a recoverable
                    365:                 * version of the file out to disk
                    366:                 */
                    367:                ChangeText
                    368:                {
                    369:                }
                    370:                clrflag(file, MODIFIED);
                    371:        }
                    372: 
                    373:        /* now we do the immediate ex command that we noticed before */
                    374:        if (cmd)
                    375:        {
                    376:                doexcmd(cmd);
                    377:        }
                    378: 
                    379:        /* repeatedly call ex() or vi() (depending on the mode) until the
                    380:         * mode is set to MODE_QUIT
                    381:         */
                    382:        while (mode != MODE_QUIT)
                    383:        {
                    384:                if (setjmp(jmpenv))
                    385:                {
                    386:                        /* Maybe we just aborted a change? */
                    387:                        abortdo();
                    388:                }
                    389:                signal(SIGINT, (void(*)()) trapint);
                    390: 
                    391:                switch (mode)
                    392:                {
                    393:                  case MODE_VI:
                    394:                        vi();
                    395:                        break;
                    396: 
                    397:                  case MODE_EX:
                    398:                        ex();
                    399:                        break;
                    400: #ifdef DEBUG
                    401:                  default:
                    402:                        msg("mode = %d?", mode);
                    403:                        mode = MODE_QUIT;
                    404: #endif
                    405:                }
                    406:        }
                    407: 
                    408:        /* free up the cut buffers */
                    409:        cutend();
                    410: 
                    411:        /* end curses */
                    412: #ifndef        NO_CURSORSHAPE
                    413:        if (has_CQ)
                    414:                do_CQ();
                    415: #endif
                    416:        endmsgs();
                    417:        move(LINES - 1, 0);
                    418:        clrtoeol();
                    419:        refresh();
                    420:        endwin();
                    421: 
                    422:        exit(exitcode);
                    423:        /*NOTREACHED*/
                    424: }
                    425: 
                    426: 
                    427: /*ARGSUSED*/
                    428: int trapint(signo)
                    429:        int     signo;
                    430: {
                    431:        beep();
                    432:        resume_curses(FALSE);
                    433:        abortdo();
                    434: #if OSK
                    435:        sigmask(-1);
                    436: #endif
                    437: #if TURBOC || __GNUC__
                    438:        signal(signo, (void (*)())trapint);
                    439: #else
                    440:        signal(signo, trapint);
                    441: #endif
                    442:        doingglobal = FALSE;
                    443: 
                    444:        longjmp(jmpenv, 1);
                    445: 
                    446:        return 0;
                    447: }
                    448: 
                    449: 
                    450: 
                    451: #ifndef NO_DIGRAPH
                    452: 
                    453: /* This stuff us used to build the default digraphs table. */
                    454: static char    digtable[][4] =
                    455: {
                    456: # ifdef CS_IBMPC
                    457:        "C,\200",       "u\"\1",        "e'\2",         "a^\3",
                    458:        "a\"\4",        "a`\5",         "a@\6",         "c,\7",
                    459:        "e^\10",        "e\"\211",      "e`\12",        "i\"\13",
                    460:        "i^\14",        "i`\15",        "A\"\16",       "A@\17",
                    461:        "E'\20",        "ae\21",        "AE\22",        "o^\23",
                    462:        "o\"\24",       "o`\25",        "u^\26",        "u`\27",
                    463:        "y\"\30",       "O\"\31",       "U\"\32",       "a'\240",
                    464:        "i'!",          "o'\"",         "u'#",          "n~$",
                    465:        "N~%",          "a-&",          "o-'",          "~?(",
                    466:        "~!-",          "\"<.",         "\">/",
                    467: #  ifdef CS_SPECIAL
                    468:        "2/+",          "4/,",          "^+;",          "^q<",
                    469:        "^c=",          "^r>",          "^t?",          "pp]",
                    470:        "^^^",          "oo_",          "*a`",          "*ba",
                    471:        "*pc",          "*Sd",          "*se",          "*uf",
                    472:        "*tg",          "*Ph",          "*Ti",          "*Oj",
                    473:        "*dk",          "*Hl",          "*hm",          "*En",
                    474:        "*No",          "eqp",          "pmq",          "ger",
                    475:        "les",          "*It",          "*iu",          "*/v",
                    476:        "*=w",          "sq{",          "^n|",          "^2}",
                    477:        "^3~",          "^_\377",
                    478: #  endif /* CS_SPECIAL */
                    479: # endif /* CS_IBMPC */
                    480: # ifdef CS_LATIN1
                    481:        "~!!",          "a-*",          "\">+",         "o-:",
                    482:        "\"<>",         "~??",
                    483: 
                    484:        "A`@",          "A'A",          "A^B",          "A~C",
                    485:        "A\"D",         "A@E",          "AEF",          "C,G",
                    486:        "E`H",          "E'I",          "E^J",          "E\"K",
                    487:        "I`L",          "I'M",          "I^N",          "I\"O",
                    488:        "-DP",          "N~Q",          "O`R",          "O'S",
                    489:        "O^T",          "O~U",          "O\"V",         "O/X",
                    490:        "U`Y",          "U'Z",          "U^[",          "U\"\\",
                    491:        "Y'_",
                    492: 
                    493:        "a``",          "a'a",          "a^b",          "a~c",
                    494:        "a\"d",         "a@e",          "aef",          "c,g",
                    495:        "e`h",          "e'i",          "e^j",          "e\"k",
                    496:        "i`l",          "i'm",          "i^n",          "i\"o",
                    497:        "-dp",          "n~q",          "o`r",          "o's",
                    498:        "o^t",          "o~u",          "o\"v",         "o/x",
                    499:        "u`y",          "u'z",          "u^{",          "u\"|",
                    500:        "y'~",
                    501: # endif /* CS_LATIN1 */
                    502:        ""
                    503: };
                    504: 
                    505: static int init_digraphs()
                    506: {
                    507:        int     i;
                    508: 
                    509:        for (i = 0; *digtable[i]; i++)
                    510:        {
                    511:                do_digraph(FALSE, digtable[i]);
                    512:        }
                    513:        do_digraph(FALSE, (char *)0);
                    514:        return 0;
                    515: }
                    516: #endif /* NO_DIGRAPH */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.