home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / the25.zip / thesrc251.zip / execute.c < prev    next >
C/C++ Source or Header  |  1998-06-08  |  123KB  |  3,368 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-1997 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@qut.edu.au
  35.  * PO Box 203                    Phone:                    +617 3802 0800
  36.  * Bellara                       http://www.gu.edu.au/gext/the/markh.html
  37.  * QLD 4507                      **** Maintainer PDCurses & REXX/SQL ****
  38.  * Australia                     ************* Author of THE ************
  39.  */
  40.  
  41. /*
  42. $Id: execute.c 2.1 1995/06/24 16:29:52 MH Rel MH $
  43. */
  44.  
  45. #include <the.h>
  46. #include <proto.h>
  47.  
  48. /***********************************************************************/
  49. #ifdef HAVE_PROTO
  50. short execute_change_command(CHARTYPE *params,bool selective)
  51. #else
  52. short execute_change_command(params,selective)
  53. CHARTYPE *params;
  54. bool selective;
  55. #endif
  56. /***********************************************************************/
  57. {
  58. /*-------------------------- external data ----------------------------*/
  59.  extern CHARTYPE *rec;
  60.  extern LENGTHTYPE rec_len;
  61.  extern VIEW_DETAILS *vd_mark;
  62.  extern CHARTYPE last_change_command[MAX_COMMAND_LENGTH];
  63. /*--------------------------- local data ------------------------------*/
  64.  LINETYPE num_lines=0L,long_n=0L,long_m=0L;
  65.  LINE *curr=NULL;
  66.  CHARTYPE *old_str=NULL,*new_str=NULL;
  67.  short rc=0,selective_rc=RC_OK;
  68.  short direction=DIRECTION_FORWARD;
  69.  long number_changes=0L,number_of_changes=0L,number_of_occ=0L;
  70.  short start_col=0,real_start=0,real_end=0,loc=0;
  71.  LINETYPE true_line=0L,last_true_line=0L,number_lines=0L;
  72.  LINETYPE num_actual_lines=0L,abs_num_lines=0L,i=0L;
  73.  LINETYPE num_file_lines=0L;
  74.  short len_old_str=0,len_new_str=0;
  75.  TARGET target;
  76.  CHARTYPE message[50];
  77.  bool lines_based_on_scope=FALSE;
  78.  CHARTYPE *save_params=NULL;
  79.  short save_target_type=TARGET_RELATIVE;
  80. /*--------------------------- processing ------------------------------*/
  81. #ifdef TRACE
  82.  trace_function("execute.c: execute_change_command");
  83. #endif
  84. /*---------------------------------------------------------------------*/
  85. /* Save the parameters for later...                                    */
  86. /*---------------------------------------------------------------------*/
  87.  if ((save_params = (CHARTYPE *)my_strdup(params)) == NULL)
  88.    {
  89. #ifdef TRACE
  90.     trace_return();
  91. #endif
  92.     return(RC_OUT_OF_MEMORY);
  93.    }
  94. /*---------------------------------------------------------------------*/
  95. /* Validate the parameters that have been supplied. Up to 4 parameters */
  96. /* may be supplied. The first is the string to change and its new      */
  97. /* value, the second is the target, the third is the number of times   */
  98. /* to change the value on one line and lastly is which occurrence to   */
  99. /* change first.                                                       */
  100. /*---------------------------------------------------------------------*/
  101.  initialise_target(&target);
  102.  rc = split_change_params(params,&old_str,&new_str,&target,&long_n,&long_m);
  103.  if (rc != RC_OK)
  104.    {
  105.     free_target(&target);
  106. #ifdef TRACE
  107.     trace_return();
  108. #endif
  109.     return(rc);
  110.    }
  111.  num_lines = target.num_lines;
  112.  true_line = target.true_line;
  113.  if (target.rt == NULL)
  114.     lines_based_on_scope = TRUE;
  115.  else
  116.    {
  117.     lines_based_on_scope = (target.rt[0].target_type == TARGET_BLOCK_CURRENT) ? FALSE : TRUE;
  118.     save_target_type = target.rt[0].target_type;
  119.    }
  120.  free_target(&target);
  121. /*---------------------------------------------------------------------*/
  122. /* Check for any hex strings in both old_str and new_str.              */
  123. /*---------------------------------------------------------------------*/
  124.  if (CURRENT_VIEW->hex)
  125.    {
  126.     if ((len_old_str = convert_hex_strings(old_str)) == (-1))
  127.       {
  128.        display_error(32,old_str,FALSE);
  129.        (*the_free)(save_params);
  130. #ifdef TRACE
  131.        trace_return();
  132. #endif
  133.        return(RC_INVALID_OPERAND);
  134.       }
  135.     if ((len_new_str = convert_hex_strings(new_str)) == (-1))
  136.       {
  137.        display_error(32,new_str,FALSE);
  138.        (*the_free)(save_params);
  139. #ifdef TRACE
  140.        trace_return();
  141. #endif
  142.        return(RC_INVALID_OPERAND);
  143.       }
  144.    }
  145.  else
  146.    {
  147.     len_old_str = strlen((DEFCHAR *)old_str);
  148.     len_new_str = strlen((DEFCHAR *)new_str);
  149.    }
  150. /*---------------------------------------------------------------------*/
  151. /* Save the last change command...                                     */
  152. /*---------------------------------------------------------------------*/
  153.  strcpy((DEFCHAR *)last_change_command,(DEFCHAR *)save_params);
  154.  (*the_free)(save_params);
  155. /*---------------------------------------------------------------------*/
  156. /* If the number of lines is zero, don't make any  changes. Exit with  */
  157. /* no rows changed.                                                    */
  158. /*---------------------------------------------------------------------*/
  159.  if (num_lines == 0L)
  160.    {
  161.     display_error(36,(CHARTYPE *)"",FALSE);
  162. #ifdef TRACE
  163.     trace_return();
  164. #endif
  165.     return(RC_NO_LINES_CHANGED);
  166.    }
  167.  if (num_lines < 0)
  168.    {
  169.     direction = DIRECTION_BACKWARD;
  170.     abs_num_lines = -num_lines;
  171.    }
  172.  else
  173.    {
  174.     direction = DIRECTION_FORWARD;
  175.     abs_num_lines = num_lines;
  176.    }
  177.  
  178.  if (true_line != CURRENT_VIEW->focus_line)
  179.    {
  180.     post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE);
  181. /*  pre_process_line(CURRENT_VIEW,true_line,(LINE *)NULL);*/
  182.    }
  183.  number_lines = 0L;
  184.  number_changes = 0L;
  185.  number_of_changes = 0L;
  186.  number_of_occ = 0L;
  187.  start_col = 0;
  188.  last_true_line = true_line;
  189.  curr = lll_find(CURRENT_FILE->first_line,CURRENT_FILE->last_line,true_line,CURRENT_FILE->number_lines);
  190.  for (i=0L,num_actual_lines=0L;;i++)
  191.    {
  192.     if (lines_based_on_scope)
  193.       {
  194.        if (num_actual_lines == abs_num_lines)
  195.           break;
  196.       }
  197.     else
  198.       {
  199.        if (abs_num_lines == i)
  200.           break;
  201.       }
  202.     rc = processable_line(CURRENT_VIEW,true_line,curr);
  203.     switch(rc)
  204.       {
  205.        case LINE_SHADOW:
  206.             break;
  207. /*       case LINE_TOF_EOF: MH12 */
  208.        case LINE_TOF:
  209.        case LINE_EOF:
  210.             num_actual_lines++;
  211.             break;
  212.        default:
  213.             pre_process_line(CURRENT_VIEW,true_line,curr);
  214.             loc = 0;
  215.             number_of_changes = number_of_occ = 0L;
  216.             while(loc != (-1))
  217.               {
  218.                if (save_target_type == TARGET_BLOCK_CURRENT)
  219.                  {
  220.                   real_end = min(rec_len+len_old_str,MARK_VIEW->mark_end_col-1);
  221.                   real_start = max(start_col,MARK_VIEW->mark_start_col-1);
  222.                  }
  223.                else
  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.  
  229.                if (rec_len < real_start && blank_field(old_str))
  230.                  {
  231.                   loc = 0;
  232.                   rec_len = real_start+1;
  233.                  }
  234.                else
  235.                  {
  236.                   loc = memfind(rec+real_start,old_str,(real_end-real_start+1),
  237.                                 len_old_str,
  238.                                 (CURRENT_VIEW->case_change == CASE_IGNORE) ? TRUE : FALSE,
  239.                                 CURRENT_VIEW->arbchar_status,
  240.                                 CURRENT_VIEW->arbchar_single,
  241.                                 CURRENT_VIEW->arbchar_multiple);
  242.                  }
  243.                if (loc != (-1))
  244.                  {
  245.                   start_col = loc+real_start;
  246.                   if (number_of_changes <= long_n-1 && number_of_occ >= long_m-1)
  247.                     {
  248.                     /* the following block is done for change or confirm of sch */
  249.                      if (!selective)
  250.                        {
  251.                         memdeln(rec,start_col,rec_len,len_old_str);
  252.                         rec_len = (LENGTHTYPE)max((LINETYPE)start_col,(LINETYPE)rec_len - (LINETYPE)len_old_str);
  253.                         meminsmem(rec,new_str,len_new_str,start_col,max_line_length,rec_len);
  254.                         rec_len += len_new_str;
  255.                         if (rec_len > max_line_length)
  256.                           {
  257.                            rec_len = max_line_length;
  258.                            loc = (-1);
  259.                           }
  260.                         start_col += len_new_str;
  261.                         number_changes++;
  262.                         number_of_changes++;
  263.                        }
  264.                      else
  265.                        {
  266.                        /* selective */
  267.                         selective_rc = selective_change(old_str,len_old_str,new_str,len_new_str,
  268.                                                         true_line,last_true_line,start_col);
  269.                         last_true_line = true_line;
  270.                         switch(selective_rc)
  271.                           {
  272.                            case QUITOK:
  273.                            case RC_OK:
  274.                                 start_col += len_new_str;
  275.                                 number_changes++;
  276.                                 number_of_changes++;
  277.                                 if (rec_len > max_line_length)
  278.                                   {
  279.                                    rec_len = max_line_length;
  280.                                    loc = (-1);
  281.                                   }
  282.                                 break;
  283.                            case SKIP:
  284.                                 start_col += len_old_str;
  285.                                 break;
  286.                            case QUIT:
  287.                                 break;
  288.                           }
  289.                         if (selective_rc == QUIT || selective_rc == QUITOK)
  290.                            break;
  291.                        }
  292.                      number_of_occ++;
  293.                     }
  294.                   else
  295.                     {
  296.                      start_col += len_old_str;
  297.                      number_of_occ++;
  298.                     }
  299.                   if (number_of_changes > long_n-1)
  300.         /*          ||  number_of_occ > long_n-1)*/
  301.                      loc = (-1);
  302.                  }
  303.               } /* end while */
  304.             if (number_of_changes != 0L)       /* changes made */
  305.               {
  306.                post_process_line(CURRENT_VIEW,true_line,curr,FALSE);
  307.                number_lines++;
  308.               }
  309.             num_actual_lines++;
  310.             break;
  311.       }
  312.     if (selective_rc == QUIT || selective_rc == QUITOK)
  313.        break;
  314.     start_col = 0;
  315.     if (direction == DIRECTION_FORWARD)
  316.        curr = curr->next;
  317.     else
  318.        curr = curr->prev;
  319.     true_line += (LINETYPE)(direction);
  320.     num_file_lines += (LINETYPE)(direction);
  321.     if (curr == NULL)
  322.        break;
  323.    }
  324. /*---------------------------------------------------------------------*/
  325. /* If no changes were made, display error message and return.          */
  326. /*---------------------------------------------------------------------*/
  327.  if (number_changes == 0L)
  328.    {
  329.     display_error(36,(CHARTYPE *)"",FALSE);
  330.     pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
  331. #ifdef TRACE
  332.     trace_return();
  333. #endif
  334.     return(RC_NO_LINES_CHANGED);
  335.    }
  336. /*---------------------------------------------------------------------*/
  337. /* Increment the alteration count here, once irrespective of the number*/
  338. /* of lines changed.                                                   */
  339. /*---------------------------------------------------------------------*/
  340.  increment_alt(CURRENT_FILE);
  341. /*---------------------------------------------------------------------*/
  342. /* If STAY is OFF, change the current and focus lines by the number    */
  343. /* of lines calculated from the target.                                */
  344. /*---------------------------------------------------------------------*/
  345.  if (selective)
  346.    {
  347.     if (!CURRENT_VIEW->stay)                            /* stay is off */
  348.       {
  349.        CURRENT_VIEW->focus_line = CURRENT_VIEW->current_line = true_line;
  350.       }
  351.     pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
  352.     build_screen(current_screen);
  353.     display_screen(current_screen);
  354.    }
  355.  else
  356.    {
  357.     pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
  358.     resolve_current_and_focus_lines(CURRENT_VIEW,last_true_line,num_file_lines,direction,TRUE,FALSE);
  359.    }
  360.  
  361.  sprintf((DEFCHAR *)message,"%ld occurrence(s) changed on %ld line(s)",number_changes,number_lines);
  362.  display_error(0,message,TRUE);
  363. #ifdef TRACE
  364.  trace_return();
  365. #endif
  366.  if (CURRENT_TOF || CURRENT_BOF)
  367.     return(RC_TOF_EOF_REACHED);
  368.  else
  369.     return(RC_OK);
  370. }
  371. /***********************************************************************/
  372. #ifdef HAVE_PROTO
  373. short selective_change(CHARTYPE *old_str,short len_old_str,CHARTYPE *new_str,
  374.                        short len_new_str,LINETYPE true_line,LINETYPE last_true_line,short start_col)
  375. #else
  376. short selective_change(old_str,len_old_str,new_str,len_new_str,true_line,last_true_line,start_col)
  377. CHARTYPE *old_str;
  378. short len_old_str;
  379. CHARTYPE *new_str;
  380. short len_new_str;
  381. LINETYPE true_line;
  382. LINETYPE last_true_line;
  383. short start_col;
  384. #endif
  385. /***********************************************************************/
  386. {
  387. /*-------------------------- external data ----------------------------*/
  388.  extern LENGTHTYPE rec_len;
  389.  extern CHARTYPE *rec;
  390. /*--------------------------- local data ------------------------------*/
  391.  register short i=0;
  392.  short y=0,x=0,rc=RC_OK;
  393.  int key=0;
  394.  bool changed=FALSE;
  395.  bool line_displayed=FALSE;
  396. /*--------------------------- processing ------------------------------*/
  397. #ifdef TRACE
  398.  trace_function("execute.c: selective_change");
  399. #endif
  400.  
  401.  getyx(CURRENT_WINDOW_FILEAREA,y,x);
  402.                 /* move cursor to old string a la cmatch */
  403.                 /* display message */
  404.                 /* accept key - C next, - N change, - Q to quit */
  405.  
  406.  CURRENT_VIEW->focus_line = true_line;
  407. /*---------------------------------------------------------------------*/
  408. /* Check if the true_line is in the currently displayed window.        */
  409. /* If not, then change the current_line to the true_line.              */
  410. /*---------------------------------------------------------------------*/
  411.  line_displayed = FALSE;
  412.  for (i=0;i<CURRENT_SCREEN.rows[WINDOW_FILEAREA];i++)
  413.    {
  414.     if (CURRENT_SCREEN.sl[i].line_number == true_line
  415.     &&  CURRENT_SCREEN.sl[i].line_type == LINE_LINE)
  416.       {
  417.        line_displayed = TRUE;
  418.        y = i;
  419.        break;
  420.       }
  421.    }
  422.  if (!line_displayed)
  423.    {
  424.     CURRENT_VIEW->current_line = CURRENT_VIEW->focus_line;
  425.     y = CURRENT_VIEW->current_row;
  426.    }
  427.  
  428.  if (start_col >= CURRENT_VIEW->verify_col-1
  429.  &&  start_col <= (CURRENT_SCREEN.cols[WINDOW_FILEAREA]+(CURRENT_VIEW->verify_col-1))-1)
  430.     x = start_col-(CURRENT_VIEW->verify_col-1);
  431.  else
  432.    {
  433.     x = CURRENT_SCREEN.cols[WINDOW_FILEAREA] / 2;
  434.     CURRENT_VIEW->verify_col = max(1,start_col-(short)x);
  435.     x = (start_col-(CURRENT_VIEW->verify_col-1));
  436.    }
  437.  
  438.  key = 0;
  439.  changed = FALSE;
  440.  while(key == 0)
  441.    {
  442.     build_screen(current_screen);
  443.     display_screen(current_screen);
  444.     if (changed)
  445.        display_prompt((CHARTYPE *)"Press 'N' for next,'C' to undo 'Q' to quit");
  446.     else
  447.        display_prompt((CHARTYPE *)"Press 'N' for next,'C' to change 'Q' to quit");
  448.     wmove(CURRENT_WINDOW_FILEAREA,y,x);
  449.     wrefresh(CURRENT_WINDOW_FILEAREA);
  450.  
  451.     key = my_getch(stdscr);
  452.     clear_msgline();
  453.     switch(key)
  454.       {
  455.        case 'N':
  456.        case 'n':
  457.             if (changed)
  458.                rc = RC_OK;
  459.             else
  460.                rc = SKIP;
  461.             break;
  462.        case 'C':
  463.        case 'c':
  464.             if (changed)
  465.               {
  466.                memdeln(rec,start_col,rec_len,len_new_str);
  467.                rec_len -= len_new_str;
  468.                meminsmem(rec,old_str,len_old_str,start_col,max_line_length,rec_len);
  469.                rec_len += len_old_str;
  470.               }
  471.             else
  472.               {
  473.                memdeln(rec,start_col,rec_len,len_old_str);
  474.                rec_len -= len_old_str;
  475.                meminsmem(rec,new_str,len_new_str,start_col,max_line_length,rec_len);
  476.                rec_len += len_new_str;
  477.               }
  478.             changed = (changed) ? FALSE : TRUE;
  479.             key = 0;
  480.             break;
  481.        case 'Q':
  482.        case 'q':
  483.             if (changed)
  484.                rc = QUITOK;
  485.             else
  486.                rc = QUIT;
  487.             break;
  488.        default:
  489.             key = 0;
  490.             break;
  491.       }
  492.    }
  493. #ifdef TRACE
  494.  trace_return();
  495. #endif
  496.  return(rc);
  497. }
  498. /***********************************************************************/
  499. #ifdef HAVE_PROTO
  500. short insert_new_line(CHARTYPE *line,unsigned short len,LINETYPE num_lines,
  501.                       LINETYPE true_line,bool start_left_col,bool make_current,
  502.                       bool inc_alt,CHARTYPE select,bool move_cursor,
  503.                       bool sos_command)
  504. #else
  505. short insert_new_line(line,len,num_lines,true_line,start_left_col,make_current,inc_alt,select,move_cursor,sos_command)
  506. CHARTYPE *line;
  507. unsigned short len;
  508. LINETYPE num_lines;
  509. LINETYPE true_line;
  510. bool start_left_col;
  511. bool make_current;
  512. bool inc_alt;
  513. CHARTYPE select;
  514. bool move_cursor;
  515. bool sos_command;
  516. #endif
  517. /***********************************************************************/
  518. {
  519. /*-------------------------- external data ----------------------------*/
  520.  extern short compatible_feel;
  521. /*--------------------------- local data ------------------------------*/
  522.  register short i=0;
  523.  LINE *curr=NULL,*save_curr=NULL;
  524.  unsigned short x=0,y=0;
  525.  short new_col=0;
  526.  bool on_bottom_of_file=FALSE,on_bottom_of_screen=FALSE;
  527.  short number_focus_rows=0;
  528.  bool leave_cursor=FALSE;
  529.  LINETYPE new_focus_line=0L,new_current_line=0L;
  530. /*--------------------------- processing ------------------------------*/
  531. #ifdef TRACE
  532.  trace_function("execute.c: insert_new_line");
  533. #endif
  534.  if (!CURRENT_VIEW->scope_all)
  535.     true_line = find_last_not_in_scope(CURRENT_VIEW,NULL,true_line,DIRECTION_FORWARD);
  536. /*---------------------------------------------------------------------*/
  537. /* If we are on the 'Bottom of File' line reduce the true_line by 1    */
  538. /* so that the new line is added before the bottom line.               */
  539. /*---------------------------------------------------------------------*/
  540.  if (true_line == CURRENT_FILE->number_lines+1L)
  541.     true_line--;
  542. /*---------------------------------------------------------------------*/
  543. /* Find the current LINE pointer for the true_line.                    */
  544. /* This is the line after which the line(s) are to be added.           */
  545. /*---------------------------------------------------------------------*/
  546.  curr = lll_find(CURRENT_FILE->first_line,CURRENT_FILE->last_line,true_line,CURRENT_FILE->number_lines);
  547. /*---------------------------------------------------------------------*/
  548. /* Insert into the linked list the number of lines specified. All lines*/
  549. /* will contain a blank line and a length of zero.                     */
  550. /*---------------------------------------------------------------------*/
  551.  save_curr = curr;
  552.  for (i=0;i<num_lines;i++)
  553.     {
  554.      if ((curr = add_line(CURRENT_FILE->first_line,curr,line,len,select,TRUE)) == NULL)
  555.        {
  556.         display_error(30,(CHARTYPE *)"",FALSE);
  557. #ifdef TRACE
  558.         trace_return();
  559. #endif
  560.         return(RC_OUT_OF_MEMORY);
  561.        }
  562.     }
  563. /*---------------------------------------------------------------------*/
  564. /* Fix the positioning of the marked block (if there is one and it is  */
  565. /* in the current view) and any pending prefix commands.               */
  566. /*---------------------------------------------------------------------*/
  567.  adjust_marked_lines(TRUE,true_line,num_lines);
  568.  adjust_pending_prefix(CURRENT_VIEW,TRUE,true_line,num_lines);
  569. /*---------------------------------------------------------------------*/
  570. /* Increment the number of lines counter for the current file and the  */
  571. /* number of alterations, only if requested to do so.                  */
  572. /*---------------------------------------------------------------------*/
  573.  if (inc_alt)
  574.     increment_alt(CURRENT_FILE);
  575.  
  576.  CURRENT_FILE->number_lines += num_lines;
  577. /*---------------------------------------------------------------------*/
  578. /* Sort out focus and current line.                                    */
  579. /*---------------------------------------------------------------------*/
  580.  if (move_cursor)
  581.    {
  582.     switch(CURRENT_VIEW->current_window)
  583.       {
  584.        case WINDOW_COMMAND:
  585.             CURRENT_VIEW->focus_line = true_line + 1L;
  586.             if (make_current)
  587.                CURRENT_VIEW->current_line = true_line + 1L;
  588.             pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
  589.             break;
  590.        case WINDOW_FILEAREA:
  591.        case WINDOW_PREFIX:
  592.             build_screen(current_screen);
  593.             getyx(CURRENT_WINDOW,y,x);
  594.             calculate_scroll_values(&number_focus_rows,&new_focus_line,
  595.                                     &new_current_line,
  596.                                     &on_bottom_of_screen,&on_bottom_of_file,
  597.                                     &leave_cursor,DIRECTION_FORWARD);
  598.             new_col = x;
  599.             if (CURRENT_VIEW->current_window == WINDOW_FILEAREA)
  600.               {
  601.                if (!start_left_col)
  602.                  {
  603.                   if (CURRENT_VIEW->newline_aligned)
  604.                     {
  605.                      new_col = memne(save_curr->line,' ',save_curr->length);
  606.                      if (new_col == (-1))
  607.                         new_col = 0;
  608. /*---------------------------------------------------------------------*/
  609. /* Special case when right margin is > than screen width...            */
  610. /*---------------------------------------------------------------------*/
  611.                      if (CURRENT_VIEW->verify_start != CURRENT_VIEW->verify_col)
  612.                        {
  613. /*---------------------------------------------------------------------*/
  614. /* If the new column position will be on the same page...              */
  615. /*---------------------------------------------------------------------*/
  616.                         if (CURRENT_VIEW->verify_col < new_col
  617.                         &&  CURRENT_VIEW->verify_col + CURRENT_SCREEN.screen_cols > new_col)
  618.                            new_col = (new_col - CURRENT_VIEW->verify_col) + 1;
  619.                         else
  620.                           {
  621.                            x = CURRENT_SCREEN.cols[WINDOW_FILEAREA] / 2;
  622.                            CURRENT_VIEW->verify_col = max(1,new_col - (short)x + 2);
  623.                            new_col = (CURRENT_VIEW->verify_col == 1) ? new_col : x - 1;
  624.                           }
  625.                        }
  626.                     }
  627.                   else
  628.                     {
  629.                      new_col = 0;
  630.                      CURRENT_VIEW->verify_col = 1;
  631.                     }
  632.                  }
  633.               }
  634. /*---------------------------------------------------------------------*/
  635. /* Move the cursor to where it should be and display the page.         */
  636. /*---------------------------------------------------------------------*/
  637.             if (on_bottom_of_screen)
  638.               {
  639.                CURRENT_VIEW->current_line = new_current_line;
  640.                CURRENT_VIEW->focus_line = new_focus_line;
  641.                wmove(CURRENT_WINDOW,y-((leave_cursor) ? 0 : 1),new_col);
  642.               }
  643.             else
  644.               {
  645. /*---------------------------------------------------------------------*/
  646. /* We are in the middle of the window, so just move the cursor down    */
  647. /* 1 line.                                                             */
  648. /*---------------------------------------------------------------------*/
  649.               wmove(CURRENT_WINDOW,y+number_focus_rows,new_col);
  650.               CURRENT_VIEW->focus_line = new_focus_line;
  651.               if (compatible_feel == COMPAT_XEDIT
  652.               && !sos_command)
  653.                  CURRENT_VIEW->current_line = new_current_line;
  654.              }
  655.             break;
  656.       }
  657.    }
  658.  pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
  659.  build_screen(current_screen);
  660.  display_screen(current_screen);
  661.  
  662. #ifdef TRACE
  663.  trace_return();
  664. #endif
  665.  return(RC_OK);
  666. }
  667. /***********************************************************************/
  668. #ifdef HAVE_PROTO
  669. short execute_os_command(CHARTYPE *cmd,bool quiet,bool pause)
  670. #else
  671. short execute_os_command(cmd,quiet,pause)
  672. CHARTYPE *cmd;
  673. bool quiet;
  674. bool pause;
  675. #endif
  676. /***********************************************************************/
  677. {
  678. /*-------------------------- external data ----------------------------*/
  679.  extern CHARTYPE *temp_cmd;
  680.  extern bool curses_started;
  681. #ifdef XCURSES
  682.  extern CHARTYPE xterm_program[MAX_FILE_NAME+1];
  683. #endif
  684. /*--------------------------- local data ------------------------------*/
  685. #if defined(DOS) || defined(OS2) || defined(WIN32)
  686. #define SHELL "COMSPEC"
  687. #else
  688. #define SHELL "SHELL"
  689. #endif
  690.  short rc=0;
  691. #ifdef XCURSES
  692.  bool save_curses_started=curses_started;
  693. #endif
  694. /*--------------------------- processing ------------------------------*/
  695. #ifdef TRACE
  696.  trace_function("execute.c: execute_os_command");
  697. #endif
  698.  
  699. #ifdef MSWIN
  700.  quiet = 1;
  701.  pause = 0;
  702. #endif
  703.  
  704. #ifdef XCURSES
  705.  curses_started=FALSE;
  706. #endif
  707.  
  708.  if (!quiet && curses_started)
  709.    {
  710.     attrset(A_NORMAL);
  711. #if 0
  712.     touchwin(stdscr);
  713.     wmove(stdscr,0,0);
  714.     addch(' ');
  715. #else
  716.     clear();
  717. #endif
  718.     wmove(stdscr,1,0);
  719.     wrefresh(stdscr);   /* clear screen */
  720.     suspend_curses();
  721.    }
  722.  if (allocate_temp_space(strlen((DEFCHAR *)cmd),TEMP_TEMP_CMD) != RC_OK)
  723.     {
  724.      display_error(30,(CHARTYPE *)"",FALSE);
  725. #ifdef TRACE
  726.      trace_return();
  727. #endif
  728.      return(RC_OUT_OF_MEMORY);
  729.     }
  730.  if (strcmp((DEFCHAR *)cmd,"") == 0)
  731. #ifdef XCURSES
  732.    {
  733.     strcpy((DEFCHAR *)temp_cmd,(DEFCHAR *)xterm_program);
  734.     strcat((DEFCHAR *)temp_cmd," &");
  735.    }
  736. #else
  737.     strcpy((DEFCHAR *)temp_cmd,getenv(SHELL));
  738. #endif
  739.  else
  740.     strcpy((DEFCHAR *)temp_cmd,(DEFCHAR *)cmd);
  741. #ifdef UNIX
  742.  if (strcmp((DEFCHAR *)temp_cmd,"") == 0)  /* no SHELL env variable set */
  743.    {
  744.     printf("No SHELL environment variable set - using /bin/sh\n");
  745.     fflush(stdout);
  746.     strcpy((DEFCHAR *)temp_cmd,"/bin/sh");
  747.    }
  748. #endif
  749.  if (quiet)
  750.    {
  751. #ifdef UNIX
  752.     strcat((DEFCHAR *)temp_cmd," > /dev/null");
  753. #endif
  754. #if defined(DOS) || defined(OS2) || defined(WIN32)
  755.     strcat((DEFCHAR *)temp_cmd," > nul:");
  756. #endif
  757.    }
  758.  rc = system((DEFCHAR *)temp_cmd);
  759. #ifndef XCURSES
  760.  if (pause)
  761.    {
  762.     printf("\n\n%s",HIT_ANY_KEY);
  763.     fflush(stdout);
  764.    }
  765. #endif
  766.  if (!quiet && curses_started)
  767.    {
  768.     resume_curses();
  769.     if (pause)
  770.        (void)my_getch(stdscr);
  771. #if defined(HAVE_BROKEN_SYSVR4_CURSES)
  772.     {
  773.      short x=0,y=0;
  774.      getyx(CURRENT_WINDOW,y,x);
  775.      force_curses_background();
  776.      wmove(CURRENT_WINDOW,y,x);
  777.      refresh();
  778.     }
  779. #endif
  780.     restore_THE();
  781.    }
  782.  if (curses_started)
  783.     draw_cursor(TRUE);
  784.  
  785. #ifdef XCURSES
  786.  curses_started = save_curses_started;
  787. #endif
  788. #ifdef TRACE
  789.  trace_return();
  790. #endif
  791.  return(rc);
  792. }
  793. /***********************************************************************/
  794. #ifdef HAVE_PROTO
  795. short execute_makecurr(LINETYPE line)
  796. #else
  797. short execute_makecurr(line)
  798. LINETYPE line;
  799. #endif
  800. /***********************************************************************/
  801. {
  802. /*-------------------------- external data ----------------------------*/
  803. /*--------------------------- local data ------------------------------*/
  804.  unsigned short y=0,x=0;
  805. /*--------------------------- processing ------------------------------*/
  806. #ifdef TRACE
  807.  trace_function("execute.c: execute_makecurr");
  808. #endif
  809.  post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE);
  810.  
  811.  CURRENT_VIEW->current_line = line;
  812.  if (CURRENT_VIEW->current_window == WINDOW_PREFIX)
  813.     getyx(CURRENT_WINDOW,y,x);
  814.  else
  815.     getyx(CURRENT_WINDOW_FILEAREA,y,x);
  816.  build_screen(current_screen);
  817.  display_screen(current_screen);
  818.  y = get_row_for_focus_line(current_screen,CURRENT_VIEW->focus_line,
  819.                             CURRENT_VIEW->current_row);
  820.  if (CURRENT_VIEW->current_window == WINDOW_PREFIX)
  821.     wmove(CURRENT_WINDOW,y,x);
  822.  else
  823.     wmove(CURRENT_WINDOW_FILEAREA,y,x);
  824. #ifdef TRACE
  825.  trace_return();
  826. #endif
  827.  return(RC_OK);
  828. }
  829. /***********************************************************************/
  830. #ifdef HAVE_PROTO
  831. short execute_shift_command(short shift_left,short num_cols,LINETYPE true_line,LINETYPE num_lines,bool lines_based_on_scope,short target_type,bool sos)
  832. #else
  833. short execute_shift_command(shift_left,num_cols,true_line,num_lines,lines_based_on_scope,target_type,sos)
  834. short shift_left,num_cols;
  835. LINETYPE true_line,num_lines;
  836. bool lines_based_on_scope;
  837. short target_type;
  838. bool sos;
  839. #endif
  840. /***********************************************************************/
  841. {
  842. /*-------------------------- external data ----------------------------*/
  843.  extern VIEW_DETAILS *vd_mark;
  844.  extern bool curses_started;
  845. /*-------------------------- external data ----------------------------*/
  846.  extern unsigned short trec_len;
  847.  extern CHARTYPE *trec;
  848. /*--------------------------- local data ------------------------------*/
  849.  unsigned short y=0,x=0;
  850.  LINE *curr=NULL;
  851.  LINETYPE abs_num_lines=(num_lines < 0L ? -num_lines : num_lines);
  852.  LINETYPE num_file_lines=0L,i=0L;
  853.  LINETYPE num_actual_lines=0L;
  854.  LENGTHTYPE left_col=0;
  855.  register short j=0;
  856.  short actual_cols=0;
  857.  short rc=RC_OK;
  858.  short direction=(num_lines < 0L ? DIRECTION_BACKWARD : DIRECTION_FORWARD);
  859.  bool adjust_alt=FALSE;
  860. /*--------------------------- processing ------------------------------*/
  861. #ifdef TRACE
  862.  trace_function("execute.c: execute_shift_command");
  863. #endif
  864.  post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE);
  865.  if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
  866.     getyx(CURRENT_WINDOW_FILEAREA,y,x);
  867.  else
  868.     getyx(CURRENT_WINDOW,y,x);
  869.  curr = lll_find(CURRENT_FILE->first_line,CURRENT_FILE->last_line,true_line,CURRENT_FILE->number_lines);
  870.  for (i=0L,num_actual_lines=0L;;i++)
  871.    {
  872.     if (lines_based_on_scope)
  873.       {
  874.        if (num_actual_lines == abs_num_lines)
  875.           break;
  876.       }
  877.     else
  878.       {
  879.        if (abs_num_lines == num_file_lines)
  880.           break;
  881.       }
  882.     rc = processable_line(CURRENT_VIEW,true_line+(LINETYPE)(i*direction),curr);
  883.     switch(rc)
  884.       {
  885.        case LINE_SHADOW:
  886.             break;
  887. /*       case LINE_TOF_EOF: MH12 */
  888.        case LINE_TOF:
  889.        case LINE_EOF:
  890.             num_actual_lines++;
  891.             break;
  892.        default:
  893.             memset(trec,' ',max_line_length);
  894.             memcpy(trec,curr->line,curr->length);
  895.             trec_len = curr->length;
  896.             if (target_type == TARGET_BLOCK_CURRENT)
  897.               {
  898.                if (MARK_VIEW->mark_type == M_LINE)
  899.                   left_col = CURRENT_VIEW->zone_start-1;
  900.                else
  901.                   left_col = MARK_VIEW->mark_start_col-1;
  902.               }
  903.             else
  904.                left_col = CURRENT_VIEW->zone_start-1;
  905.             if (shift_left)
  906.               {
  907.                actual_cols = min(num_cols,max(0,trec_len-left_col));
  908.                memdeln(trec,left_col,trec_len,actual_cols);
  909.                trec_len -= actual_cols;
  910.               }
  911.             else
  912.               {
  913.                for (j=0;j<num_cols;j++)
  914.                   meminschr(trec,' ',left_col,max_line_length,trec_len++);
  915.                trec_len = min(trec_len,max_line_length);
  916.                actual_cols = num_cols;
  917.               }
  918. /*---------------------------------------------------------------------*/
  919. /* Set a flag to cause alteration counts to be incremented.            */
  920. /*---------------------------------------------------------------------*/
  921.             if (actual_cols != 0)
  922.               {
  923.                adjust_alt = TRUE;
  924. /*---------------------------------------------------------------------*/
  925. /* Add the old line contents to the line recovery list.                */
  926. /*---------------------------------------------------------------------*/
  927.                add_to_recovery_list(curr->line,curr->length);
  928. /*---------------------------------------------------------------------*/
  929. /* Realloc the dynamic memory for the line if the line is now longer.  */
  930. /*---------------------------------------------------------------------*/
  931.                if (trec_len > curr->length)
  932.                               /* what if realloc fails ?? */
  933.                   curr->line = (CHARTYPE *)(*the_realloc)((void *)curr->line,(trec_len+1)*sizeof(CHARTYPE));
  934. /*---------------------------------------------------------------------*/
  935. /* Copy the contents of trec into the line.                            */
  936. /*---------------------------------------------------------------------*/
  937.                memcpy(curr->line,trec,trec_len);
  938.                curr->length = trec_len;
  939.                *(curr->line+trec_len) = '\0';
  940.                curr->changed_flag = TRUE;
  941.               }
  942.             num_actual_lines++;
  943.             break;
  944.       }
  945. /*---------------------------------------------------------------------*/
  946. /* Proceed to the next record, even if the current record not in scope.*/
  947. /*---------------------------------------------------------------------*/
  948.     if (direction == DIRECTION_BACKWARD)
  949.        curr = curr->prev;
  950.     else
  951.        curr = curr->next;
  952.     num_file_lines += (LINETYPE)direction;
  953.     if (curr == NULL)
  954.        break;
  955.    }
  956. /*---------------------------------------------------------------------*/
  957. /* Increment the alteration counters once if any line has changed...   */
  958. /*---------------------------------------------------------------------*/
  959.  if (adjust_alt)
  960.     increment_alt(CURRENT_FILE);
  961. /*---------------------------------------------------------------------*/
  962. /* Display the new screen...                                           */
  963. /*---------------------------------------------------------------------*/
  964.  pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
  965.  resolve_current_and_focus_lines(CURRENT_VIEW,true_line,num_file_lines,direction,TRUE,sos);
  966. #if 0
  967.  if (!CURRENT_VIEW->stay                                 /* stay is off */
  968.  &&  num_lines != 0L)
  969.     CURRENT_VIEW->focus_line = CURRENT_VIEW->current_line = true_line+num_lines-(LINETYPE)direction;
  970.  pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
  971.  build_screen(current_screen);
  972.  display_screen(current_screen);
  973.  if (CURRENT_VIEW->current_window != WINDOW_COMMAND
  974.  &&  curses_started)
  975.    {
  976.     getyx(CURRENT_WINDOW,y,x);
  977.     y = get_row_for_focus_line(current_screen,CURRENT_VIEW->focus_line,
  978.                                CURRENT_VIEW->current_row);
  979.     wmove(CURRENT_WINDOW,y,x);
  980.    }
  981. #endif
  982. #ifdef TRACE
  983.  trace_return();
  984. #endif
  985.  if (CURRENT_TOF || CURRENT_BOF)
  986.     return(RC_TOF_EOF_REACHED);
  987.  else
  988.     return(RC_OK);
  989. }
  990. /***********************************************************************/
  991. #ifdef HAVE_PROTO
  992. static bool change_case(CHARTYPE *str,short start,short end,CHARTYPE which_case)
  993. #else
  994. static bool change_case(str,start,end,which_case)
  995. CHARTYPE *str;
  996. short start,end;
  997. CHARTYPE which_case;
  998. #endif
  999. /*---------------------------------------------------------------------*/
  1000. /* Returns TRUE if a lines was changed, FALSE otherwise.               */
  1001. /* This function MUST proceed execute_change_case().                   */
  1002. /***********************************************************************/
  1003. {
  1004. /*-------------------------- external data ----------------------------*/
  1005. /*--------------------------- local data ------------------------------*/
  1006.  register short i=0;
  1007.  bool altered=FALSE;
  1008. /*--------------------------- processing ------------------------------*/
  1009. #ifdef TRACE
  1010.  trace_function("execute.c: change_case");
  1011. #endif
  1012.  for (i=start;i<end+1;i++)
  1013.    {
  1014.     switch(which_case)
  1015.       {
  1016.        case CASE_UPPER:
  1017.                        if (islower(*(str+i)))
  1018.                          {
  1019.                           *(str+i) = toupper(*(str+i));
  1020.                           altered = TRUE;
  1021.                          }
  1022.                        break;
  1023.        case CASE_LOWER:
  1024.                        if (isupper(*(str+i)))
  1025.                          {
  1026.                           *(str+i) = tolower(*(str+i));
  1027.                           altered = TRUE;
  1028.                          }
  1029.                        break;
  1030.       }
  1031.    }
  1032. #ifdef TRACE
  1033.  trace_return();
  1034. #endif
  1035.  return(altered);
  1036. }
  1037. /***********************************************************************/
  1038. #ifdef HAVE_PROTO
  1039. short execute_change_case(CHARTYPE *params,CHARTYPE which_case)
  1040. #else
  1041. short execute_change_case(params,which_case)
  1042. CHARTYPE *params;
  1043. CHARTYPE which_case;
  1044. #endif
  1045. /***********************************************************************/
  1046. {
  1047. /*-------------------------- external data ----------------------------*/
  1048.  extern bool curses_started;
  1049.  extern VIEW_DETAILS *vd_mark;
  1050. /*--------------------------- local data ------------------------------*/
  1051.  LINETYPE num_lines=0L,true_line=0L,num_actual_lines=0L,i=0L,num_file_lines=0L;
  1052.  unsigned short x=0,y=0;
  1053.  short  direction=0;
  1054.  LINE *curr=NULL;
  1055.  LENGTHTYPE start_col=0,end_col=0;
  1056.  short rc=RC_OK;
  1057.  TARGET target;
  1058.  short target_type=TARGET_NORMAL|TARGET_BLOCK_CURRENT|TARGET_ALL;
  1059.  bool lines_based_on_scope=TRUE;
  1060.  bool adjust_alt=FALSE;
  1061. /*--------------------------- processing ------------------------------*/
  1062. #ifdef TRACE
  1063.  trace_function("execute.c: execute_change_case");
  1064. #endif
  1065. /*---------------------------------------------------------------------*/
  1066. /* Validate the parameters that have been supplied.                    */
  1067. /* Valid values are: a target or "block".                              */
  1068. /* If no parameter is supplied, 1 is assumed.                          */
  1069. /*---------------------------------------------------------------------*/
  1070.  if (strcmp("",(DEFCHAR *)params) == 0)
  1071.     params = (CHARTYPE *)"1";
  1072.  initialise_target(&target);
  1073.  if ((rc = validate_target(params,&target,target_type,get_true_line(TRUE),TRUE,TRUE)) != RC_OK)
  1074.    {
  1075.     free_target(&target);
  1076. #ifdef TRACE
  1077.     trace_return();
  1078. #endif
  1079.     return(rc);
  1080.    }
  1081.  post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE);
  1082. /*---------------------------------------------------------------------*/
  1083. /* Determine in which direction we are working.                        */
  1084. /*---------------------------------------------------------------------*/
  1085.  if (target.num_lines < 0L)
  1086.    {
  1087.     direction = DIRECTION_BACKWARD;
  1088.     num_lines = target.num_lines * (-1L);
  1089.    }
  1090.  else
  1091.    {
  1092.     direction = DIRECTION_FORWARD;
  1093.     num_lines = target.num_lines;
  1094.    }
  1095.  true_line = target.true_line;
  1096. /*---------------------------------------------------------------------*/
  1097. /* If the target is BLOCK set the left and right margins to be the     */
  1098. /* margins of the BOX BLOCK, otherwise use ZONE settings.              */
  1099. /*---------------------------------------------------------------------*/
  1100.  start_col = CURRENT_VIEW->zone_start-1;
  1101.  end_col = CURRENT_VIEW->zone_end-1;
  1102.  if (target.rt[0].target_type == TARGET_BLOCK_CURRENT)
  1103.    {
  1104.     num_lines = MARK_VIEW->mark_end_line-MARK_VIEW->mark_start_line+1L;
  1105.     true_line = MARK_VIEW->mark_start_line;
  1106.     direction = DIRECTION_FORWARD;
  1107.     lines_based_on_scope = FALSE;
  1108.     if (MARK_VIEW->mark_type != M_LINE)
  1109.       {
  1110.        start_col = MARK_VIEW->mark_start_col-1;
  1111.        end_col   = MARK_VIEW->mark_end_col-1;
  1112.       }
  1113.    }
  1114. /*---------------------------------------------------------------------*/
  1115. /* Find the current LINE pointer for the true_line.                    */
  1116. /* This is the first line to change.                                   */
  1117. /*---------------------------------------------------------------------*/
  1118.  curr = lll_find(CURRENT_FILE->first_line,CURRENT_FILE->last_line,true_line,CURRENT_FILE->number_lines);
  1119. /*---------------------------------------------------------------------*/
  1120. /* Change the case for the target lines and columns...                 */
  1121. /*---------------------------------------------------------------------*/
  1122.  for (i=0L,num_actual_lines=0L;;i++)
  1123.    {
  1124.     if (lines_based_on_scope)
  1125.       {
  1126.        if (num_actual_lines == num_lines)
  1127.           break;
  1128.       }
  1129.     else
  1130.       {
  1131.        if (num_lines == i)
  1132.           break;
  1133.       }
  1134.     rc = processable_line(CURRENT_VIEW,true_line+(LINETYPE)(i*direction),curr);
  1135.     switch(rc)
  1136.       {
  1137.        case LINE_SHADOW:
  1138.             break;
  1139. /*       case LINE_TOF_EOF: MH12 */
  1140.        case LINE_TOF:
  1141.        case LINE_EOF:
  1142.             num_actual_lines++;
  1143.             break;
  1144.        default:
  1145.             add_to_recovery_list(curr->line,curr->length);
  1146.             if (change_case(curr->line,start_col,min(curr->length-1,end_col),which_case))
  1147.               {
  1148.                adjust_alt = TRUE;
  1149.                curr->changed_flag = TRUE;
  1150.               }
  1151.             num_actual_lines++;
  1152.             break;
  1153.        }
  1154. /*---------------------------------------------------------------------*/
  1155. /* Proceed to the next record, even if the current record not in scope.*/
  1156. /*---------------------------------------------------------------------*/
  1157.      if (direction == DIRECTION_FORWARD)
  1158.         curr = curr->next;
  1159.      else
  1160.         curr = curr->prev;
  1161.      num_file_lines += (LINETYPE)direction;
  1162.      if (curr == NULL)
  1163.         break;
  1164.     }
  1165. /*---------------------------------------------------------------------*/
  1166. /* Increment the alteration counts if any lines changed...             */
  1167. /*---------------------------------------------------------------------*/
  1168.  if (adjust_alt)
  1169.     increment_alt(CURRENT_FILE);
  1170. /*---------------------------------------------------------------------*/
  1171. /* Display the new screen...                                           */
  1172. /*---------------------------------------------------------------------*/
  1173.  pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
  1174.  resolve_current_and_focus_lines(CURRENT_VIEW,true_line,num_file_lines,direction,TRUE,FALSE);
  1175. #ifdef TRACE
  1176.  trace_return();
  1177. #endif
  1178.  if (CURRENT_TOF || CURRENT_BOF)
  1179.     return(RC_TOF_EOF_REACHED);
  1180.  else
  1181.     return(RC_OK);
  1182. }
  1183. /***********************************************************************/
  1184. #ifdef HAVE_PROTO
  1185. short rearrange_line_blocks(CHARTYPE command,CHARTYPE source,
  1186.                             LINETYPE start_line,LINETYPE end_line,LINETYPE dest_line,
  1187.                             short num_occ,VIEW_DETAILS *src_view,VIEW_DETAILS *dst_view,
  1188.                             bool lines_based_on_scope,LINETYPE *lines_affected)
  1189. #else
  1190. short rearrange_line_blocks(command,source,start_line,end_line,dest_line,num_occ,
  1191.                             src_view,dst_view,lines_based_on_scope,lines_affected)
  1192. CHARTYPE command,source;
  1193. LINETYPE start_line,end_line,dest_line;
  1194. short num_occ;
  1195. VIEW_DETAILS *src_view,*dst_view;
  1196. bool lines_based_on_scope;
  1197. LINETYPE *lines_affected;
  1198. #endif
  1199. /***********************************************************************/
  1200. /* Parameters:                                                         */
  1201. /*    command: the command being executed; COPY,DELETE,DUPLICATE,MOVE  */
  1202. /*     source: where the command is executed; COMMAND, PREFIX, BLOCK   */
  1203. /* start_line: the first line (or only line) number to be acted on     */
  1204. /*   end_line: the last line number to be acted on                     */
  1205. /*  dest_line: the destination line for copy,move and duplicate. For   */
  1206. /*             delete this is not applicable.                          */
  1207. /*    num_occ: the number of times to execute the command; only for DUP*/
  1208. /* lines_affected: number of "real" lines affected by copy operation   */
  1209. /***********************************************************************/
  1210. {
  1211. /*-------------------------- external data ----------------------------*/
  1212.  extern bool curses_started;
  1213.  extern VIEW_DETAILS *vd_mark;
  1214.  extern CHARTYPE display_screens;
  1215. /*--------------------------- local data ------------------------------*/
  1216.  register short j=0,k=0;
  1217.  short rc=RC_OK;
  1218.  static unsigned short y=0,x=0;
  1219.  bool dst_inside_src=FALSE,lines_added=FALSE,reset_block=FALSE;
  1220.  bool dest_in_block=FALSE;
  1221.  short  direction=0;
  1222.  LINETYPE num_lines=0L,off=0L,adjust_line=dest_line,num_actual_lines=0L;
  1223.  LINETYPE i=0L,num_pseudo_lines=0L;
  1224.  LINE *curr_src=NULL,*curr_dst=NULL;
  1225.  LINE *save_curr_src=NULL,*save_curr_dst=NULL;
  1226.  FILE_DETAILS *src_file=NULL,*dst_file=NULL;
  1227. /*--------------------------- processing ------------------------------*/
  1228. #ifdef TRACE
  1229.  trace_function("execute.c: rearrange_line_blocks");
  1230. #endif
  1231.  src_file = src_view->file_for_view;
  1232.  dst_file = dst_view->file_for_view;
  1233.  if (source == SOURCE_BLOCK)
  1234.     reset_block = FALSE;
  1235.  else
  1236.     reset_block = TRUE;
  1237. /*---------------------------------------------------------------------*/
  1238. /* This block of commands is for copying lines...                      */
  1239. /*---------------------------------------------------------------------*/
  1240.  switch(command)
  1241.    {
  1242.     case COMMAND_COPY:
  1243.     case COMMAND_OVERLAY_COPY:
  1244.     case COMMAND_MOVE_COPY_SAME:
  1245.     case COMMAND_MOVE_COPY_DIFF:
  1246.     case COMMAND_DUPLICATE:
  1247.          lines_added = TRUE;
  1248.          switch(source)
  1249.            {
  1250.             case SOURCE_BLOCK:
  1251.             case SOURCE_BLOCK_RESET:
  1252.                  if (src_view == dst_view
  1253.                  &&  dest_line >= start_line
  1254.                  &&  dest_line <  end_line)
  1255.                      dest_in_block = TRUE;
  1256.                  break;
  1257.             case SOURCE_PREFIX:
  1258.                  if (dest_line >= start_line
  1259.                  &&  dest_line <  end_line)
  1260.                      dest_in_block = TRUE;
  1261.                  break;
  1262.             default:
  1263.                  break;
  1264.            }
  1265. /*---------------------------------------------------------------------*/
  1266. /* If the destination line is within the marked block then we have to  */
  1267. /* handle the processing of the src_curr pointer differently.          */
  1268. /*---------------------------------------------------------------------*/
  1269.          if (dest_in_block)
  1270.            {
  1271.             dst_inside_src = TRUE;
  1272.             off = dest_line - start_line;
  1273.            }
  1274.          else
  1275.             dst_inside_src = FALSE;
  1276.          num_lines = end_line - start_line + 1L;
  1277.          save_curr_src = lll_find(src_file->first_line,src_file->last_line,start_line,src_file->number_lines);
  1278.          save_curr_dst = lll_find(dst_file->first_line,dst_file->last_line,dest_line,dst_file->number_lines);
  1279.          for (k=0;k<num_occ;k++)
  1280.            {
  1281.             curr_src = save_curr_src;
  1282.             curr_dst = save_curr_dst;
  1283.             for (i=0L,num_actual_lines=0L;;i++)
  1284.                {
  1285.                 if (lines_based_on_scope)
  1286.                   {
  1287.                    if (num_actual_lines == num_lines)
  1288.                       break;
  1289.                   }
  1290.                 else
  1291.                   {
  1292.                    if (num_lines == i)
  1293.                       break;
  1294.                   }
  1295.                 rc = processable_line(src_view,start_line+i,curr_src);
  1296.                 switch(rc)
  1297.                   {
  1298.                    case LINE_SHADOW:
  1299.                         break;
  1300. /*                   case LINE_TOF_EOF: MH12 */
  1301.                    case LINE_TOF:
  1302.                    case LINE_EOF:
  1303.                         num_actual_lines++;
  1304.                         num_pseudo_lines++;
  1305.                         break;
  1306.                    default:
  1307.                         if ((curr_dst = add_line(dst_file->first_line,curr_dst,
  1308.                                         curr_src->line,curr_src->length,
  1309.                                         dst_view->display_low,TRUE)) == NULL)
  1310. /*                                      curr_src->select)) == NULL)*/
  1311.                           {
  1312.                            display_error(30,(CHARTYPE *)"",FALSE);
  1313. #ifdef TRACE
  1314.                            trace_return();
  1315. #endif
  1316.                            return(RC_OUT_OF_MEMORY);
  1317.                           }
  1318. /*---------------------------------------------------------------------*/
  1319. /* If moving lines within the same file, move any line name with the   */
  1320. /* line also.                                                          */
  1321. /*---------------------------------------------------------------------*/
  1322.                           if (command == COMMAND_MOVE_COPY_SAME)
  1323.                             {
  1324.                              if (curr_src->name != (CHARTYPE *)NULL)
  1325.                                {
  1326.                                 curr_dst->name = curr_src->name;
  1327.                                 curr_src->name = (CHARTYPE *)NULL;
  1328.                                }
  1329.                             }
  1330.                           num_actual_lines++;
  1331.                           break;
  1332.                   }
  1333.                    if (dst_inside_src && i == off)
  1334.                       for (j=0;j<off+1;j++)
  1335.                          curr_src = curr_src->next;
  1336.                    curr_src = curr_src->next;
  1337.               }
  1338.             }
  1339.          dst_file->number_lines += (num_actual_lines-num_pseudo_lines)*num_occ;
  1340.          *lines_affected = (num_actual_lines-num_pseudo_lines)*num_occ;
  1341.          break;
  1342.     default:
  1343.          break;
  1344.    }
  1345. /*---------------------------------------------------------------------*/
  1346. /* This block of commands is for deleting lines...                     */
  1347. /*---------------------------------------------------------------------*/
  1348.  switch(command)
  1349.    {
  1350.     case COMMAND_DELETE:
  1351.     case COMMAND_OVERLAY_DELETE:
  1352.     case COMMAND_MOVE_DELETE_SAME:
  1353.     case COMMAND_MOVE_DELETE_DIFF:
  1354.          lines_added = FALSE;
  1355.          if (start_line > end_line)
  1356.            {
  1357.             direction = DIRECTION_BACKWARD;
  1358.             num_lines = start_line - end_line + 1L;
  1359.            }
  1360.          else
  1361.            {
  1362.             direction = DIRECTION_FORWARD;
  1363.             num_lines = end_line - start_line + 1L;
  1364.            }
  1365.          curr_dst = lll_find(dst_file->first_line,dst_file->last_line,start_line,dst_file->number_lines);
  1366.          for (i=0L,num_actual_lines=0L;;i++)
  1367.            {
  1368.             if (lines_based_on_scope)
  1369.               {
  1370.                if (num_actual_lines == num_lines)
  1371.                   break;
  1372.               }
  1373.             else
  1374.               {
  1375.                if (num_lines == i)
  1376.                   break;
  1377.               }
  1378.             rc = processable_line(dst_view,start_line+i,curr_dst);
  1379.             switch(rc)
  1380.               {
  1381. /*               case LINE_TOF_EOF: MH12 */
  1382.                case LINE_TOF:
  1383.                case LINE_EOF:
  1384.                     num_actual_lines++; /* this is meant to fall through */
  1385.                     num_pseudo_lines++;
  1386.                case LINE_SHADOW:
  1387.                     if (direction == DIRECTION_FORWARD)
  1388.                        curr_dst = curr_dst->next;
  1389.                     else
  1390.                        curr_dst = curr_dst->prev;
  1391.                     break;
  1392.                default:
  1393.                     if (command != COMMAND_MOVE_DELETE_SAME)
  1394.                        add_to_recovery_list(curr_dst->line,curr_dst->length);
  1395.                     curr_dst = delete_line(dst_file->first_line,curr_dst,direction);
  1396.                     num_actual_lines++;
  1397.               }
  1398.             if (curr_dst == NULL)
  1399.                break;
  1400.            }
  1401.          dst_file->number_lines -= (num_actual_lines-num_pseudo_lines)*num_occ;
  1402.          break;
  1403.     default:
  1404.          break;
  1405.    }
  1406. /*---------------------------------------------------------------------*/
  1407. /* Increment alteration count for all but COMMAND_MOVE_COPY_SAME...    */
  1408. /*---------------------------------------------------------------------*/
  1409.  if (command != COMMAND_MOVE_COPY_SAME
  1410.  &&  command != COMMAND_OVERLAY_COPY
  1411.  &&  (num_actual_lines-num_pseudo_lines) != 0)
  1412.     increment_alt(dst_file);
  1413. /*---------------------------------------------------------------------*/
  1414. /* This block of commands is for sorting out cursor position...        */
  1415. /*---------------------------------------------------------------------*/
  1416.  if (curses_started)
  1417.     getyx(CURRENT_WINDOW,y,x);
  1418.  switch(command)
  1419.    {
  1420.     case COMMAND_COPY:
  1421.     case COMMAND_OVERLAY_COPY:
  1422.     case COMMAND_MOVE_COPY_SAME:
  1423.     case COMMAND_MOVE_COPY_DIFF:
  1424.     case COMMAND_DUPLICATE:
  1425.          if (source == SOURCE_COMMAND
  1426.          &&  CURRENT_VIEW->current_window == WINDOW_COMMAND
  1427.          &&  CURRENT_VIEW->stay)
  1428.              break;
  1429. #if PRE_23_BEHAVIOUR
  1430.          if (IN_VIEW(dst_view,dest_line))
  1431.            {
  1432.             dst_view->focus_line = dest_line+1L;
  1433.            }
  1434.          if (dst_view->current_window != WINDOW_COMMAND
  1435.          &&  dst_view == CURRENT_SCREEN.screen_view)
  1436.            {
  1437.             if (y == CURRENT_SCREEN.rows[WINDOW_FILEAREA]-1)/* on bottom line of window */
  1438.               {
  1439.                dst_view->current_line = dst_view->focus_line;
  1440.                y = dst_view->current_row;
  1441.               }
  1442.             else
  1443.                y = get_row_for_focus_line(current_screen,dst_view->focus_line,
  1444.                                           dst_view->current_row);
  1445.            }
  1446. #else
  1447.          if (command == COMMAND_DUPLICATE)
  1448.            {
  1449.             dst_view->focus_line = dest_line+1L;
  1450.             if (dst_view == CURRENT_SCREEN.screen_view)
  1451.               {
  1452.                unsigned short last_focus_row=0;
  1453.                find_last_focus_line(&last_focus_row);
  1454.                if (dest_line >= CURRENT_SCREEN.sl[last_focus_row].line_number)
  1455.                  {
  1456.                   dst_view->current_line = dst_view->focus_line;
  1457.                   y = dst_view->current_row;
  1458.                  }
  1459.                else
  1460.                  {
  1461.                   y = get_row_for_focus_line(current_screen,dst_view->focus_line,
  1462.                                              dst_view->current_row);
  1463.                  }
  1464.               }
  1465.            }
  1466.          else
  1467.            {
  1468.             if (IN_VIEW(dst_view,dest_line))
  1469.               {
  1470.                dst_view->focus_line = dest_line+1L;
  1471.               }
  1472.             if (dst_view->current_window != WINDOW_COMMAND
  1473.             &&  dst_view == CURRENT_SCREEN.screen_view)
  1474.               {
  1475.                unsigned short last_focus_row=0;
  1476.                find_last_focus_line(&last_focus_row);
  1477.                if (y == last_focus_row)
  1478.                  {
  1479.                   dst_view->current_line = dst_view->focus_line;
  1480.                   y = dst_view->current_row;
  1481.                  }
  1482.                else
  1483.                   y = get_row_for_focus_line(current_screen,dst_view->focus_line,
  1484.                                              dst_view->current_row);
  1485.               }
  1486.            }
  1487. #endif
  1488.          break;
  1489.     case COMMAND_DELETE:
  1490.     case COMMAND_OVERLAY_DELETE:
  1491.     case COMMAND_MOVE_DELETE_SAME:
  1492.     case COMMAND_MOVE_DELETE_DIFF:
  1493.          if (dst_view->focus_line >= start_line
  1494.          &&  dst_view->focus_line <= end_line)
  1495.            {
  1496.             if (IN_VIEW(dst_view,dest_line))
  1497.               {
  1498.                if (dst_view->current_line > dst_file->number_lines+1L)
  1499.                  {
  1500. #if 0
  1501.                   dst_view->current_line -= (num_actual_lines-num_pseudo_lines);
  1502. #else
  1503.                   /*
  1504.                    * This is better than before, but the cursor still ends up NOT on the
  1505.                    * focus line ?????
  1506.                    */
  1507.                   dst_view->current_line = dst_file->number_lines+1L;
  1508. /*                dst_view->focus_line = dst_view->current_line; */
  1509.                   dst_view->focus_line = dest_line;
  1510. #endif
  1511.                  }
  1512.                else
  1513.                   dst_view->focus_line = dest_line;
  1514.               }
  1515.             else
  1516.               {
  1517.                if (dest_line > dst_file->number_lines)
  1518.                   dst_view->focus_line = dst_view->current_line = dst_file->number_lines;
  1519.                else
  1520.                   dst_view->focus_line = dst_view->current_line = dest_line;
  1521.               }
  1522.            }
  1523.          else
  1524.            {
  1525.             dest_line = (dst_view->focus_line < start_line ? dst_view->focus_line : dst_view->focus_line - num_lines);
  1526.             if (IN_VIEW(dst_view,dest_line))
  1527.               {
  1528.                if (dst_view->current_line > dst_file->number_lines+1L)
  1529.                   dst_view->current_line -= (num_actual_lines-num_pseudo_lines);
  1530.                dst_view->focus_line = dest_line;
  1531.               }
  1532.             else
  1533.               {
  1534.                if (dest_line > dst_file->number_lines)
  1535.                   dst_view->focus_line = dst_view->current_line = dst_file->number_lines;
  1536.                else
  1537.                   dst_view->focus_line = dst_view->current_line = dest_line;
  1538.               }
  1539.            }
  1540.          if (dst_file->number_lines == 0L)
  1541.                dst_view->focus_line = dst_view->current_line = 0L;
  1542.          if (dst_view->current_window != WINDOW_COMMAND
  1543.          &&  dst_view == CURRENT_SCREEN.screen_view)
  1544.            {
  1545.             build_screen(current_screen); /* MH */
  1546.             y = get_row_for_focus_line(current_screen,dst_view->focus_line,
  1547.                                        dst_view->current_row);
  1548.            }
  1549. /*---------------------------------------------------------------------*/
  1550. /* This is set here so that the adjust_pending_prefix command will work*/
  1551. /*---------------------------------------------------------------------*/
  1552.          if (direction == DIRECTION_BACKWARD)
  1553.             adjust_line = end_line;
  1554.          else
  1555.             adjust_line = start_line;
  1556.          dst_view->current_line = find_next_in_scope(dst_view,NULL,dst_view->current_line,DIRECTION_FORWARD);
  1557.          break;
  1558.     default:
  1559.          break;
  1560.    }
  1561. /*---------------------------------------------------------------------*/
  1562. /* This block of commands is for adjusting prefix and block lines...   */
  1563. /*---------------------------------------------------------------------*/
  1564.  switch(source)
  1565.    {
  1566.     case SOURCE_BLOCK:
  1567.     case SOURCE_BLOCK_RESET:
  1568.          adjust_pending_prefix(dst_view,lines_added,adjust_line,(num_actual_lines-num_pseudo_lines)*num_occ);
  1569.          if (command == COMMAND_MOVE_DELETE_SAME)
  1570.             adjust_marked_lines(lines_added,adjust_line,(num_actual_lines-num_pseudo_lines)*num_occ);
  1571.          else
  1572.             switch(command)
  1573.               {
  1574.                case COMMAND_MOVE_DELETE_DIFF:
  1575.                     src_view->marked_line = src_view->marked_col = FALSE;
  1576.                     break;
  1577.                case COMMAND_OVERLAY_DELETE:
  1578.                     break;
  1579.                default:
  1580.                     if (command == COMMAND_COPY
  1581.                     &&  src_view != dst_view)
  1582.                        src_view->marked_line = src_view->marked_col = FALSE;
  1583. /*---------------------------------------------------------------------*/
  1584. /* The following does a 'reset block' in the current view.             */
  1585. /*---------------------------------------------------------------------*/
  1586.                     if (reset_block)
  1587.                       {
  1588.                        dst_view->marked_line = dst_view->marked_col = FALSE;
  1589.                        MARK_VIEW = (VIEW_DETAILS *)NULL;
  1590.                       }
  1591.                     else
  1592.                       {
  1593.                        if (command == COMMAND_OVERLAY_DELETE)
  1594.                           dst_view->mark_start_line = dest_line;
  1595.                        else
  1596.                           dst_view->mark_start_line = dest_line + 1L;
  1597.                        dst_view->mark_end_line = dest_line + (num_actual_lines-num_pseudo_lines);
  1598.                        dst_view->marked_col = FALSE;
  1599.                        dst_view->mark_type = M_LINE;
  1600.                        dst_view->focus_line = dst_view->mark_start_line;
  1601.                        MARK_VIEW = dst_view;
  1602.                       }
  1603.                     break;
  1604.               }
  1605.          break;
  1606.     case SOURCE_PREFIX:
  1607.     case SOURCE_COMMAND:
  1608.          adjust_marked_lines(lines_added,adjust_line,(num_actual_lines-num_pseudo_lines)*num_occ);
  1609.          adjust_pending_prefix(dst_view,lines_added,adjust_line,(num_actual_lines-num_pseudo_lines)*num_occ);
  1610.          break;
  1611.    }
  1612.  if (command != COMMAND_MOVE_DELETE_DIFF)
  1613.     pre_process_line(CURRENT_VIEW,dst_view->focus_line,(LINE *)NULL);
  1614.  if ((source == SOURCE_BLOCK
  1615.  ||   source == SOURCE_BLOCK_RESET)
  1616.  && display_screens > 1)
  1617.    {
  1618.     build_screen(other_screen);
  1619.     display_screen(other_screen);
  1620.    }
  1621.  if (command != COMMAND_MOVE_DELETE_DIFF
  1622.  &&  command != COMMAND_MOVE_COPY_SAME
  1623.  &&  command != COMMAND_OVERLAY_COPY
  1624.  &&  command != COMMAND_OVERLAY_DELETE)
  1625.    {
  1626.     build_screen(current_screen);
  1627.     display_screen(current_screen);
  1628.    }
  1629.  if (dst_view->current_window != WINDOW_COMMAND
  1630.  &&  dst_view == CURRENT_SCREEN.screen_view)
  1631.    {
  1632.     if (curses_started)
  1633.        wmove(CURRENT_WINDOW,y,x);
  1634.    }
  1635. #ifdef TRACE
  1636.  trace_return();
  1637. #endif
  1638.  return(RC_OK);
  1639. }
  1640. /***********************************************************************/
  1641. #ifdef HAVE_PROTO
  1642. short execute_set_point(CHARTYPE *name,LINETYPE true_line,bool point_on)
  1643. #else
  1644. short execute_set_point(name,true_line,point_on)
  1645. CHARTYPE *name;
  1646. LINETYPE true_line;
  1647. bool point_on;
  1648. #endif
  1649. /***********************************************************************/
  1650. /* Parameters:                                                         */
  1651. /*       name: the name of the line to be processed                    */
  1652. /*  true_line: the line number of the line                             */
  1653. /*   point_on: indicates if the line name is to be turned on or off    */
  1654. /***********************************************************************/
  1655. {
  1656. /*-------------------------- external data ----------------------------*/
  1657. /*--------------------------- local data ------------------------------*/
  1658.  LINE *curr=NULL;
  1659.  LINETYPE dummy=0L;
  1660. /*--------------------------- processing ------------------------------*/
  1661. #ifdef TRACE
  1662.  trace_function("execute.c: execute_set_point");
  1663. #endif
  1664.  if (point_on)
  1665.    {
  1666. /*---------------------------------------------------------------------*/
  1667. /* Find a line that already has the same name. If one exists, remove   */
  1668. /* the name.                                                           */
  1669. /*---------------------------------------------------------------------*/
  1670.     if ((curr = find_named_line(name,&dummy,FALSE)) != (LINE *)NULL)
  1671.       {
  1672.        (*the_free)(curr->name);
  1673.        curr->name = (CHARTYPE *)NULL;
  1674.       }
  1675. /*---------------------------------------------------------------------*/
  1676. /* Allocate space for the name and attach it to the true_line.         */
  1677. /*---------------------------------------------------------------------*/
  1678.     curr = lll_find(CURRENT_FILE->first_line,CURRENT_FILE->last_line,true_line,CURRENT_FILE->number_lines);
  1679.     if ((curr->name=(CHARTYPE *)(*the_malloc)(strlen((DEFCHAR *)name)+1)) == NULL)
  1680.       {
  1681.        display_error(30,(CHARTYPE *)"",FALSE);
  1682. #ifdef TRACE
  1683.        trace_return();
  1684. #endif
  1685.        return(RC_OUT_OF_MEMORY);
  1686.       }
  1687.     strcpy((DEFCHAR *)curr->name,(DEFCHAR *)name);
  1688.    }
  1689.  else
  1690.    {
  1691. /*---------------------------------------------------------------------*/
  1692. /* Find a line that already has the same name. If one exists, remove   */
  1693. /* the name otherwise display an error.                                */
  1694. /*---------------------------------------------------------------------*/
  1695.     if ((curr = find_named_line(name,&dummy,FALSE)) != (LINE *)NULL)
  1696.       {
  1697.        (*the_free)(curr->name);
  1698.        curr->name = (CHARTYPE *)NULL;
  1699.       }
  1700.     else
  1701.       {
  1702.        display_error(60,name,FALSE);
  1703. #ifdef TRACE
  1704.        trace_return();
  1705. #endif
  1706.        return(RC_INVALID_OPERAND);
  1707.       }
  1708.    }
  1709.  
  1710. #ifdef TRACE
  1711.  trace_return();
  1712. #endif
  1713.  return(RC_OK);
  1714. }
  1715. /***********************************************************************/
  1716. #ifdef HAVE_PROTO
  1717. short execute_wrap_word(unsigned short col)
  1718. #else
  1719. short execute_wrap_word(col)
  1720. unsigned short col;
  1721. #endif
  1722. /***********************************************************************/
  1723. /* Parameters: col   - current column position within rec              */
  1724. /***********************************************************************/
  1725. {
  1726. /*-------------------------- external data ----------------------------*/
  1727.  extern bool INSERTMODEx;
  1728.  extern LENGTHTYPE rec_len;
  1729.  extern CHARTYPE *rec;
  1730. /*--------------------------- local data ------------------------------*/
  1731.  register short i=0;
  1732.  short col_break=0,cursor_offset=0;
  1733.  LINE *curr=NULL,*next_line=NULL;
  1734.  bool newline=FALSE,cursor_wrap=FALSE;
  1735.  CHARTYPE *buf=NULL,*word_to_wrap=NULL;
  1736.  short next_line_start=0,length_word=0,last_col=0;
  1737.  short rc=RC_OK;
  1738. /*--------------------------- processing ------------------------------*/
  1739. #ifdef TRACE
  1740.  trace_function("execute.c: execute_wrap_word");
  1741. #endif
  1742. /*---------------------------------------------------------------------*/
  1743. /* This function is called when the length of the focus line exceeds   */
  1744. /* the right margin. If the cursor is positioned in the last word of   */
  1745. /* the line, the cursor moves with that word to the next line.         */
  1746. /* If the combined length of the word to be wrapped and a space and the*/
  1747. /* line following the focus line exceeds the right margin, a new line  */
  1748. /* is inserted with the word being wrapped, otherwise the word to be   */
  1749. /* wrapped is prepended to the following line.                         */
  1750. /*---------------------------------------------------------------------*/
  1751. /*---------------------------------------------------------------------*/
  1752. /* Find the current LINE pointer for the focus_line.                   */
  1753. /*---------------------------------------------------------------------*/
  1754.  curr = lll_find(CURRENT_FILE->first_line,CURRENT_FILE->last_line,CURRENT_VIEW->focus_line,CURRENT_FILE->number_lines);
  1755. /*---------------------------------------------------------------------*/
  1756. /* Determine where to start splitting the line in relation to end of   */
  1757. /* line...                                                             */
  1758. /*---------------------------------------------------------------------*/
  1759.  col_break = memreveq(rec,' ',rec_len);
  1760. /*---------------------------------------------------------------------*/
  1761. /* If there is no word break, don't attempt any wrap.                  */
  1762. /*---------------------------------------------------------------------*/
  1763.  if (col_break == (-1))
  1764.    {
  1765. #ifdef TRACE
  1766.     trace_return();
  1767. #endif
  1768.     return(RC_OK);
  1769.    }
  1770. /*---------------------------------------------------------------------*/
  1771. /* Actual column to break on is 1 character to right of last space.    */
  1772. /*---------------------------------------------------------------------*/
  1773.  col_break++;
  1774. /*---------------------------------------------------------------------*/
  1775. /* Make a null terminated string out of current line so we can grab the*/
  1776. /* word to be wrapped.                                                 */
  1777. /*---------------------------------------------------------------------*/
  1778.  rec[rec_len] = '\0';
  1779. /*---------------------------------------------------------------------*/
  1780. /* Point to word to wrap and determine its length.                     */
  1781. /*---------------------------------------------------------------------*/
  1782.  length_word = rec_len - col_break;
  1783.  word_to_wrap = (CHARTYPE *)rec+col_break;
  1784. /*---------------------------------------------------------------------*/
  1785. /* If the position of the cursor is before the word to wrap leave the  */
  1786. /* cursor where it is.                                                 */
  1787. /*---------------------------------------------------------------------*/
  1788.  if (col >= col_break)
  1789.    {
  1790.     cursor_wrap = TRUE;
  1791.     cursor_offset = col - col_break - 1;
  1792.    }
  1793.  else
  1794.     cursor_wrap = FALSE;
  1795. /*---------------------------------------------------------------------*/
  1796. /* Now we have to work out if a new line is to added or we prepend to  */
  1797. /* the following line...                                               */
  1798. /*---------------------------------------------------------------------*/
  1799.  if (curr->next->next == NULL)             /* next line bottom of file */
  1800.     newline = TRUE;
  1801.  else
  1802.    {
  1803.     next_line = curr->next;
  1804.     if (!in_scope(CURRENT_VIEW,next_line))
  1805.        newline = TRUE;
  1806.     else
  1807.       {
  1808.        next_line_start = memne(next_line->line,' ',next_line->length);
  1809.        if (next_line_start != CURRENT_VIEW->margin_left-1) /* next line doesn't start in left margin */
  1810.           newline = TRUE;
  1811.        else
  1812.          {
  1813.           if (next_line->length + length_word + 1 > CURRENT_VIEW->margin_right)
  1814.              newline = TRUE;
  1815.          }
  1816.       }
  1817.    }
  1818. /*---------------------------------------------------------------------*/
  1819. /* Save the word to be wrapped...                                      */
  1820. /*---------------------------------------------------------------------*/
  1821.  buf = (CHARTYPE *)(*the_malloc)(length_word+CURRENT_VIEW->margin_left);
  1822.  if (buf == NULL)
  1823.    {
  1824.     display_error(30,(CHARTYPE *)"",FALSE);
  1825. #ifdef TRACE
  1826.     trace_return();
  1827. #endif
  1828.     return(RC_OUT_OF_MEMORY);
  1829.    }
  1830.  memcpy(buf,word_to_wrap,length_word);
  1831. /*---------------------------------------------------------------------*/
  1832. /* Remove the word to be wrapped from the focus line buffer; rec...    */
  1833. /*---------------------------------------------------------------------*/
  1834.  for (i=col_break;i<rec_len+1;i++)
  1835.     rec[i] = ' ';
  1836.  last_col = memrevne(rec,' ',max_line_length);
  1837.  rec_len = (last_col == (-1)) ? 0 : last_col + 1;
  1838. /*---------------------------------------------------------------------*/
  1839. /* We now should know if a new line is to added or not.                */
  1840. /*---------------------------------------------------------------------*/
  1841.  if (newline)
  1842.    {
  1843.     for (i=0;i<CURRENT_VIEW->margin_left-1;i++)
  1844.        (void)meminschr(buf,' ',0,max_line_length,i+length_word);
  1845.     curr = add_line(CURRENT_FILE->first_line,curr,buf,length_word+CURRENT_VIEW->margin_left-1,curr->select,TRUE);
  1846.     CURRENT_FILE->number_lines++;
  1847.    }
  1848.  else
  1849.    {
  1850.     post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE);
  1851.     pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line+1L,(LINE *)NULL);
  1852.     (void)meminschr(rec,' ',CURRENT_VIEW->margin_left-1,max_line_length,rec_len++);
  1853.     (void)meminsmem(rec,buf,length_word,CURRENT_VIEW->margin_left-1,
  1854.                     max_line_length,rec_len);
  1855.     rec_len += length_word;
  1856.     post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line+1L,(LINE *)NULL,TRUE);
  1857.     pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
  1858.    }
  1859.  (*the_free)(buf);
  1860. /*---------------------------------------------------------------------*/
  1861. /* We now should know if the cursor is to wrap or stay where it is.    */
  1862. /*---------------------------------------------------------------------*/
  1863.  if (cursor_wrap)
  1864.    {
  1865.     post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE);
  1866.     build_screen(current_screen);
  1867.     cursor_down(TRUE);
  1868.     rc = Sos_firstchar((CHARTYPE *)"");
  1869.     for (i=0;i<cursor_offset+1;i++)
  1870.        rc = cursor_right(TRUE,FALSE);
  1871.    }
  1872.  else
  1873.    {
  1874.     if (INSERTMODEx)
  1875.        rc = cursor_right(TRUE,FALSE);
  1876.    }
  1877.  build_screen(current_screen);
  1878.  display_screen(current_screen);
  1879.  
  1880. #ifdef TRACE
  1881.  trace_return();
  1882. #endif
  1883.  return(rc);
  1884. }
  1885. /***********************************************************************/
  1886. #ifdef HAVE_PROTO
  1887. short execute_split_join(short action,bool aligned,bool cursorarg)
  1888. #else
  1889. short execute_split_join(action,aligned,cursorarg)
  1890. short action;
  1891. bool aligned;
  1892. bool cursorarg;
  1893. #endif
  1894. /***********************************************************************/
  1895. /* Parameters: action  - split, join or spltjoin                       */
  1896. /*             aligned - whether to align text or not                  */
  1897. /*             cursor  - whether to split focus line at cursor or      */
  1898. /*                       command line at current column                */
  1899. /***********************************************************************/
  1900. {
  1901. /*-------------------------- external data ----------------------------*/
  1902.  extern LENGTHTYPE rec_len;
  1903.  extern CHARTYPE *rec;
  1904.  extern bool curses_started;
  1905.  extern short compatible_feel;
  1906. /*--------------------------- local data ------------------------------*/
  1907.  register short i=0;
  1908.  short num_cols=0,num_blanks_focus=0,num_blanks_next=0;
  1909.  unsigned short x=0,y=0;
  1910.  LINE *curr=NULL;
  1911.  LINETYPE true_line=0L;
  1912.  LENGTHTYPE col=0;
  1913. /*--------------------------- processing ------------------------------*/
  1914. #ifdef TRACE
  1915.  trace_function("execute.c: execute_split_join");
  1916. #endif
  1917. /*---------------------------------------------------------------------*/
  1918. /* Determine line and column to use.                                   */
  1919. /*---------------------------------------------------------------------*/
  1920.  if (CURRENT_VIEW->current_window == WINDOW_COMMAND
  1921.  ||  cursorarg == FALSE)
  1922.    {
  1923.     col = CURRENT_VIEW->current_column-1;
  1924.     true_line = CURRENT_VIEW->current_line;
  1925.    }
  1926.  else
  1927.    {
  1928.     if (curses_started)
  1929.       {
  1930.        getyx(CURRENT_WINDOW_FILEAREA,y,x);
  1931.        col = (x+CURRENT_VIEW->verify_col-1);
  1932.        true_line = CURRENT_VIEW->focus_line;
  1933.       }
  1934.     else
  1935.       {
  1936.        col = 0;
  1937.        true_line = CURRENT_VIEW->current_line;
  1938.       }
  1939.    }
  1940. /*---------------------------------------------------------------------*/
  1941. /* Reject the command if true_line is top or bottom of file.           */
  1942. /*---------------------------------------------------------------------*/
  1943.  if (VIEW_TOF(CURRENT_VIEW,true_line) || VIEW_BOF(CURRENT_VIEW,true_line))
  1944.    {
  1945.     display_error(38,(CHARTYPE *)"",FALSE);
  1946. #ifdef TRACE
  1947.     trace_return();
  1948. #endif
  1949.     return(RC_INVALID_ENVIRON);
  1950.    }
  1951. /*---------------------------------------------------------------------*/
  1952. /* If this function called from SPLTJOIN(), then determine if SPLIT    */
  1953. /* or JOIN is required.                                                */
  1954. /*---------------------------------------------------------------------*/
  1955.  if (action == SPLTJOIN_SPLTJOIN)
  1956.     action = (col >= rec_len) ? SPLTJOIN_JOIN : SPLTJOIN_SPLIT;
  1957. /*---------------------------------------------------------------------*/
  1958. /* Copy any changes in the focus line to the linked list.              */
  1959. /*---------------------------------------------------------------------*/
  1960.  post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE);
  1961. /*---------------------------------------------------------------------*/
  1962. /* Find the current LINE pointer for the true line.                    */
  1963. /*---------------------------------------------------------------------*/
  1964.  curr = lll_find(CURRENT_FILE->first_line,CURRENT_FILE->last_line,true_line,CURRENT_FILE->number_lines);
  1965.  
  1966.  getyx(CURRENT_WINDOW,y,x);
  1967.  switch(action)
  1968.    {
  1969.     case SPLTJOIN_SPLIT:
  1970.          memset(rec,' ',max_line_length);
  1971.          if (col < curr->length)
  1972.            {
  1973.             memcpy(rec,curr->line+col,curr->length-col);
  1974.             rec_len = curr->length-col;
  1975.            }
  1976.          else
  1977.             rec_len = 0;
  1978.          curr->changed_flag = TRUE;
  1979. /*---------------------------------------------------------------------*/
  1980. /* Calculate the number of leading blanks on the current line so that  */
  1981. /* the new line can have this many blanks prepended to align properly. */
  1982. /*---------------------------------------------------------------------*/
  1983.          if (aligned)
  1984.            {
  1985.             num_cols = memne(curr->line,' ',curr->length);
  1986.             if (num_cols == (-1))
  1987.                num_cols = 0;
  1988.             for (i=0;i<num_cols;i++)
  1989.                meminschr(rec,' ',0,max_line_length,rec_len++);
  1990.             rec_len = min(rec_len,max_line_length);
  1991.            }
  1992.          add_line(CURRENT_FILE->first_line,curr,(rec),rec_len,curr->select,TRUE);
  1993.          CURRENT_FILE->number_lines++;
  1994.          if (CURRENT_VIEW->current_window == WINDOW_COMMAND
  1995.          ||  cursorarg == FALSE)
  1996.            {
  1997.             if (curr->length > col)
  1998.               {
  1999.                curr->length = col;
  2000.                *(curr->line+(col)) = '\0';
  2001.                increment_alt(CURRENT_FILE);
  2002.               }
  2003.             pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
  2004.            }
  2005.          else
  2006.            {
  2007.             pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
  2008.             Sos_delend((CHARTYPE *)"");
  2009.             post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE);
  2010.            }
  2011.          break;
  2012.     case SPLTJOIN_JOIN:
  2013.          if (curr->next->next == NULL)
  2014.            {
  2015. /*---------------------------------------------------------------------*/
  2016. /* Trying to join with the bottom of file line.                        */
  2017. /*---------------------------------------------------------------------*/
  2018. #ifdef TRACE
  2019.            trace_return();
  2020. #endif
  2021.            return(RC_INVALID_ENVIRON);
  2022.           }
  2023. /*---------------------------------------------------------------------*/
  2024. /* Calculate the number of leading blanks for the focus line and also  */
  2025. /* for the line to be joined. To align the join properly, we have to   */
  2026. /* remove up the number of leading blanks in the focus line from the   */
  2027. /* beginning of the line to be joined.                                 */
  2028. /*---------------------------------------------------------------------*/
  2029.          if (aligned)
  2030.            {
  2031.             num_blanks_focus = memne(curr->line,' ',curr->length);
  2032.             if (num_blanks_focus == (-1))
  2033.                num_blanks_focus = 0;
  2034.             num_blanks_next = memne(curr->next->line,' ',curr->length);
  2035.             if (num_blanks_next == (-1))
  2036.                num_blanks_next = 0;
  2037.             num_cols = min(num_blanks_focus,num_blanks_next);
  2038.            }
  2039.          else
  2040.             num_cols = 0;
  2041.          if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
  2042.             pre_process_line(CURRENT_VIEW,CURRENT_VIEW->current_line,(LINE *)NULL);
  2043.          meminsmem(rec,curr->next->line+num_cols,curr->next->length-num_cols,
  2044.                       col,max_line_length,col);
  2045.          if (col+curr->next->length-num_cols > max_line_length)
  2046.            {
  2047.             display_error(0,(CHARTYPE*)"Truncated",FALSE);
  2048.            }
  2049.          rec_len = min(max_line_length,col+curr->next->length-num_cols);
  2050.          post_process_line(CURRENT_VIEW,true_line,(LINE *)NULL,TRUE);
  2051.          curr = delete_line(CURRENT_FILE->first_line,curr->next,DIRECTION_BACKWARD);
  2052.          if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
  2053.             pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
  2054. /*---------------------------------------------------------------------*/
  2055. /* If on the bottom line, use the previous line.                       */
  2056. /*---------------------------------------------------------------------*/
  2057.          if (CURRENT_BOF)
  2058.            {
  2059.             CURRENT_VIEW->current_line--;
  2060.             y++;
  2061.            }
  2062. /*---------------------------------------------------------------------*/
  2063. /* Decrement the number of lines counter for the current file and move */
  2064. /* the cursor to the appropriate line.                                 */
  2065. /*---------------------------------------------------------------------*/
  2066.          CURRENT_FILE->number_lines--;
  2067.          if (CURRENT_VIEW->current_window == WINDOW_FILEAREA)
  2068.             wmove(CURRENT_WINDOW,y,x);
  2069.          break;
  2070.    }
  2071. /*
  2072.  * Determine new current line if cursorarg == false
  2073.  */
  2074.  if (CURRENT_VIEW->current_window == WINDOW_COMMAND
  2075.  ||  cursorarg == FALSE)
  2076.    {
  2077.     CURRENT_VIEW->current_line++;
  2078.     pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
  2079.     if (CURRENT_VIEW->current_window != WINDOW_COMMAND)
  2080.       {
  2081.        build_screen(current_screen);
  2082.        if (!line_in_view(current_screen,CURRENT_VIEW->focus_line)
  2083.        &&  compatible_feel == COMPAT_XEDIT)
  2084.          {
  2085.           cursor_cmdline(1);
  2086.          }
  2087.        else
  2088.          {
  2089.           y = get_row_for_focus_line(current_screen,CURRENT_VIEW->focus_line,
  2090.                                   CURRENT_VIEW->current_row);
  2091.           wmove(CURRENT_WINDOW,y,x);
  2092.          }
  2093.       }
  2094.    }
  2095. /*---------------------------------------------------------------------*/
  2096. /* Fix the positioning of the marked block (if there is one and it is  */
  2097. /* in the current view) and any pending prefix commands.               */
  2098. /*---------------------------------------------------------------------*/
  2099.  adjust_marked_lines((action==SPLTJOIN_SPLIT)?TRUE:FALSE,true_line,1L);
  2100.  adjust_pending_prefix(CURRENT_VIEW,(action==SPLTJOIN_SPLIT)?TRUE:FALSE,true_line,1L);
  2101.  build_screen(current_screen);
  2102.  display_screen(current_screen);
  2103. #ifdef TRACE
  2104.  trace_return();
  2105. #endif
  2106.  return(RC_OK);
  2107. }
  2108. /***********************************************************************/
  2109. #ifdef HAVE_PROTO
  2110. short execute_put(CHARTYPE *params,bool putdel)
  2111. #else
  2112. short execute_put(params,putdel)
  2113. CHARTYPE *params;
  2114. bool putdel;
  2115. #endif
  2116. /***********************************************************************/
  2117. {
  2118. /*-------------------------- external data ----------------------------*/
  2119.  extern CHARTYPE *tempfilename;
  2120.  extern CHARTYPE sp_path[MAX_FILE_NAME+1] ;
  2121.  extern CHARTYPE sp_fname[MAX_FILE_NAME+1] ;
  2122.  extern VIEW_DETAILS *vd_mark;
  2123.  extern CHARTYPE *temp_cmd;
  2124.  extern bool curses_started;
  2125. /*--------------------------- local data ------------------------------*/
  2126.  LINETYPE num_lines=0L,true_line=0L,num_file_lines=0L;
  2127.  bool append=FALSE;
  2128.  CHARTYPE *filename=NULL;
  2129.  short rc=RC_OK;
  2130.  LENGTHTYPE start_col=0,end_col=max_line_length;
  2131.  bool lines_based_on_scope = TRUE;
  2132.  TARGET target;
  2133.  short target_type=TARGET_NORMAL|TARGET_BLOCK_CURRENT|TARGET_ALL|TARGET_SPARE;
  2134.  short direction=DIRECTION_FORWARD;
  2135.  int y=0,x=0;
  2136. /*--------------------------- processing ------------------------------*/
  2137. #ifdef TRACE
  2138.  trace_function("execute.c: execute_put");
  2139. #endif
  2140. /*---------------------------------------------------------------------*/
  2141. /* If there are no arguments, default to "1"...                        */
  2142. /*---------------------------------------------------------------------*/
  2143.  if (strcmp("",(DEFCHAR *)params) == 0)
  2144.     params = (CHARTYPE *)"1";
  2145. /*---------------------------------------------------------------------*/
  2146. /* Validate first argument as a target...                              */
  2147. /*---------------------------------------------------------------------*/
  2148.  initialise_target(&target);
  2149.  if ((rc = validate_target(params,&target,target_type,get_true_line(TRUE),TRUE,TRUE)) != RC_OK)
  2150.    {
  2151.     free_target(&target);
  2152. #ifdef TRACE
  2153.     trace_return();
  2154. #endif
  2155.     return(rc);
  2156.    }
  2157. /*---------------------------------------------------------------------*/
  2158. /* If there is no second argument, no filename supplied...             */
  2159. /*---------------------------------------------------------------------*/
  2160.  if (target.spare == (-1))
  2161.    {
  2162.     append = FALSE;
  2163.     filename = tempfilename;
  2164.    }
  2165.  else
  2166.    {
  2167.     if ((rc = splitpath(strtrunc(target.rt[target.spare].string))) != RC_OK)
  2168.       {
  2169.        display_error(10,strtrunc(target.rt[target.spare].string),FALSE);
  2170.        free_target(&target);
  2171. #ifdef TRACE
  2172.        trace_return();
  2173. #endif
  2174.        return(rc);
  2175.       }
  2176.     strcpy((DEFCHAR *)temp_cmd,(DEFCHAR *)sp_path);
  2177.     strcat((DEFCHAR *)temp_cmd,(DEFCHAR *)sp_fname);
  2178.     filename = temp_cmd;
  2179.     append = TRUE;
  2180.    }
  2181.  true_line = target.true_line;
  2182.  num_lines = target.num_lines;
  2183. /*---------------------------------------------------------------------*/
  2184. /* Determine in which direction we are working.                        */
  2185. /*---------------------------------------------------------------------*/
  2186.  direction = (target.num_lines < 0L) ? DIRECTION_BACKWARD : DIRECTION_FORWARD;
  2187. /*---------------------------------------------------------------------*/
  2188. /* If the marked block is a BOX block, set up the left and right column*/
  2189. /* values.                                                             */
  2190. /*---------------------------------------------------------------------*/
  2191.  if (target.rt[0].target_type == TARGET_BLOCK_CURRENT)
  2192.    {
  2193.     lines_based_on_scope = FALSE;
  2194.     if (MARK_VIEW->mark_type == M_BOX)
  2195.       {
  2196.        start_col = MARK_VIEW->mark_start_col-1;
  2197.        end_col = MARK_VIEW->mark_end_col-1;
  2198.       }
  2199.    }
  2200.  post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE);
  2201.  if ((rc = save_file(CURRENT_FILE,
  2202.                      filename,
  2203.                      TRUE,
  2204.                      num_lines,
  2205.                      true_line,
  2206.                      &num_file_lines,
  2207.                      append,
  2208.                      start_col,
  2209.                      end_col,
  2210.                      FALSE,
  2211.                      lines_based_on_scope)) != RC_OK)
  2212.    {
  2213.     free_target(&target);
  2214. #ifdef TRACE
  2215.     trace_return();
  2216. #endif
  2217.     return(rc);
  2218.    }
  2219. /*---------------------------------------------------------------------*/
  2220. /* If we are executing a putd command, delete the target...            */
  2221. /*---------------------------------------------------------------------*/
  2222.  if (putdel)
  2223.     rc = DeleteLine(target.string);
  2224.  else
  2225.    {
  2226. /*---------------------------------------------------------------------*/
  2227. /* If STAY is OFF, change the current and focus lines by the number    */
  2228. /* of lines calculated from the target. This is only applicable for    */
  2229. /* PUT and NOT for PUTDEL.                                             */
  2230. /*---------------------------------------------------------------------*/
  2231.    resolve_current_and_focus_lines(CURRENT_VIEW,true_line,num_file_lines,direction,FALSE,FALSE);
  2232.   }
  2233.  free_target(&target);
  2234. #ifdef TRACE
  2235.  trace_return();
  2236. #endif
  2237.  return(rc);
  2238. }
  2239. /***********************************************************************/
  2240. #ifdef HAVE_PROTO
  2241. short execute_macro(CHARTYPE *params,bool error_on_not_found,short *macrorc)
  2242. #else
  2243. short execute_macro(params,error_on_not_found,macrorc)
  2244. CHARTYPE *params;
  2245. bool error_on_not_found;
  2246. short *macrorc;
  2247. #endif
  2248. /***********************************************************************/
  2249. {
  2250. /*-------------------------- external data ----------------------------*/
  2251.  extern bool in_macro;
  2252.  extern bool rexx_support;
  2253.  extern CHARTYPE number_of_files;
  2254.  extern CHARTYPE display_screens;
  2255.  extern LINETYPE original_screen_line;
  2256.  extern LINETYPE original_screen_column;
  2257.  extern LINETYPE original_file_line;
  2258.  extern LINETYPE original_file_column;
  2259. /*--------------------------- local data ------------------------------*/
  2260.  short rc=RC_OK;
  2261.  short errnum=0;
  2262.  FILE *fp=NULL;
  2263. #define MAC_PARAMS  2
  2264.  CHARTYPE *word[MAC_PARAMS+1];
  2265.  CHARTYPE strip[MAC_PARAMS];
  2266.  unsigned short num_params=0;
  2267.  CHARTYPE *macroname=NULL;
  2268.  bool save_in_macro=in_macro;
  2269. /*--------------------------- processing ------------------------------*/
  2270. #ifdef TRACE
  2271.  trace_function("execute.c: execute_macro");
  2272. #endif
  2273. /*---------------------------------------------------------------------*/
  2274. /* Validate the parameters. At least 1 must be present, the filename.  */
  2275. /*---------------------------------------------------------------------*/
  2276.  strip[0]=STRIP_BOTH;
  2277.  strip[1]=STRIP_NONE;
  2278.  num_params = param_split(params,word,MAC_PARAMS,WORD_DELIMS,TEMP_PARAM,strip,TRUE);
  2279.  if (num_params == 0)
  2280.    {
  2281.     display_error(3,(CHARTYPE *)"",FALSE);
  2282. #ifdef TRACE
  2283.     trace_return();
  2284. #endif
  2285.     return(RC_INVALID_OPERAND);
  2286.    }
  2287. /*---------------------------------------------------------------------*/
  2288. /* Allocate some space for macroname...                                */
  2289. /*---------------------------------------------------------------------*/
  2290.  if ((macroname = (CHARTYPE *)(*the_malloc)((MAX_FILE_NAME+1)*sizeof(CHARTYPE))) == NULL)
  2291.    {
  2292.     display_error(30,(CHARTYPE *)"",FALSE);
  2293. #ifdef TRACE
  2294.     trace_return();
  2295. #endif
  2296.     return(RC_OUT_OF_MEMORY);
  2297.    }
  2298. /*---------------------------------------------------------------------*/
  2299. /* Find the fully qualified file name for the supplied macro name.     */
  2300. /*---------------------------------------------------------------------*/
  2301.  rc = get_valid_macro_file_name(word[0],macroname,&errnum);
  2302. /*---------------------------------------------------------------------*/
  2303. /* Validate the return code...                                         */
  2304. /*---------------------------------------------------------------------*/
  2305.  switch(rc)
  2306.    {
  2307. /*---------------------------------------------------------------------*/
  2308. /* If RC_OK, continue to process the macro...                          */
  2309. /*---------------------------------------------------------------------*/
  2310.     case RC_OK:
  2311.          break;
  2312. /*---------------------------------------------------------------------*/
  2313. /* If RC_FILE_NOT_FOUND and IMPOS is not on, display an error and exit.*/
  2314. /* If IMPOS is on, just return without displaying an error.            */
  2315. /*---------------------------------------------------------------------*/
  2316.     case RC_FILE_NOT_FOUND:
  2317.          if (error_on_not_found)
  2318.             display_error(errnum,word[0],FALSE);
  2319.          (*the_free)(macroname);
  2320. #ifdef TRACE
  2321.          trace_return();
  2322. #endif
  2323.          return(rc);
  2324.          break;
  2325. /*---------------------------------------------------------------------*/
  2326. /* All other cases, display error and return.                          */
  2327. /*---------------------------------------------------------------------*/
  2328.     default:
  2329.          display_error(errnum,word[0],FALSE);
  2330.          (*the_free)(macroname);
  2331. #ifdef TRACE
  2332.          trace_return();
  2333. #endif
  2334.          return(rc);
  2335.    }
  2336. /*---------------------------------------------------------------------*/
  2337. /* Set in_macro = TRUE to stop multiple show_page()s being performed.  */
  2338. /*---------------------------------------------------------------------*/
  2339.  in_macro = TRUE;
  2340. /*---------------------------------------------------------------------*/
  2341. /* Save the values of the cursor position...                           */
  2342. /*---------------------------------------------------------------------*/
  2343.  get_cursor_position(&original_screen_line,&original_screen_column,
  2344.                      &original_file_line,&original_file_column);
  2345. /*---------------------------------------------------------------------*/
  2346. /* If REXX is supported, process the macro as a REXX macro...          */
  2347. /*---------------------------------------------------------------------*/
  2348.  if (rexx_support)
  2349.    {
  2350.     post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE);
  2351.     rc = execute_macro_file(macroname,word[1],macrorc);
  2352.     if (rc != RC_OK)
  2353.       {
  2354.        display_error(54,(CHARTYPE *)"",FALSE);
  2355.        rc = RC_SYSTEM_ERROR;
  2356.       }
  2357.     (*the_free)(macroname);
  2358.    }
  2359.  else
  2360.    {
  2361. /*---------------------------------------------------------------------*/
  2362. /* ...otherwise, process the file as a non-REXX macro file...          */
  2363. /*---------------------------------------------------------------------*/
  2364.     if ((fp = fopen((DEFCHAR *)macroname,"r")) == NULL)
  2365.       {
  2366.        rc = RC_ACCESS_DENIED;
  2367.        display_error(8,macroname,FALSE);
  2368.       }
  2369.     post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE);
  2370.     if (rc == RC_OK)
  2371.       {
  2372.        rc = execute_command_file(fp);
  2373.        fclose(fp);
  2374.       }
  2375.     (*the_free)(macroname);
  2376.     if (rc == RC_SYSTEM_ERROR)
  2377.        display_error(53,(CHARTYPE *)"",FALSE);
  2378.     if (rc == RC_NOREXX_ERROR)
  2379.        display_error(52,(CHARTYPE *)"",FALSE);
  2380.    }
  2381. /*---------------------------------------------------------------------*/
  2382. /* Set in_macro = FALSE to indicate we are out of the macro and do a   */
  2383. /* show_page() now as long as there are still file(s) in the ring.     */
  2384. /*---------------------------------------------------------------------*/
  2385.  in_macro = save_in_macro;
  2386.  if (number_of_files > 0)
  2387.    {
  2388.     if (display_screens > 1)
  2389.       {
  2390.        build_screen(other_screen);
  2391.        display_screen(other_screen);
  2392.       }
  2393.     build_screen(current_screen);
  2394.     display_screen(current_screen);
  2395.    }
  2396. #ifdef TRACE
  2397.  trace_return();
  2398. #endif
  2399.  return(rc);
  2400. }
  2401. /***********************************************************************/
  2402. #ifdef HAVE_PROTO
  2403. short execute_set_on_off(CHARTYPE *inparams,bool *flag)
  2404. #else
  2405. short execute_set_on_off(inparams,flag)
  2406. CHARTYPE *inparams;
  2407. bool *flag;
  2408. #endif
  2409. /***********************************************************************/
  2410. {
  2411. /*-------------------------- external data ----------------------------*/
  2412. /*--------------------------- local data ------------------------------*/
  2413.  short rc=RC_OK;
  2414.  CHARTYPE *params=NULL;
  2415. /*--------------------------- processing ------------------------------*/
  2416. #ifdef TRACE
  2417.  trace_function("execute.c: execute_set_on_off");
  2418. #endif
  2419. /*---------------------------------------------------------------------*/
  2420. /* Strip the leading and trailing spaces from parameters...            */
  2421. /*---------------------------------------------------------------------*/
  2422.  if ((params = (CHARTYPE *)my_strdup(inparams)) == NULL)
  2423.    {
  2424. #ifdef TRACE
  2425.     trace_return();
  2426. #endif
  2427.     return(RC_OUT_OF_MEMORY);
  2428.    }
  2429.  params = MyStrip(params,STRIP_BOTH,' ');
  2430. /*---------------------------------------------------------------------*/
  2431. /* Validate the parameter. It must be ON or OFF.                       */
  2432. /*---------------------------------------------------------------------*/
  2433.  if (equal((CHARTYPE *)"off",params,3))
  2434.     *flag = FALSE;
  2435.  else
  2436.     if (equal((CHARTYPE *)"on",params,2))
  2437.        *flag = TRUE;
  2438.     else
  2439.       {
  2440.        display_error(1,(CHARTYPE *)inparams,FALSE);
  2441. #ifdef TRACE
  2442.        trace_return();
  2443. #endif
  2444.        rc = RC_INVALID_OPERAND;
  2445.       }
  2446.  (*the_free)(params);
  2447. #ifdef TRACE
  2448.  trace_return();
  2449. #endif
  2450.  return(rc);
  2451. }
  2452. /***********************************************************************/
  2453. #ifdef HAVE_PROTO
  2454. short execute_set_row_position(CHARTYPE *inparams,short *base,short *off)
  2455. #else
  2456. short execute_set_row_position(inparams,base,off)
  2457. CHARTYPE *inparams;
  2458. short *base,*off;
  2459. #endif
  2460. /***********************************************************************/
  2461. {
  2462. /*-------------------------- external data ----------------------------*/
  2463. /*--------------------------- local data ------------------------------*/
  2464.  short rc=RC_OK;
  2465.  CHARTYPE *params=NULL,*save_param_ptr=NULL;
  2466. /*--------------------------- processing ------------------------------*/
  2467. #ifdef TRACE
  2468.  trace_function("execute.c: execute_set_row_position");
  2469. #endif
  2470. /*---------------------------------------------------------------------*/
  2471. /* Strip the leading and trailing spaces from parameters...            */
  2472. /*---------------------------------------------------------------------*/
  2473.  if ((params = save_param_ptr = (CHARTYPE *)my_strdup(inparams)) == NULL)
  2474.    {
  2475. #ifdef TRACE
  2476.     trace_return();
  2477. #endif
  2478.     return(RC_OUT_OF_MEMORY);
  2479.    }
  2480.  params = MyStrip(params,STRIP_BOTH,' ');
  2481. /*---------------------------------------------------------------------*/
  2482. /* Parse the position parameter...                                     */
  2483. /*---------------------------------------------------------------------*/
  2484.  if (*params == 'M'
  2485.  ||  *params == 'm')
  2486.    {
  2487.     *base = POSITION_MIDDLE;
  2488.     params++;
  2489.     if (blank_field(params))
  2490.        *off = 0;
  2491.     else
  2492.       {
  2493.        if ((*params != '-'
  2494.        &&  *params != '+')
  2495.        || ((*off = atoi((DEFCHAR *)params)) == 0))
  2496.          {
  2497.           display_error(1,inparams,FALSE);
  2498.           (*the_free)(save_param_ptr);
  2499. #ifdef TRACE
  2500.           trace_return();
  2501. #endif
  2502.           return(RC_INVALID_OPERAND);
  2503.          }
  2504.       }
  2505.    }
  2506.  else
  2507.    {
  2508.     if ((*off = atoi((DEFCHAR *)params)) == 0)
  2509.       {
  2510.        display_error(1,inparams,FALSE);
  2511.           (*the_free)(save_param_ptr);
  2512. #ifdef TRACE
  2513.        trace_return();
  2514. #endif
  2515.        return(RC_INVALID_OPERAND);
  2516.       }
  2517.     *base = (*off > 0) ? POSITION_TOP : POSITION_BOTTOM;
  2518.    }
  2519.  (*the_free)(save_param_ptr);
  2520. #ifdef TRACE
  2521.  trace_return();
  2522. #endif
  2523.  return(rc);
  2524. }
  2525. /***********************************************************************/
  2526. #ifdef HAVE_PROTO
  2527. short processable_line(VIEW_DETAILS *view,LINETYPE true_line,LINE *curr)
  2528. #else
  2529. short processable_line(view,true_line,curr)
  2530. VIEW_DETAILS *view;
  2531. LINETYPE true_line;
  2532. LINE *curr;
  2533. #endif
  2534. /***********************************************************************/
  2535. {
  2536. /*-------------------------- external data ----------------------------*/
  2537. /*--------------------------- local data ------------------------------*/
  2538. /*--------------------------- processing ------------------------------*/
  2539. #ifdef TRACE
  2540.  trace_function("execute.c: processable_line");
  2541. #endif
  2542.  
  2543. #if 0
  2544. /* MH12 */
  2545.  if (VIEW_TOF(view,true_line)
  2546.  ||  VIEW_BOF(view,true_line))
  2547.    {
  2548. #ifdef TRACE
  2549.     trace_return();
  2550. #endif
  2551.     return(LINE_TOF_EOF);
  2552.    }
  2553. #endif
  2554.  if (VIEW_TOF(view,true_line))
  2555.    {
  2556. #ifdef TRACE
  2557.     trace_return();
  2558. #endif
  2559.     return(LINE_TOF);
  2560.    }
  2561.  if (VIEW_BOF(view,true_line))
  2562.    {
  2563. #ifdef TRACE
  2564.     trace_return();
  2565. #endif
  2566.     return(LINE_EOF);
  2567.    }
  2568.  
  2569.  if (in_scope(view,curr)
  2570.  ||  view->scope_all)
  2571.    {
  2572. #ifdef TRACE
  2573.     trace_return();
  2574. #endif
  2575.     return(LINE_LINE);
  2576.    }
  2577. #ifdef TRACE
  2578.  trace_return();
  2579. #endif
  2580.  return(LINE_SHADOW);
  2581. }
  2582. /***********************************************************************/
  2583. #ifdef HAVE_PROTO
  2584. short execute_expand_compress(CHARTYPE *params,bool expand,bool inc_alt,bool use_tabs,bool add_to_recovery)
  2585. #else
  2586. short execute_expand_compress(params,expand,inc_alt,use_tabs,add_to_recovery)
  2587. CHARTYPE *params;
  2588. bool expand,inc_alt,use_tabs,add_to_recovery;
  2589. #endif
  2590. /***********************************************************************/
  2591. {
  2592. /*-------------------------- external data ----------------------------*/
  2593.  extern bool curses_started;
  2594.  extern VIEW_DETAILS *vd_mark;
  2595. /*--------------------------- local data ------------------------------*/
  2596.  LINETYPE i=0L,num_actual_lines=0L;
  2597.  LINETYPE num_lines=0L,true_line=0L,num_file_lines=0L;
  2598.  unsigned short x=0,y=0;
  2599.  short direction=0,rc=RC_OK;
  2600.  LINE *curr=NULL;
  2601.  TARGET target;
  2602.  short target_type=TARGET_NORMAL|TARGET_BLOCK_CURRENT|TARGET_ALL;
  2603.  bool lines_based_on_scope=FALSE;
  2604.  bool adjust_alt=FALSE;
  2605. /*--------------------------- processing ------------------------------*/
  2606. /*---------------------------------------------------------------------*/
  2607. /* Validate the parameters that have been supplied.                    */
  2608. /* If no parameter is supplied, 1 is assumed.                          */
  2609. /*---------------------------------------------------------------------*/
  2610.  true_line = get_true_line(TRUE);
  2611.  if (strcmp("",(DEFCHAR *)params) == 0)
  2612.     params = (CHARTYPE *)"1";
  2613.  initialise_target(&target);
  2614.  if ((rc = validate_target(params,&target,target_type,true_line,TRUE,TRUE)) != RC_OK)
  2615.    {
  2616.     free_target(&target);
  2617. #ifdef TRACE
  2618.     trace_return();
  2619. #endif
  2620.     return(rc);
  2621.    }
  2622. /*---------------------------------------------------------------------*/
  2623. /* If a BOX BLOCK target requested, return an error...                 */
  2624. /*---------------------------------------------------------------------*/
  2625.  if (target.rt[0].target_type == TARGET_BLOCK_CURRENT)
  2626.    {
  2627.     switch(MARK_VIEW->mark_type)
  2628.       {
  2629.        case M_BOX:
  2630.        case M_COLUMN:
  2631.        case M_WORD:
  2632.             display_error(48,(CHARTYPE *)"",FALSE);
  2633.             rc = RC_INVALID_OPERAND;
  2634.             break;
  2635.        case M_STREAM:
  2636.             display_error(49,(CHARTYPE *)"",FALSE);
  2637.             rc = RC_INVALID_OPERAND;
  2638.             break;
  2639.        default:
  2640.             break;
  2641.       }
  2642.     if (MARK_VIEW->mark_type != M_LINE)
  2643.       {
  2644.        free_target(&target);
  2645. #ifdef TRACE
  2646.        trace_return();
  2647. #endif
  2648.        return(rc);
  2649.       }
  2650.    }
  2651.  post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE);
  2652. /*---------------------------------------------------------------------*/
  2653. /* Determine in which direction we are working.                        */
  2654. /*---------------------------------------------------------------------*/
  2655.  if (target.num_lines < 0L)
  2656.    {
  2657.     direction = DIRECTION_BACKWARD;
  2658.     num_lines = -target.num_lines;
  2659.    }
  2660.  else
  2661.    {
  2662.     direction = DIRECTION_FORWARD;
  2663.     num_lines = target.num_lines;
  2664.    }
  2665.  true_line = target.true_line;
  2666.  lines_based_on_scope = (target.rt[0].target_type == TARGET_BLOCK_CURRENT) ? FALSE : TRUE;
  2667.  free_target(&target);
  2668. /*---------------------------------------------------------------------*/
  2669. /* Find the current LINE pointer for the true_line.                    */
  2670. /* This is the first line to change.                                   */
  2671. /*---------------------------------------------------------------------*/
  2672.  curr = lll_find(CURRENT_FILE->first_line,CURRENT_FILE->last_line,true_line,CURRENT_FILE->number_lines);
  2673. /*---------------------------------------------------------------------*/
  2674. /* Convert all tabs in the current line to spaces.                     */
  2675. /*---------------------------------------------------------------------*/
  2676.  for (i=0L,num_actual_lines=0L;;i++)
  2677.    {
  2678.     if (lines_based_on_scope)
  2679.       {
  2680.        if (num_actual_lines == num_lines)
  2681.           break;
  2682.       }
  2683.     else
  2684.       {
  2685.        if (num_lines == i)
  2686.           break;
  2687.       }
  2688.     rc = processable_line(CURRENT_VIEW,true_line+(LINETYPE)(i*direction),curr);
  2689.     switch(rc)
  2690.       {
  2691.        case LINE_SHADOW:
  2692.             break;
  2693. /*       case LINE_TOF_EOF: MH12 */
  2694.        case LINE_TOF:
  2695.        case LINE_EOF:
  2696.             num_actual_lines++;
  2697.             break;
  2698.        default:
  2699.             rc = tabs_convert(curr,expand,use_tabs,add_to_recovery);
  2700.             if (rc == RC_FILE_CHANGED)
  2701.                adjust_alt = TRUE;
  2702.             else
  2703.                if (rc != RC_OK)
  2704.                  {
  2705. #ifdef TRACE
  2706.                   trace_return();
  2707. #endif
  2708.                   return(rc);
  2709.                  }
  2710.             num_actual_lines++;
  2711.       }
  2712.     if (direction == DIRECTION_FORWARD)
  2713.        curr = curr->next;
  2714.     else
  2715.        curr = curr->prev;
  2716.     num_file_lines += (LINETYPE)direction;
  2717.     if (curr == NULL)
  2718.        break;
  2719.    }
  2720. /*---------------------------------------------------------------------*/
  2721. /* Increment the number of alterations count if required...            */
  2722. /*---------------------------------------------------------------------*/
  2723.  if (inc_alt
  2724.  &&  adjust_alt)
  2725.     increment_alt(CURRENT_FILE);
  2726. /*---------------------------------------------------------------------*/
  2727. /* If STAY is OFF, change the current and focus lines by the number    */
  2728. /* of lines calculated from the target.                                */
  2729. /*---------------------------------------------------------------------*/
  2730.  pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
  2731.  resolve_current_and_focus_lines(CURRENT_VIEW,true_line,num_file_lines,direction,TRUE,FALSE);
  2732. #ifdef TRACE
  2733.  trace_return();
  2734. #endif
  2735.  if (CURRENT_TOF || CURRENT_BOF)
  2736.     return(RC_TOF_EOF_REACHED);
  2737.  else
  2738.     return(RC_OK);
  2739. }
  2740. /***********************************************************************/
  2741. #ifdef HAVE_PROTO
  2742. short execute_select(CHARTYPE *params,bool relative,short off)
  2743. #else
  2744. short execute_select(params,relative,off)
  2745. CHARTYPE *params;
  2746. bool relative;
  2747. short off;
  2748. #endif
  2749. /***********************************************************************/
  2750. {
  2751. /*-------------------------- external data ----------------------------*/
  2752. /*--------------------------- local data ------------------------------*/
  2753.  LINETYPE i=0L,num_actual_lines=0L;
  2754.  LINETYPE num_lines=0L,true_line=0L;
  2755.  short direction=0,rc=RC_OK;
  2756.  LINE *curr=NULL;
  2757.  TARGET target;
  2758.  short target_type=TARGET_NORMAL|TARGET_BLOCK_CURRENT|TARGET_ALL;
  2759.  bool lines_based_on_scope=FALSE;
  2760. /*--------------------------- processing ------------------------------*/
  2761. /*---------------------------------------------------------------------*/
  2762. /* Validate the parameters that have been supplied.                    */
  2763. /* If no parameter is supplied, 1 is assumed.                          */
  2764. /*---------------------------------------------------------------------*/
  2765.  true_line = get_true_line(TRUE);
  2766.  initialise_target(&target);
  2767.  if ((rc = validate_target(params,&target,target_type,true_line,TRUE,TRUE)) != RC_OK)
  2768.    {
  2769.     free_target(&target);
  2770. #ifdef TRACE
  2771.     trace_return();
  2772. #endif
  2773.     return(rc);
  2774.    }
  2775.  post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE);
  2776. /*---------------------------------------------------------------------*/
  2777. /* Determine in which direction we are working.                        */
  2778. /*---------------------------------------------------------------------*/
  2779.  if (target.num_lines < 0L)
  2780.    {
  2781.     direction = DIRECTION_BACKWARD;
  2782.     num_lines = -target.num_lines;
  2783.    }
  2784.  else
  2785.    {
  2786.     direction = DIRECTION_FORWARD;
  2787.     num_lines = target.num_lines;
  2788.    }
  2789.  true_line = target.true_line;
  2790.  lines_based_on_scope = (target.rt[0].target_type == TARGET_BLOCK_CURRENT) ? FALSE : TRUE;
  2791. /*---------------------------------------------------------------------*/
  2792. /* Find the current LINE pointer for the true_line.                    */
  2793. /* This is the first line to change.                                   */
  2794. /*---------------------------------------------------------------------*/
  2795.  curr = lll_find(CURRENT_FILE->first_line,CURRENT_FILE->last_line,true_line,CURRENT_FILE->number_lines);
  2796. /*---------------------------------------------------------------------*/
  2797. /* Convert all tabs in the current line to spaces.                     */
  2798. /*---------------------------------------------------------------------*/
  2799.  for (i=0L,num_actual_lines=0L;;i++)
  2800.    {
  2801.     if (lines_based_on_scope)
  2802.       {
  2803.        if (num_actual_lines == num_lines)
  2804.           break;
  2805.       }
  2806.     else
  2807.       {
  2808.        if (num_lines == i)
  2809.           break;
  2810.       }
  2811.     rc = processable_line(CURRENT_VIEW,true_line+(LINETYPE)(i*direction),curr);
  2812.     switch(rc)
  2813.       {
  2814.        case LINE_SHADOW:
  2815.             break;
  2816.        case LINE_TOF:
  2817.        case LINE_EOF:
  2818.             num_actual_lines++;
  2819.             break;
  2820.        default:
  2821.             if (relative)
  2822.               {
  2823.                if (((short)curr->select + off) > 255)
  2824.                   curr->select = 255;
  2825.                else
  2826.                   if (((short)curr->select + off) < 0)
  2827.                      curr->select = 0;
  2828.                   else
  2829.                      curr->select += off;
  2830.               }
  2831.             else
  2832.                curr->select = off;
  2833.             num_actual_lines++;
  2834.       }
  2835.     if (direction == DIRECTION_FORWARD)
  2836.        curr = curr->next;
  2837.     else
  2838.        curr = curr->prev;
  2839.     if (curr == NULL)
  2840.        break;
  2841.    }
  2842.  free_target(&target);
  2843. #ifdef TRACE
  2844.  trace_return();
  2845. #endif
  2846.  if (CURRENT_TOF || CURRENT_BOF)
  2847.     return(RC_TOF_EOF_REACHED);
  2848.  else
  2849.     return(RC_OK);
  2850. }
  2851. /***********************************************************************/
  2852. #ifdef HAVE_PROTO
  2853. short execute_move_cursor(LENGTHTYPE col)
  2854. #else
  2855. short execute_move_cursor(col)
  2856. LENGTHTYPE col;
  2857. #endif
  2858. /***********************************************************************/
  2859. {
  2860. /*-------------------------- external data ----------------------------*/
  2861. /*--------------------------- local data ------------------------------*/
  2862.  short y=0,x=0;
  2863.  COLTYPE new_screen_col=0;
  2864.  LENGTHTYPE new_verify_col=0;
  2865. /*--------------------------- processing ------------------------------*/
  2866. #ifdef TRACE
  2867.  trace_function("execute.c: execute_move_cursor");
  2868. #endif
  2869. /*---------------------------------------------------------------------*/
  2870. /* Don't do anything for PREFIX window...                              */
  2871. /*---------------------------------------------------------------------*/
  2872.  if (CURRENT_VIEW->current_window == WINDOW_PREFIX)
  2873.    {
  2874. #ifdef TRACE
  2875.     trace_return();
  2876. #endif
  2877.     return(RC_OK);
  2878.    }
  2879.  
  2880.  getyx(CURRENT_WINDOW,y,x);
  2881.  calculate_new_column(x,CURRENT_VIEW->verify_col,col,&new_screen_col,&new_verify_col);
  2882.  if (CURRENT_VIEW->verify_col != new_verify_col
  2883.  &&  CURRENT_VIEW->current_window == WINDOW_FILEAREA)
  2884.    {
  2885.     CURRENT_VIEW->verify_col = new_verify_col;
  2886.     build_screen(current_screen);
  2887.     display_screen(current_screen);
  2888.    }
  2889.  wmove(CURRENT_WINDOW,y,new_screen_col);
  2890.  
  2891. #ifdef TRACE
  2892.  trace_return();
  2893. #endif
  2894.  return(RC_OK);
  2895. }
  2896. /***********************************************************************/
  2897. #ifdef HAVE_PROTO
  2898. short execute_find_command(CHARTYPE *str,short target_type)
  2899. #else
  2900. short execute_find_command(str,target_type)
  2901. CHARTYPE *str;
  2902. short target_type;
  2903. #endif
  2904. /***********************************************************************/
  2905. {
  2906. /*-------------------------- external data ----------------------------*/
  2907.  extern short compatible_feel;
  2908. /*--------------------------- local data ------------------------------*/
  2909.  short rc=RC_OK;
  2910.  LENGTHTYPE save_zone_start=CURRENT_VIEW->zone_start;
  2911.  LENGTHTYPE save_zone_end=CURRENT_VIEW->zone_end;
  2912.  bool save_arbchar_status=CURRENT_VIEW->arbchar_status;
  2913.  bool save_hex=CURRENT_VIEW->hex;
  2914.  bool negative=FALSE,wrapped=FALSE;
  2915.  CHARTYPE save_arbchar_single=CURRENT_VIEW->arbchar_single;
  2916.  TARGET target;
  2917.  LINETYPE true_line=0L;
  2918.  LINETYPE save_focus_line=CURRENT_VIEW->focus_line;
  2919.  LINETYPE save_current_line=CURRENT_VIEW->current_line;
  2920. /*--------------------------- processing ------------------------------*/
  2921. #ifdef TRACE
  2922.  trace_function("execute.c: execute_find_command");
  2923. #endif
  2924.  if (strcmp((DEFCHAR *)str,"") == 0) /* argument supplied */
  2925.    {
  2926.     display_error(1,str,FALSE);
  2927. #ifdef TRACE
  2928.     trace_return();
  2929. #endif
  2930.     return(RC_INVALID_OPERAND);
  2931.    }
  2932.  post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE);
  2933.  initialise_target(&target);
  2934. /*---------------------------------------------------------------------*/
  2935. /* Force the ZONE settings to start at 1 and end at parameter length.  */
  2936. /* Ensure ARBCHAR and HEX will be ignored in the search...             */
  2937. /*---------------------------------------------------------------------*/
  2938.  CURRENT_VIEW->zone_start = 1;
  2939.  CURRENT_VIEW->zone_end = strlen((DEFCHAR *)str);
  2940.  CURRENT_VIEW->arbchar_status = TRUE;
  2941.  CURRENT_VIEW->arbchar_single = find_unique_char(str);
  2942.  CURRENT_VIEW->hex = FALSE;
  2943.  rc = validate_target(str,&target,target_type,get_true_line(TRUE),TRUE,FALSE);
  2944.  if (rc == RC_TARGET_NOT_FOUND
  2945.  &&  CURRENT_VIEW->wrap)
  2946.    {
  2947.     wrapped = TRUE;
  2948.     negative = target.rt[0].negative;
  2949.     free_target(&target);
  2950.     initialise_target(&target);
  2951.     true_line = (negative ? CURRENT_FILE->number_lines+1 : 0L);
  2952.     CURRENT_VIEW->focus_line = CURRENT_VIEW->current_line = true_line;
  2953.     pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
  2954.     rc = validate_target(str,&target,target_type,true_line,TRUE,FALSE);
  2955.    }
  2956. /*---------------------------------------------------------------------*/
  2957. /* Put ZONE, ARBCHAR and HEX back the way they were...                 */
  2958. /*---------------------------------------------------------------------*/
  2959.  CURRENT_VIEW->zone_start = save_zone_start;
  2960.  CURRENT_VIEW->zone_end = save_zone_end;
  2961.  CURRENT_VIEW->arbchar_status = save_arbchar_status;
  2962.  CURRENT_VIEW->arbchar_single = save_arbchar_single;
  2963.  CURRENT_VIEW->hex = save_hex;
  2964. /*---------------------------------------------------------------------*/
  2965. /* Check for target not found...                                       */
  2966. /*---------------------------------------------------------------------*/
  2967.  if (rc == RC_TARGET_NOT_FOUND)
  2968.    {
  2969.     if (wrapped)
  2970.       {
  2971.        CURRENT_VIEW->focus_line = save_focus_line;
  2972.        CURRENT_VIEW->current_line = save_current_line;
  2973.       }
  2974.     display_error(34,(CHARTYPE *)"",FALSE);
  2975.     free_target(&target);
  2976. #ifdef TRACE
  2977.     trace_return();
  2978. #endif
  2979.     return(rc);
  2980.    }
  2981. /*---------------------------------------------------------------------*/
  2982. /* Target found, so advance the cursor...                              */
  2983. /*---------------------------------------------------------------------*/
  2984. /* post_process_line(CURRENT_VIEW,save_focus_line,(LINE *)NULL,TRUE);*/
  2985.  if (wrapped)
  2986.    {
  2987.     CURRENT_VIEW->focus_line = save_focus_line;
  2988.     CURRENT_VIEW->current_line = save_current_line;
  2989.     build_screen(current_screen);
  2990.     if (CURRENT_VIEW->current_window == WINDOW_COMMAND
  2991.     ||  compatible_feel == COMPAT_XEDIT)
  2992.        CURRENT_VIEW->current_line = true_line;
  2993.     else
  2994.        CURRENT_VIEW->focus_line = true_line;
  2995.     pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
  2996.    }
  2997.  rc = advance_current_or_focus_line(target.num_lines);
  2998.  free_target(&target);
  2999.  if (wrapped)
  3000.     display_error(0,(CHARTYPE*)"Wrapped...",FALSE);
  3001. #ifdef TRACE
  3002.  trace_return();
  3003. #endif
  3004.  return(rc);
  3005. }
  3006. /***********************************************************************/
  3007. #ifdef HAVE_PROTO
  3008. short execute_modify_command(CHARTYPE *str)
  3009. #else
  3010. short execute_modify_command(str)
  3011. CHARTYPE *str;
  3012. #endif
  3013. /***********************************************************************/
  3014. {
  3015. /*-------------------------- external data ----------------------------*/
  3016.  extern VALUE item_values[18];
  3017.  extern CHARTYPE *temp_cmd;
  3018. /*--------------------------- local data ------------------------------*/
  3019.  register short i=0;
  3020.  short itemno=0;
  3021. /*--------------------------- processing ------------------------------*/
  3022. #ifdef TRACE
  3023.  trace_function("execute.c: execute_modify_command");
  3024. #endif
  3025.  if ((itemno = find_item(str,QUERY_MODIFY)) == (-1))
  3026.     {
  3027.      display_error(1,str,FALSE);
  3028. #ifdef TRACE
  3029.      trace_return();
  3030. #endif
  3031.      return(RC_INVALID_OPERAND);
  3032.     }
  3033.  
  3034.  itemno = get_item_values(itemno,(CHARTYPE *)"",QUERY_MODIFY,0L,NULL,0L);
  3035.  strcpy((DEFCHAR *)temp_cmd,"set");
  3036.  for (i=0;i<itemno+1;i++)
  3037.    {
  3038.     strcat((DEFCHAR *)temp_cmd," ");
  3039.     strcat((DEFCHAR *)temp_cmd,(DEFCHAR *)item_values[i].value);
  3040.    }
  3041. #ifdef TRACE
  3042.  trace_return();
  3043. #endif
  3044.  return(RC_OK);
  3045. }
  3046. /***********************************************************************/
  3047. #ifdef HAVE_PROTO
  3048. LENGTHTYPE calculate_rec_len(short action,LENGTHTYPE current_rec_len,LENGTHTYPE start_col,LINETYPE num_cols)
  3049. #else
  3050. LENGTHTYPE calculate_rec_len(action,current_rec_len,start_col,num_cols)
  3051. short action;
  3052. LENGTHTYPE current_rec_len,start_col;
  3053. LINETYPE num_cols;
  3054. #endif
  3055. /***********************************************************************/
  3056. {
  3057. /*-------------------------- external data ----------------------------*/
  3058. /*--------------------------- local data ------------------------------*/
  3059.  LENGTHTYPE new_rec_len=0;
  3060. /*--------------------------- processing ------------------------------*/
  3061. #ifdef TRACE
  3062.  trace_function("execute.c: calcualte_rec_len");
  3063. #endif
  3064.  switch(action)
  3065.    {
  3066.     case ADJUST_DELETE:
  3067.          if (num_cols > 0)
  3068.            {
  3069.             if (start_col < current_rec_len)
  3070.                new_rec_len = (LENGTHTYPE)(LINETYPE)current_rec_len -
  3071.                               (min((LINETYPE)current_rec_len - (LINETYPE)start_col,num_cols));
  3072.            }
  3073.          else
  3074.            {
  3075.             new_rec_len = current_rec_len;
  3076.            }
  3077.          break;
  3078.     case ADJUST_INSERT:
  3079.          new_rec_len = current_rec_len;
  3080.          break;
  3081.     case ADJUST_OVERWRITE:
  3082.          new_rec_len = current_rec_len;
  3083.          break;
  3084.    }
  3085. #ifdef TRACE
  3086.  trace_return();
  3087. #endif
  3088.  return(new_rec_len);
  3089. }
  3090.  
  3091. /***********************************************************************/
  3092. #ifdef HAVE_PROTO
  3093. static short set_editv(CHARTYPE *var,CHARTYPE *val,bool editv_file,bool rexx_var)
  3094. #else
  3095. static short set_editv(var,val,editv_file,rexx_var)
  3096. CHARTYPE *var;
  3097. CHARTYPE *val;
  3098. bool editv_file;
  3099. bool rexx_var;
  3100. #endif
  3101. /***********************************************************************/
  3102. {
  3103. /*-------------------------- external data ----------------------------*/
  3104.  extern LINE *editv;
  3105. /*--------------------------- local data ------------------------------*/
  3106.  short rc=RC_OK;
  3107.  LINE *curr=NULL;
  3108.  int len_var=0,len_val=0;
  3109.  CHARTYPE *value=NULL;
  3110.  LINE *first=NULL;
  3111. /*--------------------------- processing ------------------------------*/
  3112. #ifdef TRACE
  3113.  trace_function("execute.c: set_editv");
  3114. #endif
  3115.  first = (editv_file)?CURRENT_FILE->editv:editv;
  3116.  if (rexx_var)
  3117.    {
  3118.     rc = get_rexx_variable(var,&value,&len_val);
  3119.     if (rc != RC_OK)
  3120.       {
  3121. #ifdef TRACE
  3122.        trace_return();
  3123. #endif
  3124.        return(rc);
  3125.       }
  3126.    }
  3127.  else
  3128.    {
  3129.     if (val == NULL)
  3130.        value = (CHARTYPE*)"";
  3131.     else
  3132.        value = val;
  3133.     len_val = strlen((DEFCHAR*)value);
  3134.    }
  3135.  var = make_upper(var);
  3136.  len_var = strlen((DEFCHAR*)var);
  3137.  curr = lll_locate(first,var);
  3138.  if (curr) /* found an existing variable */
  3139.    {
  3140.     if (len_val > curr->length)
  3141.       {
  3142.        curr->line = (CHARTYPE *)(*the_realloc)(curr->line,(len_val+1)*sizeof(CHARTYPE));
  3143.        if (curr->line == NULL)
  3144.          {
  3145.           if (rexx_var && value)
  3146.              (*the_free)(value);
  3147.           display_error(30,(CHARTYPE *)"",FALSE);
  3148. #ifdef TRACE
  3149.           trace_return();
  3150. #endif
  3151.           return(RC_OUT_OF_MEMORY);
  3152.          }
  3153.       }
  3154.     if (len_val == 0)  /* need to delete the entry */
  3155.       {
  3156.        if (editv_file)
  3157.           lll_del(&(CURRENT_FILE->editv),NULL,curr,DIRECTION_FORWARD);
  3158.        else
  3159.           lll_del(&editv,NULL,curr,DIRECTION_FORWARD);
  3160.       }
  3161.     else
  3162.        strcpy((DEFCHAR*)curr->line,(DEFCHAR*)value);
  3163.    }
  3164.  else
  3165.    {
  3166.     curr = lll_add(first,NULL,sizeof(LINE));
  3167.     if (curr == NULL)
  3168.       {
  3169.        if (rexx_var && value)
  3170.           (*the_free)(value);
  3171.        display_error(30,(CHARTYPE *)"",FALSE);
  3172. #ifdef TRACE
  3173.        trace_return();
  3174. #endif
  3175.        return(RC_OUT_OF_MEMORY);
  3176.       }
  3177. /*---------------------------------------------------------------------*/
  3178. /* As the current variable is always inserted as the start of the LL   */
  3179. /* we must set the first pointer to the current variable each time.    */
  3180. /*---------------------------------------------------------------------*/
  3181.     if (editv_file)
  3182.        CURRENT_FILE->editv = curr;
  3183.     else
  3184.        editv = curr;
  3185.     curr->line = (CHARTYPE *)(*the_malloc)((len_val+1)*sizeof(CHARTYPE));
  3186.     if (curr->line == NULL)
  3187.       {
  3188.        if (rexx_var && value)
  3189.           (*the_free)(value);
  3190.        display_error(30,(CHARTYPE *)"",FALSE);
  3191. #ifdef TRACE
  3192.        trace_return();
  3193. #endif
  3194.        return(RC_OUT_OF_MEMORY);
  3195.       }
  3196.     strcpy((DEFCHAR*)curr->line,(DEFCHAR*)value);
  3197.     curr->length = len_val;
  3198.     curr->name = (CHARTYPE *)(*the_malloc)((len_var+1)*sizeof(CHARTYPE));
  3199.     if (curr->name == NULL)
  3200.       {
  3201.        if (rexx_var && value)
  3202.           (*the_free)(value);
  3203.        display_error(30,(CHARTYPE *)"",FALSE);
  3204. #ifdef TRACE
  3205.        trace_return();
  3206. #endif
  3207.        return(RC_OUT_OF_MEMORY);
  3208.       }
  3209.     strcpy((DEFCHAR*)curr->name,(DEFCHAR*)var);
  3210.    }
  3211.  if (rexx_var && value)
  3212.     (*the_free)(value);
  3213. #ifdef TRACE
  3214.  trace_return();
  3215. #endif
  3216.  return(rc);
  3217. }
  3218.  
  3219. /***********************************************************************/
  3220. #ifdef HAVE_PROTO
  3221. short execute_editv(short editv_type,bool editv_file,CHARTYPE *params)
  3222. #else
  3223. short execute_editv(editv_type,editv_file,params)
  3224. short editv_type;
  3225. bool editv_file;
  3226. CHARTYPE *params;
  3227. #endif
  3228. /***********************************************************************/
  3229. {
  3230. /*-------------------------- external data ----------------------------*/
  3231.  extern LINE *editv;
  3232.  extern short terminal_lines;
  3233. /*--------------------------- local data ------------------------------*/
  3234. #define EDITV_PARAMS  2
  3235.  CHARTYPE *word[EDITV_PARAMS+1];
  3236.  CHARTYPE strip[EDITV_PARAMS];
  3237.  CHARTYPE *p=NULL,*str=NULL;
  3238.  unsigned short num_params=0;
  3239.  LINE *curr=NULL,*first=NULL;
  3240.  int key=0,lineno=0;
  3241.  short rc=RC_OK;
  3242. /*--------------------------- processing ------------------------------*/
  3243. #ifdef TRACE
  3244.  trace_function("execute.c: execute_editv");
  3245. #endif
  3246.  first = (editv_file)?CURRENT_FILE->editv:editv;
  3247.  switch(editv_type)
  3248.    {
  3249.     case EDITV_SETL:
  3250.          strip[0] = STRIP_BOTH;
  3251.          strip[1] = STRIP_NONE;
  3252.          num_params = param_split(params,word,EDITV_PARAMS,WORD_DELIMS,TEMP_PARAM,strip,FALSE);
  3253.          if (num_params == 0)
  3254.            {
  3255.             display_error(3,(CHARTYPE *)"",FALSE);
  3256. #ifdef TRACE
  3257.             trace_return();
  3258. #endif
  3259.             return(RC_INVALID_OPERAND);
  3260.            }
  3261.          rc = set_editv(word[0],word[1],editv_file,FALSE);
  3262.          break;
  3263.     case EDITV_SET:
  3264.          p = (CHARTYPE *)strtok((DEFCHAR *)params," ");
  3265.          while(p != NULL)
  3266.            {
  3267.             p = make_upper(p);
  3268.             str = (CHARTYPE *)strtok(NULL," ");
  3269.             rc = set_editv(p,str,editv_file,FALSE);
  3270.             if (str == NULL)
  3271.                break;
  3272.             p = (CHARTYPE *)strtok(NULL," ");
  3273.            }
  3274.          break;
  3275.     case EDITV_PUT:
  3276.          p = (CHARTYPE *)strtok((DEFCHAR *)params," ");
  3277.          while(p != NULL)
  3278.            {
  3279.             p = make_upper(p);
  3280.             rc = set_editv(p,NULL,editv_file,TRUE);
  3281.             p = (CHARTYPE *)strtok(NULL," ");
  3282.            }
  3283.          break;
  3284.     case EDITV_GET:
  3285.          p = (CHARTYPE *)strtok((DEFCHAR *)params," ");
  3286.          while(p != NULL)
  3287.            {
  3288.             p = make_upper(p);
  3289.             curr = lll_locate(first,p);
  3290.             if (curr
  3291.             &&  curr->line)
  3292.                str = curr->line;
  3293.             else
  3294.                str = (CHARTYPE *)"";
  3295.             if (set_rexx_variable(p,str,strlen((DEFCHAR*)str),-1) != RC_OK)
  3296.                break;
  3297.             p = (CHARTYPE *)strtok(NULL," ");
  3298.            }
  3299.          break;
  3300.     case EDITV_LIST:
  3301.          wclear(stdscr);
  3302.          if (blank_field(params))
  3303.            {
  3304.             curr = first;
  3305.             while (curr != NULL)
  3306.               {
  3307.                if (curr->line)
  3308.                   str = curr->line;
  3309.                else
  3310.                   str = (CHARTYPE *)"";
  3311.                attrset(A_BOLD);
  3312.                mvaddstr(lineno,0,(DEFCHAR *)curr->name);
  3313.                attrset(A_NORMAL);
  3314.                mvaddstr(lineno,12,(DEFCHAR *)str);
  3315.                lineno++;
  3316.                curr = curr->next;
  3317.               }
  3318.            }
  3319.          else
  3320.            {
  3321.             p = (CHARTYPE *)strtok((DEFCHAR *)params," ");
  3322.             while(p != NULL)
  3323.               {
  3324.                p = make_upper(p);
  3325.                curr = lll_locate(first,p);
  3326.                if (curr
  3327.                &&  curr->line)
  3328.                   str = curr->line;
  3329.                else
  3330.                   str = (CHARTYPE *)"";
  3331.                attrset(A_BOLD);
  3332.                mvaddstr(lineno,0,(DEFCHAR *)p);
  3333.                attrset(A_NORMAL);
  3334.                mvaddstr(lineno,12,(DEFCHAR *)str);
  3335.                lineno++;
  3336.                p = (CHARTYPE *)strtok(NULL," ");
  3337.               }
  3338.            }
  3339.          mvaddstr(terminal_lines-2,0,HIT_ANY_KEY);
  3340.          refresh();
  3341.          while(1)
  3342.            {
  3343.             key = my_getch(stdscr);
  3344. #if defined(XCURSES)
  3345.             if (key == KEY_SF || key == KEY_SR)
  3346.                continue;
  3347. #endif
  3348. #if defined(KEY_MOUSE)
  3349.             if (key == KEY_MOUSE)
  3350.                continue;
  3351. #endif
  3352. #ifdef CAN_RESIZE
  3353.             if (is_termresized())
  3354.                continue;
  3355. #endif     
  3356.             break;
  3357.            }
  3358.          THERefresh((CHARTYPE *)"");
  3359.          restore_THE();
  3360.          break;
  3361.    }
  3362.  
  3363. #ifdef TRACE
  3364.  trace_return();
  3365. #endif
  3366.  return(rc);
  3367. }
  3368.