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