home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / thesrc15.zip / execute.c < prev    next >
C/C++ Source or Header  |  1993-12-01  |  75KB  |  2,109 lines

  1. /***********************************************************************/
  2. /* EXECUTE.C -                                                         */
  3. /* This file contains all functions that actually execute one or other */
  4. /* commands.                                                           */
  5. /***********************************************************************/
  6. /*
  7.  * THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
  8.  * Copyright (C) 1991-1993 Mark Hessling
  9.  *
  10.  * This program is free software; you can redistribute it and/or
  11.  * modify it under the terms of the GNU General Public License as
  12.  * published by the Free Software Foundation; either version 2 of
  13.  * the License, or any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18.  * General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to:
  22.  *
  23.  *    The Free Software Foundation, Inc.
  24.  *    675 Mass Ave,
  25.  *    Cambridge, MA 02139 USA.
  26.  *
  27.  *
  28.  * If you make modifications to this software that you feel increases
  29.  * it usefulness for the rest of the community, please email the
  30.  * changes, enhancements, bug fixes as well as any and all ideas to me.
  31.  * This software is going to be maintained and enhanced as deemed
  32.  * necessary by the community.
  33.  *
  34.  * Mark Hessling                     email: M.Hessling@gu.edu.au
  35.  * 36 David Road                     Phone: +61 7 849 7731
  36.  * Holland Park                      Fax:   +61 7 875 5314
  37.  * QLD 4121
  38.  * Australia
  39.  */
  40.  
  41. /*
  42. $Header: C:\THE\RCS\execute.c 1.4 1993/09/01 16:26:20 MH Interim MH $
  43. */
  44.  
  45. #include <stdio.h>
  46.  
  47. #include "the.h"
  48. #include "proto.h"
  49.  
  50. /*-------------------------- external data ----------------------------*/
  51. extern VIEW_DETAILS *vd_current,*vd_first,*vd_mark;
  52. extern char current_screen;
  53. extern SCREEN_DETAILS screen[MAX_SCREENS];        /* screen structures */
  54. extern WINDOW *foot,*error_window;
  55. extern bool error_on_screen;
  56. extern char *rec;
  57. extern unsigned short rec_len;
  58. extern char in_profile;    /* indicates if processing profile */
  59. extern char *temp_cmd;
  60. /***********************************************************************/
  61. #ifdef PROTO
  62. int execute_change_command(char *params,bool selective)
  63. #else
  64. int execute_change_command(params,selective)
  65. char *params;
  66. bool selective;
  67. #endif
  68. /***********************************************************************/
  69. {
  70. /*-------------------------- external data ----------------------------*/
  71. /*--------------------------- local data ------------------------------*/
  72. #define ALT_PARAMS  4
  73.  char *word[ALT_PARAMS];
  74.  char parm[ALT_PARAMS];
  75.  register int i;
  76.  unsigned short num_params;
  77.  long num_lines,long_n,long_m;
  78.  unsigned short x,y;
  79.  LINE *curr;
  80.  char old_str[60],new_str[60],target[60],n[20],m[20];
  81.  short rc,selective_rc=RC_OK;
  82.  int  direction;
  83.  short number_lines,number_changes,number_of_changes,number_of_occ;
  84.  short start_col,real_start,real_end,loc;
  85.  long true_line,last_true_line,final_target;
  86.  int len_old_str,len_new_str;
  87. /*--------------------------- processing ------------------------------*/
  88. #ifdef TRACE
  89.  trace_function("commutil.c:execute_change_command");
  90. #endif
  91. /*---------------------------------------------------------------------*/
  92. /* Validate the parameters that have been supplied. Up to 4 parameters */
  93. /* may be supplied. The first is the string to change and its new      */
  94. /* value, the second is the target, the third is the number of times   */
  95. /* to change the value on one line and lastly is which occurrence to   */
  96. /* change first.                                                       */
  97. /*---------------------------------------------------------------------*/
  98.  rc = split_change_params(params,old_str,new_str,target,n,m);
  99.  if (rc == (-1))
  100.    {
  101.     display_error(36,(char *)"");
  102. #ifdef TRACE
  103.     trace_return();
  104. #endif
  105.     return(RC_NO_LINES_CHANGED);
  106.    }
  107. /*---------------------------------------------------------------------*/
  108. /* Check for any hex strings in both old_str and new_str.              */
  109. /*---------------------------------------------------------------------*/
  110.  if (CURRENT_VIEW->hex == ON)
  111.    {
  112.     if ((len_old_str = convert_hex_strings(old_str)) == (-1))
  113.       {
  114.        display_error(32,(char *)"");
  115. #ifdef TRACE
  116.        trace_return();
  117. #endif
  118.        return(RC_INVALID_OPERAND);
  119.       }
  120.     if ((len_new_str = convert_hex_strings(new_str)) == (-1))
  121.       {
  122.        display_error(32,(char *)"");
  123. #ifdef TRACE
  124.        trace_return();
  125. #endif
  126.        return(RC_INVALID_OPERAND);
  127.       }
  128.    }
  129.  else
  130.    {
  131.     len_old_str = strlen(old_str);
  132.     len_new_str = strlen(new_str);
  133.    }
  134.  
  135.  if ((num_lines = valid_target(target,get_true_line())) == TARGET_ERROR
  136.  || CURRENT_FILE->number_lines == 0L)
  137.     {
  138.      display_error(17,target);
  139. #ifdef TRACE
  140.     trace_return();
  141. #endif
  142.      return(RC_TARGET_NOT_FOUND);
  143.     }
  144. /*---------------------------------------------------------------------*/
  145. /* If the number of lines is zero, don't make an y changes. Exit with  */
  146. /* no rows changed.                                                    */
  147. /*---------------------------------------------------------------------*/
  148.  if (num_lines == 0L)
  149.    {
  150.     display_error(36,(char *)"");
  151. #ifdef TRACE
  152.     trace_return();
  153. #endif
  154.     return(RC_NO_LINES_CHANGED);
  155.    }
  156.  
  157.  if (strcmp(n,"*") == 0)
  158.     long_n = MAX_LONG;
  159.  else
  160.     if (!valid_positive_integer(n))
  161.       {
  162.        display_error(4,n);
  163. #ifdef TRACE
  164.        trace_return();
  165. #endif
  166.        return(RC_INVALID_OPERAND);
  167.       }
  168.     else
  169.       long_n = atol(n);
  170.  if (!valid_positive_integer(m))
  171.     {
  172.      display_error(4,m);
  173. #ifdef TRACE
  174.      trace_return();
  175. #endif
  176.      return(RC_INVALID_OPERAND);
  177.     }
  178.  else
  179.    long_m = atol(m);
  180.  direction = (num_lines < 0) ? DIRECTION_BACKWARD : DIRECTION_FORWARD;
  181. /*---------------------------------------------------------------------*/
  182. /* Determine where to start changing.                                  */
  183. /* If target is ALL, start with first line...                          */
  184. /* If on command line or in profile, use current_line...               */
  185. /* Else, use focus line.                                               */
  186. /*---------------------------------------------------------------------*/
  187.  if (equal((char *)"all",target,3))
  188.     true_line = 1L;
  189.  else
  190.     true_line = get_true_line();
  191.  final_target = true_line+num_lines;
  192. /*---------------------------------------------------------------------*/
  193. /* If the true_line is on the top or bottom of file lines and we are   */
  194. /* searching forward or backward respectively, set the true_line to be */
  195. /* the next line in the appropriate direction.                         */
  196. /*---------------------------------------------------------------------*/
  197.  if (true_line == 0L
  198.  && direction == DIRECTION_FORWARD)
  199.     true_line++;
  200.  if (true_line == CURRENT_FILE->number_lines+1L
  201.  && direction == DIRECTION_BACKWARD)
  202.     true_line--;
  203.  if (true_line != CURRENT_VIEW->focus_line)
  204.    {
  205.     post_process_line(CURRENT_VIEW->focus_line);
  206.     pre_process_line(true_line);
  207.    }
  208.  number_lines = 0;
  209.  number_changes = 0;
  210.  number_of_changes = 0;
  211.  number_of_occ = 0;
  212.  start_col = 0;
  213.  last_true_line = true_line;
  214. #ifdef USE_VOID
  215.  curr = (LINE *)ll_find((void *)CURRENT_FILE->first_line,true_line);
  216. #else
  217.  curr = lll_find(CURRENT_FILE->first_line,true_line);
  218. #endif
  219.  while(1)
  220.    {
  221.     loc = 0;
  222.     number_of_changes = number_of_occ = 0;
  223.     while(loc != (-1))
  224.       {
  225.        real_end = min(rec_len+len_old_str,CURRENT_VIEW->zone_end-1);
  226.        real_start = max(start_col,CURRENT_VIEW->zone_start-1);
  227.  
  228.        if (rec_len < real_start && blank_field(old_str))
  229.          {
  230.           loc = 0;
  231.           rec_len = real_start+1;
  232.          }
  233.        else
  234.          {
  235.           loc = memfind(rec+real_start,old_str,(real_end-real_start+1),
  236.                         len_old_str,
  237.                         (CURRENT_VIEW->case_change == CASE_IGNORE) ? TRUE : FALSE,
  238.                         CURRENT_VIEW->arbchar_status,
  239.                         CURRENT_VIEW->arbchar_char);
  240.          }
  241.        if (loc != (-1))
  242.          {
  243.           start_col = loc+real_start;
  244.           if (number_of_changes <= long_n-1 && number_of_occ >= long_m-1)
  245.             {
  246.             /* the following block is done for change or confirm of sch */
  247.              if (!selective)
  248.                {
  249.                 memdelchr(rec,start_col,rec_len,len_old_str);
  250. /*              rec_len -= len_old_str; */
  251.                 rec_len = max(start_col,rec_len - len_old_str);
  252.                 meminsmem(rec,new_str,len_new_str,start_col,max_line_length,rec_len);
  253.                 rec_len += len_new_str;
  254.                 if (rec_len > max_line_length)
  255.                   {
  256.                    rec_len = max_line_length;
  257.                    loc = (-1);
  258.                   }
  259.                 start_col += len_new_str;
  260.                 number_changes++;
  261.                 number_of_changes++;
  262.                }
  263.              else
  264.                {
  265.                /* selective */
  266.                 selective_rc = selective_change(old_str,len_old_str,new_str,len_new_str,
  267.                                                 true_line,last_true_line,start_col);
  268.                 last_true_line = true_line;
  269.                 switch(selective_rc)
  270.                   {
  271.                    case QUITOK:
  272.                    case RC_OK:
  273.                         start_col += len_new_str;
  274.                         number_changes++;
  275.                         number_of_changes++;
  276.                         if (rec_len > max_line_length)
  277.                           {
  278.                            rec_len = max_line_length;
  279.                            loc = (-1);
  280.                           }
  281.                         break;
  282.                    case SKIP:
  283.                         start_col += len_old_str;
  284.                         break;
  285.                    case QUIT:
  286.                         break;
  287.                   }
  288.                 if (selective_rc == QUIT || selective_rc == QUITOK)
  289.                    break;
  290.                }
  291.              number_of_occ++;
  292.             }
  293.           else
  294.             {
  295.              start_col += len_old_str;
  296.              number_of_occ++;
  297.             }
  298.           if (number_of_changes > long_n-1)
  299. /*          ||  number_of_occ > long_n-1)*/
  300.              loc = (-1);
  301.          }
  302.       } /* end while */
  303.     if (number_of_changes != 0)       /* changes made */
  304.       {
  305.        post_process_line(true_line);
  306.        number_lines++;
  307.       }
  308.  
  309.     if (selective_rc == QUIT || selective_rc == QUITOK)
  310.        break;
  311.     true_line += (long)direction;
  312.     start_col = 0;
  313.     if (direction == DIRECTION_FORWARD)
  314.       {
  315.        if (true_line >= final_target)
  316.           break;
  317.        curr = curr->next;
  318.       }
  319.     else
  320.       {
  321.        if (true_line <= final_target)
  322.           break;
  323.        curr = curr->prev;
  324.       }
  325.     pre_process_line(true_line);
  326.  
  327.    }
  328. /*---------------------------------------------------------------------*/
  329. /* If no changes were made, display error message and return.          */
  330. /*---------------------------------------------------------------------*/
  331.  if (number_changes == 0)
  332.    {
  333.     display_error(36,(char *)"");
  334.     pre_process_line(CURRENT_VIEW->focus_line);
  335. #ifdef TRACE
  336.     trace_return();
  337. #endif
  338.     return(RC_NO_LINES_CHANGED);
  339.    }
  340. /*---------------------------------------------------------------------*/
  341. /* If STAY is OFF, change the current and focus lines by the number    */
  342. /* of lines calculated from the target.                                */
  343. /*---------------------------------------------------------------------*/
  344.  if (!CURRENT_VIEW->stay)                                /* stay is off */
  345.    {
  346.     if (equal((char *)"all",target,3))
  347.        CURRENT_VIEW->focus_line = CURRENT_VIEW->current_line = num_lines+1L;
  348.     else
  349.        CURRENT_VIEW->focus_line = CURRENT_VIEW->current_line += num_lines-1L;
  350.    }
  351.  
  352.  pre_process_line(CURRENT_VIEW->focus_line);
  353.  show_page();
  354.  
  355.  sprintf(old_str,"%d occurrence(s) changed on %d line(s)",number_changes,number_lines);
  356.  display_error(0,old_str);
  357. #ifdef TRACE
  358.  trace_return();
  359. #endif
  360.  if (CURRENT_TOF || CURRENT_BOF)
  361.     return(RC_TOF_EOF_REACHED);
  362.  else
  363.     return(RC_OK);
  364. }
  365. /***********************************************************************/
  366. #ifdef PROTO
  367. short selective_change(char *old_str,int len_old_str,char *new_str,
  368.                        int len_new_str,long true_line,long last_true_line,short start_col)
  369. #else
  370. short selective_change(old_str,len_old_str,new_str,len_new_str,true_line,last_true_line,start_col)
  371. char *old_str;
  372. int len_old_str;
  373. char *new_str;
  374. int len_new_str;
  375. long true_line;
  376. long last_true_line;
  377. short start_col;
  378. #endif
  379. /***********************************************************************/
  380. {
  381. /*--------------------------- local data ------------------------------*/
  382.  short y,x,rc;
  383.  long top_line,bottom_line;
  384.  unsigned short key;
  385.  bool changed;
  386. /*--------------------------- processing ------------------------------*/
  387. #ifdef TRACE
  388.  trace_function("commutil.c:selective_change");
  389. #endif
  390.  
  391.  getyx(CURRENT_WINDOW_MAIN,y,x);
  392.                 /* move cursor to old string a la cmatch */
  393.                 /* display message */
  394.                 /* accept key - C next, - N change, - Q to quit */
  395.  
  396.  CURRENT_VIEW->focus_line = true_line;
  397. /*---------------------------------------------------------------------*/
  398. /* Check if the true_line is in the currently displayed window.        */
  399. /* If not, then change the current_line to the true_line.              */
  400. /*---------------------------------------------------------------------*/
  401.  top_line = (long)CURRENT_VIEW->current_line - (long)CURRENT_VIEW->current_row;
  402.  bottom_line = (long)CURRENT_VIEW->current_line + ((long)CURRENT_SCREEN.rows - (long)CURRENT_VIEW->current_row);
  403.  if (true_line < top_line
  404.  ||  true_line >= bottom_line)
  405. /* if (offset + y <= 0
  406.  ||  offset + y >= CURRENT_SCREEN.rows)*/
  407.    {
  408.     CURRENT_VIEW->current_line = CURRENT_VIEW->focus_line;
  409.     y = CURRENT_VIEW->current_row;
  410.    }
  411.  else
  412.     y = get_row_for_focus_line(CURRENT_VIEW->current_row,
  413.                                CURRENT_VIEW->focus_line,
  414.                                CURRENT_VIEW->current_line);
  415.  if (start_col >= CURRENT_VIEW->verify_col-1
  416.  &&  start_col <= (CURRENT_SCREEN.cols+(CURRENT_VIEW->verify_col-1))-1)
  417.     x = start_col-(CURRENT_VIEW->verify_col-1);
  418.  else
  419.    {
  420.     x = CURRENT_SCREEN.cols / 2;
  421.     CURRENT_VIEW->verify_col = max(1,start_col-(short)x);
  422.     x = (start_col-(CURRENT_VIEW->verify_col-1));
  423.    }
  424.  
  425.  key = 0;
  426.  changed = FALSE;
  427.  while(key == 0)
  428.    {
  429.     if (changed)
  430.        display_error(0,(char *)"Press 'N' for next,'C' to undo 'Q' to quit");
  431.     else
  432.        display_error(0,(char *)"Press 'N' for next,'C' to change 'Q' to quit");
  433.     touchwin(error_window);
  434.     show_page();
  435.     wmove(CURRENT_WINDOW_MAIN,y,x);
  436.     wrefresh(CURRENT_WINDOW_MAIN);
  437.  
  438.     key = my_getch(CURRENT_WINDOW_MAIN);
  439.     switch(key)
  440.       {
  441.        case 'N':
  442.        case 'n':
  443.             if (changed)
  444.                rc = RC_OK;
  445.             else
  446.                rc = SKIP;
  447.             break;
  448.        case 'C':
  449.        case 'c':
  450.             if (changed)
  451.               {
  452.                memdelchr(rec,start_col,rec_len,len_new_str);
  453.                rec_len -= len_new_str;
  454.                meminsmem(rec,old_str,len_old_str,start_col,max_line_length,rec_len);
  455.                rec_len += len_old_str;
  456.               }
  457.             else
  458.               {
  459.                memdelchr(rec,start_col,rec_len,len_old_str);
  460.                rec_len -= len_old_str;
  461.                meminsmem(rec,new_str,len_new_str,start_col,max_line_length,rec_len);
  462.                rec_len += len_new_str;
  463.               }
  464.             changed = (changed) ? FALSE : TRUE;
  465.             key = 0;
  466.             break;
  467.        case 'Q':
  468.        case 'q':
  469.             if (changed)
  470.                rc = QUITOK;
  471.             else
  472.                rc = QUIT;
  473.             break;
  474.        default:
  475.             key = 0;
  476.             break;
  477.       }
  478.    }
  479.  
  480.  error_on_screen = FALSE;
  481.  touchwin(foot);
  482.  wrefresh(foot);
  483. #ifdef TRACE
  484.  trace_return();
  485. #endif
  486.  return(rc);
  487. }
  488. /***********************************************************************/
  489. #ifdef PROTO
  490. int insert_new_line(char *line,int len,long num_lines,long true_line,bool start_left_col,bool make_current)
  491. #else
  492. int insert_new_line(line,len,num_lines,true_line,start_left_col,make_current)
  493. char *line;
  494. int len;
  495. long num_lines;
  496. long true_line;
  497. bool start_left_col;
  498. bool make_current;
  499. #endif
  500. /***********************************************************************/
  501. {
  502. /*--------------------------- local data ------------------------------*/
  503.  register int i;
  504.  LINE *curr,*save_curr;
  505.  unsigned short x,y;
  506.  bool on_bottom=FALSE;
  507.  int rc,new_col;
  508. /*--------------------------- processing ------------------------------*/
  509. #ifdef TRACE
  510.  trace_function("commutil.c:insert_new_line");
  511. #endif
  512. /*---------------------------------------------------------------------*/
  513. /* If we are on the 'Bottom of File' line reduce the true_line by 1    */
  514. /* so that the new line is added before the bottom line.               */
  515. /*---------------------------------------------------------------------*/
  516.  if (true_line == CURRENT_FILE->number_lines+1L)
  517.     true_line--;
  518. /*---------------------------------------------------------------------*/
  519. /* Find the current LINE pointer for the true_line.                    */
  520. /* This is the line after which the line(s) are to be added.           */
  521. /*---------------------------------------------------------------------*/
  522. #ifdef USE_VOID
  523.  curr = (LINE *)ll_find((void *)CURRENT_FILE->first_line,true_line);
  524. #else
  525.  curr = lll_find(CURRENT_FILE->first_line,true_line);
  526. #endif
  527. /*---------------------------------------------------------------------*/
  528. /* Insert into the linked list the number of lines specified. All lines*/
  529. /* will contain a blank line and a length of zero.                     */
  530. /*---------------------------------------------------------------------*/
  531.  save_curr = curr;
  532.  for (i=0;i<num_lines;i++)
  533.     {
  534.      if ((curr = add_line(CURRENT_FILE->first_line,curr,line,len)) == NULL)
  535.        {
  536.         display_error(30,(char *)"");
  537. #ifdef TRACE
  538.         trace_return();
  539. #endif
  540.         return(RC_OUT_OF_MEMORY);
  541.        }
  542.     }
  543. /*---------------------------------------------------------------------*/
  544. /* Fix the positioning of the marked block (if there is one and it is  */
  545. /* in the current view).                                               */
  546. /*---------------------------------------------------------------------*/
  547.  adjust_marked_lines(TRUE,true_line,num_lines);
  548.  adjust_pending_prefix(CURRENT_VIEW,TRUE,true_line,num_lines);
  549. /*---------------------------------------------------------------------*/
  550. /* Increment the number of lines counter for the current file and the  */
  551. /* number of alterations.                                              */
  552. /*---------------------------------------------------------------------*/
  553.  if ((rc = increment_alt(CURRENT_FILE)) != RC_OK)
  554.    {
  555. #ifdef TRACE
  556.     trace_return();
  557. #endif
  558.     return(rc);
  559.    }
  560.  CURRENT_FILE->number_lines += num_lines;
  561. /*---------------------------------------------------------------------*/
  562. /* Sort out focus and current line.                                    */
  563. /*---------------------------------------------------------------------*/
  564.  CURRENT_VIEW->focus_line = true_line + 1;
  565.  switch(CURRENT_VIEW->current_window)
  566.    {
  567.     case WINDOW_COMMAND:
  568.          if (make_current)
  569.             CURRENT_VIEW->current_line = true_line + 1;
  570.          break;
  571.     case WINDOW_MAIN:
  572.          if (!in_profile)
  573.             getyx(CURRENT_WINDOW,y,x);
  574.          if (y == CURRENT_SCREEN.rows - 1)
  575.             CURRENT_VIEW->current_line++;
  576.          y = get_row_for_focus_line(CURRENT_VIEW->current_row,
  577.                                     CURRENT_VIEW->focus_line,
  578.                                     CURRENT_VIEW->current_line);
  579.          new_col = x;
  580.          if (!start_left_col)
  581.            {
  582.             if (CURRENT_VIEW->newline_aligned)
  583.               {
  584.                new_col = memne(save_curr->line,' ',save_curr->length);
  585.                if (new_col == (-1))
  586.                   new_col = 0;
  587. /*---------------------------------------------------------------------*/
  588. /* Special case when right margin is > than screen width...            */
  589. /*---------------------------------------------------------------------*/
  590.                if (CURRENT_VIEW->verify_start != CURRENT_VIEW->verify_col)
  591.                  {
  592. /*---------------------------------------------------------------------*/
  593. /* If the new column position will be on the same page...              */
  594. /*---------------------------------------------------------------------*/
  595.                   if (CURRENT_VIEW->verify_col < new_col
  596.                   &&  CURRENT_VIEW->verify_col + CURRENT_SCREEN.screen_cols > new_col)
  597.                      new_col = (new_col - CURRENT_VIEW->verify_col) + 1;
  598.                   else
  599.                     {
  600.                      x = CURRENT_SCREEN.cols / 2;
  601.                      CURRENT_VIEW->verify_col = max(1,new_col - (int)x + 2);
  602.                      new_col = (CURRENT_VIEW->verify_col == 1) ? new_col : x - 1;
  603.                     }
  604.                  }
  605.               }
  606.             else
  607.               {
  608.                new_col = 0;
  609.                CURRENT_VIEW->verify_col = 1;
  610.               }
  611.            }
  612. /*---------------------------------------------------------------------*/
  613. /* Move the cursor to where it should be and display the page.         */
  614. /*---------------------------------------------------------------------*/
  615.          wmove(CURRENT_WINDOW,y,new_col);
  616.          break;
  617.     case WINDOW_PREFIX:
  618.          if (!in_profile)
  619.            {
  620.             getyx(CURRENT_WINDOW,y,x);
  621.             if (y == CURRENT_SCREEN.rows - 1)
  622.                CURRENT_VIEW->current_line++;
  623.             y = get_row_for_focus_line(CURRENT_VIEW->current_row,
  624.                                        CURRENT_VIEW->focus_line,
  625.                                        CURRENT_VIEW->current_line);
  626.             wmove(CURRENT_WINDOW,y,0);
  627.            }
  628.          break;
  629.    }
  630.  pre_process_line(CURRENT_VIEW->focus_line);
  631. /*---------------------------------------------------------------------*/
  632. /* Re-display the main window.                                         */
  633. /*---------------------------------------------------------------------*/
  634.  show_page();
  635.  
  636. #ifdef TRACE
  637.  trace_return();
  638. #endif
  639.  return(RC_OK);
  640. }
  641. /***********************************************************************/
  642. #ifdef PROTO
  643. int execute_os_command(char *cmd,bool quiet,bool pause)
  644. #else
  645. int execute_os_command(cmd,quiet,pause)
  646. char *cmd;
  647. bool quiet;
  648. bool pause;
  649. #endif
  650. /***********************************************************************/
  651. {
  652. /*--------------------------- local data ------------------------------*/
  653. #if defined(DOS) || defined(OS2)
  654. #define SHELL "COMSPEC"
  655. #else
  656. #define SHELL "SHELL"
  657. #endif
  658.  int rc;
  659. /*--------------------------- processing ------------------------------*/
  660. #ifdef TRACE
  661.  trace_function("commutil.c:execute_os_command");
  662. #endif
  663.  
  664.  if (!quiet)
  665.    {
  666.     attrset(A_NORMAL);
  667.     touchwin(stdscr);
  668.     wmove(stdscr,0,0);
  669.     addch(' ');
  670.     wmove(stdscr,1,0);
  671.     wrefresh(stdscr);   /* clear screen */
  672.     suspend_curses();
  673.    }
  674.  if (allocate_temp_space(strlen(cmd),TEMP_TEMP_CMD) != RC_OK)
  675.     {
  676.      display_error(30,(char *)"");
  677. #ifdef TRACE
  678.      trace_return();
  679. #endif
  680.      return(RC_OUT_OF_MEMORY);
  681.     }
  682.  if (strcmp(cmd,"") == 0)
  683.     strcpy(temp_cmd,getenv(SHELL));
  684.  else
  685.     strcpy(temp_cmd,cmd);
  686. #ifdef UNIX
  687.  if (strcmp(temp_cmd,"") == 0)           /* no SHELL env variable set */
  688.    {
  689.     printf("No SHELL environment variable set - using /bin/sh\n");
  690.     fflush(stdout);
  691.     strcpy(temp_cmd,"/bin/sh");
  692.    }
  693. #endif
  694.  if (quiet)
  695.    {
  696. #ifdef UNIX
  697.     strcat(temp_cmd," > /dev/null");
  698. #endif
  699. #if defined(DOS) || defined(OS2)
  700.     strcat(temp_cmd," > nul:");
  701. #endif
  702.    }
  703.  system(temp_cmd);
  704.  if (pause)
  705.    {
  706.     printf("\n\n%s",HIT_ANY_KEY);
  707.     fflush(stdout);
  708.    }
  709.  if (!quiet)
  710.    {
  711.     resume_curses();
  712.     if (pause)
  713.        wgetch(stdscr);
  714.     restore_THE();
  715.    }
  716.  draw_cursor(ON);
  717. #ifdef TRACE
  718.  trace_return();
  719. #endif
  720.  return(RC_OK);
  721. }
  722. /***********************************************************************/
  723. #ifdef PROTO
  724. int execute_makecurr(long line)
  725. #else
  726. int execute_makecurr(line)
  727. long line;
  728. #endif
  729. /***********************************************************************/
  730. {
  731. /*--------------------------- local data ------------------------------*/
  732.  unsigned short y,x;
  733. /*--------------------------- processing ------------------------------*/
  734. #ifdef TRACE
  735.  trace_function("commutil.c:execute_makecurr");
  736. #endif
  737.  post_process_line(CURRENT_VIEW->focus_line);
  738.  
  739.  CURRENT_VIEW->current_line = line;
  740.  if (CURRENT_VIEW->current_window == WINDOW_PREFIX)
  741.     getyx(CURRENT_WINDOW,y,x);
  742.  else
  743.     getyx(CURRENT_WINDOW_MAIN,y,x);
  744.  show_page();
  745.  y = get_row_for_focus_line(CURRENT_VIEW->current_row,
  746.                             CURRENT_VIEW->focus_line,
  747.                             CURRENT_VIEW->current_line);
  748.  if (CURRENT_VIEW->current_window == WINDOW_PREFIX)
  749.     wmove(CURRENT_WINDOW,y,x);
  750.  else
  751.     wmove(CURRENT_WINDOW_MAIN,y,x);
  752. #ifdef TRACE
  753.  trace_return();
  754. #endif
  755.  return(RC_OK);
  756. }
  757. /***********************************************************************/
  758. #ifdef PROTO
  759. int execute_shift_command(int shift_left,int num_cols,long true_line,long num_lines)
  760. #else
  761. int execute_shift_command(shift_left,num_cols,true_line,num_lines)
  762. int shift_left,num_cols;
  763. long true_line,num_lines;
  764. #endif
  765. /***********************************************************************/
  766. {
  767. /*--------------------------- local data ------------------------------*/
  768.  unsigned short y,x;
  769.  LINE *curr;
  770.  long abs_num_lines = (num_lines < 0L ? -num_lines : num_lines);
  771.  long i;
  772.  register int j;
  773.  int actual_cols;
  774.  int rc;
  775. /*--------------------------- processing ------------------------------*/
  776. #ifdef TRACE
  777.  trace_function("commutil.c:execute_shift_command");
  778. #endif
  779.  post_process_line(CURRENT_VIEW->focus_line);
  780.  if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
  781.     getyx(CURRENT_WINDOW_MAIN,y,x);
  782.  else
  783.     getyx(CURRENT_WINDOW,y,x);
  784. #ifdef USE_VOID
  785.  curr = (LINE *)ll_find((void *)CURRENT_FILE->first_line,true_line);
  786. #else
  787.  curr = lll_find(CURRENT_FILE->first_line,true_line);
  788. #endif
  789.  for (i=0L;i<abs_num_lines;i++)
  790.    {
  791.     memset(rec,' ',max_line_length);
  792.     memcpy(rec,curr->line,curr->length);
  793.     rec_len = curr->length;
  794.     if (shift_left)
  795.       {
  796.        actual_cols = min(num_cols,rec_len);
  797.        memdelchr(rec,CURRENT_VIEW->zone_start-1,rec_len,actual_cols);
  798.        rec_len -= actual_cols;
  799.       }
  800.     else
  801.       {
  802.        for (j=0;j<num_cols;j++)
  803.           meminschr(rec,' ',CURRENT_VIEW->zone_start-1,max_line_length,rec_len++);
  804.        rec_len = min(rec_len,max_line_length);
  805.       }
  806. /*---------------------------------------------------------------------*/
  807. /* Increment the alteration counters...                                */
  808. /*---------------------------------------------------------------------*/
  809.     if ((rc = increment_alt(CURRENT_FILE)) != RC_OK)
  810.       {
  811. #ifdef TRACE
  812.        trace_return();
  813. #endif
  814.        return(rc);
  815.       }
  816. /*---------------------------------------------------------------------*/
  817. /* Add the old line contents to the line recovery list.                */
  818. /*---------------------------------------------------------------------*/
  819.     add_to_recovery_list(curr->line,curr->length);
  820. /*---------------------------------------------------------------------*/
  821. /* Realloc the dynamic memory for the line if the line is now longer.  */
  822. /*---------------------------------------------------------------------*/
  823.     if (rec_len > curr->length)
  824.                               /* what if realloc fails ?? */
  825.        curr->line = (char *)realloc((void *)curr->line,(rec_len+1)*sizeof(char));
  826. /*---------------------------------------------------------------------*/
  827. /* Copy the contents of rec into the line.                             */
  828. /*---------------------------------------------------------------------*/
  829.     memcpy(curr->line,rec,rec_len);
  830.     curr->length = rec_len;
  831.     *(curr->line+rec_len) = '\0';
  832.  
  833.     if (num_lines < 0L)
  834.        curr = curr->prev;
  835.     else
  836.        curr = curr->next;
  837.    }
  838. /*---------------------------------------------------------------------*/
  839. /* If STAY is OFF, change the current and focus lines by the number    */
  840. /* of lines calculated from the target.                                */
  841. /*---------------------------------------------------------------------*/
  842.  if (!CURRENT_VIEW->stay)                                /* stay is off */
  843.    {
  844.     CURRENT_VIEW->focus_line = min(CURRENT_VIEW->focus_line+num_lines-1L,CURRENT_FILE->number_lines+1L);
  845.     CURRENT_VIEW->current_line = min(CURRENT_VIEW->current_line+num_lines-1L,CURRENT_FILE->number_lines+1L);
  846.    }
  847.  
  848.  pre_process_line(CURRENT_VIEW->focus_line);
  849.  show_page();
  850.  
  851.  y = get_row_for_focus_line(CURRENT_VIEW->current_row,
  852.                             CURRENT_VIEW->focus_line,
  853.                             CURRENT_VIEW->current_line);
  854.  if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
  855.     wmove(CURRENT_WINDOW_MAIN,y,x);
  856.  else
  857.     wmove(CURRENT_WINDOW,y,x);
  858.  
  859. #ifdef TRACE
  860.  trace_return();
  861. #endif
  862.  return(RC_OK);
  863. }
  864. /***********************************************************************/
  865. #ifdef PROTO
  866. int execute_change_case(char *params,char which_case)
  867. #else
  868. int execute_change_case(params,which_case)
  869. char *params;
  870. char which_case;
  871. #endif
  872. /***********************************************************************/
  873. {
  874. /*--------------------------- local data ------------------------------*/
  875. #define LOW_PARAMS  1
  876.  char *word[LOW_PARAMS+1];
  877.  char parm[LOW_PARAMS];
  878.  register int i;
  879.  unsigned short num_params;
  880.  long num_lines,true_line;
  881.  unsigned short x,y;
  882.  int  direction;
  883.  LINE *curr;
  884.  bool block_delete=FALSE;
  885.  int start_col,end_col;
  886. /*--------------------------- processing ------------------------------*/
  887. #ifdef TRACE
  888.  trace_function("commutil.c:execute_change_case");
  889. #endif
  890. /*---------------------------------------------------------------------*/
  891. /* Validate the parameters that have been supplied.                    */
  892. /* Valid values are: a target or "block".                              */
  893. /* If no parameter is supplied, 1 is assumed.                          */
  894. /*---------------------------------------------------------------------*/
  895.  num_params = param_split(params,word,LOW_PARAMS,WORD_DELIMS,TEMP_PARAM);
  896.  if (num_params == 0)
  897.     {
  898.      num_params = 1;
  899.      word[0] = (char *)"1";
  900.     }
  901.  if (equal((char *)"block",word[0],5))
  902.    {
  903.     if (marked_block(TRUE) != RC_OK)
  904.       {
  905. #ifdef TRACE
  906.        trace_return();
  907. #endif
  908.        return(RC_INVALID_ENVIRON);
  909.       }
  910.     num_lines = MARK_VIEW->mark_end_line-MARK_VIEW->mark_start_line+1L;
  911.     true_line = MARK_VIEW->mark_start_line;
  912.     direction = DIRECTION_FORWARD;
  913.     if (MARK_VIEW->mark_type == M_LINE)
  914.       {
  915.        start_col = CURRENT_VIEW->zone_start-1;
  916.        end_col = CURRENT_VIEW->zone_end-1;
  917.       }
  918.     else
  919.       {
  920.        start_col = MARK_VIEW->mark_start_col-1;
  921.        end_col   = MARK_VIEW->mark_end_col-1;
  922.       }
  923.    }
  924.  else
  925.    {
  926.     if (equal((char *)"all",word[0],3))
  927.        true_line = 1L;
  928.     else
  929.        true_line = get_true_line();
  930.    
  931.     if ((num_lines = valid_target(word[0],true_line)) == TARGET_ERROR)
  932.       {
  933.        display_error(4,(char *)word[0]);
  934. #ifdef TRACE
  935.        trace_return();
  936. #endif
  937.        return(RC_INVALID_OPERAND);
  938.       }
  939.     if (num_lines == TARGET_NOT_FOUND)
  940.       {
  941.        display_error(17,(char *)"");
  942. #ifdef TRACE
  943.        trace_return();
  944. #endif
  945.        return(RC_TARGET_NOT_FOUND);
  946.       }
  947. /*---------------------------------------------------------------------*/
  948. /* Determine in which direction we are working.                        */
  949. /*---------------------------------------------------------------------*/
  950.     if (num_lines < 0)
  951.       {
  952.        direction = DIRECTION_BACKWARD;
  953.        num_lines = num_lines * (-1L);
  954.       }
  955.     else
  956.        direction = DIRECTION_FORWARD;
  957. /*---------------------------------------------------------------------*/
  958. /* Check from which window the command was issued and make adjustments */
  959. /* as required.                                                        */
  960. /* Commands issued from the command window relate to the current line, */
  961. /* commands issued from either the prefix or main window relate to the */
  962. /* focus line.                                                         */
  963. /*---------------------------------------------------------------------*/
  964.     if (!equal((char *)"all",word[0],3))
  965.       {
  966.        if (CURRENT_VIEW->current_window == WINDOW_COMMAND
  967.        || in_profile)
  968.          {
  969.           if (TOF(true_line))
  970.             {
  971.              true_line++;
  972.              if (!valid_integer(word[0]))
  973.                 num_lines--;
  974.             }
  975.           if (BOF(true_line))
  976.             {
  977.              true_line--;
  978.              if (!valid_integer(word[0]))
  979.                 num_lines--;
  980.             }
  981.          }
  982.        else
  983.          {
  984.           if (TOF(true_line) || BOF(true_line))
  985.             {
  986.              display_error(38,(char *)"");
  987. #ifdef TRACE
  988.              trace_return();
  989. #endif
  990.              return(RC_INVALID_ENVIRON);
  991.             }
  992.          }
  993.       }
  994.     start_col = CURRENT_VIEW->zone_start-1;
  995.     end_col = CURRENT_VIEW->zone_end-1;
  996.    }
  997.  post_process_line(CURRENT_VIEW->focus_line);
  998. /*---------------------------------------------------------------------*/
  999. /* Find the current LINE pointer for the true_line.                    */
  1000. /* This is the first line to change.                                   */
  1001. /*---------------------------------------------------------------------*/
  1002. #ifdef USE_VOID
  1003.  curr = (LINE *)ll_find((void *)CURRENT_FILE->first_line,true_line);
  1004. #else
  1005.  curr = lll_find(CURRENT_FILE->first_line,true_line);
  1006. #endif
  1007. /*---------------------------------------------------------------------*/
  1008. /* Change the values in the linked list for the specified number of    */
  1009. /* lines in the direction specified.                                   */
  1010. /*---------------------------------------------------------------------*/
  1011.  for (i=0;i<num_lines;i++)
  1012.     {
  1013.      add_to_recovery_list(curr->line,curr->length);
  1014.      change_case(curr->line,max(0,start_col),min(curr->length-1,end_col),which_case);
  1015.      if (direction == DIRECTION_FORWARD)
  1016.         curr = curr->next;
  1017.      else
  1018.         curr = curr->prev;
  1019.     }
  1020. /*---------------------------------------------------------------------*/
  1021. /* If STAY is OFF, change the current and focus lines by the number    */
  1022. /* of lines calculated from the target.                                */
  1023. /*---------------------------------------------------------------------*/
  1024.  if (!CURRENT_VIEW->stay)                                /* stay is off */
  1025.    {
  1026.     if (equal((char *)"all",word[0],3))
  1027.        CURRENT_VIEW->focus_line = CURRENT_VIEW->current_line = num_lines+1L;
  1028.     else
  1029.        CURRENT_VIEW->focus_line = CURRENT_VIEW->current_line += num_lines-1L;
  1030.    }
  1031. /*---------------------------------------------------------------------*/
  1032. /* If we are in the profile, then don't do any more processing.        */
  1033. /*---------------------------------------------------------------------*/
  1034.  if (in_profile)
  1035.    {
  1036.     pre_process_line(CURRENT_VIEW->focus_line);
  1037. #ifdef TRACE
  1038.     trace_return();
  1039. #endif
  1040.     if (CURRENT_TOF || CURRENT_BOF)
  1041.        return(RC_TOF_EOF_REACHED);
  1042.     else
  1043.        return(RC_OK);
  1044.    }
  1045.  pre_process_line(CURRENT_VIEW->focus_line);
  1046.  show_page();
  1047.  if (CURRENT_VIEW->current_window != WINDOW_COMMAND)
  1048.    {
  1049.     getyx(CURRENT_WINDOW,y,x);
  1050.     y = get_row_for_focus_line(CURRENT_VIEW->current_row,
  1051.                                CURRENT_VIEW->focus_line,
  1052.                                CURRENT_VIEW->current_line);
  1053.     wmove(CURRENT_WINDOW,y,x);
  1054.    }
  1055.  
  1056. #ifdef TRACE
  1057.  trace_return();
  1058. #endif
  1059.  if (CURRENT_TOF || CURRENT_BOF)
  1060.     return(RC_TOF_EOF_REACHED);
  1061.  else
  1062.     return(RC_OK);
  1063. }
  1064. /***********************************************************************/
  1065. #ifdef PROTO
  1066. int change_case(char *str,int start,int end,char which_case)
  1067. #else
  1068. int change_case(str,start,end,which_case)
  1069. char *str;
  1070. int start,end;
  1071. char which_case;
  1072. #endif
  1073. /***********************************************************************/
  1074. {
  1075. /*--------------------------- local data ------------------------------*/
  1076.  register int i;
  1077.  bool altered = FALSE;
  1078.  int rc;
  1079. /*--------------------------- processing ------------------------------*/
  1080. #ifdef TRACE
  1081.  trace_function("commutil.c:change_case");
  1082. #endif
  1083.  for (i=start;i<end+1;i++)
  1084.    {
  1085.     switch(which_case)
  1086.       {
  1087.        case CASE_UPPER:
  1088.                        if (islower(*(str+i)))
  1089.                          {
  1090.                           *(str+i) = toupper(*(str+i));
  1091.                           altered = TRUE;
  1092.                          }
  1093.                        break;
  1094.        case CASE_LOWER:
  1095.                        if (isupper(*(str+i)))
  1096.                          {
  1097.                           *(str+i) = tolower(*(str+i));
  1098.                           altered = TRUE;
  1099.                          }
  1100.                        break;
  1101.       }
  1102.    }
  1103. /*---------------------------------------------------------------------*/
  1104. /* Increment the number of alterations count if anything cahnged.      */
  1105. /*---------------------------------------------------------------------*/
  1106.  if (altered)
  1107.     if ((rc = increment_alt(CURRENT_FILE)) != RC_OK)
  1108.       {
  1109. #ifdef TRACE
  1110.        trace_return();
  1111. #endif
  1112.        return(rc);
  1113.       }
  1114.  
  1115. #ifdef TRACE
  1116.  trace_return();
  1117. #endif
  1118.  return(RC_OK);
  1119. }
  1120. /***********************************************************************/
  1121. #ifdef PROTO
  1122. int rearrange_line_blocks(char command,char source,
  1123.                           long start_line,long end_line,long dest_line,int num_occ,
  1124.                           VIEW_DETAILS *src_view,VIEW_DETAILS *dst_view)
  1125. #else
  1126. int rearrange_line_blocks(command,source,start_line,end_line,dest_line,num_occ,src_view,dst_view)
  1127. char command,source;
  1128. long start_line,end_line,dest_line;
  1129. int num_occ;
  1130. VIEW_DETAILS *src_view,*dst_view;
  1131. #endif
  1132. /***********************************************************************/
  1133. /* Parameters:                                                         */
  1134. /*    command: the command being executed; COPY,DELETE,DUPLICATE,MOVE  */
  1135. /*     source: where the command is executed; COMMAND, PREFIX, BLOCK   */
  1136. /* start_line: the first line (or only line) number to be acted on     */
  1137. /*   end_line: the last line number to be acted on                     */
  1138. /*  dest_line: the destination line for copy,move and duplicate. For   */
  1139. /*             delete this is not applicable.                          */
  1140. /*    num_occ: the number of times to execute the command; only for DUP*/
  1141. /***********************************************************************/
  1142. {
  1143. #define VIEW_CURRENT_WINDOW(view)  (view->win[vd_current->current_window])
  1144. /*--------------------------- local data ------------------------------*/
  1145.  register int i,j,k;
  1146.  int rc;
  1147.  static unsigned short y,x;
  1148.  bool dst_inside_src,lines_added,reset_block;
  1149.  bool dest_in_block=FALSE;
  1150.  int  direction;
  1151.  long num_lines,off,adjust_line=dest_line;
  1152.  LINE *curr_src,*curr_dst;
  1153.  LINE *save_curr_src,*save_curr_dst;
  1154.  FILE_DETAILS *src_file,*dst_file;
  1155. /*--------------------------- processing ------------------------------*/
  1156. #ifdef TRACE
  1157.  trace_function("commutil.c:rearrange_line_blocks");
  1158. #endif
  1159.  
  1160.  src_file = src_view->file_for_view;
  1161.  dst_file = dst_view->file_for_view;
  1162.  switch(source)
  1163.    {
  1164.     case SOURCE_BLOCK:
  1165.     case SOURCE_BLOCK_RESET:
  1166.          if (source == SOURCE_BLOCK)
  1167.             reset_block = FALSE;
  1168.          else
  1169.             reset_block = TRUE;
  1170.          break;
  1171.     default:
  1172.          break;
  1173.    }
  1174. /*---------------------------------------------------------------------*/
  1175. /* This block of commands is for copying lines...                      */
  1176. /*---------------------------------------------------------------------*/
  1177.  switch(command)
  1178.    {
  1179.     case COMMAND_COPY:
  1180.     case COMMAND_MOVE_COPY_SAME:
  1181.     case COMMAND_MOVE_COPY_DIFF:
  1182.     case COMMAND_DUPLICATE:
  1183.          lines_added = TRUE;
  1184.          switch(source)
  1185.            {
  1186.             case SOURCE_BLOCK:
  1187.             case SOURCE_BLOCK_RESET:
  1188.                  if (src_view == dst_view
  1189.                  &&  dest_line >= start_line
  1190.                  &&  dest_line <  end_line)
  1191.                      dest_in_block = TRUE;
  1192.                  break;
  1193.             case SOURCE_PREFIX:
  1194.                  if (dest_line >= start_line
  1195.                  &&  dest_line <  end_line)
  1196.                      dest_in_block = TRUE;
  1197.                  break;
  1198.             default:
  1199.                  break;
  1200.            }
  1201. /*---------------------------------------------------------------------*/
  1202. /* If the destination line is within the marked block then we have to  */
  1203. /* handle the processing of the src_curr pointer differently.          */
  1204. /*---------------------------------------------------------------------*/
  1205.          if (dest_in_block)
  1206.            {
  1207.             dst_inside_src = TRUE;
  1208.             off = dest_line - start_line;
  1209.            }
  1210.          else
  1211.             dst_inside_src = FALSE;
  1212.          num_lines = end_line - start_line + 1L;
  1213. #ifdef USE_VOID
  1214.          save_curr_src = (LINE *)ll_find((void *)src_file->first_line,start_line);
  1215. #else
  1216.          save_curr_src = lll_find(src_file->first_line,start_line);
  1217. #endif
  1218. #ifdef USE_VOID
  1219.          save_curr_dst = (LINE *)ll_find((void *)dst_file->first_line,dest_line);
  1220. #else
  1221.          save_curr_dst = lll_find(dst_file->first_line,dest_line);
  1222. #endif
  1223.          for (k=0;k<num_occ;k++)
  1224.            {
  1225.             curr_src = save_curr_src;
  1226.             curr_dst = save_curr_dst;
  1227.             for (i=0;i<num_lines;i++)
  1228.                {
  1229.                 if ((curr_dst = add_line(dst_file->first_line,curr_dst,
  1230.                                      curr_src->line,curr_src->length)) == NULL)
  1231.                   {
  1232.                    display_error(30,(char *)"");
  1233. #ifdef TRACE
  1234.                    trace_return();
  1235. #endif
  1236.                    return(RC_OUT_OF_MEMORY);
  1237.                   }
  1238. /*---------------------------------------------------------------------*/
  1239. /* If moving lines within the same file, move any line name with the   */
  1240. /* line also.                                                          */
  1241. /*---------------------------------------------------------------------*/
  1242.                 if (command == COMMAND_MOVE_COPY_SAME)
  1243.                   {
  1244.                    if (curr_src->name != (char *)NULL)
  1245.                      {
  1246.                       curr_dst->name = curr_src->name;
  1247.                       curr_src->name = (char *)NULL;
  1248.                      }
  1249.                   }
  1250.                 if (dst_inside_src && i == off)
  1251.                    for (j=0;j<off+1;j++)
  1252.                       curr_src = curr_src->next;
  1253.                 curr_src = curr_src->next;
  1254.               }
  1255.             }
  1256.          dst_file->number_lines += num_lines*num_occ;
  1257.          break;
  1258.     default:
  1259.          break;
  1260.    }
  1261. /*---------------------------------------------------------------------*/
  1262. /* This block of commands is for deleting lines...                     */
  1263. /*---------------------------------------------------------------------*/
  1264.  switch(command)
  1265.    {
  1266.     case COMMAND_DELETE:
  1267.     case COMMAND_MOVE_DELETE_SAME:
  1268.     case COMMAND_MOVE_DELETE_DIFF:
  1269.          lines_added = FALSE;
  1270.          if (start_line > end_line)
  1271.            {
  1272.             direction = DIRECTION_BACKWARD;
  1273.             num_lines = start_line - end_line + 1L;
  1274.            }
  1275.          else
  1276.            {
  1277.             direction = DIRECTION_FORWARD;
  1278.             num_lines = end_line - start_line + 1L;
  1279.            }
  1280. #ifdef USE_VOID
  1281.          curr_dst = (LINE *)ll_find((void *)dst_file->first_line,start_line);
  1282. #else
  1283.          curr_dst = lll_find(dst_file->first_line,start_line);
  1284. #endif
  1285.          for (i=0;i<num_lines;i++)
  1286.            {
  1287.             if (command != COMMAND_MOVE_DELETE_SAME)
  1288.                add_to_recovery_list(curr_dst->line,curr_dst->length);
  1289.             curr_dst = delete_line(dst_file->first_line,curr_dst,direction);
  1290.            }
  1291.          dst_file->number_lines -= num_lines*num_occ;
  1292.          break;
  1293.     default:
  1294.          break;
  1295.    }
  1296. /*---------------------------------------------------------------------*/
  1297. /* Increment alteration count for all but COMMAND_MOVE_COPY_SAME...    */
  1298. /*---------------------------------------------------------------------*/
  1299.  if (command != COMMAND_MOVE_COPY_SAME)
  1300.    {
  1301.     if ((rc = increment_alt(dst_file)) != RC_OK)
  1302.       {
  1303. #ifdef TRACE
  1304.        trace_return();
  1305. #endif
  1306.        return(rc);
  1307.       }
  1308.    }
  1309. /*---------------------------------------------------------------------*/
  1310. /* This block of commands is for sorting out cursor position...        */
  1311. /*---------------------------------------------------------------------*/
  1312.  switch(command)
  1313.    {
  1314.     case COMMAND_COPY:
  1315.     case COMMAND_MOVE_COPY_SAME:
  1316.     case COMMAND_MOVE_COPY_DIFF:
  1317.     case COMMAND_DUPLICATE:
  1318.          if (IN_VIEW(dst_view,dest_line))
  1319.            {
  1320.             dst_view->focus_line = dest_line+1L;
  1321.            }
  1322.          if (dst_view->current_window != WINDOW_COMMAND)
  1323.            {
  1324.             getyx(VIEW_CURRENT_WINDOW(dst_view),y,x);
  1325.             if (y == CURRENT_SCREEN.rows-1)/* on bottom line of window */
  1326.               {
  1327.                dst_view->current_line = dst_view->focus_line;
  1328.                y = dst_view->current_row;
  1329.               }
  1330.             else
  1331.                y = get_row_for_focus_line(dst_view->current_row,
  1332.                                           dst_view->focus_line,
  1333.                                           dst_view->current_line);
  1334.            }
  1335.          break;
  1336.     case COMMAND_DELETE:
  1337.     case COMMAND_MOVE_DELETE_SAME:
  1338.     case COMMAND_MOVE_DELETE_DIFF:
  1339.          if (dst_view->focus_line >= start_line
  1340.          &&  dst_view->focus_line <= end_line)
  1341.            {
  1342.             if (IN_VIEW(dst_view,dest_line))
  1343.               {
  1344.                if (dst_view->current_line > dst_file->number_lines+1L)
  1345.                   dst_view->current_line -= num_lines;
  1346.                dst_view->focus_line = dest_line;
  1347.               }
  1348.             else
  1349.               {
  1350.                if (dest_line > dst_file->number_lines)
  1351.                   dst_view->focus_line = dst_view->current_line = dst_file->number_lines;
  1352.                else
  1353.                   dst_view->focus_line = dst_view->current_line = dest_line;
  1354.               }
  1355.            }
  1356.          else
  1357.            {
  1358.             dest_line = (dst_view->focus_line < start_line ? dst_view->focus_line : dst_view->focus_line - num_lines);
  1359.             if (IN_VIEW(dst_view,dest_line))
  1360.               {
  1361.                if (dst_view->current_line > dst_file->number_lines+1L)
  1362.                   dst_view->current_line -= num_lines;
  1363.                dst_view->focus_line = dest_line;
  1364.               }
  1365.             else
  1366.               {
  1367.                if (dest_line > dst_file->number_lines)
  1368.                   dst_view->focus_line = dst_view->current_line = dst_file->number_lines;
  1369.                else
  1370.                   dst_view->focus_line = dst_view->current_line = dest_line;
  1371.               }
  1372.            }
  1373.          if (dst_file->number_lines == 0L)
  1374.                dst_view->focus_line = dst_view->current_line = 0L;
  1375.          if (dst_view->current_window != WINDOW_COMMAND)
  1376.            {
  1377.             getyx(VIEW_CURRENT_WINDOW(dst_view),y,x);
  1378.             y = get_row_for_focus_line(dst_view->current_row,
  1379.                                        dst_view->focus_line,
  1380.                                        dst_view->current_line);
  1381.            }
  1382. /*---------------------------------------------------------------------*/
  1383. /* This is set here so that the adjust_pending_prefix command will work*/
  1384. /*---------------------------------------------------------------------*/
  1385.          if (direction == DIRECTION_BACKWARD)
  1386.             adjust_line = end_line;
  1387.          else
  1388.             adjust_line = start_line;
  1389.          break;
  1390.     default:
  1391.          break;
  1392.    }
  1393. /*---------------------------------------------------------------------*/
  1394. /* This block of commands is for adjusting prefix and block lines...   */
  1395. /*---------------------------------------------------------------------*/
  1396.  switch(source)
  1397.    {
  1398.     case SOURCE_BLOCK:
  1399.     case SOURCE_BLOCK_RESET:
  1400.          adjust_pending_prefix(dst_view,lines_added,adjust_line,num_lines*num_occ);
  1401.          if (command == COMMAND_MOVE_DELETE_SAME)
  1402.             adjust_marked_lines(lines_added,adjust_line,num_lines*num_occ);
  1403.          else
  1404.             if (command != COMMAND_MOVE_DELETE_DIFF)
  1405.               {
  1406.                MARK_VIEW->mark_start_line = MARK_VIEW->mark_end_line = (-1L);
  1407.                MARK_VIEW->mark_start_col = MARK_VIEW->mark_end_col = (-1);
  1408.            
  1409.                dst_view->mark_start_line = dest_line + 1L;
  1410.                dst_view->mark_end_line = dest_line + num_lines;
  1411.                dst_view->mark_start_col = dst_view->mark_end_col = (-1);
  1412.                dst_view->mark_type = M_LINE;
  1413.            
  1414.                dst_view->focus_line = dst_view->mark_start_line;
  1415.            
  1416.                MARK_VIEW = dst_view;
  1417. /*---------------------------------------------------------------------*/
  1418. /* The following does a 'reset block' in the current view.             */
  1419. /*---------------------------------------------------------------------*/
  1420.                if (reset_block)
  1421.                  {
  1422.                   dst_view->mark_start_line = dst_view->mark_end_line = (-1L);
  1423.                   dst_view->mark_start_col = dst_view->mark_end_col = (-1);
  1424.                   MARK_VIEW = (VIEW_DETAILS *)NULL;
  1425.                  }
  1426.               }
  1427.          break;
  1428.     case SOURCE_PREFIX:
  1429.     case SOURCE_COMMAND:
  1430.          adjust_marked_lines(lines_added,adjust_line,num_lines*num_occ);
  1431.          adjust_pending_prefix(dst_view,lines_added,adjust_line,num_lines*num_occ);
  1432.          break;
  1433.    }
  1434.  if (command != COMMAND_MOVE_DELETE_DIFF)
  1435.     pre_process_line(dst_view->focus_line);
  1436. /*---------------------------------------------------------------------*/
  1437. /* If run from the profile, exit here.                                 */
  1438. /*---------------------------------------------------------------------*/
  1439.  if (in_profile)
  1440.    {
  1441. #ifdef TRACE
  1442.     trace_return();
  1443. #endif
  1444.     return(RC_OK);
  1445.    }
  1446.  if (command != COMMAND_MOVE_DELETE_DIFF
  1447.  &&  command != COMMAND_MOVE_COPY_SAME)
  1448.     show_page();
  1449.  if (dst_view->current_window != WINDOW_COMMAND)
  1450.     wmove(VIEW_CURRENT_WINDOW(dst_view),y,x);
  1451. #ifdef TRACE
  1452.  trace_return();
  1453. #endif
  1454.  return(RC_OK);
  1455. }
  1456. /***********************************************************************/
  1457. #ifdef PROTO
  1458. int execute_set_point(char *name,long true_line,bool point_on)
  1459. #else
  1460. int execute_set_point(name,true_line,point_on)
  1461. char *name;
  1462. long true_line;
  1463. bool point_on;
  1464. #endif
  1465. /***********************************************************************/
  1466. /* Parameters:                                                         */
  1467. /*       name: the name of the line to be processed                    */
  1468. /*  true_line: the line number of the line                             */
  1469. /*   point_on: indicates if the line name is to be turned on or off    */
  1470. /***********************************************************************/
  1471. {
  1472. /*--------------------------- local data ------------------------------*/
  1473.  LINE *curr;
  1474.  long dummy;
  1475. /*--------------------------- processing ------------------------------*/
  1476. #ifdef TRACE
  1477.  trace_function("commutil.c:execute_set_point");
  1478. #endif
  1479.  if (point_on)
  1480.    {
  1481. /*---------------------------------------------------------------------*/
  1482. /* Find a line that already has the same name. If one exists, remove   */
  1483. /* the name.                                                           */
  1484. /*---------------------------------------------------------------------*/
  1485.     if ((curr = find_named_line(name,&dummy)) != (LINE *)NULL)
  1486.       {
  1487.        free(curr->name);
  1488.        curr->name = (char *)NULL;
  1489.       }
  1490. /*---------------------------------------------------------------------*/
  1491. /* Allocate space for the name and attach it to the true_line.         */
  1492. /*---------------------------------------------------------------------*/
  1493. #ifdef USE_VOID
  1494.     curr = (LINE *)ll_find((void *)CURRENT_FILE->first_line,true_line);
  1495. #else
  1496.     curr = lll_find(CURRENT_FILE->first_line,true_line);
  1497. #endif
  1498.     if ((curr->name=(char *)malloc(strlen(name)+1)) == (char *)NULL)
  1499.       {
  1500.        display_error(30,(char *)"");
  1501. #ifdef TRACE
  1502.        trace_return();
  1503. #endif
  1504.        return(RC_OUT_OF_MEMORY);
  1505.       }
  1506.     strcpy(curr->name,name);
  1507.    }
  1508.  else
  1509.    {
  1510. /*---------------------------------------------------------------------*/
  1511. /* Find a line that already has the same name. If one exists, remove   */
  1512. /* the name otherwise display an error.                                */
  1513. /*---------------------------------------------------------------------*/
  1514.     if ((curr = find_named_line(name,&dummy)) != (LINE *)NULL)
  1515.       {
  1516.        free(curr->name);
  1517.        curr->name = (char *)NULL;
  1518.       }
  1519.     else
  1520.       {
  1521.        display_error(60,name);
  1522. #ifdef TRACE
  1523.        trace_return();
  1524. #endif
  1525.        return(RC_INVALID_OPERAND);
  1526.       }
  1527.    }
  1528.  
  1529. #ifdef TRACE
  1530.  trace_return();
  1531. #endif
  1532.  return(RC_OK);
  1533. }
  1534. /***********************************************************************/
  1535. #ifdef PROTO
  1536. int execute_wrap_word(unsigned short col)
  1537. #else
  1538. int execute_wrap_word(col)
  1539. unsigned short col;
  1540. #endif
  1541. /***********************************************************************/
  1542. /* Parameters: col   - current column position within rec              */
  1543. /***********************************************************************/
  1544. {
  1545. /*--------------------------- local data ------------------------------*/
  1546.  register int i;
  1547.  unsigned short y,x;
  1548.  int col_break,cursor_offset,new_col;
  1549.  LINE *curr;
  1550. /*--------------------------- processing ------------------------------*/
  1551. #ifdef TRACE
  1552.  trace_function("commutil.c:execute_wrap_word");
  1553. #endif
  1554. /*---------------------------------------------------------------------*/
  1555. /* All characters from the current word to the end of the line will be */
  1556. /* wrapped and a new line created. If the cursor is on a space, the    */
  1557. /* first non-blank will appear in the paragraph column. If the cursor  */
  1558. /* is in a word, the beginning of the word will appear in the paragraph*/
  1559. /* column, and the cursor will appear 1 character to the right of the  */
  1560. /* last character entered.                                             */
  1561. /*---------------------------------------------------------------------*/
  1562. /*---------------------------------------------------------------------*/
  1563. /* Find the current LINE pointer for the focus_line.                   */
  1564. /*---------------------------------------------------------------------*/
  1565. #ifdef USE_VOID
  1566.  curr = (LINE *)ll_find((void *)CURRENT_FILE->first_line,CURRENT_VIEW->focus_line);
  1567. #else
  1568.  curr = lll_find(CURRENT_FILE->first_line,CURRENT_VIEW->focus_line);
  1569. #endif
  1570. /*---------------------------------------------------------------------*/
  1571. /* Determine where to start splitting the line in relation to right    */
  1572. /* margin (not current column)...                                      */
  1573. /*---------------------------------------------------------------------*/
  1574.  col_break = (-1);
  1575.  if (rec[CURRENT_VIEW->margin_right-1] == ' ')
  1576.    {
  1577.     cursor_offset = 0;
  1578.     for (i=CURRENT_VIEW->margin_right-1;i<rec_len;i++)
  1579.       {
  1580.        if (rec[i] != ' ')
  1581.          {
  1582.           col_break = i;
  1583.           break;
  1584.          }
  1585.       }
  1586.     if (col_break == (-1))
  1587.       {
  1588.        col_break = col;
  1589.        add_line(CURRENT_FILE->first_line,curr,"",0);
  1590.       }
  1591.     else
  1592.        add_line(CURRENT_FILE->first_line,curr,(rec+col_break),
  1593.                rec_len - col_break);
  1594.     cursor_offset = col - col_break;
  1595.    }
  1596.  else
  1597. /*---------------------------------------------------------------------*/
  1598. /* Find start of word at the right margin...                           */
  1599. /*---------------------------------------------------------------------*/
  1600.    {
  1601. /*    for (i=CURRENT_VIEW->margin_right-1;i>0;i--) to start of line */
  1602.     for (i=CURRENT_VIEW->margin_right-1;i>CURRENT_VIEW->margin_left-1;i--) /* to left margin */
  1603.       {
  1604.        if (rec[i] == ' ')
  1605.          {
  1606.           col_break = i+1;
  1607.           break;
  1608.          }
  1609.       }
  1610. /*---------------------------------------------------------------------*/
  1611. /* If the word begins in column 1, then look for the first word break  */
  1612. /* after the right margin, to break there.                             */
  1613. /*---------------------------------------------------------------------*/
  1614.     if (col_break == (-1))
  1615.       {
  1616.        for (i=0;i<rec_len;i++)
  1617.           if (rec[i] == ' ')
  1618.              col_break = i;
  1619.       }
  1620. /*---------------------------------------------------------------------*/
  1621. /* If there is no word break, don't attempt any wrap.                  */
  1622. /*---------------------------------------------------------------------*/
  1623.     if (col_break == (-1))
  1624.       {
  1625. #ifdef TRACE
  1626.        trace_return();
  1627. #endif
  1628.        return(RC_OK);
  1629.       }
  1630.     cursor_offset = col - col_break;
  1631.     add_line(CURRENT_FILE->first_line,curr,(rec+col_break),
  1632.                rec_len - col_break);
  1633.    }
  1634.  CURRENT_FILE->number_lines++;
  1635. /*---------------------------------------------------------------------*/
  1636. /* Blank out that portion of rec that has been copied to the new line  */
  1637. /* and copy rec back into linked list.                                 */
  1638. /*---------------------------------------------------------------------*/
  1639.  for (i=col_break;i<rec_len;i++)
  1640.     rec[i] = ' ';
  1641.  rec_len = col_break;
  1642.  post_process_line(CURRENT_VIEW->focus_line);
  1643. /*---------------------------------------------------------------------*/
  1644. /* Make the newly added line the focus line. This also copies the      */
  1645. /* contents of the line into rec.                                      */
  1646. /*---------------------------------------------------------------------*/
  1647.  Down_arrow((char *)"");
  1648.  for (i=1;i<PARACOL;i++)
  1649.     meminschr(rec,' ',0,max_line_length,rec_len++);
  1650.  rec_len = min(rec_len,max_line_length);
  1651. /*---------------------------------------------------------------------*/
  1652. /* Determine cursor location relative to start of rec (0 based).       */
  1653. /*---------------------------------------------------------------------*/
  1654.  getyx(CURRENT_WINDOW,y,x);
  1655.  new_col = PARACOL+cursor_offset-1;
  1656. /*---------------------------------------------------------------------*/
  1657. /* Special case when right margin is > than screen width...            */
  1658. /*---------------------------------------------------------------------*/
  1659.  if (CURRENT_VIEW->verify_start != CURRENT_VIEW->verify_col)
  1660.    {
  1661. /*---------------------------------------------------------------------*/
  1662. /* If the new column position will be on the same page...              */
  1663. /*---------------------------------------------------------------------*/
  1664.     if (CURRENT_VIEW->verify_col < new_col
  1665.     &&  CURRENT_VIEW->verify_col + CURRENT_SCREEN.screen_cols > new_col)
  1666.        new_col = (new_col - CURRENT_VIEW->verify_col) + 1;
  1667.     else
  1668.       {
  1669.        x = CURRENT_SCREEN.cols / 2;
  1670.        CURRENT_VIEW->verify_col = max(1,new_col - x + 2);
  1671.        new_col = (CURRENT_VIEW->verify_col == 1) ? new_col : x - 1;
  1672.       }
  1673.    }
  1674. /*---------------------------------------------------------------------*/
  1675. /* Move the cursor to where it should be and display the page.         */
  1676. /*---------------------------------------------------------------------*/
  1677.  wmove(CURRENT_WINDOW,y,new_col);
  1678.  show_page();
  1679. #ifdef TRACE
  1680.  trace_return();
  1681. #endif
  1682.  return(RC_OK);
  1683. }
  1684. /***********************************************************************/
  1685. #ifdef PROTO
  1686. int execute_split_join(bool action,bool aligned)
  1687. #else
  1688. int execute_split_join(action,aligned)
  1689. bool action,aligned;
  1690. #endif
  1691. /***********************************************************************/
  1692. /* Parameters: action  - split or join line                            */
  1693. /*             aligned - whether to align text or not                  */
  1694. /***********************************************************************/
  1695. {
  1696. /*--------------------------- local data ------------------------------*/
  1697.  register int i;
  1698.  int num_cols,num_blanks_focus,num_blanks_next;
  1699.  unsigned short x,y,col;
  1700.  LINE *curr;
  1701. /*--------------------------- processing ------------------------------*/
  1702. #ifdef TRACE
  1703.  trace_function("execute.c: execute_split_join");
  1704. #endif
  1705.  if (CURRENT_VIEW->current_window != WINDOW_MAIN)
  1706.    {
  1707.     display_error(38,(char *)"");
  1708. #ifdef TRACE
  1709.     trace_return();
  1710. #endif
  1711.     return(RC_INVALID_ENVIRON);
  1712.    }
  1713. /*---------------------------------------------------------------------*/
  1714. /* Reject the command if on the top or bottom line.                    */
  1715. /*---------------------------------------------------------------------*/
  1716.  if (FOCUS_TOF || FOCUS_BOF)
  1717.    {
  1718.     display_error(38,(char *)"");
  1719. #ifdef TRACE
  1720.     trace_return();
  1721. #endif
  1722.     return(RC_INVALID_ENVIRON);
  1723.    }
  1724. /*---------------------------------------------------------------------*/
  1725. /* Copy any changes in the focus line to the linked list.              */
  1726. /*---------------------------------------------------------------------*/
  1727.  post_process_line(CURRENT_VIEW->focus_line);
  1728. /*---------------------------------------------------------------------*/
  1729. /* Find the current LINE pointer for the focus_line.                   */
  1730. /*---------------------------------------------------------------------*/
  1731. #ifdef USE_VOID
  1732.  curr = (LINE *)ll_find((void *)CURRENT_FILE->first_line,CURRENT_VIEW->focus_line);
  1733. #else
  1734.  curr = lll_find(CURRENT_FILE->first_line,CURRENT_VIEW->focus_line);
  1735. #endif
  1736.  
  1737.  getyx(CURRENT_WINDOW,y,x);
  1738.  col = (x+CURRENT_VIEW->verify_col-1);
  1739.  
  1740.  switch(action)
  1741.    {
  1742.     case SPLIT_TRUE:
  1743.          memset(rec,' ',max_line_length);
  1744.          memcpy(rec,curr->line+col,curr->length);
  1745.          rec_len = curr->length-col;
  1746. /*---------------------------------------------------------------------*/
  1747. /* Calculate the number of leading blanks on the current line so that  */
  1748. /* the new line can have this many blanks prepended to align properly. */
  1749. /*---------------------------------------------------------------------*/
  1750.          if (aligned)
  1751.            {
  1752.             num_cols = memne(curr->line,' ',curr->length);
  1753.             if (num_cols == (-1))
  1754.                num_cols = 0;
  1755.             for (i=0;i<num_cols;i++)
  1756.                meminschr(rec,' ',0,max_line_length,rec_len++);
  1757.             rec_len = min(rec_len,max_line_length);
  1758.            }
  1759.          add_line(CURRENT_FILE->first_line,curr,(rec),
  1760.                rec_len);
  1761.          CURRENT_FILE->number_lines++;
  1762.          pre_process_line(CURRENT_VIEW->focus_line);
  1763.          Sos_delend("");
  1764.          post_process_line(CURRENT_VIEW->focus_line);
  1765.          break;
  1766.     case SPLIT_FALSE:
  1767.          if (curr->next->next == NULL)
  1768.            {
  1769. /*---------------------------------------------------------------------*/
  1770. /* Trying to join with the bottom of file line.                        */
  1771. /*---------------------------------------------------------------------*/
  1772. #ifdef TRACE
  1773.            trace_return();
  1774. #endif
  1775.            return(RC_INVALID_ENVIRON);
  1776.           }
  1777. /*---------------------------------------------------------------------*/
  1778. /* Calculate the number of leading blanks for the focus line and also  */
  1779. /* for the line to be joined. To align the join properly, we have to   */
  1780. /* remove up the number of leading blanks in the focus line from the   */
  1781. /* beginning of the line to be joined.                                 */
  1782. /*---------------------------------------------------------------------*/
  1783.          if (aligned)
  1784.            {
  1785.             num_blanks_focus = memne(curr->line,' ',curr->length);
  1786.             if (num_blanks_focus == (-1))
  1787.                num_blanks_focus = 0;
  1788.             num_blanks_next = memne(curr->next->line,' ',curr->length);
  1789.             if (num_blanks_next == (-1))
  1790.                num_blanks_next = 0;
  1791.             num_cols = min(num_blanks_focus,num_blanks_next);
  1792.            }
  1793.          else
  1794.             num_cols = 0;
  1795.          meminsmem(rec,curr->next->line+num_cols,curr->next->length-num_cols,
  1796.                       col,max_line_length,col);
  1797.          rec_len = min(max_line_length,col+curr->next->length-num_cols);
  1798.          post_process_line(CURRENT_VIEW->focus_line);
  1799.          curr = delete_line(CURRENT_FILE->first_line,curr->next,DIRECTION_BACKWARD);
  1800. /*---------------------------------------------------------------------*/
  1801. /* If on the bottom line, use the previous line.                       */
  1802. /*---------------------------------------------------------------------*/
  1803.          if (CURRENT_BOF)
  1804.            {
  1805.             CURRENT_VIEW->current_line--;
  1806.             y++;
  1807.            }
  1808. /*---------------------------------------------------------------------*/
  1809. /* Decrement the number of lines counter for the current file and move */
  1810. /* the cursor to the appropriate line.                                 */
  1811. /*---------------------------------------------------------------------*/
  1812.          CURRENT_FILE->number_lines--;
  1813.          wmove(CURRENT_WINDOW,y,x);
  1814.          break;
  1815.    }
  1816.  show_page();
  1817. #ifdef TRACE
  1818.  trace_return();
  1819. #endif
  1820.  return(RC_OK);
  1821. }
  1822. /***********************************************************************/
  1823. #ifdef PROTO
  1824. int execute_put(char *params,bool putdel)
  1825. #else
  1826. int execute_put(params,putdel)
  1827. char *params;
  1828. bool putdel;
  1829. #endif
  1830. /***********************************************************************/
  1831. {
  1832. /*-------------------------- external data ----------------------------*/
  1833.  extern char *tempfilename;
  1834.  extern char sp_path[MAX_FILE_NAME+1] ;
  1835.  extern char sp_fname[MAX_FILE_NAME+1] ;
  1836. /*--------------------------- local data ------------------------------*/
  1837. #define PUT_PARAMS  2
  1838.  char *word[PUT_PARAMS+1];
  1839.  unsigned short num_params;
  1840.  long num_lines,true_line;
  1841.  char append;
  1842.  char *filename;
  1843.  int rc,start_col=0,end_col=max_line_length;
  1844. /*--------------------------- processing ------------------------------*/
  1845. #ifdef TRACE
  1846.  trace_function("execute.c: execute_put");
  1847. #endif
  1848.  num_params = param_split(params,word,PUT_PARAMS,WORD_DELIMS,TEMP_PARAM);
  1849.  if (num_params == 0)
  1850.    {
  1851.     num_params = 1;
  1852.     word[0] = (char *)"1";
  1853.    }
  1854.  if (num_params > 2)
  1855.    {
  1856.     display_error(1,word[2]);
  1857. #ifdef TRACE
  1858.     trace_return();
  1859. #endif
  1860.     return(RC_INVALID_OPERAND);
  1861.    }
  1862.  if ((num_lines = valid_target(word[0],get_true_line())) == TARGET_ERROR)
  1863.    {
  1864.     display_error(4,word[0]);
  1865. #ifdef TRACE
  1866.     trace_return();
  1867. #endif
  1868.     return(RC_INVALID_OPERAND);
  1869.    }
  1870.  if (strcmp(word[1],"") == 0)   /* no fileid supplied */
  1871.    {
  1872.     append = NO;
  1873.     filename = tempfilename;
  1874.    }
  1875.  else
  1876.    {
  1877.     if ((rc = splitpath(word[1])) != RC_OK)
  1878.       {
  1879.        display_error(10,word[1]);
  1880. #ifdef TRACE
  1881.        trace_return();
  1882. #endif
  1883.        return(rc);
  1884.       }
  1885.     strcpy(temp_cmd,sp_path);
  1886.     strcat(temp_cmd,sp_fname);
  1887.     filename = temp_cmd;
  1888.     append = YES;
  1889.    }
  1890. /*---------------------------------------------------------------------*/
  1891. /* Get the true_line here. If the target is BLOCK, then the true_line  */
  1892. /* will be set to the first line of the marked block.                  */
  1893. /*---------------------------------------------------------------------*/
  1894.  true_line = get_true_line();
  1895. /*---------------------------------------------------------------------*/
  1896. /* If the target is "all", set number of lines to 0L. This ensures that*/
  1897. /* save_file() will write out the whole file.                          */
  1898. /*---------------------------------------------------------------------*/
  1899.  if (equal((char *)"all",word[0],3))
  1900.     num_lines = 0L;
  1901.  else
  1902. /*---------------------------------------------------------------------*/
  1903. /* If the target is "block", the marked block must be a line block in  */
  1904. /* the current view.                                                   */
  1905. /*---------------------------------------------------------------------*/
  1906.     if (equal((char *)"block",word[0],5))
  1907.       {
  1908. /*---------------------------------------------------------------------*/
  1909. /* Validate the marked block.                                          */
  1910. /*---------------------------------------------------------------------*/
  1911.        if (marked_block(TRUE) != RC_OK)
  1912.          {
  1913. #ifdef TRACE
  1914.           trace_return();
  1915. #endif
  1916.           return(RC_INVALID_ENVIRON);
  1917.          }
  1918. /*---------------------------------------------------------------------*/
  1919. /* If the marked block is a BOX block, set up the left and right column*/
  1920. /* values.                                                             */
  1921. /*---------------------------------------------------------------------*/
  1922.        if (MARK_VIEW->mark_type == M_BOX)
  1923.          {
  1924.           start_col = MARK_VIEW->mark_start_col-1;
  1925.           end_col = MARK_VIEW->mark_end_col-1;
  1926.          }
  1927.        true_line = MARK_VIEW->mark_start_line;
  1928.        num_lines = MARK_VIEW->mark_end_line - MARK_VIEW->mark_start_line + 1;
  1929.       }
  1930.    else
  1931. /*---------------------------------------------------------------------*/
  1932. /* For other targets, adjust for beginning on TOF or EOF and for the   */
  1933. /* direction of the command.                                           */
  1934. /*---------------------------------------------------------------------*/
  1935.       {
  1936.        if (TOF(true_line))
  1937.          {
  1938.           true_line++;
  1939.           if (!valid_integer(word[0]))
  1940.              num_lines--;
  1941.          }
  1942.        if (BOF(true_line))
  1943.          {
  1944.           true_line--;
  1945.           if (!valid_integer(word[0]))
  1946.              (num_lines < 0L) ? num_lines++ : num_lines--;
  1947.          }
  1948.        if (num_lines < 0L)
  1949.          {
  1950.           num_lines = -num_lines;
  1951.           true_line = true_line - num_lines + 1L;
  1952.          }
  1953.       }
  1954.  
  1955.  post_process_line(CURRENT_VIEW->focus_line);
  1956.  if ((rc = save_file(CURRENT_FILE,filename,YES,num_lines,true_line,append,start_col,end_col)) != RC_OK)
  1957.    {
  1958. #ifdef TRACE
  1959.     trace_return();
  1960. #endif
  1961.     return(rc);
  1962.    }
  1963. /*---------------------------------------------------------------------*/
  1964. /* If we are executing a putd command, delete the target...            */
  1965. /*---------------------------------------------------------------------*/
  1966.  if (putdel)
  1967.     rc = DeleteLine(word[0]);
  1968. #ifdef TRACE
  1969.  trace_return();
  1970. #endif
  1971.  return(rc);
  1972. }
  1973. /***********************************************************************/
  1974. #ifdef PROTO
  1975. int execute_macro(char *params,bool error_on_not_found)
  1976. #else
  1977. int execute_macro(params,error_on_not_found)
  1978. char *params;
  1979. bool error_on_not_found;
  1980. #endif
  1981. /***********************************************************************/
  1982. {
  1983. /*-------------------------- external data ----------------------------*/
  1984.  extern char in_macro;
  1985.  extern char number_of_files;
  1986. /*--------------------------- local data ------------------------------*/
  1987.  int rc;
  1988.  int errnum=0;
  1989.  FILE *fp;
  1990. #define MAC_PARAMS  2
  1991.  char *word[MAC_PARAMS+1];
  1992.  unsigned short num_params;
  1993.  char *macroname;
  1994. /*--------------------------- processing ------------------------------*/
  1995. #ifdef TRACE
  1996.  trace_function("execute.c: execute_macro");
  1997. #endif
  1998. /*---------------------------------------------------------------------*/
  1999. /* Validate the parameters. At least 1 must be present, the filename.  */
  2000. /*---------------------------------------------------------------------*/
  2001.  num_params = param_split(params,word,MAC_PARAMS,WORD_DELIMS,TEMP_PARAM);
  2002.  if (num_params == 0)
  2003.    {
  2004.     display_error(3,(char *)"");
  2005. #ifdef TRACE
  2006.     trace_return();
  2007. #endif
  2008.     return(RC_INVALID_OPERAND);
  2009.    }
  2010. /*---------------------------------------------------------------------*/
  2011. /* Allocate some space for macroname...                                */
  2012. /*---------------------------------------------------------------------*/
  2013.  if ((macroname = (char *)malloc((MAX_FILE_NAME+1)*sizeof(char))) == NULL)
  2014.    {
  2015.     display_error(30,(char *)"");
  2016. #ifdef TRACE
  2017.     trace_return();
  2018. #endif
  2019.     return(RC_OUT_OF_MEMORY);
  2020.    }
  2021. /*---------------------------------------------------------------------*/
  2022. /* Find the fully qualified file name for the supplied macro name.     */
  2023. /*---------------------------------------------------------------------*/
  2024.  rc = get_valid_macro_file_name(word[0],macroname,&errnum);
  2025. /*---------------------------------------------------------------------*/
  2026. /* Validate the return code...                                         */
  2027. /*---------------------------------------------------------------------*/
  2028.  switch(rc)
  2029.    {
  2030. /*---------------------------------------------------------------------*/
  2031. /* If RC_OK, continue to process the macro...                          */
  2032. /*---------------------------------------------------------------------*/
  2033.     case RC_OK:
  2034.          break;
  2035. /*---------------------------------------------------------------------*/
  2036. /* If RC_FILE_NOT_FOUND and IMPOS is not on, display an error and exit.*/
  2037. /* If IMPOS is on, just return without displaying an error.            */
  2038. /*---------------------------------------------------------------------*/
  2039.     case RC_FILE_NOT_FOUND:
  2040.          if (error_on_not_found)
  2041. /*         if (!CURRENT_VIEW->imp_os)*/
  2042.             display_error(errnum,macroname);
  2043.          free(macroname);
  2044. #ifdef TRACE
  2045.          trace_return();
  2046. #endif
  2047.          return(rc);
  2048.          break;
  2049. /*---------------------------------------------------------------------*/
  2050. /* All other cases, display error and return.                          */
  2051. /*---------------------------------------------------------------------*/
  2052.     default:
  2053.          free(macroname);
  2054.          display_error(errnum,macroname);
  2055. #ifdef TRACE
  2056.          trace_return();
  2057. #endif
  2058.          return(rc);
  2059.    }
  2060. /*---------------------------------------------------------------------*/
  2061. /* Set in_macro = TRUE to stop multiple show_page()s being performed.  */
  2062. /*---------------------------------------------------------------------*/
  2063.  in_macro = TRUE;
  2064. /*---------------------------------------------------------------------*/
  2065. /* If REXX is supported, process the macro as a REXX macro...          */
  2066. /*---------------------------------------------------------------------*/
  2067. #if !defined(NOREXX)
  2068.  post_process_line(CURRENT_VIEW->focus_line);
  2069.  rc = execute_macro_file(macroname,word[1]);
  2070.  if (rc != RC_OK)
  2071.    {
  2072.     display_error(54,(char *)"");
  2073.     rc = RC_SYSTEM_ERROR;
  2074.    }
  2075. #else
  2076. /*---------------------------------------------------------------------*/
  2077. /* ...otherwise, process the file as a non-REXX macro file...          */
  2078. /*---------------------------------------------------------------------*/
  2079.  if ((fp = fopen(macroname,"r")) == NULL)
  2080.    {
  2081. #ifdef TRACE
  2082.     trace_return();
  2083. #endif
  2084.     in_macro = FALSE;
  2085.     free(macroname);
  2086.     return(RC_ACCESS_DENIED);
  2087.    }
  2088.  post_process_line(CURRENT_VIEW->focus_line);
  2089.  
  2090.  rc = execute_command_file(fp);
  2091.  
  2092.  fclose(fp);
  2093.  free(macroname);
  2094. #endif
  2095.  
  2096. /*---------------------------------------------------------------------*/
  2097. /* Set in_macro = FALSE to indicate we are out of the macro and do a   */
  2098. /* show_page() now as long as there are still file(s) in the ring.     */
  2099. /*---------------------------------------------------------------------*/
  2100.  in_macro = FALSE;
  2101.  if (number_of_files > 0)
  2102.     show_page();
  2103.  
  2104. #ifdef TRACE
  2105.  trace_return();
  2106. #endif
  2107.  return(rc);
  2108. }
  2109.