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

  1. /*
  2. *              Assorted commands.
  3. * The file contains the command
  4. * processors for a large assortment of unrelated
  5. * commands. The only thing they have in common is
  6. * that they are all command processors.
  7. */
  8.  
  9. #include    "def.h"
  10.  
  11. char    backdel ();
  12. bool    fill_out ();
  13. void    bad_key ();
  14.  
  15.  
  16.  
  17. extern    char    MSG_sh_pos[];
  18. extern    char    MSG_sh_pos1[];
  19. extern    char    MSG_f_str[];
  20. extern    char    MSG_3u[];
  21. extern    char    MSG_5u[];
  22. extern    char    MSG_lu[];
  23. extern    char    MSG_03u[];
  24. extern    char    MSG_05u[];
  25. extern    char    MSG_010lu[];
  26. extern    char    MSG_lnk[];
  27. extern    char    MSG_unlink[];
  28. extern    char    MSG_link[];
  29. extern    char    MSG_bad_key[];
  30. extern    char    MSG_esc[];
  31. extern    char    MSG_ctl_x[];
  32. extern    char    MSG_ctl[];
  33. extern    char    MSG_key_code[];
  34. extern    char    char_str[];
  35. extern    char    MSG_w_not_empty[];
  36. extern    char    MSG_procing[];
  37. extern    char    MSG_ok[];
  38. #if RUNCHK
  39. extern    char    ERR_rnd_1[];
  40. extern    char    ERR_rnd_2[];
  41. extern    char    ERR_rnd_3[];
  42. extern    char    ERR_rnd_4[];
  43. extern    char    ERR_rnd_5[];
  44. extern    char    ERR_rnd_6[];
  45. extern    char    ERR_rnd_7[];
  46. #endif
  47.  
  48. extern  ROW_FMT ascii_fmt;
  49. extern  ROW_FMT ebcdic_fmt;
  50. extern  ROW_FMT binary_8_fmt;
  51. extern  ROW_FMT binary_16_fmt;
  52. extern  ROW_FMT binary_32_fmt;
  53. extern  ROW_FMT octal_8_fmt;
  54. extern  ROW_FMT octal_16_fmt;
  55. extern  ROW_FMT octal_32_fmt;
  56. extern  ROW_FMT decimal_8_fmt;
  57. extern  ROW_FMT decimal_16_fmt;
  58. extern  ROW_FMT decimal_32_fmt;
  59. extern  ROW_FMT hex_8_fmt;
  60. extern  ROW_FMT hex_16_fmt;
  61. extern  ROW_FMT hex_32_fmt;
  62.  
  63. extern  bool    read_pat_mode;
  64. extern  bool    dont_repeat;
  65. extern    BUFFER  sav_buf;
  66.  
  67. char    dec_chr_ok ();
  68. ulong   get_long ();
  69. void wind_on_dot_all ();
  70.  
  71. /*
  72. * Display a bunch of useful information about
  73. * the current location of dot and mark.
  74. * The position of the dot and mark and the difference between them.
  75. * The total buffer size is displayed.
  76. * This is normally bound to "C-X =".
  77. */
  78. bool showcpos (f, n, k)
  79. int f, n, k;
  80. {
  81.  
  82.     A32     dotoff,
  83.         markoff,
  84.         fsize,
  85.         bsize;
  86.     char    buf[NCOL * 2], buf1[NCOL * 2];
  87.  
  88.     dotoff = curwp -> w_dotp -> l_file_offset;
  89.     dotoff += curwp -> w_doto;
  90.  
  91.     if (curwp -> w_markp != NULL)
  92.     {
  93.         markoff = curwp -> w_markp -> l_file_offset;
  94.         markoff += curwp -> w_marko;
  95.     }
  96.  
  97.     bsize = curwp -> w_bufp -> b_linep -> l_bp -> l_file_offset;
  98.     bsize += curwp -> w_bufp -> b_linep -> l_bp -> l_used;
  99.     fsize = curbp -> b_file_size;
  100.  
  101.     if (curwp -> w_markp != NULL)
  102.     {
  103.         /* build format string */
  104.         sprintf (buf1, MSG_sh_pos, R_POS_FMT(curwp), R_POS_FMT(curwp),
  105.             R_POS_FMT(curwp), R_POS_FMT(curwp));
  106.         sprintf (buf, buf1, dotoff, markoff, bsize, fsize);
  107.     }
  108.     else
  109.     {
  110.         /* build format string */
  111.         sprintf (buf1, MSG_sh_pos1, R_POS_FMT(curwp), R_POS_FMT(curwp),
  112.             R_POS_FMT(curwp));
  113.         sprintf (buf, buf1, dotoff, bsize, fsize);
  114.     }
  115.  
  116.     sprintf (&buf[strlen(buf)], MSG_f_str, curbp -> b_fname);
  117.     writ_echo (buf);
  118.  
  119.     return (TRUE);
  120. }
  121.  
  122.  
  123. /*
  124. * Twiddle the two characters on either side of
  125. * dot. If dot is at the end of the line twiddle the
  126. * two characters before it. Return with an error if dot
  127. * is at the beginning of line; it seems to be a bit
  128. * pointless to make this work. This fixes up a very
  129. * common typo with a single stroke. Normally bound
  130. * to "C-T". This always works within a line, so
  131. * "WFEDIT" is good enough.
  132. */
  133. bool twiddle ()
  134. {
  135.  
  136.     register    LINE * dotp;
  137.     register short  doto;
  138.     char    b_per_u,
  139.     f_buf[4],
  140.     s_buf[4],
  141.     i;
  142.  
  143.     dotp = curwp -> w_dotp;
  144.     doto = curwp -> w_doto;
  145.     b_per_u = curwp -> w_fmt_ptr -> r_b_per_u;
  146.     /* try to move back one unit */
  147.     if (!move_ptr (curwp, (long) - b_per_u, TRUE, TRUE, TRUE))
  148.     {
  149.         curwp -> w_dotp = dotp; /* if fail then restore dot and quit */
  150.         curwp -> w_doto = doto;
  151.         ttbeep ();
  152.         return (FALSE);
  153.     }
  154.     /* pick up first unit byte by byte */
  155.     for (i = 0; i < b_per_u; i++)
  156.     {
  157.         f_buf[i] = DOT_CHAR(curwp);
  158.         move_ptr (curwp, 1L, TRUE, FALSE, TRUE);
  159.     }
  160.     /* move to the end of the second unit */
  161.     if (!move_ptr (curwp, (long) (b_per_u - 1), TRUE, FALSE, TRUE))
  162.     {
  163.         curwp -> w_dotp = dotp; /* if fail then restore dot and quit */
  164.         curwp -> w_doto = doto;
  165.         ttbeep ();
  166.         return (FALSE);
  167.     }
  168.     /* pick up second unit (reverse order) and deposit second unit */
  169.     for (i = 0; i < b_per_u; i++)
  170.     {
  171.         s_buf[i] = DOT_CHAR(curwp);
  172.         DOT_CHAR(curwp) = f_buf[b_per_u - 1 - i];
  173.         move_ptr (curwp, -1L, TRUE, FALSE, TRUE);
  174.     }
  175.     /* deposit first unit */
  176.     for (i = 0; i < b_per_u; i++)
  177.     {
  178.         DOT_CHAR(curwp) = s_buf[i];
  179.         move_ptr (curwp, -1L, TRUE, FALSE, TRUE);
  180.     }
  181.     curwp -> w_dotp = dotp;
  182.     curwp -> w_doto = doto;
  183.     lchange (WFHARD);
  184.     return (TRUE);
  185. }
  186.  
  187. /*
  188. * Quote the next character, and
  189. * insert it into the buffer. All the characters
  190. * are taken literally.
  191. * The character
  192. * is always read, even if it is inserted 0 times, for
  193. * regularity.
  194. */
  195. bool quote (f, n, k)
  196. int f, n, k;
  197. {
  198.     register int    c;
  199.  
  200.     if (kbdmop != NULL)
  201.         c = *kbdmop++;
  202.     else
  203.     {
  204.         c = ttgetc ();
  205.         if (kbdmip != NULL)
  206.         {
  207.             if (kbdmip > &kbdm[NKBDM - 4])
  208.             {
  209.                 ctrlg (FALSE, 0, KRANDOM);
  210.                 return (ABORT);
  211.             }
  212.  
  213.             *kbdmip++ = c;
  214.         }
  215.  
  216.     }
  217.  
  218.     if (n < 0)
  219.         return (FALSE);
  220.     if (n == 0)
  221.         return (TRUE);
  222.  
  223.     return (linsert (n, (uchar) c));
  224. }
  225.  
  226. /*
  227. * Toggle the insert mode.  Insert mode is used only in ASCII or EBCDIC modes.
  228. */
  229. bool insert_toggle ()    /* toggle routine for selfinsert */
  230. {
  231.     register    WINDOW * wp;
  232.  
  233.     if (curbp -> b_flag & BFSLOCK)
  234.         return (TRUE);
  235.  
  236.     if (read_pat_mode)
  237.         dont_repeat = TRUE;
  238.  
  239.     insert_mode = !insert_mode;
  240.     for (wp = wheadp; wp; wp = wp -> w_wndp)
  241.         wp -> w_flag |= WFMODE; /* force mode line update */
  242.     return (TRUE);
  243. }
  244.  
  245. /*
  246. * Ordinary text characters are bound to this function,
  247. * which inserts them into the buffer. Characters marked as control
  248. * characters (using the CTRL flag) may be remapped to their ASCII
  249. * equivalent. This makes TAB (C-I) work right, and also makes the
  250. * world look reasonable if a control character is bound to this
  251. * this routine by hand. Any META or CTLX flags on the character
  252. * are discarded.
  253. *
  254. *   Edit the unit under the cursor.
  255. *   Check that the character is valid for the current display mode.
  256. */
  257.  
  258. bool selfinsert (f, n, k)
  259. int f, n, k;
  260. {
  261.  
  262.     register int    c;
  263.     char    edt_buf[4],
  264.     i_chr,
  265.     b_per_u,
  266.     u_offs,
  267.     u_roffs,
  268.     bit_shf,
  269.     i;
  270.     LINE    * l_ptr;
  271.     short   d_offs;
  272.     int     bytes,
  273.     temp_int;
  274.     long    dot_shf,
  275.     l_mask,
  276.     l_val;
  277.     char    text_buf[12];
  278.     static char max_dec_8[] = "255";
  279.     static char max_dec_16[] = "65535";
  280.     static char max_dec_32[] = "4294967295";
  281.     int        cur_col;
  282.  
  283.     bool intel;
  284.  
  285.     if (n < 0)
  286.     {
  287.         ttbeep ();
  288.         return (FALSE);
  289.     }
  290.     if (n == 0)
  291.     {
  292.         ttbeep ();
  293.         return (TRUE);
  294.     }
  295.     c = k & KCHAR;
  296.     if ((k & KCTRL) != 0 && c >= '@' && c <= '_')/* ASCII-ify.           */
  297.         c -= '@';
  298.     b_per_u = curwp -> w_fmt_ptr -> r_b_per_u;
  299.     u_offs = curwp -> w_unit_offset;
  300.     u_roffs = curwp -> w_fmt_ptr -> r_chr_per_u - u_offs - 1;
  301.     intel = curwp -> w_intel_mode;
  302.  
  303.     cur_col = ttcol;
  304.  
  305.     switch (curwp -> w_fmt_ptr -> r_type)
  306.     {
  307.     case EBCDIC:
  308.         c = to_ebcdic ((char) c);  /* convert ASCII to EBCDIC */
  309.     case ASCII:
  310.         if ((insert_mode) || (DOT_POS(curwp) == BUF_SIZE(curwp)))
  311.         {
  312.             linsert (n, (uchar) c);
  313.             if (read_pat_mode)
  314.                 forwchar (0, 1, KRANDOM);/* advance the cursor */
  315.         }
  316.         else
  317.             lreplace (n, (char) c);
  318.         break;
  319.  
  320.     case HEX:
  321.         if ((c >= '0') && (c <= '9'))
  322.         {
  323.             i_chr = c - '0';/* convert to binary */
  324.         }
  325.         else
  326.             if ((c >= 'A') && (c <= 'F'))
  327.             {
  328.                 i_chr = c - 'A' + 10;/* convert to binary */
  329.             }
  330.             else
  331.                 if ((c >= 'a') && (c <= 'f'))
  332.                 {
  333.                     i_chr = c - 'a' + 10;/* convert to binary */
  334.                 }
  335.                 else
  336.                 {
  337.                     bad_key (k);
  338.                     return (FALSE);
  339.                 }
  340.         fill_out (); /* expand buffer if necessary */
  341.  
  342.         /* position dot to byte to be altered */
  343.         if (intel)
  344.             dot_shf = u_roffs >> 1;
  345.         else
  346.             dot_shf = u_offs >> 1;
  347.  
  348.         /* save dot position for later */
  349.         l_ptr = curwp -> w_dotp;
  350.         d_offs = curwp -> w_doto;
  351.         move_ptr (curwp, dot_shf, TRUE, FALSE, TRUE);
  352.  
  353.         if (u_offs & 1)
  354.         {               /* lower nibble in byte */
  355.             i_chr &= 0x0f;
  356.             DOT_CHAR(curwp) &= 0xf0;
  357.             DOT_CHAR(curwp) |= i_chr;
  358.         }
  359.         else
  360.         {               /* upper nibble in byte */
  361.             i_chr <<= 4;
  362.             i_chr &= 0xf0;
  363.             DOT_CHAR(curwp) &= 0x0f;
  364.             DOT_CHAR(curwp) |= i_chr;
  365.         }
  366.  
  367.         /* restore dot position */
  368.         curwp -> w_dotp = l_ptr;
  369.         curwp -> w_doto = d_offs;
  370.         forwchar (0, 1, KRANDOM);/* advance the cursor */
  371.         break;
  372.  
  373.     case BINARY:
  374.         if ((c != '0') && (c != '1'))
  375.         {
  376.             bad_key (k);
  377.             return (FALSE);
  378.         }
  379.  
  380.         /* position dot to byte to be altered */
  381.         if (intel)
  382.             dot_shf = u_roffs >> 3;
  383.         else
  384.             dot_shf = u_offs >> 3;
  385.  
  386.         fill_out (); /* expand buffer if necessary */
  387.  
  388.         /* save dot position for later */
  389.         l_ptr = curwp -> w_dotp;
  390.         d_offs = curwp -> w_doto;
  391.         move_ptr (curwp, dot_shf, TRUE, FALSE, TRUE);
  392.  
  393.         bit_shf = u_roffs & 0x07;
  394.  
  395.         if (c == '0')
  396.         {
  397.             DOT_CHAR(curwp) &= ~(1 << bit_shf);
  398.         }
  399.         else
  400.         {
  401.             DOT_CHAR(curwp) |= 1 << bit_shf;
  402.         }
  403.  
  404.         /* restore dot position */
  405.         curwp -> w_dotp = l_ptr;
  406.         curwp -> w_doto = d_offs;
  407.         forwchar (0, 1, KRANDOM);/* advance the cursor */
  408.         break;
  409.  
  410.     case OCTAL:
  411.         if (c < '0')
  412.         {
  413.             bad_key (k);
  414.             return (FALSE);
  415.         }
  416.         else
  417.             if ((c > '1') && (u_offs == 0) &&
  418.                 ((curwp -> w_fmt_ptr -> r_size) == WORDS))
  419.             {
  420.                 bad_key (k);
  421.                 return (FALSE);
  422.             }
  423.             else
  424.                 if ((c > '3') && (u_offs == 0))
  425.                 {
  426.                     bad_key (k);
  427.                     return (FALSE);
  428.                 }
  429.                 else
  430.                     if (c > '7')
  431.                     {
  432.                         bad_key (k);
  433.                         return (FALSE);
  434.                     }
  435.  
  436.         dot_shf = (c - '0') & 7;/* get binary value */
  437.         l_mask = 7;         /* create bit mask */
  438.  
  439.         dot_shf <<= (u_roffs * 3);
  440.         l_mask <<= (u_roffs * 3);
  441.  
  442.         fill_out (); /* expand buffer if necessary */
  443.  
  444.         /* save dot position for later */
  445.         l_ptr = curwp -> w_dotp;
  446.         d_offs = curwp -> w_doto;
  447.  
  448.         /* position dot to the byte to be altered */
  449.         if (intel)
  450.         {
  451.             for (i = 0; i < b_per_u; i++)
  452.             {
  453.                 DOT_CHAR(curwp) &= ~((D8) l_mask & 0xff);
  454.                 DOT_CHAR(curwp) |= (D8) dot_shf & 0xff;
  455.                 l_mask >>= 8;
  456.                 dot_shf >>= 8;
  457.                 move_ptr (curwp, 1L, TRUE, FALSE, TRUE);
  458.             }
  459.         }
  460.         else
  461.         {
  462.             move_ptr (curwp, (long) (b_per_u - 1), TRUE, FALSE, TRUE);
  463.             /* move to last byte */
  464.             for (i = 0; i < b_per_u; i++)
  465.             {
  466.                 DOT_CHAR(curwp) &= ~((D8) l_mask & 0xff);
  467.                 DOT_CHAR(curwp) |= (D8) dot_shf & 0xff;
  468.                 l_mask >>= 8;
  469.                 dot_shf >>= 8;
  470.                 move_ptr (curwp, -1L, TRUE, FALSE, TRUE);/* step back one byte */
  471.             }
  472.         }
  473.  
  474.         /* restore dot position */
  475.         curwp -> w_dotp = l_ptr;
  476.         curwp -> w_doto = d_offs;
  477.         forwchar (0, 1, KRANDOM);/* advance the cursor */
  478.         break;
  479.  
  480.     case DECIMAL:
  481.         fill_out (); /* expand buffer if necessary */
  482.  
  483.         /* save dot position for later */
  484.         l_ptr = curwp -> w_dotp;
  485.         d_offs = curwp -> w_doto;
  486.  
  487.         bytes = fill_buf (curwp, l_ptr, d_offs, edt_buf, b_per_u);
  488.         /* if last unit is not full and must be extended */
  489.         for (; bytes < b_per_u; bytes++)
  490.         {
  491.             edt_buf[3] = edt_buf[2];/* shuffle bytes down */
  492.             edt_buf[2] = edt_buf[1];
  493.             edt_buf[1] = edt_buf[0];
  494.             edt_buf[0] = 0;
  495.         }
  496.         switch (curwp -> w_fmt_ptr -> r_size)
  497.         {
  498.         case BYTES:
  499.             sprintf (text_buf, MSG_03u, (int) (edt_buf[0] & 0xff));
  500.             if (!dec_chr_ok (text_buf, max_dec_8, (char) c, u_offs))
  501.             {
  502.                 bad_key (k);
  503.                 return (TRUE);  /* TRUE so that mask will be same len */
  504.             }
  505.             sscanf (text_buf, MSG_3u, &i);/* convert back to binary */
  506.             l_val = (long) i & 0xff;
  507.             break;
  508.  
  509.         case WORDS:
  510.             l_val = get_int (edt_buf);/* do intel swap */
  511.             sprintf (text_buf, MSG_05u, (int) (l_val & 0xFFFF));
  512.             if (!dec_chr_ok (text_buf, max_dec_16, (char) c, u_offs))
  513.             {
  514.                 bad_key (k);
  515.                 return (TRUE);  /* TRUE so that mask will be same len */
  516.             }
  517.             sscanf (text_buf, MSG_5u, &temp_int);
  518.             /* convert back to binary */
  519.             l_val = get_int ((char *) & temp_int);/* do intel swap */
  520.             break;
  521.  
  522.         case DWORDS:
  523.             l_val = get_long (edt_buf);/* do intel swap */
  524.             sprintf (text_buf, MSG_010lu, l_val);
  525.             if (!dec_chr_ok (text_buf, max_dec_32, (char) c, u_offs))
  526.             {
  527.                 bad_key (k);
  528.                 return (TRUE);  /* TRUE so that mask will be same len */
  529.             }
  530.             sscanf (text_buf, MSG_lu, &l_val);
  531.             /* convert back to binary */
  532.             l_val = get_long ((char *) & l_val);/* do intel swap */
  533.             break;
  534. #if RUNCHK
  535.         default:
  536.             writ_echo (ERR_rnd_2);
  537.             break;
  538. #endif
  539.         }
  540.         DOT_CHAR(curwp) = (char) l_val & 0xff;
  541.         for (i = 1; i < b_per_u; i++)
  542.         {
  543.             l_val >>= 8;
  544.             move_ptr (curwp, 1L, TRUE, FALSE, TRUE);/* step forward one byte */
  545.             DOT_CHAR(curwp) = (char) l_val & 0xff;
  546.         }
  547.  
  548.         /* restore dot position */
  549.         curwp -> w_dotp = l_ptr;
  550.         curwp -> w_doto = d_offs;
  551.         forwchar (0, 1, KRANDOM);/* advance the cursor */
  552.         break;
  553.  
  554. #if RUNCHK
  555.     default:
  556.         writ_echo (ERR_rnd_3);
  557.         break;
  558. #endif
  559.     }
  560.     /* if cursor has wrapped to the next line then previous line
  561.         will not be refreshed with WFEDIT so do a WFHARD */
  562.     if (cur_col > get_curcol(curwp))
  563.         lchange (WFHARD);
  564.     else
  565.         lchange (WFEDIT);
  566.  
  567.     return (TRUE);
  568. }
  569.  
  570. /*
  571. *   Insert one unit of zeros at the current dot position.
  572. */
  573. bool    insertunit (f, n, k)
  574. int f, n, k;
  575. {
  576.     lchange (WFEDIT);
  577.     linsert ((R_B_PER_U(curwp) * n), 0);
  578.     return (TRUE);
  579. }
  580.  
  581. /*
  582. *   Increase the size of the buffer if necessary.
  583. *   If dot is at the byte after the last full unit
  584. *   then add enough bytes to the buffer to create
  585. *   a full unit at the end.
  586. */
  587.  
  588. bool    fill_out ()
  589. {
  590.     long    buf_size, dot_pos, last_unit;
  591.     int     b_per_u;
  592.     char    stat, shift;
  593.     int     insert_val;
  594.  
  595.     buf_size = BUF_SIZE(curwp);
  596.     dot_pos = DOT_POS(curwp);
  597.     b_per_u = R_B_PER_U(curwp);
  598.     shift = curwp -> w_disp_shift;
  599.     stat = TRUE;
  600.     insert_val = 0;
  601.     last_unit = buf_size & ~((long)(b_per_u - 1));
  602.     /* there is an even number of units step back one */
  603.     if (last_unit == buf_size)
  604.         last_unit -= b_per_u;
  605.     last_unit += shift;
  606.  
  607.     /* if dot is one byte past the end of the buffer */
  608.     if (dot_pos > last_unit)
  609.     {
  610.         insert_val = b_per_u;
  611.     }
  612.  
  613.     /* if dot is pointed at the end of the buffer */
  614.     else if (dot_pos == last_unit)
  615.     {
  616.         insert_val = b_per_u - (buf_size - last_unit);
  617.     }
  618.  
  619.     /* if insert is necessary then do it */
  620.     if (insert_val != 0)
  621.     {
  622.         lchange (WFHARD);
  623.         move_ptr (curwp, buf_size, TRUE, FALSE, FALSE); /* move dot to end */
  624.         stat = linsert (insert_val, 0);
  625.         move_ptr (curwp, dot_pos, TRUE, TRUE, FALSE); /* put dot back */
  626.     }
  627.     return (stat);
  628. }
  629.  
  630. /*
  631. *   This checks that an entered character is ok
  632. *   for the position given.
  633. */
  634.  
  635. char    dec_chr_ok (char_buf, max_str, chr, pos)
  636. char    chr, pos;
  637. char    *char_buf, *max_str;
  638. {
  639.     char    i;
  640.  
  641.     if ((chr < '0') || (chr > '9'))
  642.         return (FALSE);
  643.  
  644.     char_buf[pos] = chr;        /* insert typed char */
  645.  
  646.     /* check if number is too big */
  647.     for (i = 0; max_str[i] != 0; i++)
  648.     {
  649.         if (char_buf[i] < max_str[i])
  650.             break;              /* if char is smaller then must be ok */
  651.  
  652.         if (char_buf[i] > max_str[i])
  653.             return (FALSE);     /* val is too large; ERROR */
  654.     }
  655.     return (TRUE);
  656. }
  657.  
  658. /*
  659. * Set the rest of the variables for the mode change.
  660. */
  661. void    set_mode_vars ()
  662. {
  663.     curwp -> w_disp_shift = 0;  /* shift to 0 when changing mode */
  664.     curwp -> w_unit_offset = 0; /* go to end of unit */
  665.     /* if we are in the middle of a search then use the proper format struc */
  666.     if (read_pat_mode)
  667.         curwp -> w_fmt_ptr = curwp -> w_fmt_ptr -> r_srch_fmt;
  668.  
  669.     wind_on_dot (curwp);
  670.     curwp -> w_flag = WFHARD;
  671.     update ();
  672. }
  673.  
  674. /*
  675. * Change the display mode to ASCII.
  676. * The default binding is META C-A.
  677. */
  678. bool    asciimode ()
  679. {
  680.     curwp -> w_fmt_ptr = &ascii_fmt;
  681.     set_mode_vars ();
  682.     return (TRUE);
  683. }
  684.  
  685. /*
  686. * Change the display mode to EBCDIC.
  687. * The default binding is META C-E.
  688. */
  689. bool    ebcdicmode ()
  690. {
  691.     curwp -> w_fmt_ptr = &ebcdic_fmt;
  692.     set_mode_vars ();
  693.     return (TRUE);
  694. }
  695.  
  696. /*
  697. * Change the display mode to DECIMAL.
  698. * The default binding is META C-D.
  699. */
  700. bool    decimalmode ()
  701. {
  702.     switch (curwp -> w_fmt_ptr -> r_size)
  703.     {
  704.     case BYTES:
  705.         curwp -> w_fmt_ptr = &decimal_8_fmt;
  706.         break;
  707.     case WORDS:
  708.         curwp -> w_fmt_ptr = &decimal_16_fmt;
  709.         break;
  710.  
  711.     case DWORDS:
  712.         curwp -> w_fmt_ptr = &decimal_32_fmt;
  713.         break;
  714. #if RUNCHK
  715.     default:
  716.         writ_echo (ERR_rnd_4);
  717.         break;
  718. #endif
  719.     }
  720.     set_mode_vars ();
  721.     return (TRUE);
  722. }
  723.  
  724. /*
  725. * Change the display mode to HEXADECIMAL.
  726. * The default binding is META C-H.
  727. */
  728. bool    hexmode ()
  729. {
  730.     switch (curwp -> w_fmt_ptr -> r_size)
  731.     {
  732.     case BYTES:
  733.         curwp -> w_fmt_ptr = &hex_8_fmt;
  734.         break;
  735.     case WORDS:
  736.         curwp -> w_fmt_ptr = &hex_16_fmt;
  737.         break;
  738.     case DWORDS:
  739.         curwp -> w_fmt_ptr = &hex_32_fmt;
  740.         break;
  741. #if RUNCHK
  742.     default:
  743.         writ_echo (ERR_rnd_5);
  744.         break;
  745. #endif
  746.     }
  747.     set_mode_vars ();
  748.     return (TRUE);
  749. }
  750.  
  751. /*
  752. * Change the display mode to OCTAL.
  753. * The default binding is META C-O.
  754. */
  755. bool    octalmode ()
  756. {
  757.     switch (curwp -> w_fmt_ptr -> r_size)
  758.     {
  759.     case BYTES:
  760.         curwp -> w_fmt_ptr = &octal_8_fmt;
  761.         break;
  762.  
  763.     case WORDS:
  764.         curwp -> w_fmt_ptr = &octal_16_fmt;
  765.         break;
  766.  
  767.     case DWORDS:
  768.         curwp -> w_fmt_ptr = &octal_32_fmt;
  769.         break;
  770. #if RUNCHK
  771.     default:
  772.         writ_echo (ERR_rnd_6);
  773.         break;
  774. #endif
  775.     }
  776.     set_mode_vars ();
  777.     return (TRUE);
  778. }
  779.  
  780. /*
  781. * Change the display mode to BINARY.
  782. * The default binding is META C-B.
  783. */
  784. bool    binarymode ()
  785. {
  786.     switch (curwp -> w_fmt_ptr -> r_size)
  787.     {
  788.     case BYTES:
  789.         curwp -> w_fmt_ptr = &binary_8_fmt;
  790.         break;
  791.     case WORDS:
  792.         curwp -> w_fmt_ptr = &binary_16_fmt;
  793.         break;
  794.     case DWORDS:
  795.         curwp -> w_fmt_ptr = &binary_32_fmt;
  796.         break;
  797. #if RUNCHK
  798.     default:
  799.         writ_echo (ERR_rnd_7);
  800.         break;
  801. #endif
  802.     }
  803.     set_mode_vars ();
  804.     return (TRUE);
  805. }
  806.  
  807. /*
  808. * Change the display shift.
  809. * Circularly rotate through display shift of 0 through 3.
  810. * This value is used to shift the display by the designated number of bytes.
  811. * This is used to cause WORD and DWORD values to be calculated
  812. * from the correct offset.
  813. */
  814. bool dispshift (f, n, k)
  815. int f, n, k;
  816. {
  817.     char    mode,
  818.     size;
  819.  
  820.     if (read_pat_mode)
  821.         return (TRUE);  /* no shift is allowed in search mode */
  822.  
  823.  
  824.     mode = curwp -> w_fmt_ptr -> r_type;
  825.     size = curwp -> w_fmt_ptr -> r_size;
  826.  
  827.     if (((mode == HEX) ||
  828.         (mode == DECIMAL) ||
  829.         (mode == BINARY) ||
  830.         (mode == OCTAL)) &&
  831.         (size != BYTES))
  832.     {
  833.         if ((size == WORDS) &&
  834.             (curwp -> w_disp_shift >= 1))
  835.         {                   /* roll over on words */
  836.             curwp -> w_disp_shift = 0;
  837.         }
  838.         else
  839.             if ((size == DWORDS) &&
  840.                 (curwp -> w_disp_shift >= 3))
  841.             {               /* roll over on double words */
  842.                 curwp -> w_disp_shift = 0;
  843.             }
  844.             else
  845.             {
  846.                 curwp -> w_disp_shift++;/* increment shift */
  847.             }
  848.     }
  849.     else
  850.     {
  851.         curwp -> w_disp_shift = 0;/* set to no shift */
  852.     }
  853.     move_ptr (curwp, 0L, TRUE, TRUE, TRUE);
  854.     wind_on_dot (curwp);
  855.     curwp -> w_flag = WFHARD;   /* force full window refresh */
  856.     return (TRUE);
  857. }
  858.  
  859. /*
  860. * Delete forward. This is real
  861. * easy, because the basic delete routine does
  862. * all of the work. Watches for negative arguments,
  863. * and does the right thing. If any argument is
  864. * present, it kills rather than deletes, to prevent
  865. * loss of text if typed with a big argument.
  866. * Normally bound to "C-D".
  867. */
  868. char    forwdel (f, n, k)
  869. int f, n, k;
  870. {
  871.     char    s;
  872.  
  873.     if (n < 0)
  874.         return (backdel (f, -n, KRANDOM));
  875.  
  876.     s = FALSE;
  877.     if (R_SIZE(curwp) == BYTES)
  878.     {
  879.         if (f != FALSE)
  880.         {
  881.             /* Really a kill.       */
  882.             if ((lastflag & CFKILL) == 0)
  883.                 bclear (&sav_buf);
  884.             thisflag |= CFKILL;
  885.         }
  886.         s = ldelete ((A32)n, f);
  887.         curwp -> w_unit_offset = 0;
  888.     }
  889.     return (s);
  890. }
  891.  
  892.  
  893. /*
  894. * Delete backwards. This is quite easy too,
  895. * because it's all done with other functions. Just
  896. * move the cursor back, and delete forwards.
  897. * Like delete forward, this actually does a kill
  898. * if presented with an argument.
  899. */
  900. char    backdel (f, n, k)
  901. int f, n, k;
  902. {
  903.  
  904.     int     u_off;
  905.     char    s;
  906.  
  907.     if (n < 0)
  908.         return (forwdel (f, -n, KRANDOM));
  909.  
  910.     s = FALSE;
  911.     if (R_SIZE(curwp) == BYTES)
  912.     {
  913.         u_off = curwp -> w_unit_offset;
  914.         curwp -> w_unit_offset = 0;
  915.         if ((s = backchar (f, n * R_CHR_PER_U(curwp), KRANDOM)) == TRUE)
  916.         {
  917.             s = ldelete ((A32)n, f);
  918.             if (f != FALSE)
  919.             {
  920.                 /* Really a kill.       */
  921.                 if ((lastflag & CFKILL) == 0)
  922.                     bclear (&sav_buf);
  923.                 thisflag |= CFKILL;
  924.             }
  925.         }
  926.         curwp -> w_unit_offset = u_off;
  927.     }
  928.     return (s);
  929. }
  930.  
  931.  
  932. /*
  933. * Change the size of the display unit to BYTE.
  934. * Adjust byte shift to the allowable range.
  935. * Normally bound to "META-1".
  936. */
  937. bool dispsize1 ()
  938. {
  939.     curwp -> w_disp_shift = 0;  /* shift to 0 when changing size */
  940.     curwp -> w_unit_offset = 0; /* go to end of unit */
  941.  
  942.     switch (R_TYPE(curwp))
  943.     {
  944.     case OCTAL:
  945.         curwp -> w_fmt_ptr = &octal_8_fmt;
  946.         break;
  947.  
  948.     case DECIMAL:
  949.         curwp -> w_fmt_ptr = &decimal_8_fmt;
  950.         break;
  951.  
  952.     case HEX:
  953.         curwp -> w_fmt_ptr = &hex_8_fmt;
  954.         break;
  955.  
  956.     case BINARY:
  957.         curwp -> w_fmt_ptr = &binary_8_fmt;
  958.         break;
  959.  
  960.     default:
  961.         return (TRUE);
  962.         break;
  963.     }
  964.  
  965.     /* if we are in the middle of a search then use the proper format struc */
  966.     if (read_pat_mode)
  967.         curwp -> w_fmt_ptr = curwp -> w_fmt_ptr -> r_srch_fmt;
  968.  
  969.     move_ptr (curwp, 0L, TRUE, TRUE, TRUE);
  970.     wind_on_dot (curwp);
  971.     curwp -> w_flag = WFHARD;
  972.     update ();
  973.     return (TRUE);
  974. }
  975.  
  976. /*
  977. * Change the size of the display unit to WORD.
  978. * Adjust byte shift to the allowable range.
  979. * Normally bound to "META-2".
  980. */
  981. bool dispsize2 ()
  982. {
  983.     curwp -> w_disp_shift = 0;  /* shift to 0 when changing size */
  984.     curwp -> w_unit_offset = 0; /* go to end of unit */
  985.  
  986.     switch (R_TYPE(curwp))
  987.     {
  988.     case OCTAL:
  989.         curwp -> w_fmt_ptr = &octal_16_fmt;
  990.         break;
  991.  
  992.     case DECIMAL:
  993.         curwp -> w_fmt_ptr = &decimal_16_fmt;
  994.         break;
  995.  
  996.     case HEX:
  997.         curwp -> w_fmt_ptr = &hex_16_fmt;
  998.         break;
  999.  
  1000.     case BINARY:
  1001.         curwp -> w_fmt_ptr = &binary_16_fmt;
  1002.         break;
  1003.  
  1004.     default:
  1005.         return (TRUE);
  1006.         break;
  1007.     }
  1008.  
  1009.     /* if we are in the middle of a search then use the proper format struc */
  1010.     if (read_pat_mode)
  1011.         curwp -> w_fmt_ptr = curwp -> w_fmt_ptr -> r_srch_fmt;
  1012.  
  1013.     move_ptr (curwp, 0L, TRUE, TRUE, TRUE);
  1014.     wind_on_dot (curwp);
  1015.     curwp -> w_flag = WFHARD;
  1016.     update ();
  1017.     return (TRUE);
  1018. }
  1019.  
  1020. /*
  1021. * Change the size of the display unit to DOUBLE WORD.
  1022. * Adjust byte shift to the allowable range.
  1023. * Normally bound to "META-4".
  1024. */
  1025. bool dispsize4 ()
  1026. {
  1027.     curwp -> w_disp_shift = 0;  /* shift to 0 when changing size */
  1028.     curwp -> w_unit_offset = 0; /* go to end of unit */
  1029.  
  1030.     switch (R_TYPE(curwp))
  1031.     {
  1032.     case OCTAL:
  1033.         curwp -> w_fmt_ptr = &octal_32_fmt;
  1034.         break;
  1035.  
  1036.     case DECIMAL:
  1037.         curwp -> w_fmt_ptr = &decimal_32_fmt;
  1038.         break;
  1039.  
  1040.     case HEX:
  1041.         curwp -> w_fmt_ptr = &hex_32_fmt;
  1042.         break;
  1043.  
  1044.     case BINARY:
  1045.         curwp -> w_fmt_ptr = &binary_32_fmt;
  1046.         break;
  1047.  
  1048.     default:
  1049.         return (TRUE);
  1050.         break;
  1051.     }
  1052.  
  1053.     /* if we are in the middle of a search then use the proper format struc */
  1054.     if (read_pat_mode)
  1055.         curwp -> w_fmt_ptr = curwp -> w_fmt_ptr -> r_srch_fmt;
  1056.  
  1057.     move_ptr (curwp, 0L, TRUE, TRUE, TRUE);
  1058.     wind_on_dot (curwp);
  1059.     curwp -> w_flag = WFHARD;
  1060.     update ();
  1061.     return (TRUE);
  1062. }
  1063.  
  1064. /*
  1065. * Display byte swaped.   This command causes the bytes
  1066. * that are displayed in WORD and DWORD mode to be swaped
  1067. * in the way that the INTEL microprocessors do it.
  1068. */
  1069. bool dispswapbyte (f, n, k)
  1070. int f, n, k;
  1071. {
  1072.     if ((curwp -> w_fmt_ptr -> r_size) == BYTES)
  1073.         return (TRUE);
  1074.  
  1075.     if (curwp -> w_intel_mode)
  1076.         curwp -> w_intel_mode = FALSE;
  1077.     else
  1078.         curwp -> w_intel_mode = TRUE;
  1079.  
  1080.     curwp -> w_flag = WFHARD;
  1081.     update ();
  1082.     return (TRUE);
  1083. }
  1084.  
  1085. /*
  1086. * Yank text back from the kill buffer. This
  1087. * is really easy. All of the work is done by the
  1088. * standard insert routines. All you do is run the loop,
  1089. * and check for errors.
  1090. * An attempt has been made to fix the cosmetic bug
  1091. * associated with a yank when dot is on the top line of
  1092. * the window (nothing moves, because all of the new
  1093. * text landed off screen).
  1094. */
  1095. bool yank (f, n, k)
  1096. int f, n, k;
  1097. {
  1098.     register D16    c;
  1099.     register A32    i;
  1100.     char        buf[NCOL], buf1[NCOL];
  1101.  
  1102.     if (n < 0)
  1103.         return (FALSE);
  1104.     while (n--)
  1105.     {
  1106.         i = 0;
  1107.         save_buf_home ();
  1108.         while ((c = get_save_char ()) != (D16)-1)
  1109.         {
  1110.             if (linsert (1, (uchar) c) == FALSE)
  1111.                 return (FALSE);
  1112.             if ((i & 0x2ff) == 0)
  1113.             {
  1114.                 sprintf (buf1, MSG_procing, R_POS_FMT(curwp));
  1115.                 sprintf (buf, buf1, (ulong)i);
  1116.                 writ_echo (buf);
  1117.                 /* check if we should quit */
  1118.                 if (ttkeyready ())
  1119.                 {
  1120.                     wind_on_dot_all();
  1121.                     if (ttgetc () == CTL_G)
  1122.                         return (FALSE);
  1123.                 }
  1124.             }
  1125.             ++i;
  1126.         }
  1127.     }
  1128.     /* update buffer display */
  1129.     if ((blistp -> b_nwnd != 0) &&
  1130.         (blistp -> b_type == BTLIST))
  1131.         listbuffers ();
  1132.  
  1133.     curwp -> w_flag |= WFHARD;
  1134.     return (TRUE);
  1135. }
  1136.  
  1137. /*
  1138. *   Link windows.   pvr
  1139. *   This function toggles the window linking function.
  1140. *   When linking is enabled all windows that look at
  1141. *   the same buffer will be forced to have the same
  1142. *   dot position.   Each window is then moved to be
  1143. *   positioned on the dot.   Thus when a user moves
  1144. *   arround a buffer all other views into that buffer
  1145. *   will follow.
  1146. */
  1147.  
  1148. bool linkwind ()
  1149.  
  1150. {
  1151.     char    buf[NCOL];
  1152.  
  1153.     if (curwp -> w_bufp -> b_flag & BFLINK)
  1154.     {
  1155.         curwp -> w_bufp -> b_flag &= ~(BFLINK & 0xff);
  1156.         sprintf (buf, MSG_lnk, curwp -> w_bufp -> b_bname, MSG_unlink);
  1157.     }
  1158.     else
  1159.     {
  1160.         curwp -> w_bufp -> b_flag |= BFLINK;
  1161.         sprintf (buf, MSG_lnk, curwp -> w_bufp -> b_bname, MSG_link);
  1162.     }
  1163.     writ_echo (buf);
  1164.     return (TRUE);
  1165. }
  1166. /*
  1167. *   Print all bad keys to the screen and beep
  1168. */
  1169. void    bad_key (key)
  1170. int     key;
  1171. {
  1172.     char    buf[NCOL];
  1173.  
  1174.     ttbeep ();
  1175.     sprintf (buf, MSG_bad_key);
  1176.     keyname (&buf[strlen (buf)], key);
  1177.     sprintf (&buf[strlen (buf)], ", %X", key);
  1178.     writ_echo (buf);
  1179. }
  1180.  
  1181. /*
  1182.  *    Combine sequential bytes from the rest of the windows
  1183.  *    into this window.   This is useful in combining PROM
  1184.  *    image files from odd and even bytes into one file.
  1185.  */
  1186. bool    n_way_combine (f, n, k)
  1187. int     f, n, k;
  1188. {
  1189.     WINDOW * dest_wp, *src_wp;
  1190.     BUFFER *src_bp;
  1191.     A32    dotp;
  1192.     D8    byt;
  1193.     int j = 0;
  1194.     char        buf[NCOL], buf1[NCOL];
  1195.  
  1196.     /* save the destination window for later restore */
  1197.     dest_wp = curwp;
  1198.  
  1199.     if ((BUF_SIZE (curwp)) != (A32)0)
  1200.     {
  1201.         writ_echo (MSG_w_not_empty);
  1202.         return(FALSE);
  1203.     }
  1204.     /* Current window must be empty, modifiable and not the only one. */
  1205.     if ((BUF_SIZE (curwp) != 0) ||
  1206.         (curwp -> w_wndp == NULL) ||
  1207.         (curwp -> w_bufp -> b_flag & (BFVIEW | BFSLOCK)))
  1208.     {
  1209.         writ_echo (MSG_w_not_empty);
  1210.         return(FALSE);
  1211.     }
  1212.  
  1213.  
  1214.  
  1215.  
  1216.     for (;;)
  1217.     {
  1218.         /* step to the next window after the destination window */
  1219.         nextwind();
  1220.  
  1221.         /* as I cycle around the windows skip the destination window */
  1222.         if (curwp == dest_wp)
  1223.         {
  1224.             continue;
  1225.         }
  1226.         byt = DOT_CHAR(curwp) & 0xff;
  1227.         dotp = DOT_POS(curwp);   /* get the current dot position */
  1228.         /* move the dot position ahead in current buffer */
  1229.         if (move_ptr (curwp, 1L, TRUE, FALSE, TRUE) == FALSE)
  1230.         {
  1231.             /* did we advance? */
  1232.             if (DOT_POS(curwp) == dotp)
  1233.             {
  1234.                 wind_on_dot_all();
  1235.                 writ_echo (MSG_ok);
  1236.                 return (TRUE);   /* done all that we could */
  1237.             }
  1238.         }
  1239.  
  1240.         src_wp = curwp;
  1241.         src_bp = curwp -> w_bufp;
  1242.         curwp = dest_wp;
  1243.         curbp = dest_wp -> w_bufp;
  1244.         if (linsert (1, byt) == FALSE)
  1245.         {
  1246.             wind_on_dot_all();
  1247.             return (FALSE);    /* insert failed for some reason */
  1248.         }
  1249.         curwp = src_wp;
  1250.         curbp = src_bp;
  1251.         if ((j++ & 0x2ff) == 0)
  1252.         {
  1253.             sprintf (buf1, MSG_procing, R_POS_FMT(curwp));
  1254.             sprintf (buf, buf1, dotp);
  1255.             writ_echo (buf);
  1256.             /* check if we should quit */
  1257.             if (ttkeyready ())
  1258.             {
  1259.                 wind_on_dot_all();
  1260.                 if (ttgetc () == CTL_G)
  1261.                     return (FALSE);
  1262.             }
  1263.         }
  1264.     }
  1265. }
  1266.  
  1267. /*
  1268.  *    Split the current buffer into the rest of the windows.
  1269.  *    This is useful in splitting a binary file into PROM
  1270.  *    image files.
  1271.  */
  1272. bool    n_way_split (f, n, k)
  1273. int     f, n, k;
  1274. {
  1275.     WINDOW  *src_wp;
  1276.     A32     b_size;
  1277.     D8    byt;
  1278.     int j = 0;
  1279.     char        buf[NCOL], buf1[NCOL];
  1280.  
  1281.     /* save the source window and buffer for later restore */
  1282.     src_wp = curwp;
  1283.  
  1284.     /* step to the next window after the source window */
  1285.     nextwind();
  1286.  
  1287.     /* check that all the destination windows are empty and modifiable */
  1288.     for (;;)
  1289.     {
  1290.         if ((BUF_SIZE (curwp) != 0) ||
  1291.             (curwp -> w_bufp -> b_flag & (BFVIEW | BFSLOCK)))
  1292.         {
  1293.             writ_echo (MSG_w_not_empty);
  1294.             return(FALSE);
  1295.         }
  1296.  
  1297.         /* force all windows to be refreshed */
  1298.         lchange (WFHARD);
  1299.         /* step to the next window */
  1300.         nextwind();
  1301.         /* stop after one pass around the windows */
  1302.         if (curwp == src_wp)
  1303.             break;
  1304.     }
  1305.  
  1306.     b_size = BUF_SIZE(src_wp);  /* get the buffer size */
  1307.  
  1308.     /* do the split until source is exhausted */
  1309.     for (;;)
  1310.     {
  1311.         /* step to the next window after the source window */
  1312.         nextwind();
  1313.  
  1314.         /* current window cannot be the source */
  1315.         if (curwp == src_wp)
  1316.             continue;
  1317.  
  1318.         byt = DOT_CHAR(src_wp) & 0xff;   /* get the byte to copy */
  1319.  
  1320.         /* are we at the end of the buffer */
  1321.         if (b_size == DOT_POS(src_wp))
  1322.         {
  1323.             wind_on_dot_all();
  1324.             writ_echo (MSG_ok);
  1325.             return (TRUE);
  1326.         }
  1327.         if (linsert (1, byt) == FALSE)
  1328.         {
  1329.             wind_on_dot_all();
  1330.             return (FALSE);
  1331.         }
  1332.         if ((j++ & 0x2ff) == 0)
  1333.         {
  1334.             sprintf (buf1, MSG_procing, R_POS_FMT(src_wp));
  1335.             sprintf (buf, buf1, DOT_POS(src_wp));
  1336.             writ_echo (buf);
  1337.             /* check if we should quit */
  1338.             if (ttkeyready ())
  1339.             {
  1340.                 wind_on_dot_all();
  1341.                 if (ttgetc () == CTL_G)
  1342.                     return (FALSE);
  1343.             }
  1344.         }
  1345.         if (move_ptr (src_wp, 1L, TRUE, FALSE, TRUE) == FALSE)
  1346.         {
  1347.             wind_on_dot_all();
  1348.             writ_echo (MSG_ok);
  1349.             return (TRUE);    /* hit the end of the source buffer */
  1350.         }
  1351.     }
  1352. }
  1353.  
  1354. void wind_on_dot_all ()
  1355. {
  1356.     WINDOW  *wp;
  1357.  
  1358.     wp = curwp;
  1359.     do
  1360.     {
  1361.         wind_on_dot (curwp);
  1362.         nextwind();
  1363.     }    while (wp != curwp);
  1364. }
  1365.  
  1366.