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