home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2880 / random.c
Encoding:
C/C++ Source or Header  |  1991-02-28  |  30.0 KB  |  1,164 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.  
  36. #if RUNCHK
  37. extern    char    ERR_rnd_1[];
  38. extern    char    ERR_rnd_2[];
  39. extern    char    ERR_rnd_3[];
  40. extern    char    ERR_rnd_4[];
  41. extern    char    MSG_rnd_5[];
  42. extern    char    ERR_rnd_6[];
  43. extern    char    ERR_rnd_7[];
  44. #endif
  45. #include    "lintfunc.dec"
  46.  
  47. extern  ROW_FMT ascii_fmt;
  48. extern  ROW_FMT ebcdic_fmt;
  49. extern  ROW_FMT binary_8_fmt;
  50. extern  ROW_FMT binary_16_fmt;
  51. extern  ROW_FMT binary_32_fmt;
  52. extern  ROW_FMT octal_8_fmt;
  53. extern  ROW_FMT octal_16_fmt;
  54. extern  ROW_FMT octal_32_fmt;
  55. extern  ROW_FMT decimal_8_fmt;
  56. extern  ROW_FMT decimal_16_fmt;
  57. extern  ROW_FMT decimal_32_fmt;
  58. extern  ROW_FMT hex_8_fmt;
  59. extern  ROW_FMT hex_16_fmt;
  60. extern  ROW_FMT hex_32_fmt;
  61.  
  62. extern  bool    read_pat_mode;
  63. extern  bool    dont_repeat;
  64.  
  65. char    dec_chr_ok ();
  66. ulong   get_long ();
  67.  
  68. /*
  69. * Display a bunch of useful information about
  70. * the current location of dot and mark.
  71. * The position of the dot and mark and the difference between them.
  72. * The total buffer size is displayed.
  73. * This is normally bound to "C-X =".
  74. */
  75. bool showcpos (f, n, k)
  76. {
  77.  
  78.     A32     dotoff,
  79.             markoff,
  80.             fsize,
  81.             bsize;
  82.     char    buf[80], buf1[80];
  83.  
  84.     dotoff = curwp -> w_dotp -> l_file_offset;
  85.     dotoff += curwp -> w_doto;
  86.  
  87.     if (curwp -> w_markp != NULL)
  88.         {
  89.         markoff = curwp -> w_markp -> l_file_offset;
  90.         markoff += curwp -> w_marko;
  91.         }
  92.  
  93.     bsize = curwp -> w_bufp -> b_linep -> l_bp -> l_file_offset;
  94.     bsize += curwp -> w_bufp -> b_linep -> l_bp -> l_used;
  95.     fsize = curbp -> b_file_size;
  96.  
  97.     if (curwp -> w_markp != NULL)
  98.         {
  99.         /* build format string */
  100.         sprintf (buf1, MSG_sh_pos, R_POS_FMT(curwp), R_POS_FMT(curwp), 
  101.                                 R_POS_FMT(curwp), R_POS_FMT(curwp)); 
  102.         sprintf (buf, buf1, dotoff, markoff, bsize, fsize);
  103.         }
  104.     else
  105.         {
  106.         /* build format string */
  107.         sprintf (buf1, MSG_sh_pos1, R_POS_FMT(curwp), R_POS_FMT(curwp), 
  108.                                 R_POS_FMT(curwp)); 
  109.         sprintf (buf, buf1, dotoff, bsize, fsize);
  110.         }
  111.  
  112.     sprintf (&buf[strlen(buf)], MSG_f_str, curbp -> b_fname);
  113.     writ_echo (buf);
  114.  
  115.     return (TRUE);
  116. }
  117.  
  118.  
  119. /*
  120. * Twiddle the two characters on either side of
  121. * dot. If dot is at the end of the line twiddle the
  122. * two characters before it. Return with an error if dot
  123. * is at the beginning of line; it seems to be a bit
  124. * pointless to make this work. This fixes up a very
  125. * common typo with a single stroke. Normally bound
  126. * to "C-T". This always works within a line, so
  127. * "WFEDIT" is good enough.
  128. */
  129. bool twiddle ()
  130. {
  131.  
  132.     register    LINE * dotp;
  133.     register short  doto;
  134.     register int    cl;
  135.     register int    cr;
  136.     char    b_per_u,
  137.             f_buf[4],
  138.             s_buf[4],
  139.             i;
  140.  
  141.     dotp = curwp -> w_dotp;
  142.     doto = curwp -> w_doto;
  143.     b_per_u = curwp -> w_fmt_ptr -> r_b_per_u;
  144.  /* try to move back one unit */
  145.     if (!move_ptr (curwp, (long) - b_per_u, TRUE, TRUE, TRUE))
  146.         {
  147.         curwp -> w_dotp = dotp; /* if fail then restore dot and quit */
  148.         curwp -> w_doto = doto;
  149.         ttbeep ();
  150.         return (FALSE);
  151.         }
  152.  /* pick up first unit byte by byte */
  153.     for (i = 0; i < b_per_u; i++)
  154.         {
  155.         f_buf[i] = DOT_CHAR(curwp);
  156.         move_ptr (curwp, 1L, TRUE, FALSE, TRUE);
  157.         }
  158.  /* move to the end of the second unit */
  159.     if (!move_ptr (curwp, (long) (b_per_u - 1), TRUE, FALSE, TRUE))
  160.         {
  161.         curwp -> w_dotp = dotp; /* if fail then restore dot and quit */
  162.         curwp -> w_doto = doto;
  163.         ttbeep ();
  164.         return (FALSE);
  165.         }
  166.  /* pick up second unit (reverse order) and deposit second unit */
  167.     for (i = 0; i < b_per_u; i++)
  168.         {
  169.         s_buf[i] = DOT_CHAR(curwp);
  170.         DOT_CHAR(curwp) = f_buf[b_per_u - 1 - i];
  171.         move_ptr (curwp, -1L, TRUE, FALSE, TRUE);
  172.         }
  173.  /* deposit first unit */
  174.     for (i = 0; i < b_per_u; i++)
  175.         {
  176.         DOT_CHAR(curwp) = s_buf[i];
  177.         move_ptr (curwp, -1L, TRUE, FALSE, TRUE);
  178.         }
  179.     curwp -> w_dotp = dotp;
  180.     curwp -> w_doto = doto;
  181.     lchange (WFHARD);
  182.     return (TRUE);
  183. }
  184.  
  185. /*
  186. * Quote the next character, and
  187. * insert it into the buffer. All the characters
  188. * are taken literally.
  189. * The character
  190. * is always read, even if it is inserted 0 times, for
  191. * regularity.
  192. */
  193. bool quote (f, n, k)
  194. {
  195.  
  196.     register int    s;
  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, c));
  223. }
  224.  
  225. /*
  226. * Toggle the insert mode.  Insert mode is used only in ASCII or EBCDIC modes.
  227. */
  228. bool insert_toggle ()    /* toggle routine for selfinsert */
  229. {
  230.     register    WINDOW * wp;
  231.  
  232.     if (curbp -> b_flag & BFSLOCK)
  233.         return (TRUE);
  234.     
  235.     if (read_pat_mode)
  236.         dont_repeat = TRUE;
  237.  
  238.     insert_mode = !insert_mode;
  239.     for (wp = wheadp; wp; wp = wp -> w_wndp)
  240.         wp -> w_flag |= WFMODE; /* force mode line update */
  241.     return (TRUE);
  242. }
  243.  
  244. /*
  245. * Ordinary text characters are bound to this function,
  246. * which inserts them into the buffer. Characters marked as control
  247. * characters (using the CTRL flag) may be remapped to their ASCII
  248. * equivalent. This makes TAB (C-I) work right, and also makes the
  249. * world look reasonable if a control character is bound to this
  250. * this routine by hand. Any META or CTLX flags on the character
  251. * are discarded. 
  252. *   Edit the unit under the cursor.
  253. *   Check that the character is valid for the current display mode.
  254. */
  255.  
  256. bool selfinsert (f, n, k)
  257. {
  258.  
  259.     register int    c;
  260.     register int    s;
  261.     char    edt_buf[4],
  262.             i_chr,
  263.             b_per_u,
  264.             u_offs,
  265.             u_roffs,
  266.             bit_shf,
  267.             bit_mask,
  268.             i;
  269.     LINE    * l_ptr;
  270.     short   d_offs;
  271.     int     bytes,
  272.             temp_int;
  273.     long    dot_shf,
  274.             l_mask,
  275.             l_val;
  276.     char    text_buf[12];
  277.     static char max_dec_8[] = "255";
  278.     static char max_dec_16[] = "65535";
  279.     static char max_dec_32[] = "4294967295";
  280.     int        cur_col;
  281.  
  282.     bool intel;
  283.  
  284.     if (n < 0)
  285.         {
  286.         ttbeep ();
  287.         return (FALSE);
  288.         }
  289.     if (n == 0)
  290.         {
  291.         ttbeep ();
  292.         return (TRUE);
  293.         }
  294.     c = k & KCHAR;
  295.     if ((k & KCTRL) != 0 && c >= '@' && c <= '_')/* ASCII-ify.           */
  296.         c -= '@';
  297.     b_per_u = curwp -> w_fmt_ptr -> r_b_per_u;
  298.     u_offs = curwp -> w_unit_offset;
  299.     u_roffs = curwp -> w_fmt_ptr -> r_chr_per_u - u_offs - 1;
  300.     intel = curwp -> w_intel_mode;
  301.  
  302.     cur_col = ttcol;
  303.  
  304.     switch (curwp -> w_fmt_ptr -> r_type)
  305.         {
  306.         case EBCDIC: 
  307.             c = to_ebcdic (c);  /* convert ASCII to EBCDIC */
  308.         case ASCII: 
  309.             if ((insert_mode) || (DOT_POS(curwp) == BUF_SIZE(curwp)))
  310.                 {
  311.                 s = linsert (n, c);
  312.                 if (read_pat_mode)
  313.                     forwchar (0, 1, KRANDOM);/* advance the cursor */
  314.                 }
  315.             else
  316.                 s = lreplace (n, c);
  317.             break;
  318.  
  319.         case HEX: 
  320.             if ((c >= '0') && (c <= '9'))
  321.                 {
  322.                 i_chr = c - '0';/* convert to binary */
  323.                 }
  324.             else
  325.                 if ((c >= 'A') && (c <= 'F'))
  326.                     {
  327.                     i_chr = c - 'A' + 10;/* convert to binary */
  328.                     }
  329.                 else
  330.                     if ((c >= 'a') && (c <= 'f'))
  331.                         {
  332.                         i_chr = c - 'a' + 10;/* convert to binary */
  333.                         }
  334.                     else
  335.                         {
  336.                         bad_key (k);
  337.                         return (FALSE);
  338.                         }
  339.             fill_out (); /* expand buffer if necessary */
  340.  
  341.         /* position dot to byte to be altered */
  342.             if (intel)
  343.                 dot_shf = u_roffs >> 1;
  344.             else
  345.                 dot_shf = u_offs >> 1;
  346.  
  347.             /* save dot position for later */
  348.             l_ptr = curwp -> w_dotp;
  349.             d_offs = curwp -> w_doto;
  350.             move_ptr (curwp, dot_shf, TRUE, FALSE, TRUE);
  351.  
  352.             if (u_offs & 1)
  353.                 {               /* lower nibble in byte */
  354.                 i_chr &= 0x0f;
  355.                 DOT_CHAR(curwp) &= 0xf0;
  356.                 DOT_CHAR(curwp) |= i_chr;
  357.                 }
  358.             else
  359.                 {               /* upper nibble in byte */
  360.                 i_chr <<= 4;
  361.                 i_chr &= 0xf0;
  362.                 DOT_CHAR(curwp) &= 0x0f;
  363.                 DOT_CHAR(curwp) |= i_chr;
  364.                 }
  365.  
  366.         /* restore dot position */
  367.             curwp -> w_dotp = l_ptr;
  368.             curwp -> w_doto = d_offs;
  369.             forwchar (0, 1, KRANDOM);/* advance the cursor */
  370.             break;
  371.  
  372.         case BINARY: 
  373.             if ((c != '0') && (c != '1'))
  374.                 {
  375.                 bad_key (k);
  376.                 return (FALSE);
  377.                 }
  378.  
  379.         /* position dot to byte to be altered */
  380.             if (intel)
  381.                 dot_shf = u_roffs >> 3;
  382.             else
  383.                 dot_shf = u_offs >> 3;
  384.  
  385.             fill_out (); /* expand buffer if necessary */
  386.  
  387.             /* save dot position for later */
  388.             l_ptr = curwp -> w_dotp;
  389.             d_offs = curwp -> w_doto;
  390.             move_ptr (curwp, dot_shf, TRUE, FALSE, TRUE);
  391.  
  392.             bit_shf = u_roffs & 0x07;
  393.  
  394.             if (c == '0')
  395.                 {
  396.                 DOT_CHAR(curwp) &= ~(1 << bit_shf);
  397.                 }
  398.             else
  399.                 {
  400.                 DOT_CHAR(curwp) |= 1 << bit_shf;
  401.                 }
  402.  
  403.         /* restore dot position */
  404.             curwp -> w_dotp = l_ptr;
  405.             curwp -> w_doto = d_offs;
  406.             forwchar (0, 1, KRANDOM);/* advance the cursor */
  407.             break;
  408.  
  409.         case OCTAL: 
  410.             if (c < '0')
  411.                 {
  412.                 bad_key (k);
  413.                 return (FALSE);
  414.                 }
  415.             else
  416.                 if ((c > '1') && (u_offs == 0) &&
  417.                         ((curwp -> w_fmt_ptr -> r_size) == WORDS))
  418.                     {
  419.                     bad_key (k);
  420.                     return (FALSE);
  421.                     }
  422.                 else
  423.                     if ((c > '3') && (u_offs == 0))
  424.                         {
  425.                         bad_key (k);
  426.                         return (FALSE);
  427.                         }
  428.                     else
  429.                         if (c > '7')
  430.                             {
  431.                             bad_key (k);
  432.                             return (FALSE);
  433.                             }
  434.  
  435.             dot_shf = (c - '0') & 7;/* get binary value */
  436.             l_mask = 7;         /* create bit mask */
  437.  
  438.             dot_shf <<= (u_roffs * 3);
  439.             l_mask <<= (u_roffs * 3);
  440.  
  441.             fill_out (); /* expand buffer if necessary */
  442.  
  443.             /* save dot position for later */
  444.             l_ptr = curwp -> w_dotp;
  445.             d_offs = curwp -> w_doto;
  446.  
  447.         /* position dot to the byte to be altered */
  448.             if (intel)
  449.                 {
  450.                 for (i = 0; i < b_per_u; i++)
  451.                     {
  452.                     DOT_CHAR(curwp) &= ~((D8) l_mask & 0xff);
  453.                     DOT_CHAR(curwp) |= (D8) dot_shf & 0xff;
  454.                     l_mask >>= 8;
  455.                     dot_shf >>= 8;
  456.                     move_ptr (curwp, 1L, TRUE, FALSE, TRUE);
  457.                     }
  458.                 }
  459.             else
  460.                 {
  461.                 move_ptr (curwp, (long) (b_per_u - 1), TRUE, FALSE, TRUE);
  462.                                 /* move to last byte */
  463.                 for (i = 0; i < b_per_u; i++)
  464.                     {
  465.                     DOT_CHAR(curwp) &= ~((D8) l_mask & 0xff);
  466.                     DOT_CHAR(curwp) |= (D8) dot_shf & 0xff;
  467.                     l_mask >>= 8;
  468.                     dot_shf >>= 8;
  469.                     move_ptr (curwp, -1L, TRUE, FALSE, TRUE);/* step back one byte */
  470.                     }
  471.                 }
  472.  
  473.         /* restore dot position */
  474.             curwp -> w_dotp = l_ptr;
  475.             curwp -> w_doto = d_offs;
  476.             forwchar (0, 1, KRANDOM);/* advance the cursor */
  477.             break;
  478.  
  479.         case DECIMAL: 
  480.             fill_out (); /* expand buffer if necessary */
  481.  
  482.             /* save dot position for later */
  483.             l_ptr = curwp -> w_dotp;
  484.             d_offs = curwp -> w_doto;
  485.  
  486.             bytes = fill_buf (curwp, l_ptr, d_offs, edt_buf, b_per_u);
  487.         /* if last unit is not full and must be extended */
  488.             for (; bytes < b_per_u; bytes++)
  489.                 {
  490.                 edt_buf[3] = edt_buf[2];/* shuffle bytes down */
  491.                 edt_buf[2] = edt_buf[1];
  492.                 edt_buf[1] = edt_buf[0];
  493.                 edt_buf[0] = 0;
  494.                 }
  495.             switch (curwp -> w_fmt_ptr -> r_size)
  496.                 {
  497.                 case BYTES: 
  498.                     sprintf (text_buf, MSG_03u, (int) (edt_buf[0] & 0xff));
  499.                     if (!dec_chr_ok (text_buf, max_dec_8, c, u_offs))
  500.                         {
  501.                         bad_key (k);
  502.                         return (TRUE);  /* TRUE so that mask will be same len */
  503.                         }
  504.                     sscanf (text_buf, MSG_3u, &i);/* convert back to binary */
  505.                     l_val = (long) i & 0xff;
  506.                     break;
  507.  
  508.                 case WORDS: 
  509.                     l_val = get_int (edt_buf);/* do intel swap */
  510.                     sprintf (text_buf, MSG_05u, (int) (l_val & 0xFFFF));
  511.                     if (!dec_chr_ok (text_buf, max_dec_16, c, u_offs))
  512.                         {
  513.                         bad_key (k);
  514.                         return (TRUE);  /* TRUE so that mask will be same len */
  515.                         }
  516.                     sscanf (text_buf, MSG_5u, &temp_int);
  517.                                 /* convert back to binary */
  518.                     l_val = get_int ((char *) & temp_int);/* do intel swap */
  519.                     break;
  520.  
  521.                 case DWORDS: 
  522.                     l_val = get_long (edt_buf);/* do intel swap */
  523.                     sprintf (text_buf, MSG_010lu, l_val);
  524.                     if (!dec_chr_ok (text_buf, max_dec_32, c, u_offs))
  525.                         {
  526.                         bad_key (k);
  527.                         return (TRUE);  /* TRUE so that mask will be same len */
  528.                         }
  529.                     sscanf (text_buf, MSG_lu, &l_val);
  530.                                 /* convert back to binary */
  531.                     l_val = get_long ((char *) & l_val);/* do intel swap */
  532.                     break;
  533. #if RUNCHK
  534.                 default:
  535.                     writ_echo (ERR_rnd_2);
  536.                     break;
  537. #endif
  538.                 }
  539.             DOT_CHAR(curwp) = (char) l_val & 0xff;
  540.             for (i = 1; i < b_per_u; i++)
  541.                 {
  542.                 l_val >>= 8;
  543.                 move_ptr (curwp, 1L, TRUE, FALSE, TRUE);/* step forward one byte */
  544.                 DOT_CHAR(curwp) = (char) l_val & 0xff;
  545.                 }
  546.  
  547.         /* restore dot position */
  548.             curwp -> w_dotp = l_ptr;
  549.             curwp -> w_doto = d_offs;
  550.             forwchar (0, 1, KRANDOM);/* advance the cursor */
  551.             break;
  552.  
  553. #if RUNCHK
  554.         default:
  555.             writ_echo (ERR_rnd_3);
  556.             break;
  557. #endif
  558.         }
  559.     /* if cursor has wrapped to the next line then previous line
  560.         will not be refreshed with WFEDIT so do a WFHARD */
  561.     if (cur_col > get_curcol(curwp))
  562.         lchange (WFHARD);
  563.     else
  564.         lchange (WFEDIT);
  565.  
  566.     return (TRUE);
  567. }
  568.  
  569. /*
  570. *   Insert one unit of zeros at the current dot position.
  571. */
  572. bool    insertunit (f, n, k)
  573. {
  574.     lchange (WFEDIT);
  575.     linsert ((R_B_PER_U(curwp) * n), 0);
  576.     return (TRUE);
  577. }
  578.  
  579. /* 
  580. *   Increase the size of the buffer if necessary.
  581. *   If dot is at the byte after the last full unit
  582. *   then add enough bytes to the buffer to create 
  583. *   a full unit at the end.
  584. */  
  585.  
  586. bool    fill_out ()
  587. {
  588.     long    buf_size, dot_pos, l_val, last_unit;   
  589.     int     b_per_u;    
  590.     char    stat, shift;   
  591.     int     insert_val;
  592.  
  593.     buf_size = BUF_SIZE(curwp);
  594.     dot_pos = DOT_POS(curwp);
  595.     b_per_u = R_B_PER_U(curwp);
  596.     shift = curwp -> w_disp_shift;       
  597.     stat = TRUE;    
  598.     insert_val = 0;
  599.     last_unit = buf_size & ~((long)(b_per_u - 1));
  600.     /* there is an even number of units step back one */
  601.     if (last_unit == buf_size)
  602.         last_unit -= b_per_u;
  603.     last_unit += shift;
  604.  
  605.     /* if dot is one byte past the end of the buffer */
  606.     if (dot_pos > last_unit)
  607.         {
  608.         insert_val = b_per_u;
  609.         }
  610.  
  611.     /* if dot is pointed at the end of the buffer */
  612.     else if (dot_pos == last_unit)
  613.         {
  614.         insert_val = b_per_u - (buf_size - last_unit);
  615.         }
  616.  
  617.     /* if insert is necessary then do it */
  618.     if (insert_val != 0)
  619.         {
  620.         lchange (WFHARD);
  621.         move_ptr (curwp, buf_size, TRUE, FALSE, FALSE); /* move dot to end */
  622.         stat = linsert (insert_val, 0);
  623.         move_ptr (curwp, dot_pos, TRUE, TRUE, FALSE); /* put dot back */
  624.         }
  625.     return (stat);
  626. }
  627.  
  628. /*
  629. *   This checks that an entered character is ok
  630. *   for the position given.
  631. */
  632.  
  633. char    dec_chr_ok (char_buf, max_str, chr, pos)
  634.  
  635. char    chr,
  636.         pos,
  637.        *char_buf,
  638.        *max_str;
  639.  
  640. {
  641.     char    i;
  642.  
  643.     if ((chr < '0') || (chr > '9'))
  644.         return (FALSE);
  645.  
  646.     char_buf[pos] = chr;        /* insert typed char */
  647.  
  648.  /* check if number is too big */
  649.     for (i = 0; max_str[i] != 0; i++)
  650.         {
  651.         if (char_buf[i] < max_str[i])
  652.             break;              /* if char is smaller then must be ok */
  653.  
  654.         if (char_buf[i] > max_str[i])
  655.             return (FALSE);     /* val is too large; ERROR */
  656.         }
  657.     return (TRUE);
  658. }
  659.  
  660. /*
  661. * Set the rest of the variables for the mode change.
  662. */
  663. void    set_mode_vars ()
  664. {
  665.     curwp -> w_disp_shift = 0;  /* shift to 0 when changing mode */
  666.     curwp -> w_unit_offset = 0; /* go to end of unit */
  667.     /* if we are in the middle of a search then use the proper format struc */
  668.     if (read_pat_mode)
  669.         curwp -> w_fmt_ptr = curwp -> w_fmt_ptr -> r_srch_fmt;
  670.         
  671.     wind_on_dot (curwp);
  672.     curwp -> w_flag = WFHARD;
  673.     update ();
  674. }
  675.  
  676. /*
  677. * Change the display mode to ASCII.
  678. * The default binding is META C-A.
  679. */
  680. bool    asciimode ()
  681. {
  682.     curwp -> w_fmt_ptr = &ascii_fmt;
  683.     set_mode_vars ();
  684.     return (TRUE);
  685. }
  686.  
  687. /*
  688. * Change the display mode to EBCDIC.
  689. * The default binding is META C-E.
  690. */
  691. bool    ebcdicmode ()
  692. {
  693.     curwp -> w_fmt_ptr = &ebcdic_fmt;
  694.     set_mode_vars ();
  695.     return (TRUE);
  696. }
  697.  
  698. /*
  699. * Change the display mode to DECIMAL.
  700. * The default binding is META C-D.
  701. */
  702. bool    decimalmode ()
  703. {
  704.     switch (curwp -> w_fmt_ptr -> r_size)
  705.         {
  706.         case BYTES: 
  707.             curwp -> w_fmt_ptr = &decimal_8_fmt;
  708.             break;
  709.         case WORDS: 
  710.             curwp -> w_fmt_ptr = &decimal_16_fmt;
  711.             break;
  712.  
  713.         case DWORDS: 
  714.             curwp -> w_fmt_ptr = &decimal_32_fmt;
  715.             break;
  716. #if RUNCHK
  717.         default:
  718.             writ_echo (ERR_rnd_4);
  719.             break;
  720. #endif
  721.         }
  722.     set_mode_vars ();
  723.     return (TRUE);
  724. }
  725.  
  726. /*
  727. * Change the display mode to HEXADECIMAL.
  728. * The default binding is META C-H.
  729. */
  730. bool    hexmode ()
  731. {
  732.     switch (curwp -> w_fmt_ptr -> r_size)
  733.         {
  734.         case BYTES: 
  735.             curwp -> w_fmt_ptr = &hex_8_fmt;
  736.             break;
  737.         case WORDS: 
  738.             curwp -> w_fmt_ptr = &hex_16_fmt;
  739.             break;
  740.         case DWORDS: 
  741.             curwp -> w_fmt_ptr = &hex_32_fmt;
  742.             break;
  743. #if RUNCHK
  744.         default:
  745.             writ_echo (MSG_rnd_5);
  746.             break;
  747. #endif
  748.         }
  749.     set_mode_vars ();
  750.     return (TRUE);
  751. }
  752.  
  753. /*
  754. * Change the display mode to OCTAL.
  755. * The default binding is META C-O.
  756. */
  757. bool    octalmode ()
  758. {
  759.     switch (curwp -> w_fmt_ptr -> r_size)
  760.         {
  761.         case BYTES: 
  762.             curwp -> w_fmt_ptr = &octal_8_fmt;
  763.             break;
  764.  
  765.         case WORDS: 
  766.             curwp -> w_fmt_ptr = &octal_16_fmt;
  767.             break;
  768.  
  769.         case DWORDS: 
  770.             curwp -> w_fmt_ptr = &octal_32_fmt;
  771.             break;
  772. #if RUNCHK
  773.         default:
  774.             writ_echo (ERR_rnd_6);
  775.             break;
  776. #endif
  777.         }
  778.     set_mode_vars ();
  779.     return (TRUE);
  780. }
  781.  
  782. /*
  783. * Change the display mode to BINARY.
  784. * The default binding is META C-B.
  785. */
  786. bool    binarymode ()
  787. {
  788.     switch (curwp -> w_fmt_ptr -> r_size)
  789.         {
  790.         case BYTES: 
  791.             curwp -> w_fmt_ptr = &binary_8_fmt;
  792.             break;
  793.         case WORDS: 
  794.             curwp -> w_fmt_ptr = &binary_16_fmt;
  795.             break;
  796.         case DWORDS: 
  797.             curwp -> w_fmt_ptr = &binary_32_fmt;
  798.             break;
  799. #if RUNCHK
  800.         default:
  801.             writ_echo (ERR_rnd_7);
  802.             break;
  803. #endif
  804.         }
  805.     set_mode_vars ();
  806.     return (TRUE);
  807. }
  808.  
  809. /*
  810. * Change the display shift.
  811. * Circularly rotate through display shift of 0 through 3.
  812. * This value is used to shift the display by the designated number of bytes.
  813. * This is used to cause WORD and DWORD values to be calculated
  814. * from the correct offset.
  815. */
  816. bool dispshift (f, n, k)
  817. {
  818.     char    mode,
  819.             size;
  820.  
  821.     if (read_pat_mode)
  822.         return (TRUE);  /* no shift is allowed in search mode */    
  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. {
  870.     char    s;
  871.  
  872.     if (n < 0)
  873.         return (backdel (f, -n, KRANDOM));
  874.     
  875.     s = FALSE;
  876.     if (R_SIZE(curwp) == BYTES)
  877.         {
  878.         if (f != FALSE)
  879.             {
  880.         /* Really a kill.       */
  881.             if ((lastflag & CFKILL) == 0)
  882.                 kdelete ();
  883.             thisflag |= CFKILL;
  884.             }
  885.         s = ldelete (n, f);
  886.         curwp -> w_unit_offset = 0;
  887.         }
  888.     return (s);
  889. }
  890.  
  891.  
  892. /*
  893. * Delete backwards. This is quite easy too,
  894. * because it's all done with other functions. Just
  895. * move the cursor back, and delete forwards.
  896. * Like delete forward, this actually does a kill
  897. * if presented with an argument.
  898. */
  899. char    backdel (f, n, k)
  900. {
  901.  
  902.     int     u_off;
  903.     char    s;
  904.  
  905.     if (n < 0)
  906.         return (forwdel (f, -n, KRANDOM));
  907.  
  908.     s = FALSE;
  909.     if (R_SIZE(curwp) == BYTES)
  910.         {
  911.         u_off = curwp -> w_unit_offset;
  912.         curwp -> w_unit_offset = 0;
  913.         if ((s = backchar (f, n * R_CHR_PER_U(curwp), KRANDOM)) == TRUE)
  914.             {
  915.             s = ldelete (n, f);
  916.             if (f != FALSE)
  917.                 {
  918.                 /* Really a kill.       */
  919.                 if ((lastflag & CFKILL) == 0)
  920.                     kdelete ();
  921.                 thisflag |= CFKILL;
  922.                 }
  923.             }
  924.         curwp -> w_unit_offset = u_off;
  925.         }
  926.     return (s);
  927. }
  928.  
  929.  
  930. /*
  931. * Change the size of the display unit to BYTE.
  932. * Adjust byte shift to the allowable range.
  933. * Normally bound to "META-1".
  934. */
  935. bool dispsize1 ()
  936. {
  937.     curwp -> w_disp_shift = 0;  /* shift to 0 when changing size */
  938.     curwp -> w_unit_offset = 0; /* go to end of unit */
  939.  
  940.     switch (R_TYPE(curwp))
  941.         {
  942.         case OCTAL: 
  943.             curwp -> w_fmt_ptr = &octal_8_fmt;
  944.             break;
  945.  
  946.         case DECIMAL: 
  947.             curwp -> w_fmt_ptr = &decimal_8_fmt;
  948.             break;
  949.  
  950.         case HEX: 
  951.             curwp -> w_fmt_ptr = &hex_8_fmt;
  952.             break;
  953.  
  954.         case BINARY: 
  955.             curwp -> w_fmt_ptr = &binary_8_fmt;
  956.             break;
  957.  
  958.         default:
  959.             return (TRUE);
  960.             break;
  961.         }
  962.  
  963.     /* if we are in the middle of a search then use the proper format struc */
  964.     if (read_pat_mode)
  965.         curwp -> w_fmt_ptr = curwp -> w_fmt_ptr -> r_srch_fmt;
  966.         
  967.     move_ptr (curwp, 0L, TRUE, TRUE, TRUE);
  968.     wind_on_dot (curwp);
  969.     curwp -> w_flag = WFHARD;
  970.     update ();
  971.     return (TRUE);
  972. }
  973.  
  974. /*
  975. * Change the size of the display unit to WORD.
  976. * Adjust byte shift to the allowable range.
  977. * Normally bound to "META-2".
  978. */
  979. bool dispsize2 ()
  980. {
  981.     curwp -> w_disp_shift = 0;  /* shift to 0 when changing size */
  982.     curwp -> w_unit_offset = 0; /* go to end of unit */
  983.  
  984.     switch (R_TYPE(curwp))
  985.         {
  986.         case OCTAL: 
  987.             curwp -> w_fmt_ptr = &octal_16_fmt;
  988.             break;
  989.  
  990.         case DECIMAL: 
  991.             curwp -> w_fmt_ptr = &decimal_16_fmt;
  992.             break;
  993.  
  994.         case HEX: 
  995.             curwp -> w_fmt_ptr = &hex_16_fmt;
  996.             break;
  997.  
  998.         case BINARY: 
  999.             curwp -> w_fmt_ptr = &binary_16_fmt;
  1000.             break;
  1001.  
  1002.         default:
  1003.             return (TRUE);
  1004.             break;
  1005.         }
  1006.  
  1007.     /* if we are in the middle of a search then use the proper format struc */
  1008.     if (read_pat_mode)
  1009.         curwp -> w_fmt_ptr = curwp -> w_fmt_ptr -> r_srch_fmt;
  1010.         
  1011.     move_ptr (curwp, 0L, TRUE, TRUE, TRUE);
  1012.     wind_on_dot (curwp);
  1013.     curwp -> w_flag = WFHARD;
  1014.     update ();
  1015.     return (TRUE);
  1016. }
  1017.  
  1018. /*
  1019. * Change the size of the display unit to DOUBLE WORD.
  1020. * Adjust byte shift to the allowable range.
  1021. * Normally bound to "META-4".
  1022. */
  1023. bool dispsize4 ()
  1024. {
  1025.     curwp -> w_disp_shift = 0;  /* shift to 0 when changing size */
  1026.     curwp -> w_unit_offset = 0; /* go to end of unit */
  1027.  
  1028.     switch (R_TYPE(curwp))
  1029.         {
  1030.         case OCTAL: 
  1031.             curwp -> w_fmt_ptr = &octal_32_fmt;
  1032.             break;
  1033.  
  1034.         case DECIMAL: 
  1035.             curwp -> w_fmt_ptr = &decimal_32_fmt;
  1036.             break;
  1037.  
  1038.         case HEX: 
  1039.             curwp -> w_fmt_ptr = &hex_32_fmt;
  1040.             break;
  1041.  
  1042.         case BINARY: 
  1043.             curwp -> w_fmt_ptr = &binary_32_fmt;
  1044.             break;
  1045.  
  1046.         default:
  1047.             return (TRUE);
  1048.             break;
  1049.         }
  1050.  
  1051.     /* if we are in the middle of a search then use the proper format struc */
  1052.     if (read_pat_mode)
  1053.         curwp -> w_fmt_ptr = curwp -> w_fmt_ptr -> r_srch_fmt;
  1054.         
  1055.     move_ptr (curwp, 0L, TRUE, TRUE, TRUE);
  1056.     wind_on_dot (curwp);
  1057.     curwp -> w_flag = WFHARD;
  1058.     update ();
  1059.     return (TRUE);
  1060. }
  1061.  
  1062. /*
  1063. * Display byte swaped.   This command causes the bytes
  1064. * that are displayed in WORD and DWORD mode to be swaped
  1065. * in the way that the INTEL microprocessors do it.
  1066. */
  1067. bool dispswapbyte (f, n, k)
  1068. {
  1069.     if ((curwp -> w_fmt_ptr -> r_size) == BYTES)
  1070.         return (TRUE);
  1071.  
  1072.     if (curwp -> w_intel_mode)
  1073.         curwp -> w_intel_mode = FALSE;
  1074.     else
  1075.         curwp -> w_intel_mode = TRUE;
  1076.  
  1077.     curwp -> w_flag = WFHARD;
  1078.     update ();
  1079.     return (TRUE);
  1080. }
  1081.  
  1082. /*
  1083. * Yank text back from the kill buffer. This
  1084. * is really easy. All of the work is done by the
  1085. * standard insert routines. All you do is run the loop,
  1086. * and check for errors. 
  1087. * An attempt has been made to fix the cosmetic bug
  1088. * associated with a yank when dot is on the top line of
  1089. * the window (nothing moves, because all of the new
  1090. * text landed off screen).
  1091. */
  1092. bool yank (f, n, k)
  1093. {
  1094.     register int    c;
  1095.     register int    i;
  1096.     register    LINE * lp;
  1097.  
  1098.     if (n < 0)
  1099.         return (FALSE);
  1100.     while (n--)
  1101.         {
  1102.         i = 0;
  1103.         while ((c = kremove (i)) >= 0)
  1104.             {
  1105.             if (linsert (1, c) == FALSE)
  1106.                 return (FALSE);
  1107.             ++i;
  1108.             }
  1109.         }
  1110.     curwp -> w_flag |= WFHARD;
  1111.     return (TRUE);
  1112. }
  1113.  
  1114. /*
  1115. *   Link windows.   pvr
  1116. *   This function toggles the window linking function.
  1117. *   When linking is enabled all windows that look at 
  1118. *   the same buffer will be forced to have the same 
  1119. *   dot position.   Each window is then moved to be
  1120. *   positioned on the dot.   Thus when a user moves
  1121. *   arround a buffer all other views into that buffer 
  1122. *   will follow.
  1123. */
  1124.  
  1125. bool linkwind ()
  1126.  
  1127. {
  1128.     char    buf[80];
  1129.  
  1130.     if (curwp -> w_bufp -> b_flag & BFLINK)
  1131.         {
  1132.         curwp -> w_bufp -> b_flag &= ~(BFLINK & 0xff);
  1133.         sprintf (buf, MSG_lnk, curwp -> w_bufp -> b_bname, MSG_unlink);
  1134.         }
  1135.     else
  1136.         {
  1137.         curwp -> w_bufp -> b_flag |= BFLINK;
  1138.         sprintf (buf, MSG_lnk, curwp -> w_bufp -> b_bname, MSG_link);
  1139.         }
  1140.     writ_echo (buf);
  1141.     return (TRUE);
  1142. }
  1143. /*
  1144. *   Print all bad keys to the screen and beep 
  1145. */
  1146. void    bad_key (key)
  1147. int     key;
  1148.     {
  1149.     char    buf[80], buf1[40];
  1150.  
  1151.     ttbeep ();
  1152.     sprintf (buf, MSG_bad_key);
  1153.     if (key & KMETA)
  1154.         sprintf (&buf[strlen (buf)], MSG_esc);
  1155.     if (key & KCTLX)
  1156.         sprintf (&buf[strlen (buf)], MSG_ctl_x);
  1157.     if (key & KCTRL)
  1158.         sprintf (&buf[strlen (buf)], MSG_ctl);
  1159.     sprintf (buf1, MSG_key_code, char_str, R_BYTE_FMT(curwp));
  1160.     sprintf (&buf[strlen (buf)], buf1, (key & KCHAR), key);
  1161.     writ_echo (buf);
  1162.     }
  1163.