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