home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / editor / stevie / main.c < prev    next >
C/C++ Source or Header  |  1994-01-31  |  8KB  |  334 lines

  1. /* $Header: /nw/tony/src/stevie/src/RCS/main.c,v 1.12 89/08/02 19:53:27 tony Exp $
  2.  *
  3.  * The main routine and routines to deal with the input buffer.
  4.  */
  5.  
  6. #include "stevie.h"
  7.  
  8. int Rows;        /* Number of Rows and Columns */
  9. int Columns;        /* in the current window. */
  10.  
  11. char *Realscreen = NULL;    /* What's currently on the screen, a single */
  12.                 /* array of size Rows*Columns. */
  13. char *Nextscreen = NULL;    /* What's to be put on the screen. */
  14.  
  15. char *Filename = NULL;    /* Current file name */
  16.  
  17. LPTR *Filemem;        /* Pointer to the first line of the file */
  18.  
  19. LPTR *Filetop;        /* Line 'above' the start of the file */
  20.  
  21. LPTR *Fileend;        /* Pointer to the end of the file in Filemem. */
  22.             /* (It points to the byte AFTER the last byte.) */
  23.  
  24. LPTR *Topchar;        /* Pointer to the byte in Filemem which is */
  25.             /* in the upper left corner of the screen. */
  26.  
  27. LPTR *Botchar;        /* Pointer to the byte in Filemem which is */
  28.             /* just off the bottom of the screen. */
  29.  
  30. LPTR *Curschar;        /* Pointer to byte in Filemem at which the */
  31.             /* cursor is currently placed. */
  32.  
  33. int Cursrow, Curscol;    /* Current position of cursor */
  34.  
  35. int Cursvcol;        /* Current virtual column, the column number of */
  36.             /* the file's actual line, as opposed to the */
  37.             /* column number we're at on the screen.  This */
  38.             /* makes a difference on lines that span more */
  39.             /* than one screen line. */
  40.  
  41. int Curswant = 0;    /* The column we'd like to be at. This is used */
  42.             /* try to stay in the same column through up/down */
  43.             /* cursor motions. */
  44.  
  45. bool_t set_want_col;    /* If set, then update Curswant the next time */
  46.             /* through cursupdate() to the current virtual */
  47.             /* column. */
  48.  
  49. int State = NORMAL;    /* This is the current state of the command */
  50.             /* interpreter. */
  51.  
  52. int Prenum = 0;        /* The (optional) number before a command. */
  53.  
  54. LPTR *Insstart;        /* This is where the latest insert/append */
  55.             /* mode started. */
  56.  
  57. bool_t Changed = 0;    /* Set to 1 if something in the file has been */
  58.             /* changed and not written out. */
  59.  
  60. char Redobuff[1024];    /* Each command should stuff characters into this */
  61.             /* buffer that will re-execute itself. */
  62.  
  63. char Insbuff[1024];    /* Each insertion gets stuffed into this buffer. */
  64.  
  65. int Ninsert = 0;    /* Number of characters in the current insertion. */
  66. char *Insptr = NULL;
  67.  
  68. bool_t    got_int=FALSE;    /* set to TRUE when an interrupt occurs (if possible) */
  69.  
  70. bool_t    interactive = FALSE;    /* set TRUE when main() is ready to roll */
  71.  
  72. char **files;        /* list of input files */
  73. int  numfiles;        /* number of input files */
  74. int  curfile;        /* number of the current file */
  75.  
  76. static void
  77. usage()
  78. {
  79.     fprintf(stderr, "usage: stevie [file ...]\n");
  80.     fprintf(stderr, "       stevie -t tag\n");
  81.     fprintf(stderr, "       stevie +[num] file\n");
  82.     fprintf(stderr, "       stevie +/pat  file\n");
  83.     exit(1);
  84. }
  85.  
  86. main(argc,argv)
  87. int    argc;
  88. char    *argv[];
  89. {
  90.     char    *initstr, *getenv();    /* init string from the environment */
  91.     char    *tag = NULL;        /* tag from command line */
  92.     char    *pat = NULL;        /* pattern from command line */
  93.     int    line = -1;        /* line number from command line */
  94.  
  95.     /*
  96.      * Process the command line arguments.
  97.      */
  98.     if (argc > 1) {
  99.         switch (argv[1][0]) {
  100.         
  101.         case '-':            /* -t tag */
  102.             if (argv[1][1] != 't')
  103.                 usage();
  104.  
  105.             if (argv[2] == NULL)
  106.                 usage();
  107.  
  108.             Filename = NULL;
  109.             tag = argv[2];
  110.             numfiles = 1;
  111.             break;
  112.  
  113.         case '+':            /* +n or +/pat */
  114.             if (argv[1][1] == '/') {
  115.                 if (argv[2] == NULL)
  116.                     usage();
  117.                 Filename = strsave(argv[2]);
  118.                 pat = &(argv[1][1]);
  119.                 numfiles = 1;
  120.  
  121.             } else if (isdigit(argv[1][1]) || argv[1][1] == NUL) {
  122.                 if (argv[2] == NULL)
  123.                     usage();
  124.                 Filename = strsave(argv[2]);
  125.                 numfiles = 1;
  126.  
  127.                 line = (isdigit(argv[1][1])) ?
  128.                     atoi(&(argv[1][1])) : 0;
  129.             } else
  130.                 usage();
  131.  
  132.             break;
  133.  
  134.         default:            /* must be a file name */
  135.             Filename = strsave(argv[1]);
  136.             files = &(argv[1]);
  137.             numfiles = argc - 1;
  138.             break;
  139.         }
  140.     } else {
  141.         Filename = NULL;
  142.         numfiles = 1;
  143.     }
  144.     curfile = 0;
  145.  
  146.      if (numfiles > 1)
  147.          fprintf(stderr, "%d files to edit\n", numfiles);
  148.  
  149.     windinit();
  150.  
  151.     /*
  152.      * Allocate LPTR structures for all the various position pointers
  153.      */
  154.      if ((Filemem = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
  155.          (Filetop = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
  156.          (Fileend = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
  157.          (Topchar = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
  158.          (Botchar = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
  159.          (Curschar = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
  160.         (Insstart = (LPTR *) malloc(sizeof(LPTR))) == NULL ||
  161.         (screenalloc() == -1) ) {
  162.         fprintf(stderr, "Can't allocate data structures\n");
  163.         windexit(0);
  164.     }
  165.  
  166.     filealloc();        /* Initialize Filemem, Filetop, and Fileend */
  167.  
  168.     screenclear();
  169.  
  170.     if ((initstr = getenv("EXINIT")) != NULL) {
  171.         char *lp, buf[128];
  172.  
  173.         if ((lp = getenv("LINES")) != NULL) {
  174.             sprintf(buf, "%s lines=%s", initstr, lp);
  175.             docmdln(buf);
  176.         } else
  177.             docmdln(initstr);
  178.     }
  179.  
  180.     if (Filename != NULL) {
  181.         if (readfile(Filename, Filemem, FALSE))
  182.             filemess("[New File]");
  183.     } else if (tag == NULL)
  184.         msg("Empty Buffer");
  185.  
  186.     setpcmark();
  187.  
  188.     if (tag) {
  189.         stuffin(":ta ");
  190.         stuffin(tag);
  191.         stuffin("\n");
  192.  
  193.     } else if (pat) {
  194.         stuffin(pat);
  195.         stuffin("\n");
  196.  
  197.     } else if (line >= 0) {
  198.         if (line > 0)
  199.             stuffnum(line);
  200.         stuffin("G");
  201.     }
  202.  
  203.     interactive = TRUE;
  204.  
  205.     edit();
  206.  
  207.     windexit(0);
  208.  
  209.     return 1;        /* shouldn't be reached */
  210. }
  211.  
  212. #define    RBSIZE    1024
  213. static char getcbuff[RBSIZE];
  214. static char *getcnext = NULL;
  215.  
  216. void
  217. stuffin(s)
  218. char    *s;
  219. {
  220.     if (s == NULL) {        /* clear the stuff buffer */
  221.         getcnext = NULL;
  222.         return;
  223.     }
  224.  
  225.     if (getcnext == NULL) {
  226.         strcpy(getcbuff,s);
  227.         getcnext = getcbuff;
  228.     } else
  229.         strcat(getcbuff,s);
  230. }
  231.  
  232. void
  233. stuffnum(n)
  234. int    n;
  235. {
  236.     char    buf[32];
  237.  
  238.     sprintf(buf, "%d", n);
  239.     stuffin(buf);
  240. }
  241.  
  242. int
  243. vgetc()
  244. {
  245.     register int    c;
  246.  
  247.     /*
  248.      * inchar() may map special keys by using stuffin(). If it does
  249.      * so, it returns -1 so we know to loop here to get a real char.
  250.      */
  251.     do {
  252.         if ( getcnext != NULL ) {
  253.             int nextc = *getcnext++;
  254.             if ( *getcnext == NUL ) {
  255.                 *getcbuff = NUL;
  256.                 getcnext = NULL;
  257.             }
  258.             return(nextc);
  259.         }
  260.         c = inchar();
  261.     } while (c == -1);
  262.  
  263.     return c;
  264. }
  265.  
  266. /*
  267.  * anyinput
  268.  *
  269.  * Return non-zero if input is pending.
  270.  */
  271.  
  272. bool_t
  273. anyinput()
  274. {
  275.     return (getcnext != NULL);
  276. }
  277.  
  278. /*
  279.  * do_mlines() - process mode lines for the current file
  280.  *
  281.  * Returns immediately if the "ml" parameter isn't set.
  282.  */
  283. #define    NMLINES    5    /* no. of lines at start/end to check for modelines */
  284.  
  285. void
  286. do_mlines()
  287. {
  288.     void    chk_mline();
  289.     int    i;
  290.     register LPTR    *p;
  291.  
  292.     if (!P(P_ML))
  293.         return;
  294.  
  295.     p = Filemem;
  296.     for (i=0; i < NMLINES ;i++) {
  297.         chk_mline(p->linep->s);
  298.         if ((p = nextline(p)) == NULL)
  299.             break;
  300.     }
  301.  
  302.     if ((p = prevline(Fileend)) == NULL)
  303.         return;
  304.  
  305.     for (i=0; i < NMLINES ;i++) {
  306.         chk_mline(p->linep->s);
  307.         if ((p = prevline(p)) == NULL)
  308.             break;
  309.     }
  310. }
  311.  
  312. /*
  313.  * chk_mline() - check a single line for a mode string
  314.  */
  315. static void
  316. chk_mline(s)
  317. register char    *s;
  318. {
  319.     register char    *cs;        /* local copy of any modeline found */
  320.     register char    *e;
  321.  
  322.     for (; *s != NUL ;s++) {
  323.         if (strncmp(s, "vi:", 3) == 0 || strncmp(s, "ex:", 3) == 0) {
  324.             cs = strsave(s+3);
  325.             if ((e = strchr(cs, ':')) != NULL) {
  326.                 *e = NUL;
  327.                 stuffin(mkstr(CTRL('o')));
  328.                 docmdln(cs);
  329.             }
  330.             free(cs);
  331.         }
  332.     }
  333. }
  334.