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