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