home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / e / elv17src.zip / MAIN.C < prev    next >
C/C++ Source or Header  |  1992-12-30  |  11KB  |  511 lines

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