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