home *** CD-ROM | disk | FTP | other *** search
/ Shareware 1 2 the Maxx / sw_1.zip / sw_1 / OS2 / BEAV132X.ZIP / MAIN.C < prev    next >
C/C++ Source or Header  |  1992-01-06  |  12KB  |  560 lines

  1. /*
  2. *    BEAV is based on the source for emacs for display and keyboard handling
  3. * functions.   The binary file handling and display formats are special
  4. * to BEAV.   There is a full manual included in this release.   There
  5. * are makefiles for unix and MSC 5.1 under DOS.   The old Wang PC is
  6. * supported.   This release is for unix.   The def_unix.h file is the
  7. * header for unix and the def_dos.h file is the header for dos.   Rename
  8. * the appropriate .h file to def.h to convert to your os.
  9. *     I am willing to maintain BEAV and will entertain suggestions for
  10. * modifications and/or bug fixes.   I can be reached at;
  11. *
  12. *         pvr@wang.com
  13. *
  14. * or at;
  15. *
  16. *         Peter Reilley
  17. *         19 Heritage Cir.
  18. *         Hudson, N.H. 03051
  19. */
  20.  
  21. /*
  22. *    Bug fix log
  23. *    3/04/91        1.20        pvr
  24. *        Create new file with read/write permisions.
  25. *        Fix polled mode system hog tty bug.
  26. *        Add ANSI define for DOS.
  27. *        Define short for D16 type.
  28. *        Call ttclose on error exit.
  29. *        Limit nrow and ncol to actual array size.
  30. *        Added beavrc key binding functionallity.
  31. *        Added delete current window command.
  32. *        Support VT100 type function keys for binding.
  33. */
  34. /*
  35. *
  36. *     Mainline, macro commands.
  37. */
  38. #include        "def.h"
  39.  
  40. bool    execute ();
  41. void    edinit ();
  42. char    flush_all ();
  43. char    quit ();
  44. char    ctrlg ();
  45. void    _lowercase ();
  46.  
  47.  
  48. extern    char    MSG_ok[];
  49. extern    char    MSG_main[];
  50. extern    char    MSG_prog_name[];
  51. extern    char    MSG_init_file[];
  52. extern    char    MSG_init_var[];
  53. extern    char    MSG_init_path[];
  54. extern    char    MSG_no_mod[];
  55. extern    char    MSG_no_s_chg[];
  56. extern    char    MSG_auto_fl[];
  57. extern    char    MSG_quit[];
  58. extern    char    MSG_not_now[];
  59. extern    char    MSG_st_mac[];
  60. extern    char    MSG_end_mac[];
  61. extern    char    MSG_num_mod[];
  62. extern    char    MSG_null[];
  63.  
  64. int     thisflag;               /* Flags, this command      */
  65. int     lastflag;               /* Flags, last command          */
  66. int     curgoal;                /* Goal column                  */
  67. int     com_line_flags;         /* Count of cmd line switches   */
  68. BUFFER * curbp;                 /* Current buffer               */
  69. WINDOW * curwp;                 /* Current window               */
  70. BUFFER * bheadp;                /* BUFFER listhead              */
  71. WINDOW * wheadp;                /* WINDOW listhead              */
  72. BUFFER * blistp;                /* Buffer list BUFFER           */
  73. short   kbdm[NKBDM] = {
  74.     (KCTLX | ')')};  /* Macro (fitz)  */
  75. short  *kbdmip;                 /* Input  for above             */
  76. short  *kbdmop;                 /* Output for above             */
  77. SYMBOL * symbol[NSHASH];        /* Symbol table listhead.       */
  78. SYMBOL * binding[NKEYS];        /* Key bindings.                */
  79. extern  ROW_FMT hex_8_fmt;
  80. extern  bool    ibm_pc, mem_map;
  81.  
  82. char   *okmsg = {
  83.     MSG_ok};
  84. int     insert_mode = {
  85.     TRUE};
  86. int     extend_buf = {
  87.     FALSE};
  88.  
  89. extern  bool    srch_mode;
  90. extern  bool    rplc_mode;
  91. extern  char    *getenv ();
  92. int     initial_load = 0;
  93. int     flush_count = 0;
  94. int     flush_num = 500;
  95. int     auto_update = 0;
  96.  
  97. void main (argc, argv)
  98. int     argc;
  99. char   *argv[];
  100. {
  101.  
  102.     register    int     c;
  103.     register    int     f;
  104.     register    int     n;
  105.     register    int     mflag;
  106.     char        bname[NBUFN];
  107.     char        initfile[NFILEN];
  108.  
  109. #if MSDOS
  110.     is_wang ();                 /* Check for computer type */
  111.  
  112. #endif
  113.     init_fmt ();                /* initialize format arrays */
  114.     strcpy (bname, MSG_main);     /* Get buffer name.     */
  115.     vtinit ();                  /* Virtual terminal.    */
  116.     keymapinit ();              /* Symbols, bindings.   */
  117.  
  118.     if (argc == 1)
  119.     {
  120.         edinit (bname);
  121.         update ();
  122.         eerase ();
  123.     }
  124.  
  125.     else
  126.     {
  127.         com_line_flags = 0;
  128.         initial_load = 1;
  129.         n = (argc - 1);         /* Load  them backwards */
  130.         if (n > com_line_flags)
  131.         {
  132.             /*            _lowercase (argv[n]); */
  133.             makename (bname, argv[n]);
  134.             edinit (bname);     /* Buffers, windows.    */
  135.             update ();
  136.             readin (argv[n--], 0L, MAXPOS);
  137.             for (; n > com_line_flags; n--)
  138.             {
  139.                 /*                _lowercase (argv[n]); */
  140.                 load_file (argv[n], 0L, MAXPOS);
  141.             }
  142.         }
  143.         else
  144.         {
  145.             edinit (bname);
  146.             update ();
  147.         }
  148.  
  149.         initial_load = 0;
  150.     }
  151.  
  152. #ifdef OS2
  153.         _searchenv(MSG_init_file, MSG_init_var, initfile);
  154.         if ( initfile[0] )
  155.            check_extend (initfile);
  156.         else
  157.         {
  158.           _searchenv(MSG_init_file, MSG_init_path, initfile);
  159.           if ( initfile[0] )
  160.              check_extend (initfile);
  161.           else
  162.              check_extend (getenv (MSG_prog_name));
  163.         }
  164. #else
  165.     check_extend (NULL);  /* check for extended keys */
  166. #endif
  167.     save_buf_init();        /* initialize save buffer */
  168.     lastflag = 0;               /* Fake last flags.     */
  169.  
  170. loop:
  171.     update ();
  172.     c = getkey ();
  173.     if (epresf != FALSE)
  174.     {
  175.         eerase ();
  176.         update ();
  177.     }
  178.     f = FALSE;
  179.     n = 1;
  180.     if (c == (KCTRL | 'U'))
  181.     {
  182.         /* ^U, start argument.  */
  183.         f = TRUE;
  184.         n = 4;
  185.         while ((c = getkey ()) == (KCTRL | 'U'))
  186.             n *= 4;
  187.         if ((c >= '0' && c <= '9') || c == '-')
  188.         {
  189.             if (c == '-')
  190.             {
  191.                 n = 0;
  192.                 mflag = TRUE;
  193.             }
  194.             else
  195.             {
  196.                 n = c - '0';
  197.                 mflag = FALSE;
  198.             }
  199.             while ((c = getkey ()) >= '0' && c <= '9')
  200.                 n = 10 * n + c - '0';
  201.             if (mflag != FALSE)
  202.                 n = -n;
  203.         }
  204.     }
  205.     if (kbdmip != NULL)
  206.     {
  207.         /* Save macro strokes.  */
  208.         if (c != (KCTLX | ')') && kbdmip > &kbdm[NKBDM - 6])
  209.         {
  210.             ctrlg (FALSE, 0, KRANDOM);
  211.             goto loop;
  212.         }
  213.         if (f != FALSE)
  214.         {
  215.             *kbdmip++ = (KCTRL | 'U');
  216.             *kbdmip++ = n;
  217.         }
  218.         *kbdmip++ = c;
  219.     }
  220.     execute (c, f, n);          /* Do it.               */
  221.     goto loop;
  222. }
  223.  
  224.  
  225. /*
  226. * Command execution. Look up the binding in the the
  227. * binding array, and do what it says. Return a very bad status
  228. * if there is no binding, or if the symbol has a type that
  229. * is not usable (there is no way to get this into a symbol table
  230. * entry now). Also fiddle with the flags.
  231. */
  232. char    execute (c, f, n)
  233. int c, f, n;
  234. {
  235.  
  236.     register    SYMBOL * sp;
  237.     register int    status;
  238.  
  239.     if ((sp = binding[c]) != NULL)
  240.     {
  241.         thisflag = 0;
  242.         if (sp -> s_modify & SMOD && (curbp -> b_flag & BFVIEW))
  243.         {
  244.             writ_echo (MSG_no_mod);
  245.             return (ABORT);
  246.         }
  247.         if (sp -> s_modify & SSIZE && (curbp -> b_flag & BFSLOCK))
  248.         {
  249.             writ_echo (MSG_no_s_chg);
  250.             return (ABORT);
  251.         }
  252.         if ((srch_mode  && !(sp -> s_modify & SSRCH)) ||
  253.             (rplc_mode  && !(sp -> s_modify & SRPLC)))
  254.         {
  255.             ttbeep ();
  256.             return (TRUE);
  257.         }
  258.  
  259.         status = (*sp -> s_funcp) (f, n, c);
  260.         if (sp -> s_modify & SMOD)
  261.             flush_count++;
  262.  
  263.         if (flush_count >= flush_num && auto_update)
  264.             if (!(kbdmip != NULL || kbdmop != NULL))/* not during macro */
  265.             {
  266.                 ttbeep ();
  267.                 writ_echo (MSG_auto_fl);
  268.                 flush_all ();
  269.             }
  270.         lastflag = thisflag;
  271.         return (status);
  272.     }
  273.     else
  274.         bad_key (c);
  275.  
  276.     lastflag = 0;
  277.     return (ABORT);
  278. }
  279.  
  280.  
  281. /*
  282. * Initialize all of the buffers
  283. * and windows. The buffer name is passed down as
  284. * an argument, because the main routine may have been
  285. * told to read in a file by default, and we want the
  286. * buffer name to be right.
  287. */
  288. void edinit (bname)
  289. char    bname[];
  290. {
  291.  
  292.     register    BUFFER * bp;
  293.     register    WINDOW * wp;
  294.  
  295.     bp = bfind (bname, TRUE);   /* Text buffer.         */
  296.     blistp = bcreate (MSG_null);      /* Special list buffer. */
  297.     wp = (WINDOW *) malloc (sizeof (WINDOW));/* Initial window.      */
  298.     if (bp == NULL || wp == NULL || blistp == NULL)
  299.         abort ();
  300.     curbp = bp;                 /* Current ones.        */
  301.     wheadp = wp;
  302.     curwp = wp;
  303.     wp -> w_wndp = NULL;        /* Initialize window.   */
  304.     wp -> w_bufp = bp;
  305.     bp -> b_nwnd = 1;           /* Displayed.           */
  306.     wp -> w_fmt_ptr = &hex_8_fmt;/* HEX 8 bit display       pvr  */
  307.     wp -> w_linep = bp -> b_linep;
  308.     wp -> w_dotp = bp -> b_linep;
  309.     wp -> w_doto = 0;           /* set dot pos  pvr */
  310.     wp -> w_markp = NULL;
  311.     wp -> w_marko = 0;
  312.     wp -> w_toprow = 0;
  313.     wp -> w_ntrows = nrow - 2;  /* 2 = mode, echo.      */
  314.     wp -> w_flag = WFMODE | WFHARD;/* Full.                */
  315.     wp -> w_intel_mode = FALSE; /* default is no byte swap     pvr  */
  316.     wp -> w_disp_shift = 0;     /* default to no byte shift    pvr  */
  317.     wp -> w_loff = 0;           /* starting line offset        pvr  */
  318.     wp -> w_unit_offset = 0;    /* dot offset from file start  pvr  */
  319. }
  320.  
  321. /*
  322. * Flush all the dirty buffers that have file names
  323. * associated with them.
  324. */
  325. char flush_all ()
  326. {
  327.     register    BUFFER * bp,
  328.     *savbp = curbp;
  329.  
  330.     for (bp = bheadp; bp != NULL; bp = bp -> b_bufp)
  331.         if (bp -> b_fname != NULL)
  332.         {
  333.             curbp = bp;         /* jam */
  334.             filesave ();
  335.             update ();
  336.         }
  337.     flush_count = 0;
  338.     writ_echo (okmsg);
  339.     curbp = savbp;
  340.     if (blistp -> b_nwnd != 0)  /* update buffer display */
  341.         listbuffers ();
  342.     update ();
  343.     return (TRUE);
  344. }
  345.  
  346.  
  347. /* call flush_all to empty the buffers
  348. * and quit
  349. */
  350. bool flushnquit (f, n, k)
  351. int f, n, k;
  352. {
  353.     flush_all ();
  354.     quit (f, n, k);
  355.     return (TRUE);
  356. }
  357.  
  358.  
  359. /*
  360. * Quit command. If an argument, always
  361. * quit. Otherwise confirm if a buffer has been
  362. * changed and not written out. Normally bound
  363. * to "C-X C-C".
  364. */
  365. char    quit (f, n, k)
  366. int f, n, k;
  367. {
  368.  
  369.     register char   s;
  370.  
  371.     if (f != FALSE              /* Argument forces it.  */
  372.     || anycb () == FALSE/* All buffers clean.   */
  373.     || (s = eyesno (MSG_quit)) == TRUE)/* User says it's OK.   */
  374.     {
  375.  
  376.         vttidy ();
  377.         exit (GOOD);
  378.     }
  379.  
  380.     return (s);
  381. }
  382.  
  383.  
  384. /*
  385. * Begin a keyboard macro.
  386. * Error if not at the top level
  387. * in keyboard processing. Set up
  388. * variables and return.
  389. */
  390. bool ctlxlp (f, n, k)
  391. int f, n, k;
  392. {
  393.  
  394.     if (kbdmip != NULL || kbdmop != NULL)
  395.     {
  396.  
  397.         writ_echo (MSG_not_now);
  398.         return (FALSE);
  399.     }
  400.  
  401.     writ_echo (MSG_st_mac);
  402.     kbdmip = &kbdm[0];
  403.     return (TRUE);
  404. }
  405.  
  406.  
  407. /*
  408. * End keyboard macro. Check for
  409. * the same limit conditions as the
  410. * above routine. Set up the variables
  411. * and return to the caller.
  412. */
  413. bool ctlxrp (f, n, k)
  414. int f, n, k;
  415. {
  416.  
  417.     if (kbdmip == NULL)
  418.     {
  419.  
  420.         writ_echo (MSG_not_now);
  421.         return (FALSE);
  422.     }
  423.  
  424.     writ_echo (MSG_end_mac);
  425.     kbdmip = NULL;
  426.     return (TRUE);
  427. }
  428.  
  429.  
  430. /*
  431. * Execute a macro.
  432. * The command argument is the
  433. * number of times to loop. Quit as
  434. * soon as a command gets an error.
  435. * Return TRUE if all ok, else
  436. * FALSE.
  437. */
  438. bool ctlxe (f, n, k)
  439. int f, n, k;
  440. {
  441.  
  442.     register int    c;
  443.     register int    af;
  444.     register int    an;
  445.     register int    s;
  446.  
  447.     if (kbdmip != NULL || kbdmop != NULL)
  448.     {
  449.  
  450.         writ_echo (MSG_not_now);
  451.         return (FALSE);
  452.     }
  453.  
  454.     if (n <= 0)
  455.         return (TRUE);
  456.     do
  457.     {
  458.  
  459.         kbdmop = &kbdm[0];
  460.         do
  461.         {
  462.  
  463.             af = FALSE;
  464.             an = 1;
  465.             if ((c = *kbdmop++) == (KCTRL | 'U'))
  466.             {
  467.  
  468.                 af = TRUE;
  469.                 an = *kbdmop++;
  470.                 c = *kbdmop++;
  471.             }
  472.  
  473.             s = TRUE;
  474.         }        while (c != (KCTLX | ')') && (s = execute (c, af, an)) == TRUE);
  475.         kbdmop = NULL;
  476.     }    while (s == TRUE && --n);
  477.     return (s);
  478. }
  479.  
  480.  
  481. /*
  482. * Abort.
  483. * Beep the beeper.
  484. * Kill off any keyboard macro,
  485. * etc., that is in progress.
  486. * Sometimes called as a routine,
  487. * to do general aborting of
  488. * stuff.
  489. */
  490. char    ctrlg (f, n, k)
  491. int f, n, k;
  492. {
  493.     /*    ttbeep (); */
  494.     if (kbdmip != NULL)
  495.     {
  496.         kbdm[0] = (KCTLX | ')');
  497.         kbdmip = NULL;
  498.     }
  499.     return (ABORT);
  500. }
  501.  
  502.  
  503. /*
  504. * Display the version. All this does
  505. * is copy the text in the external "version" array into
  506. * the message system, and call the message reading code.
  507. * Don't call display if there is an argument.
  508. */
  509. char    showversion (f, n, k)
  510. int f, n, k;
  511. {
  512.     static  char    *cp;
  513.     char    buf[NCOL];
  514.  
  515.     cp = version;
  516.     sprintf (buf, cp);
  517.     writ_echo (buf);
  518.     return (TRUE);
  519. }
  520.  
  521.  
  522. /* ughly to_lower function for
  523. * files read in under MSDOS setargv function
  524. */
  525. void _lowercase (s)
  526. register char  *s;
  527. {
  528.  
  529. #ifdef MSDOS
  530.     for (; *s; s++)
  531.         if (ISUPPER (*s))
  532.             *s = TOLOWER (*s);
  533. #endif
  534. }
  535.  
  536.  
  537. /* autosave control
  538. */
  539. bool autosave ()
  540. {
  541.     register    WINDOW * wp;
  542.     int        n;
  543.     char    buf[NCOL];
  544.  
  545.     if ((ereply (MSG_num_mod, buf, sizeof (buf), NULL)) == TRUE)
  546.     {
  547.  
  548.         n = atoi (buf);
  549.         if (n >= 0)
  550.             auto_update = flush_num = n;/* not 0! */
  551.         else
  552.             auto_update = 0;
  553.     }
  554.  
  555.     for (wp = wheadp; wp; wp = wp -> w_wndp)
  556.         if (wp -> w_bufp == curbp)
  557.             wp -> w_flag |= WFMODE;
  558.     return (TRUE);
  559. }
  560.