home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 May / W2KPRK.iso / apps / posix / source / ELVIS / MAIN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1999-11-17  |  8.4 KB  |  445 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. #ifdef DF_POSIX
  14. #include <stddef.h>
  15. #include <stdlib.h>
  16. #include <stdio.h>
  17. #endif
  18.  
  19. #include "config.h"
  20. #include <signal.h>
  21. #include <setjmp.h>
  22. #include "vi.h"
  23.  
  24. #ifdef DF_POSIX
  25. #include <termios.h>
  26.  
  27. extern struct termios    oldtermio;    /* original tty mode */
  28. extern struct termios    newtermio;    /* cbreak/noecho tty mode */
  29. #endif
  30.  
  31. extern        trapint(); /* defined below */
  32. extern char    *getenv();
  33. jmp_buf        jmpenv;
  34. #if WIN_NT && SETJMP_KLUDGE
  35. #include <excpt.h>
  36. #endif
  37.  
  38. #ifndef NO_DIGRAPH
  39. static init_digraphs();
  40. #endif
  41.  
  42. /*---------------------------------------------------------------------*/
  43.  
  44. void main(argc, argv)
  45.     int    argc;
  46.     char    *argv[];
  47. {
  48.     int    i;
  49.     char    *cmd = (char *)0;
  50.     char    *tag = (char *)0;
  51.     char    *err = (char *)0;
  52.     char    *str;
  53. #if MSDOS || TOS
  54.     char firstarg[256];
  55. #else
  56.     char *firstarg;
  57. #endif
  58.  
  59. #if WIN_NT && SETJMP_KLUDGE
  60.     try {
  61.     } except(EXCEPTION_EXECUTE_HANDLER) {
  62.         exit(EXIT_FAILURE);
  63.     }
  64. #endif
  65.     /* set mode to MODE_VI or MODE_EX depending on program name */
  66.     switch (argv[0][strlen(argv[0]) - 1])
  67.     {
  68.       case 'x':            /* "ex" */
  69.         mode = MODE_EX;
  70.         break;
  71.  
  72.       case 'w':            /* "view" */
  73.         mode = MODE_VI;
  74.         *o_readonly = TRUE;
  75.         break;
  76. #ifndef NO_EXTENSIONS
  77.       case 't':            /* "edit" or "input" */
  78.         mode = MODE_VI;
  79.         *o_inputmode = TRUE;
  80.         break;
  81. #endif
  82.       default:            /* "vi" or "elvis" */
  83.         mode = MODE_VI;
  84.     }
  85.  
  86. #ifndef DEBUG
  87. # ifdef    SIGQUIT
  88.     /* normally, we ignore SIGQUIT.  SIGINT is trapped later */
  89.     signal(SIGQUIT, SIG_IGN);
  90. # endif
  91. #endif
  92.  
  93.     /* temporarily ignore SIGINT */
  94.     signal(SIGINT, SIG_IGN);
  95.  
  96.     /* start curses */
  97.     initscr();
  98.     cbreak(newtermio);
  99.     noecho(newtermio);
  100.     scrollok(stdscr, TRUE);
  101.  
  102.     /* initialize the options */
  103.     initopts();
  104.  
  105.     /* map the arrow keys.  The KU,KD,KL,and KR variables correspond to
  106.      * the :ku=: (etc.) termcap capabilities.  The variables are defined
  107.      * as part of the curses package.
  108.      */
  109.     if (has_KU) mapkey(has_KU, "k",    WHEN_VICMD|WHEN_INMV, "<Up>");
  110.     if (has_KD) mapkey(has_KD, "j",    WHEN_VICMD|WHEN_INMV, "<Down>");
  111.     if (has_KL) mapkey(has_KL, "h",    WHEN_VICMD|WHEN_INMV, "<Left>");
  112.     if (has_KR) mapkey(has_KR, "l",    WHEN_VICMD|WHEN_INMV, "<Right>");
  113.     if (has_HM) mapkey(has_HM, "^",    WHEN_VICMD|WHEN_INMV, "<Home>");
  114.     if (has_EN) mapkey(has_EN, "$",    WHEN_VICMD|WHEN_INMV, "<End>");
  115.     if (has_PU) mapkey(has_PU, "\002", WHEN_VICMD|WHEN_INMV, "<PgUp>");
  116.     if (has_PD) mapkey(has_PD, "\006", WHEN_VICMD|WHEN_INMV, "<PgDn>");
  117. #if MSDOS
  118.     if (*o_pcbios)
  119.     {
  120.         mapkey("#R", "i", WHEN_VICMD|WHEN_INMV,    "<Insrt>");
  121.         mapkey("#S", "x", WHEN_VICMD|WHEN_INMV,    "<Del>");
  122.         mapkey("#s", "B", WHEN_VICMD|WHEN_INMV,    "^<left>");
  123.         mapkey("#t", "W", WHEN_VICMD|WHEN_INMV,    "^<right>");
  124.     }
  125. #else
  126.     if (ERASEKEY != '\177')
  127.     {
  128.         mapkey("\177", "x", WHEN_VICMD|WHEN_INMV, "<Del>");
  129.     }
  130. #endif
  131.  
  132. #ifndef NO_DIGRAPH
  133.     init_digraphs();
  134. #endif /* NO_DIGRAPH */
  135.  
  136.     /* process any flags */
  137.     for (i = 1; i < argc && *argv[i] == '-'; i++)
  138.     {
  139.         switch (argv[i][1])
  140.         {
  141.           case 'R':    /* readonly */
  142.             *o_readonly = TRUE;
  143.             break;
  144.  
  145.           case 'r':    /* recover */
  146.             msg("Use the `virec` program to recover lost files");
  147.             endmsgs();
  148.             refresh();
  149.             endwin();
  150.             exit(0);
  151.             break;
  152.  
  153.           case 't':    /* tag */
  154.             if (argv[i][2])
  155.             {
  156.                 tag = argv[i] + 2;
  157.             }
  158.             else
  159.             {
  160.                 i++;
  161.                 tag = argv[i];
  162.             }
  163.             break;
  164.  
  165.           case 'v':    /* vi mode */
  166.             mode = MODE_VI;
  167.             break;
  168.  
  169.           case 'e':    /* ex mode */
  170.             mode = MODE_EX;
  171.             break;
  172. #ifndef NO_EXTENSIONS
  173.           case 'i':    /* input mode */
  174.             *o_inputmode = TRUE;
  175.             break;
  176. #endif
  177. #ifndef NO_ERRLIST
  178.           case 'm':    /* use "errlist" as the errlist */
  179.             if (argv[i][2])
  180.             {
  181.                 err = argv[i] + 2;
  182.             }
  183.             else if (i + 1 < argc)
  184.             {
  185.                 i++;
  186.                 err = argv[i];
  187.             }
  188.             else
  189.             {
  190.                 err = "";
  191.             }
  192.             break;
  193. #endif
  194.           default:
  195.             msg("Ignoring unknown flag \"%s\"", argv[i]);
  196.         }
  197.     }
  198.  
  199.     /* if we were given an initial ex command, save it... */
  200.     if (i < argc && *argv[i] == '+')
  201.     {
  202.         if (argv[i][1])
  203.         {
  204.             cmd = argv[i++] + 1;
  205.         }
  206.         else
  207.         {
  208.             cmd = "$"; /* "vi + file" means start at EOF */
  209.             i++;
  210.         }
  211.     }
  212.  
  213.     /* the remaining args are file names. */
  214.     nargs = argc - i;
  215.     if (nargs > 0)
  216.     {
  217. #if ! ( MSDOS || TOS )
  218.         firstarg = argv[i];
  219. #endif
  220.         strcpy(args, argv[i]);
  221.         while (++i < argc && strlen(args) + 1 + strlen(argv[i]) < sizeof args)
  222.         {
  223.             strcat(args, " ");
  224.             strcat(args, argv[i]);
  225.         }
  226.     }
  227. #if ! ( MSDOS || TOS )
  228.     else
  229.     {
  230.         firstarg = "";
  231.     }
  232. #endif
  233.     argno = 0;
  234.  
  235. #if MSDOS || TOS
  236.     if (nargs > 0)
  237.     {
  238.         strcpy(args, wildcard(args));
  239.         nargs = 1;
  240.         for (i = 0; args[i]; i++)
  241.         {
  242.             if (args[i] == ' ')
  243.             {
  244.                 nargs++;
  245.             }
  246.         }
  247.         for (i = 0; args[i] && args[i] != ' '; i++)
  248.         {
  249.             firstarg[i] = args[i];
  250.         }
  251.         firstarg[i] = '\0';
  252.     }
  253.     else
  254.     {
  255.         firstarg[0] = '\0';
  256.     }
  257. #endif
  258.  
  259.     /* perform the .exrc files and EXINIT environment variable */
  260. #ifdef SYSEXRC
  261.     doexrc(SYSEXRC);
  262. #endif
  263. #ifdef HMEXRC
  264.     str = getenv("HOME");
  265.     if (str)
  266.     {
  267.         sprintf(tmpblk.c, "%s%c%s", str, SLASH, HMEXRC);
  268.         doexrc(tmpblk.c);
  269.     }
  270. #endif
  271.     doexrc(EXRC);
  272. #ifdef EXINIT
  273.     str = getenv(EXINIT);
  274.     if (str)
  275.     {
  276.         exstring(str, strlen(str));
  277.     }
  278. #endif
  279.  
  280.     /* search for a tag (or an error) now, if desired */
  281.     blkinit();
  282.     if (tag)
  283.     {
  284.         cmd_tag(MARK_FIRST, MARK_FIRST, CMD_TAG, 0, tag);
  285.     }
  286. #ifndef NO_ERRLIST
  287.     else if (err)
  288.     {
  289.         cmd_errlist(MARK_FIRST, MARK_FIRST, CMD_ERRLIST, 0, err);
  290.     }
  291. #endif
  292.  
  293.     /* if no tag/err, or tag failed, then start with first arg */
  294.     if (tmpfd < 0 && tmpstart(firstarg) == 0 && *origname)
  295.     {
  296.         ChangeText
  297.         {
  298.         }
  299.         clrflag(file, MODIFIED);
  300.     }
  301.  
  302.     /* now we do the immediate ex command that we noticed before */
  303.     if (cmd)
  304.     {
  305.         doexcmd(cmd);
  306.     }
  307.  
  308.     /* repeatedly call ex() or vi() (depending on the mode) until the
  309.      * mode is set to MODE_QUIT
  310.      */
  311.     while (mode != MODE_QUIT)
  312.     {
  313.         if (setjmp(jmpenv))
  314.         {
  315.             /* Maybe we just aborted a change? */
  316.             abortdo();
  317.         }
  318. #if TURBOC
  319.         signal(SIGINT, (void(*)()) trapint);
  320. #else
  321.         signal(SIGINT, trapint);
  322. #endif
  323.  
  324.         switch (mode)
  325.         {
  326.           case MODE_VI:
  327.             vi();
  328.             break;
  329.  
  330.           case MODE_EX:
  331.             ex();
  332.             break;
  333. #ifdef DEBUG
  334.           default:
  335.             msg("mode = %d?", mode);
  336.             mode = MODE_QUIT;
  337. #endif
  338.         }
  339.     }
  340.  
  341.     /* free up the cut buffers */
  342.     cutend();
  343.  
  344.     /* end curses */
  345. #ifndef    NO_CURSORSHAPE
  346.     if (has_CQ)
  347.         do_CQ();
  348. #endif
  349.     endmsgs();
  350.     move(LINES - 1, 0);
  351.     clrtoeol();
  352.     refresh();
  353.     endwin();
  354.  
  355.     exit(0);
  356.     /*NOTREACHED*/
  357. }
  358.  
  359.  
  360. /*ARGSUSED*/
  361. int trapint(signo)
  362.     int    signo;
  363. {
  364.     resume_curses(FALSE);
  365.     abortdo();
  366. #if OSK
  367.     sigmask(-1);
  368. #endif
  369. #if TURBO_C
  370.     signal(signo, (void (*)())trapint);
  371. #else
  372.     signal(signo, trapint);
  373. #endif
  374.     longjmp(jmpenv, 1);
  375.  
  376.     return 0;
  377. }
  378.  
  379.  
  380. #ifndef NO_DIGRAPH
  381.  
  382. /* This stuff us used to build the default digraphs table. */
  383. static char    digtable[][4] =
  384. {
  385. # if CS_IBMPC
  386.     "C,\200",    "u\"\1",    "e'\2",        "a^\3",
  387.     "a\"\4",    "a`\5",        "a@\6",        "c,\7",
  388.     "e^\10",    "e\"\211",    "e`\12",    "i\"\13",
  389.     "i^\14",    "i`\15",    "A\"\16",    "A@\17",
  390.     "E'\20",    "ae\21",    "AE\22",    "o^\23",
  391.     "o\"\24",    "o`\25",    "u^\26",    "u`\27",
  392.     "y\"\30",    "O\"\31",    "U\"\32",    "a'\240",
  393.     "i'!",        "o'\"",        "u'#",        "n~$",
  394.     "N~%",        "a-&",        "o-'",        "~?(",
  395.     "~!-",        "\"<.",        "\">/",
  396. #  if CS_SPECIAL
  397.     "2/+",        "4/,",        "^+;",        "^q<",
  398.     "^c=",        "^r>",        "^t?",        "pp]",
  399.     "^^^",        "oo_",        "*a`",        "*ba",
  400.     "*pc",        "*Sd",        "*se",        "*uf",
  401.     "*tg",        "*Ph",        "*Ti",        "*Oj",
  402.     "*dk",        "*Hl",        "*hm",        "*En",
  403.     "*No",        "eqp",        "pmq",        "ger",
  404.     "les",        "*It",        "*iu",        "*/v",
  405.     "*=w",        "sq{",        "^n|",        "^2}",
  406.     "^3~",        "^_\377",
  407. #  endif /* CS_SPECIAL */
  408. # endif /* CS_IBMPC */
  409. # if CS_LATIN1
  410.     "~!!",        "a-*",        "\">+",        "o-:",
  411.     "\"<>",        "~??",
  412.  
  413.     "A`@",        "A'A",        "A^B",        "A~C",
  414.     "A\"D",        "A@E",        "AEF",        "C,G",
  415.     "E`H",        "E'I",        "E^J",        "E\"K",
  416.     "I`L",        "I'M",        "I^N",        "I\"O",
  417.     "-DP",        "N~Q",        "O`R",        "O'S",
  418.     "O^T",        "O~U",        "O\"V",        "O/X",
  419.     "U`Y",        "U'Z",        "U^[",        "U\"\\",
  420.     "Y'_",
  421.  
  422.     "a``",        "a'a",        "a^b",        "a~c",
  423.     "a\"d",        "a@e",        "aef",        "c,g",
  424.     "e`h",        "e'i",        "e^j",        "e\"k",
  425.     "i`l",        "i'm",        "i^n",        "i\"o",
  426.     "-dp",        "n~q",        "o`r",        "o's",
  427.     "o^t",        "o~u",        "o\"v",        "o/x",
  428.     "u`y",        "u'z",        "u^{",        "u\"|",
  429.     "y'~",
  430. # endif /* CS_LATIN1 */
  431.     ""
  432. };
  433.  
  434. static init_digraphs()
  435. {
  436.     int    i;
  437.  
  438.     for (i = 0; *digtable[i]; i++)
  439.     {
  440.         do_digraph(FALSE, digtable[i]);
  441.     }
  442.     do_digraph(FALSE, (char *)0);
  443. }
  444. #endif /* NO_DIGRAPH */
  445.