home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / thesrc15.zip / prefix.c < prev    next >
C/C++ Source or Header  |  1993-11-29  |  53KB  |  1,322 lines

  1. /***********************************************************************/
  2. /* PREFIX.C - Prefix commands.                                         */
  3. /***********************************************************************/
  4. /*
  5.  * THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
  6.  * Copyright (C) 1991-1993 Mark Hessling
  7.  *
  8.  * This program is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU General Public License as
  10.  * published by the Free Software Foundation; either version 2 of
  11.  * the License, or any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16.  * General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to:
  20.  *
  21.  *    The Free Software Foundation, Inc.
  22.  *    675 Mass Ave,
  23.  *    Cambridge, MA 02139 USA.
  24.  *
  25.  *
  26.  * If you make modifications to this software that you feel increases
  27.  * it usefulness for the rest of the community, please email the
  28.  * changes, enhancements, bug fixes as well as any and all ideas to me.
  29.  * This software is going to be maintained and enhanced as deemed
  30.  * necessary by the community.
  31.  *
  32.  * Mark Hessling                     email: M.Hessling@gu.edu.au
  33.  * 36 David Road                     Phone: +61 7 849 7731
  34.  * Holland Park                      Fax:   +61 7 875 5314
  35.  * QLD 4121
  36.  * Australia
  37.  */
  38.  
  39. /*
  40. $Header: C:\THE\RCS\prefix.c 1.4 1993/09/01 16:26:56 MH Interim MH $
  41. */
  42.  
  43. #include <stdio.h>
  44.  
  45. #include "the.h"
  46. #include "proto.h"
  47. /*-------------------------- declarations -----------------------------*/
  48. #ifdef PROTO
  49. static int parse_prefix_command(int,char *,char *);
  50. static int invalidate_prefix(int);
  51. static int prefix_makecurr(int,int,long);
  52. static int prefix_add(int,int,long);
  53. static int prefix_duplicate(int,int,long);
  54. static int prefix_copy(int,int,long);
  55. static int prefix_move(int,int,long);
  56. static int prefix_delete(int,int,long);
  57. static int prefix_shift_left(int,int,long);
  58. static int prefix_shift_right(int,int,long);
  59. static int prefix_block_duplicate(int,int,long);
  60. static int prefix_block_copy(int,int,long);
  61. static int prefix_block_move(int,int,long);
  62. static int prefix_block_delete(int,int,long);
  63. static int prefix_block_shift_left(int,int,long);
  64. static int prefix_block_shift_right(int,int,long);
  65. void clear_pending_prefix_command(int ,LINE *);
  66. static int find_bottom_ppc(int,int);
  67. static int find_target_ppc(int *);
  68. static long calculate_target_line(void);
  69. #if !defined(NOREXX)
  70. static int try_rexx_prefix_macro(int);
  71. #endif
  72. static char *substr(char *, char *, int, int);
  73. #else
  74. static int parse_prefix_command();
  75. static int invalidate_prefix();
  76. static int prefix_makecurr();
  77. static int prefix_add();
  78. static int prefix_duplicate();
  79. static int prefix_copy();
  80. static int prefix_move();
  81. static int prefix_delete();
  82. static int prefix_shift_left();
  83. static int prefix_shift_right();
  84. static int prefix_block_duplicate();
  85. static int prefix_block_copy();
  86. static int prefix_block_move();
  87. static int prefix_block_delete();
  88. static int prefix_block_shift_left();
  89. static int prefix_block_shift_right();
  90. void clear_pending_prefix_command();
  91. static int find_bottom_ppc();
  92. static int find_target_ppc();
  93. static long calculate_target_line();
  94. static char *substr();
  95. #endif
  96. /*---------------------------------------------------------------------*/
  97. /* The following two are to specify the first and last items in the    */
  98. /* linked list for prefix synonyms.                                    */
  99. /*---------------------------------------------------------------------*/
  100. LINE *first_prefix_synonym=NULL;
  101. LINE *last_prefix_synonym=NULL;
  102. /*---------------------------------------------------------------------*/
  103.  
  104. #define PPC_NO_TARGET        (-1)
  105. #define PPC_NO_COMMAND       (-2)
  106. #define PPC_TARGET_PREVIOUS  0
  107. #define PPC_TARGET_FOLLOWING 1
  108. /* the above two defines correspond to the position in the pc[] array  */
  109. /* and should be changed if the position in pc[] array changes.        */
  110.  
  111. #define NUMBER_PREFIX_COMMANDS 17
  112.  static PREFIX_COMMAND pc[NUMBER_PREFIX_COMMANDS] =
  113.   {
  114.    {(char *)"p",1,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,TRUE,NULL},
  115.    {(char *)"f",1,FALSE,FALSE,FALSE,FALSE,FALSE,TRUE,FALSE,NULL},
  116.    {(char *)"\"\"",2,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,prefix_block_duplicate},
  117.    {(char *)"cc",2,TRUE,TRUE,FALSE,TRUE,TRUE,FALSE,FALSE,prefix_block_copy},
  118.    {(char *)"mm",2,TRUE,TRUE,FALSE,TRUE,TRUE,FALSE,FALSE,prefix_block_move},
  119.    {(char *)"dd",2,TRUE,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,prefix_block_delete},
  120.    {(char *)"<<",2,TRUE,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,prefix_block_shift_left},
  121.    {(char *)">>",2,TRUE,TRUE,FALSE,TRUE,FALSE,FALSE,FALSE,prefix_block_shift_right},
  122.    {(char *)"\"",1,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,prefix_duplicate},
  123.    {(char *)"c",1,TRUE,TRUE,TRUE,FALSE,TRUE,FALSE,FALSE,prefix_copy},
  124.    {(char *)"m",1,TRUE,TRUE,TRUE,FALSE,TRUE,FALSE,FALSE,prefix_move},
  125.    {(char *)"d",1,TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,prefix_delete},
  126.    {(char *)"<",1,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,prefix_shift_left},
  127.    {(char *)">",1,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,prefix_shift_right},
  128.    {(char *)"i",1,TRUE,TRUE,FALSE,FALSE,FALSE,TRUE,FALSE,prefix_add},
  129.    {(char *)"a",1,TRUE,TRUE,FALSE,FALSE,FALSE,TRUE,FALSE,prefix_add},
  130.    {(char *)"/",1,TRUE,FALSE,FALSE,FALSE,FALSE,TRUE,TRUE,prefix_makecurr},
  131.   };
  132.  
  133. char pending_prefix_command[PREFIX_WIDTH+1]="";
  134. long prefix_current_line;
  135. bool in_prefix_macro=FALSE;     /* indicate if processing prefix macro */
  136. /*-------------------------- external data ----------------------------*/
  137. extern VIEW_DETAILS *vd_current,*vd_first,*vd_mark;
  138. /***********************************************************************/
  139. #ifdef PROTO
  140. int execute_prefix_commands(void)
  141. #else
  142. int execute_prefix_commands()
  143. #endif
  144. /***********************************************************************/
  145. {
  146. /*-------------------------- external data ----------------------------*/
  147.  extern char number_of_files;
  148. /*--------------------------- local data ------------------------------*/
  149.  register int i;
  150.  int len,cmd_idx,rc,ppc_idx;
  151.  char cmd[PREFIX_WIDTH+1];
  152.  char mult[PREFIX_WIDTH+1];
  153.  int first_pending = (-1);
  154.  long long_mult=0L;
  155.  long start_line,number_lines,target_line;
  156.  int top_ppc,bot_ppc,target_ppc;
  157.  int number_prefix_commands;
  158. /*--------------------------- processing ------------------------------*/
  159. #ifdef TRACE
  160.  trace_function("prefix.c:  execute_prefix_commands");
  161. #endif
  162.  post_process_line(CURRENT_VIEW->focus_line);
  163. /*---------------------------------------------------------------------*/
  164. /* This variable is set here because post_process_line() actually sets */
  165. /* CURRENT_VIEW->prefix_command_index.                                 */
  166. /*---------------------------------------------------------------------*/
  167.  number_prefix_commands = CURRENT_VIEW->prefix_command_index;
  168. /*---------------------------------------------------------------------*/
  169. /* For each pending prefix command for the current view, validate the  */
  170. /* command and parameters.                                             */
  171. /*---------------------------------------------------------------------*/
  172.  for (i=0;i<number_prefix_commands;i++)
  173.    {
  174. /*---------------------------------------------------------------------*/
  175. /* If a set point command, validate the name.                          */
  176. /*---------------------------------------------------------------------*/
  177.     if (CURRENT_VIEW->ppc[i].ppc_command[0] == '.')
  178.       {
  179.        if (isalpha(CURRENT_VIEW->ppc[i].ppc_command[1]))
  180.          {
  181.           if (execute_set_point(CURRENT_VIEW->ppc[i].ppc_command,CURRENT_VIEW->ppc[i].ppc_line_number,TRUE) != RC_OK)
  182.             {
  183.              invalidate_prefix(i);
  184.              continue;
  185.             }
  186.           clear_pending_prefix_command(i,(LINE *)NULL);
  187.           continue;
  188.          }
  189.        else
  190.          {
  191.           invalidate_prefix(i);
  192.           continue;
  193.          }
  194.       }
  195. /*---------------------------------------------------------------------*/
  196. /* If an invalid prefix command from last time, clear it.              */
  197. /*---------------------------------------------------------------------*/
  198.     if (CURRENT_VIEW->ppc[i].ppc_command[0] == '?')
  199.       {
  200.        clear_pending_prefix_command(i,(LINE *)NULL);
  201.        continue;
  202.       }
  203. /*---------------------------------------------------------------------*/
  204. /* To get here we have 'normal' prefix command.                        */
  205. /*---------------------------------------------------------------------*/
  206. #if !defined(NOREXX)               /* if REXX support is in effect ... */
  207. /*---------------------------------------------------------------------*/
  208. /* first determine if the command is a prefix macro BEFORE looking for */
  209. /* standard prefix commands.                                           */
  210. /*---------------------------------------------------------------------*/
  211.     rc = try_rexx_prefix_macro(i);
  212. /*---------------------------------------------------------------------*/
  213. /* If at this point there are no more files in the ring; we assume that*/
  214. /* this was caused by exitting the last file in the ring from a prefix */
  215. /* macro, exit and ignore any more prefix commands. This is messy !!!  */
  216. /*---------------------------------------------------------------------*/
  217.     if (number_of_files == 0)
  218.       {
  219. /*     invalidate_prefix(i);*/
  220. #ifdef TRACE
  221.        trace_return();
  222. #endif
  223.        return(RC_COMMAND_NO_FILES);
  224.       }
  225.     if (rc != RC_NOT_COMMAND)
  226.        continue;
  227. #endif
  228. /*---------------------------------------------------------------------*/
  229. /* if no prefix macro found for the prefix command, check to see if it */
  230. /* is a standard prefix command.                                       */
  231. /*---------------------------------------------------------------------*/
  232.     if ((cmd_idx = parse_prefix_command(i,cmd,mult)) == PPC_NO_TARGET)
  233.       {
  234.        invalidate_prefix(i);
  235.        continue;
  236.       }
  237.     if (cmd_idx == PPC_NO_COMMAND)
  238.        continue;
  239. /*---------------------------------------------------------------------*/
  240. /* We now have a recognised command. We have to validate its parameters*/
  241. /* and find any associated pending commands.                           */
  242. /*---------------------------------------------------------------------*/
  243. /*---------------------------------------------------------------------*/
  244. /* Set the block_command flag for the current prefix command to the    */
  245. /* appropriate value for the prefix command.                           */
  246. /*---------------------------------------------------------------------*/
  247.     CURRENT_VIEW->ppc[i].ppc_block_command = pc[cmd_idx].block_prefix_command;
  248. /*---------------------------------------------------------------------*/
  249. /* If the command does not allow parameters and there are parameters,  */
  250. /* error.                                                              */
  251. /*---------------------------------------------------------------------*/
  252.     if (!pc[cmd_idx].multiples_allowed
  253.     && strcmp(mult,"") != 0)
  254.       {
  255.        invalidate_prefix(i);
  256.        continue;
  257.       }
  258. /*---------------------------------------------------------------------*/
  259. /* If the command does allow parameters and there are no parameters,   */
  260. /* default to 1.                                                       */
  261. /*---------------------------------------------------------------------*/
  262.     if (strcmp(mult,"") == 0)
  263.        strcpy(mult,"1");
  264. /*---------------------------------------------------------------------*/
  265. /* If the command allows full targets, validate the target.            */
  266. /*---------------------------------------------------------------------*/
  267.     if (pc[cmd_idx].multiples_allowed)
  268.       {
  269.        if (pc[cmd_idx].full_target_allowed)
  270.           long_mult = valid_target(mult,CURRENT_VIEW->ppc[i].ppc_line_number);
  271.        else
  272.           if (!valid_positive_integer(mult))
  273.              long_mult = TARGET_ERROR;
  274.           else
  275.              long_mult = atol(mult);
  276.       }
  277. /*---------------------------------------------------------------------*/
  278. /* If the target is invalid or not found, invalidate the command.      */
  279. /*---------------------------------------------------------------------*/
  280.     if (long_mult == TARGET_ERROR
  281.     ||  long_mult == TARGET_NOT_FOUND)
  282.       {
  283.        invalidate_prefix(i);
  284.        continue;
  285.       }
  286.     CURRENT_VIEW->ppc[i].ppc_cmd_param = long_mult;
  287.    }
  288. /*---------------------------------------------------------------------*/
  289. /* For each valid pending  command for the current view, execute  the  */
  290. /* command.                                                            */
  291. /*---------------------------------------------------------------------*/
  292.  strcpy(pending_prefix_command,"");
  293.  for (i=0;i<number_prefix_commands;i++)
  294.    {
  295.     top_ppc = bot_ppc = target_ppc = (-1);
  296. /*---------------------------------------------------------------------*/
  297. /* Execute the function associated with the prefix command...          */
  298. /*---------------------------------------------------------------------*/
  299.     cmd_idx = CURRENT_VIEW->ppc[i].ppc_cmd_idx;
  300.     long_mult = CURRENT_VIEW->ppc[i].ppc_cmd_param;
  301.     if (cmd_idx != (-1)
  302.     &&  pc[cmd_idx].function != NULL)
  303.        rc = (*pc[cmd_idx].function)(i,cmd_idx,long_mult);
  304.    }
  305. /*---------------------------------------------------------------------*/
  306. /* Now that we are here, we have to reset the count of the pending     */
  307. /* prefix commands.                                                    */
  308. /*---------------------------------------------------------------------*/
  309.  ppc_idx = 0;
  310.  strcpy(pending_prefix_command,"");
  311.  for (i=0;i<number_prefix_commands;i++)
  312.    {
  313.     if (CURRENT_VIEW->ppc[i].ppc_line_number != (-1L))
  314.        ppc_idx = i;
  315. /*---------------------------------------------------------------------*/
  316. /* If the heading display of pending prefix commands is blank, set it  */
  317. /* to the command for which there is no bottom block or target command.*/
  318. /*---------------------------------------------------------------------*/
  319.     if (strcmp(pending_prefix_command,"") == 0
  320.     && CURRENT_VIEW->ppc[i].ppc_cmd_idx != (-1))
  321.        strcpy(pending_prefix_command,pc[CURRENT_VIEW->ppc[i].ppc_cmd_idx].cmd);
  322.    }
  323.  pre_process_line(CURRENT_VIEW->focus_line);
  324.  show_page();
  325. #ifdef TRACE
  326.  trace_return();
  327. #endif
  328.  return(RC_OK);
  329. }
  330. /***********************************************************************/
  331. #ifdef PROTO
  332. static int parse_prefix_command(int ppc_idx,char *cmd,
  333.                                 char *mult)
  334. #else
  335. static int parse_prefix_command(ppc_idx,cmd,mult)
  336. int ppc_idx;
  337. char *cmd,*mult;
  338. #endif
  339. /***********************************************************************/
  340. {
  341. /*-------------------------- external data ----------------------------*/
  342. /*--------------------------- local data ------------------------------*/
  343.  register int i,j;
  344.  int len_pcmd;
  345.  char pcmd[PREFIX_WIDTH+1];
  346.  int pos,rc;
  347.  LINE *curr;
  348. /*--------------------------- processing ------------------------------*/
  349. #ifdef TRACE
  350.  trace_function("prefix.c:  parse_prefix_command");
  351. #endif
  352. /*---------------------------------------------------------------------*/
  353. /* For each pending prefix command for the current view, execute the   */
  354. /* appropriate command.                                                */
  355. /*---------------------------------------------------------------------*/
  356.  rc = PPC_NO_TARGET;
  357.  strcpy(pcmd,CURRENT_VIEW->ppc[ppc_idx].ppc_command);/* get our own copy to pull apart */
  358.  if (blank_field(pcmd))       /* if prefix command is blank, return */
  359.    {
  360. #ifdef TRACE
  361.     trace_return();
  362. #endif
  363.     return(PPC_NO_COMMAND);
  364.    }
  365.  len_pcmd = strlen(pcmd);
  366. /*---------------------------------------------------------------------*/
  367. /* For each prefix synonym, determine if it exists somewhere in the    */
  368. /* entered prefix command.                                             */
  369. /*---------------------------------------------------------------------*/
  370.  curr = first_prefix_synonym;
  371.  while(curr != NULL)
  372.    {
  373.     pos = memfind(pcmd,curr->name,len_pcmd,strlen(curr->name),TRUE,FALSE,' ');
  374.     if (pos == (-1))
  375.       {
  376.        curr = curr->next;
  377.        continue;
  378.       }
  379. /*---------------------------------------------------------------------*/
  380. /* Now that a match on synonym is made, determine the original prefix  */
  381. /* command associated with that synonym...                             */
  382. /*---------------------------------------------------------------------*/
  383.     for (i=0;i<NUMBER_PREFIX_COMMANDS;i++)
  384.       {
  385.        if (strcmp(pc[i].cmd,curr->line) == 0)
  386.          {
  387.           strcpy(cmd,pc[i].cmd);
  388.           for (j=0;j<strlen(curr->name);j++)
  389.              *(pcmd+pos+j) = ' ';
  390.           strtrunc(pcmd);
  391.           strcpy(mult,pcmd);
  392.           CURRENT_VIEW->ppc[ppc_idx].ppc_cmd_idx = i;
  393. #ifdef TRACE
  394.           trace_return();
  395. #endif
  396.           return(i);
  397.          }
  398.       }
  399. /*---------------------------------------------------------------------*/
  400. /* To get here we found a prefix synonym, but no matching original     */
  401. /* command, so return an error.                                        */
  402. /*---------------------------------------------------------------------*/
  403.     CURRENT_VIEW->ppc[ppc_idx].ppc_cmd_idx = (-1);
  404. #ifdef TRACE
  405.     trace_return();
  406. #endif
  407.     return(rc);
  408.    }
  409. /*---------------------------------------------------------------------*/
  410. /* For each valid prefix command,  check to see if a valid command     */
  411. /* exists somewhere in the entered prefix command.                     */
  412. /*---------------------------------------------------------------------*/
  413.  for (i=0;i<NUMBER_PREFIX_COMMANDS;i++)
  414.    {
  415.     pos = memfind(pcmd,pc[i].cmd,len_pcmd,pc[i].cmd_len,TRUE,FALSE,' ');
  416.     if (pos == (-1))
  417.        continue;
  418.     strcpy(cmd,pc[i].cmd);
  419.     for (j=0;j<pc[i].cmd_len;j++)
  420.        *(pcmd+pos+j) = ' ';
  421.     strtrunc(pcmd);
  422.     strcpy(mult,pcmd);
  423.     rc = i;
  424. /*---------------------------------------------------------------------*/
  425. /* Set a flag in ppc[] array to indicate which command is present.     */
  426. /*---------------------------------------------------------------------*/
  427.     CURRENT_VIEW->ppc[ppc_idx].ppc_cmd_idx = i;
  428.     break;
  429.    }
  430. /*---------------------------------------------------------------------*/
  431. /* If command not found, set a flag in ppc[] array to indicate command */
  432. /* is invalid.                                                         */
  433. /*---------------------------------------------------------------------*/
  434.  if (rc == PPC_NO_TARGET)
  435.     CURRENT_VIEW->ppc[ppc_idx].ppc_cmd_idx = (-1);
  436. #ifdef TRACE
  437.  trace_return();
  438. #endif
  439.  return(rc);
  440. }
  441. /***********************************************************************/
  442. #ifdef PROTO
  443. static int prefix_makecurr(int ppc_idx,int cmd_idx,long number_lines)
  444. #else
  445. static int prefix_makecurr(ppc_idx,cmd_idx,number_lines)
  446. int ppc_idx,cmd_idx;
  447. long number_lines;
  448. #endif
  449. /***********************************************************************/
  450. {
  451. /*-------------------------- external data ----------------------------*/
  452. /*--------------------------- local data ------------------------------*/
  453.  long top_line = CURRENT_VIEW->ppc[ppc_idx].ppc_line_number;
  454. /*--------------------------- processing ------------------------------*/
  455.  clear_pending_prefix_command(ppc_idx,(LINE *)NULL);
  456.  execute_makecurr(top_line);
  457.  return(0);
  458. }
  459. /***********************************************************************/
  460. #ifdef PROTO
  461. static int prefix_add(int ppc_idx,int cmd_idx,long number_lines)
  462. #else
  463. static int prefix_add(ppc_idx,cmd_idx,number_lines)
  464. int ppc_idx,cmd_idx;
  465. long number_lines;
  466. #endif
  467. /***********************************************************************/
  468. {
  469. /*-------------------------- external data ----------------------------*/
  470. /*--------------------------- local data ------------------------------*/
  471.  int rc=(-1);
  472.  long top_line = CURRENT_VIEW->ppc[ppc_idx].ppc_line_number;
  473. /*--------------------------- processing ------------------------------*/
  474.  if (top_line == CURRENT_FILE->number_lines+1)
  475.     top_line--;
  476.  clear_pending_prefix_command(ppc_idx,(LINE *)NULL);
  477.  rc = insert_new_line((char *)"",0,number_lines,
  478.                      top_line,FALSE,FALSE);
  479.  return(rc);
  480. }
  481. /***********************************************************************/
  482. #ifdef PROTO
  483. static int prefix_duplicate(int ppc_idx,int cmd_idx,long number_occ)
  484. #else
  485. static int prefix_duplicate(ppc_idx,cmd_idx,number_occ)
  486. int ppc_idx,cmd_idx;
  487. long number_occ;
  488. #endif
  489. /***********************************************************************/
  490. {
  491. /*-------------------------- external data ----------------------------*/
  492. /*--------------------------- local data ------------------------------*/
  493.  int rc=(-1);
  494.  long top_line = CURRENT_VIEW->ppc[ppc_idx].ppc_line_number;
  495. /*--------------------------- processing ------------------------------*/
  496.  clear_pending_prefix_command(ppc_idx,(LINE *)NULL);
  497.  if (top_line != 0L
  498.  &&  top_line != CURRENT_FILE->number_lines+1)
  499.     rc = rearrange_line_blocks(COMMAND_DUPLICATE,SOURCE_PREFIX,top_line,top_line,top_line,(int)number_occ,CURRENT_VIEW,CURRENT_VIEW);
  500.  return(rc);
  501. }
  502. /***********************************************************************/
  503. #ifdef PROTO
  504. static int prefix_copy(int ppc_idx,int cmd_idx,long number_lines)
  505. #else
  506. static int prefix_copy(ppc_idx,cmd_idx,number_lines)
  507. int ppc_idx,cmd_idx;
  508. long number_lines;
  509. #endif
  510. /***********************************************************************/
  511. {
  512. /*-------------------------- external data ----------------------------*/
  513. /*--------------------------- local data ------------------------------*/
  514.  long bottom_line,target_line;
  515.  long top_line = CURRENT_VIEW->ppc[ppc_idx].ppc_line_number;
  516.  int rc=(-1);
  517. /*--------------------------- processing ------------------------------*/
  518.  if ((target_line = calculate_target_line()) == (-1L))
  519.     return(-1L);
  520.  bottom_line = top_line + number_lines - ((number_lines < 0L) ? (-1L) : 1L);
  521.  clear_pending_prefix_command(ppc_idx,(LINE *)NULL);
  522.  if (top_line != 0L
  523.  &&  top_line != CURRENT_FILE->number_lines+1)
  524.     rc = rearrange_line_blocks(COMMAND_COPY,SOURCE_PREFIX,top_line,bottom_line,target_line,1,CURRENT_VIEW,CURRENT_VIEW);
  525.  return(rc);
  526. }
  527. /***********************************************************************/
  528. #ifdef PROTO
  529. static int prefix_move(int ppc_idx,int cmd_idx,long number_lines)
  530. #else
  531. static int prefix_move(ppc_idx,cmd_idx,number_lines)
  532. int ppc_idx,cmd_idx;
  533. long number_lines;
  534. #endif
  535. /***********************************************************************/
  536. {
  537. /*-------------------------- external data ----------------------------*/
  538. /*--------------------------- local data ------------------------------*/
  539.  long bottom_line,target_line;
  540.  long top_line = CURRENT_VIEW->ppc[ppc_idx].ppc_line_number;
  541.  int rc=(-1);
  542. /*--------------------------- processing ------------------------------*/
  543.  if ((target_line = calculate_target_line()) == (-1L))
  544.     return(-1L);
  545.  clear_pending_prefix_command(ppc_idx,(LINE *)NULL);
  546.  bottom_line = top_line + number_lines - ((number_lines < 0L) ? (-1L) : 1L);
  547.  
  548.  if (top_line != 0L
  549.  &&  top_line != CURRENT_FILE->number_lines+1)
  550.    {
  551.     if ((rc = rearrange_line_blocks(COMMAND_MOVE_COPY_SAME,SOURCE_PREFIX,
  552.          top_line,bottom_line,target_line,1,CURRENT_VIEW,CURRENT_VIEW)) != RC_OK)
  553.        return(rc);
  554.     if (target_line < top_line)
  555.       {
  556.        top_line += number_lines;
  557.        target_line += number_lines;
  558.        bottom_line += number_lines;
  559.       }
  560.     rc = rearrange_line_blocks(COMMAND_MOVE_DELETE_SAME,SOURCE_PREFIX,
  561.          top_line,bottom_line,target_line,1,CURRENT_VIEW,CURRENT_VIEW);
  562.    }
  563.  return(rc);
  564. }
  565. /***********************************************************************/
  566. #ifdef PROTO
  567. static int prefix_delete(int ppc_idx,int cmd_idx,long number_lines)
  568. #else
  569. static int prefix_delete(ppc_idx,cmd_idx,number_lines)
  570. int ppc_idx,cmd_idx;
  571. long number_lines;
  572. #endif
  573. /***********************************************************************/
  574. {
  575. /*-------------------------- external data ----------------------------*/
  576. /*--------------------------- local data ------------------------------*/
  577.  int rc=(-1);
  578.  long top_line = CURRENT_VIEW->ppc[ppc_idx].ppc_line_number;
  579.  long bottom_line,target_line;
  580. /*--------------------------- processing ------------------------------*/
  581.  
  582.  clear_pending_prefix_command(ppc_idx,(LINE *)NULL);
  583.  if (!TOF(top_line)
  584.  &&  !BOF(top_line))
  585.    {
  586.     bottom_line = top_line + number_lines - ((number_lines < 0L) ? (-1L) : 1L);
  587.     target_line = (number_lines < 0L) ? (bottom_line) : (top_line);
  588.     rc = rearrange_line_blocks(COMMAND_DELETE,SOURCE_PREFIX,top_line,bottom_line,target_line,1,CURRENT_VIEW,CURRENT_VIEW);
  589.    }
  590.  return(rc);
  591. }
  592. /***********************************************************************/
  593. #ifdef PROTO
  594. static int prefix_shift_left(int ppc_idx,int cmd_idx,long number_cols)
  595. #else
  596. static int prefix_shift_left(ppc_idx,cmd_idx,number_cols)
  597. int ppc_idx,cmd_idx;
  598. long number_cols;
  599. #endif
  600. /***********************************************************************/
  601. {
  602. /*-------------------------- external data ----------------------------*/
  603. /*--------------------------- local data ------------------------------*/
  604.  long top_line = CURRENT_VIEW->ppc[ppc_idx].ppc_line_number;
  605. /*--------------------------- processing ------------------------------*/
  606.  clear_pending_prefix_command(ppc_idx,(LINE *)NULL);
  607.  if (top_line != 0L
  608.  &&  top_line != CURRENT_FILE->number_lines+1)
  609.    {
  610.     execute_shift_command(TRUE,(int)number_cols,top_line,1L);
  611.    }
  612.  return(0);
  613. }
  614. /***********************************************************************/
  615. #ifdef PROTO
  616. static int prefix_shift_right(int ppc_idx,int cmd_idx,long number_cols)
  617. #else
  618. static int prefix_shift_right(ppc_idx,cmd_idx,number_cols)
  619. int ppc_idx,cmd_idx;
  620. long number_cols;
  621. #endif
  622. /***********************************************************************/
  623. {
  624. /*-------------------------- external data ----------------------------*/
  625. /*--------------------------- local data ------------------------------*/
  626.  long start_line = CURRENT_VIEW->ppc[ppc_idx].ppc_line_number;
  627. /*--------------------------- processing ------------------------------*/
  628.  clear_pending_prefix_command(ppc_idx,(LINE *)NULL);
  629.  if (start_line != 0L
  630.  &&  start_line != CURRENT_FILE->number_lines+1)
  631.    {
  632.     execute_shift_command(FALSE,(int)number_cols,start_line,1L);
  633.    }
  634.  return(0);
  635. }
  636. /***********************************************************************/
  637. #ifdef PROTO
  638. static int prefix_block_duplicate(int ppc_idx,int cmd_idx,long number_occ)
  639. #else
  640. static int prefix_block_duplicate(ppc_idx,cmd_idx,number_occ)
  641. int ppc_idx,cmd_idx;
  642. long number_occ;
  643. #endif
  644. /***********************************************************************/
  645. {
  646. /*-------------------------- external data ----------------------------*/
  647. /*--------------------------- local data ------------------------------*/
  648.  int bottom_idx,rc;
  649.  long top_line,bottom_line;
  650. /*--------------------------- processing ------------------------------*/
  651.  if ((bottom_idx = find_bottom_ppc(ppc_idx,cmd_idx)) == PPC_NO_TARGET)
  652.     return(-1L);
  653.  top_line = min(CURRENT_VIEW->ppc[ppc_idx].ppc_line_number,CURRENT_VIEW->ppc[bottom_idx].ppc_line_number);
  654.  bottom_line = max(CURRENT_VIEW->ppc[ppc_idx].ppc_line_number,CURRENT_VIEW->ppc[bottom_idx].ppc_line_number);
  655.  top_line = (top_line == 0L) ? 1L : top_line;
  656.  bottom_line = (bottom_line == CURRENT_FILE->number_lines+1L) ? bottom_line-1L : bottom_line;
  657.  clear_pending_prefix_command(ppc_idx,(LINE *)NULL);
  658.  clear_pending_prefix_command(bottom_idx,(LINE *)NULL);
  659.  rc = rearrange_line_blocks(COMMAND_DUPLICATE,SOURCE_PREFIX,top_line,bottom_line,bottom_line,(int)number_occ,CURRENT_VIEW,CURRENT_VIEW);
  660.  return(rc);
  661. }
  662. /***********************************************************************/
  663. #ifdef PROTO
  664. static int prefix_block_copy(int ppc_idx,int cmd_idx,long number_lines)
  665. #else
  666. static int prefix_block_copy(ppc_idx,cmd_idx,number_lines)
  667. int ppc_idx,cmd_idx;
  668. long number_lines;
  669. #endif
  670. /***********************************************************************/
  671. {
  672. /*-------------------------- external data ----------------------------*/
  673. /*--------------------------- local data ------------------------------*/
  674.  int bottom_idx,rc;
  675.  long top_line,bottom_line,target_line;
  676. /*--------------------------- processing ------------------------------*/
  677.  if ((bottom_idx = find_bottom_ppc(ppc_idx,cmd_idx)) == PPC_NO_TARGET)
  678.     return(-1L);
  679.  if ((target_line = calculate_target_line()) == (-1L))
  680.     return(-1L);
  681.  top_line = min(CURRENT_VIEW->ppc[ppc_idx].ppc_line_number,CURRENT_VIEW->ppc[bottom_idx].ppc_line_number);
  682.  bottom_line = max(CURRENT_VIEW->ppc[ppc_idx].ppc_line_number,CURRENT_VIEW->ppc[bottom_idx].ppc_line_number);
  683.  top_line = (top_line == 0L) ? 1L : top_line;
  684.  bottom_line = (bottom_line == CURRENT_FILE->number_lines+1L) ? bottom_line-1L : bottom_line;
  685.  clear_pending_prefix_command(ppc_idx,(LINE *)NULL);
  686.  clear_pending_prefix_command(bottom_idx,(LINE *)NULL);
  687.  rc = rearrange_line_blocks(COMMAND_COPY,SOURCE_PREFIX,top_line,bottom_line,target_line,1,CURRENT_VIEW,CURRENT_VIEW);
  688.  return(rc);
  689. }
  690. /***********************************************************************/
  691. #ifdef PROTO
  692. static int prefix_block_move(int ppc_idx,int cmd_idx,long number_lines)
  693. #else
  694. static int prefix_block_move(ppc_idx,cmd_idx,number_lines)
  695. int ppc_idx,cmd_idx;
  696. long number_lines;
  697. #endif
  698. /***********************************************************************/
  699. {
  700. /*-------------------------- external data ----------------------------*/
  701. /*--------------------------- local data ------------------------------*/
  702.  int bottom_idx,rc;
  703.  long top_line,bottom_line,target_line,num_lines;
  704. /*--------------------------- processing ------------------------------*/
  705.  if ((bottom_idx = find_bottom_ppc(ppc_idx,cmd_idx)) == PPC_NO_TARGET)
  706.     return(-1L);
  707.  if ((target_line = calculate_target_line()) == (-1L))
  708.     return(-1L);
  709.  top_line = min(CURRENT_VIEW->ppc[ppc_idx].ppc_line_number,CURRENT_VIEW->ppc[bottom_idx].ppc_line_number);
  710.  bottom_line = max(CURRENT_VIEW->ppc[ppc_idx].ppc_line_number,CURRENT_VIEW->ppc[bottom_idx].ppc_line_number);
  711.  top_line = (top_line == 0L) ? 1L : top_line;
  712.  bottom_line = (bottom_line == CURRENT_FILE->number_lines+1L) ? bottom_line-1L : bottom_line;
  713.  clear_pending_prefix_command(ppc_idx,(LINE *)NULL);
  714.  clear_pending_prefix_command(bottom_idx,(LINE *)NULL);
  715.  if ((rc = rearrange_line_blocks(COMMAND_MOVE_COPY_SAME,SOURCE_PREFIX,
  716.            top_line,bottom_line,target_line,1,CURRENT_VIEW,CURRENT_VIEW)) != RC_OK)
  717.     return(rc);
  718.  if (target_line < top_line)
  719.    {
  720.     num_lines = bottom_line - top_line + 1L;
  721.     top_line += num_lines;
  722.     bottom_line += num_lines;
  723.     target_line += num_lines;
  724.    }
  725.  rc = rearrange_line_blocks(COMMAND_MOVE_DELETE_SAME,SOURCE_PREFIX,
  726.       top_line,bottom_line,target_line,1,CURRENT_VIEW,CURRENT_VIEW);
  727.  return(rc);
  728. }
  729. /***********************************************************************/
  730. #ifdef PROTO
  731. static int prefix_block_delete(int ppc_idx,int cmd_idx,long number_lines)
  732. #else
  733. static int prefix_block_delete(ppc_idx,cmd_idx,number_lines)
  734. int ppc_idx,cmd_idx;
  735. long number_lines;
  736. #endif
  737. /***********************************************************************/
  738. {
  739. /*-------------------------- external data ----------------------------*/
  740. /*--------------------------- local data ------------------------------*/
  741.  int bottom_idx,rc;
  742.  long top_line,bottom_line;
  743. /*--------------------------- processing ------------------------------*/
  744.  if ((bottom_idx = find_bottom_ppc(ppc_idx,cmd_idx)) == PPC_NO_TARGET)
  745.     return(-1L);
  746.  top_line = min(CURRENT_VIEW->ppc[ppc_idx].ppc_line_number,CURRENT_VIEW->ppc[bottom_idx].ppc_line_number);
  747.  bottom_line = max(CURRENT_VIEW->ppc[ppc_idx].ppc_line_number,CURRENT_VIEW->ppc[bottom_idx].ppc_line_number);
  748.  top_line = (top_line == 0L) ? 1L : top_line;
  749.  bottom_line = (bottom_line == CURRENT_FILE->number_lines+1L) ? bottom_line-1L : bottom_line;
  750.  clear_pending_prefix_command(ppc_idx,(LINE *)NULL);
  751.  clear_pending_prefix_command(bottom_idx,(LINE *)NULL);
  752.  rc = rearrange_line_blocks(COMMAND_DELETE,SOURCE_PREFIX,top_line,bottom_line,bottom_line,1,CURRENT_VIEW,CURRENT_VIEW);
  753.  return(rc);
  754. /*--------------------------- processing ------------------------------*/
  755. }
  756. /***********************************************************************/
  757. #ifdef PROTO
  758. static int prefix_block_shift_left(int ppc_idx,int cmd_idx,long number_cols)
  759. #else
  760. static int prefix_block_shift_left(ppc_idx,cmd_idx,number_cols)
  761. int ppc_idx,cmd_idx;
  762. long number_cols;
  763. #endif
  764. /***********************************************************************/
  765. {
  766. /*-------------------------- external data ----------------------------*/
  767. /*--------------------------- local data ------------------------------*/
  768.  int bottom_idx;
  769.  long top_line,bottom_line;
  770. /*--------------------------- processing ------------------------------*/
  771.  if ((bottom_idx = find_bottom_ppc(ppc_idx,cmd_idx)) == PPC_NO_TARGET)
  772.     return(-1L);
  773.  top_line = min(CURRENT_VIEW->ppc[ppc_idx].ppc_line_number,CURRENT_VIEW->ppc[bottom_idx].ppc_line_number);
  774.  bottom_line = max(CURRENT_VIEW->ppc[ppc_idx].ppc_line_number,CURRENT_VIEW->ppc[bottom_idx].ppc_line_number);
  775.  
  776.  top_line = (top_line == 0L) ? 1L : top_line;
  777.  bottom_line = (bottom_line == CURRENT_FILE->number_lines+1L) ? bottom_line-1L : bottom_line;
  778.  clear_pending_prefix_command(ppc_idx,(LINE *)NULL);
  779.  clear_pending_prefix_command(bottom_idx,(LINE *)NULL);
  780.  
  781.  execute_shift_command(TRUE,(int)number_cols,top_line,bottom_line-top_line+1L);
  782.  
  783.  return(0);
  784. }
  785. /***********************************************************************/
  786. #ifdef PROTO
  787. static int prefix_block_shift_right(int ppc_idx,int cmd_idx,long number_cols)
  788. #else
  789. static int prefix_block_shift_right(ppc_idx,cmd_idx,number_cols)
  790. int ppc_idx,cmd_idx;
  791. long number_cols;
  792. #endif
  793. /***********************************************************************/
  794. {
  795. /*-------------------------- external data ----------------------------*/
  796. /*--------------------------- local data ------------------------------*/
  797.  int bottom_idx;
  798.  long top_line,bottom_line;
  799. /*--------------------------- processing ------------------------------*/
  800.  if ((bottom_idx = find_bottom_ppc(ppc_idx,cmd_idx)) == PPC_NO_TARGET)
  801.     return(-1L);
  802.  top_line = min(CURRENT_VIEW->ppc[ppc_idx].ppc_line_number,CURRENT_VIEW->ppc[bottom_idx].ppc_line_number);
  803.  bottom_line = max(CURRENT_VIEW->ppc[ppc_idx].ppc_line_number,CURRENT_VIEW->ppc[bottom_idx].ppc_line_number);
  804.  
  805.  top_line = (top_line == 0L) ? 1L : top_line;
  806.  bottom_line = (bottom_line == CURRENT_FILE->number_lines+1L) ? bottom_line-1L : bottom_line;
  807.  clear_pending_prefix_command(ppc_idx,(LINE *)NULL);
  808.  clear_pending_prefix_command(bottom_idx,(LINE *)NULL);
  809.  
  810.  execute_shift_command(FALSE,(int)number_cols,top_line,bottom_line-top_line+1L);
  811.  
  812.  return(0);
  813. }
  814. /***********************************************************************/
  815. #ifdef PROTO
  816. static int invalidate_prefix(int ppc_idx)
  817. #else
  818. static int invalidate_prefix(ppc_idx)
  819. int ppc_idx;
  820. #endif
  821. /***********************************************************************/
  822. {
  823. /*-------------------------- external data ----------------------------*/
  824. /*--------------------------- local data ------------------------------*/
  825.  int len;
  826. /*--------------------------- processing ------------------------------*/
  827.  if (*(CURRENT_VIEW->ppc[ppc_idx].ppc_command) != '?')
  828.    {
  829.     len = strlen(CURRENT_VIEW->ppc[ppc_idx].ppc_command);
  830.     meminschr(CURRENT_VIEW->ppc[ppc_idx].ppc_command,'?',0,PREFIX_WIDTH,len);
  831.     *(CURRENT_VIEW->ppc[ppc_idx].ppc_command+len+1) = '\0';
  832.    }
  833. /*---------------------------------------------------------------------*/
  834. /* ensure that there is no chance that a 'real' prefix command can be  */
  835. /* executed.                                                           */
  836. /*---------------------------------------------------------------------*/
  837.  CURRENT_VIEW->ppc[ppc_idx].ppc_cmd_idx = (-1);
  838.  
  839.  return(RC_OK);
  840. }
  841. /***********************************************************************/
  842. #ifdef PROTO
  843. void clear_pending_prefix_command(int ppc_idx,LINE *curr)
  844. #else
  845. void clear_pending_prefix_command(ppc_idx,curr)
  846. int ppc_idx;
  847. LINE *curr;
  848. #endif
  849. /***********************************************************************/
  850. {
  851. /*-------------------------- external data ----------------------------*/
  852. /*--------------------------- local data ------------------------------*/
  853. /*--------------------------- processing ------------------------------*/
  854. /*---------------------------------------------------------------------*/
  855. /* If the ppc_idx value is (-1), then do nothing.                      */
  856. /*---------------------------------------------------------------------*/
  857.  if (ppc_idx == (-1))
  858.     return;
  859.  strcpy(CURRENT_VIEW->ppc[ppc_idx].ppc_command,"");
  860.  if (curr == (LINE *)NULL)
  861. #ifdef USE_VOID
  862.     curr = (LINE *)ll_find((void *)CURRENT_FILE->first_line,CURRENT_VIEW->ppc[ppc_idx].ppc_line_number);
  863. #else
  864.     curr = lll_find(CURRENT_FILE->first_line,CURRENT_VIEW->ppc[ppc_idx].ppc_line_number);
  865. #endif
  866.  curr->pre = (-1);
  867.  CURRENT_VIEW->ppc[ppc_idx].ppc_line_number = (-1L);
  868.  CURRENT_VIEW->ppc[ppc_idx].ppc_cmd_idx = (-1);
  869.  CURRENT_VIEW->ppc[ppc_idx].ppc_block_command = FALSE;
  870.  return;
  871. }
  872. /***********************************************************************/
  873. #ifdef PROTO
  874. static int find_bottom_ppc(int top_ppc,int top_cmd_idx)
  875. #else
  876. static int find_bottom_ppc(top_ppc,top_cmd_idx)
  877. int top_ppc,top_cmd_idx;
  878. #endif
  879. /***********************************************************************/
  880. {
  881. /*-------------------------- external data ----------------------------*/
  882. /*--------------------------- local data ------------------------------*/
  883.  register int i;
  884. /*--------------------------- processing ------------------------------*/
  885.  for (i=top_ppc+1;i<CURRENT_VIEW->prefix_command_index;i++)
  886.    {
  887.     if (CURRENT_VIEW->ppc[i].ppc_cmd_idx == (-1))
  888.        continue;
  889.     if (top_cmd_idx == CURRENT_VIEW->ppc[i].ppc_cmd_idx)
  890.        return(i);
  891.    }
  892.  return(PPC_NO_TARGET);
  893. }
  894. /***********************************************************************/
  895. #ifdef PROTO
  896. static int find_target_ppc(int *target_idx)
  897. #else
  898. static int find_target_ppc(target_idx)
  899. int *target_idx;
  900. #endif
  901. /***********************************************************************/
  902. {
  903. /*-------------------------- external data ----------------------------*/
  904. /*--------------------------- local data ------------------------------*/
  905.  register int i;
  906. /*--------------------------- processing ------------------------------*/
  907.  for (i=0;i<CURRENT_VIEW->prefix_command_index;i++)
  908.    {
  909.     if (CURRENT_VIEW->ppc[i].ppc_cmd_idx == PPC_TARGET_PREVIOUS
  910.     ||  CURRENT_VIEW->ppc[i].ppc_cmd_idx == PPC_TARGET_FOLLOWING)
  911.       {
  912.        *target_idx = i;
  913.        return(CURRENT_VIEW->ppc[i].ppc_cmd_idx);
  914. /*     return(i);*/
  915.       }
  916.    }
  917.  return(PPC_NO_TARGET);
  918. }
  919. /***********************************************************************/
  920. #ifdef PROTO
  921. static long calculate_target_line(void)
  922. #else
  923. static long calculate_target_line()
  924. #endif
  925. /***********************************************************************/
  926. {
  927. /*-------------------------- external data ----------------------------*/
  928. /*--------------------------- local data ------------------------------*/
  929.  int target_idx,target_type;
  930.  long target_line;
  931. /*--------------------------- processing ------------------------------*/
  932.  if ((target_type = find_target_ppc(&target_idx)) == PPC_NO_TARGET)
  933.     return(-1L);
  934.  target_line = CURRENT_VIEW->ppc[target_idx].ppc_line_number;
  935. /*---------------------------------------------------------------------*/
  936. /* If the target line is NOT top of file line and the target type is   */
  937. /* PREVIOUS, subtract 1 from the target line.                          */
  938. /*---------------------------------------------------------------------*/
  939.  if (target_type == PPC_TARGET_PREVIOUS
  940.  && !TOF(target_line))
  941.     target_line--;
  942. /*---------------------------------------------------------------------*/
  943. /* If the target line is the bottom of file and the target type is     */
  944. /* FOLLOWING, sutract 1 from the target line.                          */
  945. /*---------------------------------------------------------------------*/
  946.  if (target_type == PPC_TARGET_FOLLOWING
  947.  && BOF(target_line))
  948.     target_line--;
  949.  clear_pending_prefix_command(target_idx,(LINE *)NULL);
  950.  return(target_line);
  951. }
  952. #if !defined(NOREXX)
  953. /***********************************************************************/
  954. #ifdef PROTO
  955. static int try_rexx_prefix_macro(int ppc_idx)
  956. #else
  957. static int try_rexx_prefix_macro(ppc_idx)
  958. int ppc_idx;
  959. #endif
  960. /***********************************************************************/
  961. {
  962. /*-------------------------- external data ----------------------------*/
  963.  extern char *temp_cmd;
  964. /*--------------------------- local data ------------------------------*/
  965.  int ctr, parm_length, pmacro_rc, errnum = 0 ;
  966.  bool found_left, found_right;
  967.  long line_number;
  968.  char pm_parms[(PREFIX_WIDTH*4)+1], t_area[PREFIX_WIDTH+1],
  969.       parms[PREFIX_WIDTH+1], tmpstr[PREFIX_WIDTH+1], 
  970.       orig_cmd[PREFIX_WIDTH+1];
  971. /*--------------------------- processing ------------------------------*/
  972.  strcpy(orig_cmd, CURRENT_VIEW->ppc[ppc_idx].ppc_command);
  973.  
  974.  found_right = FALSE;
  975.  found_left = FALSE;
  976. /*---------------------------------------------------------------------*/
  977. /* Scan 'orig_cmd' from right to left looking for an embedded macro    */
  978. /* file name.                                                          */
  979. /*---------------------------------------------------------------------*/
  980.  for (ctr = strlen(orig_cmd); ctr >= 0 && !found_right; ctr--)
  981.    {
  982.     substr(&tmpstr[0], orig_cmd, 1, ctr);
  983.     strcpy(t_area, tmpstr);
  984. /*---------------------------------------------------------------------*/
  985. /* First check if the prefix command is a synonym.                     */
  986. /*---------------------------------------------------------------------*/
  987. /* check for prefix synonym, if so use the macro name not the synonym */
  988.     get_valid_macro_file_name(find_prefix_synonym(t_area),temp_cmd,&errnum);
  989.  
  990.     if (errnum == 0)
  991.        found_right = TRUE;
  992.    }
  993.  
  994. /*---------------------------------------------------------------------*/
  995. /* No valid macro file name found ?                                    */
  996. /*                                                                     */
  997. /* Scan 'temp_cmd' from left to right looking for an embedded macro    */
  998. /* file name.                                                          */
  999. /*---------------------------------------------------------------------*/
  1000.  if (!found_right)
  1001.    for ( ctr = 0; ctr <= strlen(orig_cmd) && !found_left; ctr++)
  1002.      {
  1003.       substr(&tmpstr[0], orig_cmd, ctr + 1, strlen(temp_cmd) - ctr);
  1004.       strcpy(t_area, tmpstr);
  1005. /*---------------------------------------------------------------------*/
  1006. /* First check if the prefix command is a synonym.                     */
  1007. /*---------------------------------------------------------------------*/
  1008. /* check for prefix synonym, if so use the macro name not the synonym */
  1009.       get_valid_macro_file_name(find_prefix_synonym(t_area),temp_cmd,&errnum);
  1010.  
  1011.       if (errnum == 0)
  1012.          found_left = TRUE;
  1013.      }
  1014.  
  1015.  if (found_right || found_left)
  1016.    {
  1017.     parm_length = strlen(orig_cmd) - strlen(t_area);
  1018.  
  1019.     if (found_right)
  1020.        substr(&tmpstr[0],orig_cmd,strlen(t_area) + 1,parm_length);
  1021.     else
  1022.        substr(&tmpstr[0],orig_cmd,1,parm_length);
  1023.  
  1024.     strcpy(parms, tmpstr);
  1025.     line_number = CURRENT_VIEW->ppc[ppc_idx].ppc_line_number;
  1026.     sprintf(pm_parms," PREFIX %d %s",line_number,parms);
  1027.     strcat(temp_cmd, pm_parms);     /* add on the parameter list */
  1028.     prefix_current_line = line_number;
  1029.     in_prefix_macro = TRUE;
  1030.     pmacro_rc = execute_macro(temp_cmd,TRUE);
  1031.     in_prefix_macro = FALSE;
  1032.    }
  1033.  else
  1034.     pmacro_rc = RC_NOT_COMMAND;
  1035.  
  1036.  return(pmacro_rc);
  1037. }
  1038. #endif
  1039. /***********************************************************************/
  1040. #ifdef PROTO
  1041. static char *substr(char *temp_string,char *string,int start,int length)
  1042. #else
  1043. static char *substr(temp_string, string, start, length)
  1044. char *temp_string, *string;
  1045. int start, length;
  1046. #endif
  1047. /***********************************************************************/
  1048. /* This function is like the REXX SUBSTR function, it returns a        */
  1049. /* pointer to a string containing the result.                          */
  1050. /* Note: The address of the beginning of a blank string is passed to be*/
  1051. /* modified by address: substr(&tmpstr[0],<string>,<start>,<length>);  */
  1052. /* ( In this case, the result is contained in 'tmpstr'  :-)            */
  1053. /***********************************************************************/
  1054. {
  1055. /*-------------------------- external data ----------------------------*/
  1056. /*--------------------------- local data ------------------------------*/
  1057.  register i, target_idx = 0;
  1058. /*--------------------------- processing ------------------------------*/
  1059.  for (i = start - 1; target_idx <= length - 1; i++)
  1060.     temp_string[target_idx++] = string[i];
  1061.  temp_string[target_idx] = '\0';   /*MH*/
  1062.  return(temp_string);
  1063. }
  1064. /***********************************************************************/
  1065. #ifdef PROTO
  1066. void add_prefix_command(LINE *curr,long line_number,bool block_command)
  1067. #else
  1068. void add_prefix_command(curr,line_number,block_command)
  1069. LINE *curr;
  1070. long line_number;
  1071. bool block_command;
  1072. #endif
  1073. /***********************************************************************/
  1074. {
  1075. /*------------------------- external data -----------------------------*/
  1076. extern bool prefix_changed;
  1077. extern char *pre_rec;
  1078. extern unsigned short pre_rec_len;
  1079. /*--------------------------- local data ------------------------------*/
  1080.  register int i;
  1081.  int prefix_index;
  1082.  char temp_prefix_array[PREFIX_WIDTH+1];
  1083. /*--------------------------- processing ------------------------------*/
  1084. #ifdef TRACE
  1085.  trace_function("prefix.c:  add_prefix_command");
  1086. #endif
  1087.  if (CURRENT_VIEW->prefix_command_index >= MAX_PENDING_PREFIX_COMMANDS-1)
  1088.    {
  1089.     display_error(1,(char *)"too many pending prefix commands");
  1090. #ifdef TRACE
  1091.     trace_return();
  1092. #endif
  1093.     return;
  1094.    }
  1095.  prefix_changed = FALSE;
  1096. /*---------------------------------------------------------------------*/
  1097. /* Add prefix command to pending prefix command array...               */
  1098. /*---------------------------------------------------------------------*/
  1099.  for (i=0;i<pre_rec_len;i++)
  1100.      temp_prefix_array[i] = pre_rec[i];
  1101.  temp_prefix_array[pre_rec_len] = '\0';
  1102.  strtrunc(temp_prefix_array);
  1103. /*---------------------------------------------------------------------*/
  1104. /* First check to see if the prefix command is blank. If so, then      */
  1105. /* remove the reference to the line number and set curr->pre = (-1).   */
  1106. /*---------------------------------------------------------------------*/
  1107.  if (blank_field(temp_prefix_array))
  1108.     clear_pending_prefix_command(curr->pre,curr);
  1109.  else
  1110.    {
  1111. /*---------------------------------------------------------------------*/
  1112. /* If the input line already points to an entry in the array, use the  */
  1113. /* existing entry in the array, otherwise add to the next entry.       */
  1114. /*---------------------------------------------------------------------*/
  1115.     prefix_index = (-1);
  1116.     for (i=0;i<CURRENT_VIEW->prefix_command_index;i++)
  1117.       {
  1118.        if (line_number == CURRENT_VIEW->ppc[i].ppc_line_number)
  1119.          prefix_index = i;
  1120.       }
  1121.     if (prefix_index == (-1))                   /* new entry required */
  1122.       {
  1123.        strcpy(CURRENT_VIEW->ppc[CURRENT_VIEW->prefix_command_index].ppc_command,temp_prefix_array);
  1124.        curr->pre = CURRENT_VIEW->prefix_command_index++;
  1125.       }
  1126.     else
  1127.       {
  1128.        strcpy(CURRENT_VIEW->ppc[prefix_index].ppc_command,temp_prefix_array);
  1129.        curr->pre = prefix_index;
  1130.       }
  1131.     CURRENT_VIEW->ppc[curr->pre].ppc_line_number = line_number;
  1132.     CURRENT_VIEW->ppc[curr->pre].ppc_block_command = block_command;
  1133.    }
  1134. /*---------------------------------------------------------------------*/
  1135. /* Clear the pending prefix command line.                              */
  1136. /*---------------------------------------------------------------------*/
  1137.  memset(pre_rec,' ',PREFIX_WIDTH);
  1138.  pre_rec_len = 0;
  1139.  pre_rec[PREFIX_WIDTH] = '\0';
  1140. #ifdef TRACE
  1141.  trace_return();
  1142. #endif
  1143.  return;
  1144. }
  1145. /***********************************************************************/
  1146. #ifdef PROTO
  1147. int add_prefix_synonym(char *synonym,char *macroname)
  1148. #else
  1149. int add_prefix_synonym(synonym,macroname)
  1150. char *synonym,*macroname;
  1151. #endif
  1152. /***********************************************************************/
  1153. /* Parameters:                                                         */
  1154. /*    synonym: synonym for prefix macro                                */
  1155. /*  macroname: name of REXX macro file                                 */
  1156. /***********************************************************************/
  1157. {
  1158. /*--------------------------- local data ------------------------------*/
  1159.  register int j;
  1160.  int rc;
  1161.  LINE *curr,*next;
  1162. /*--------------------------- processing ------------------------------*/
  1163. #ifdef TRACE
  1164.  trace_function("prefix.c:  add_prefix_synonym");
  1165. #endif
  1166. /*---------------------------------------------------------------------*/
  1167. /* First thing is to delete any definitions that may exist for the     */
  1168. /* supplied synonym.                                                   */
  1169. /*---------------------------------------------------------------------*/
  1170.  curr = first_prefix_synonym;
  1171.  while(curr != NULL)
  1172.    {
  1173.     if (strcmp(curr->name,synonym) == 0)
  1174.       {
  1175.        free(curr->name);
  1176.        free(curr->line);
  1177.        curr = lll_del(&first_prefix_synonym,&last_prefix_synonym,curr,DIRECTION_FORWARD);
  1178.       }
  1179.     else
  1180.        curr = curr->next;
  1181.    }
  1182. /*---------------------------------------------------------------------*/
  1183. /* Lastly append the synonym at the end of the linked list.            */
  1184. /*---------------------------------------------------------------------*/
  1185.  curr = lll_add(first_prefix_synonym,last_prefix_synonym,sizeof(LINE));
  1186.  if (curr == NULL)
  1187.    {
  1188.     display_error(30,(char *)"");
  1189. #ifdef TRACE
  1190.     trace_return();
  1191. #endif
  1192.     return(RC_OUT_OF_MEMORY);
  1193.    }
  1194.  curr->line = (char *)malloc((strlen(macroname)+1)*sizeof(char));
  1195.  if (curr->line == NULL)
  1196.    {
  1197.     display_error(30,(char *)"");
  1198. #ifdef TRACE
  1199.     trace_return();
  1200. #endif
  1201.     return(RC_OUT_OF_MEMORY);
  1202.    }
  1203.  strcpy(curr->line,macroname);
  1204.  curr->name = (char *)malloc((strlen(synonym)+1)*sizeof(char));
  1205.  if (curr->name == NULL)
  1206.    {
  1207.     display_error(30,(char *)"");
  1208. #ifdef TRACE
  1209.     trace_return();
  1210. #endif
  1211.     return(RC_OUT_OF_MEMORY);
  1212.    }
  1213.  strcpy(curr->name,synonym);
  1214.  last_prefix_synonym = curr;
  1215.  if (first_prefix_synonym == NULL)
  1216.     first_prefix_synonym = last_prefix_synonym;
  1217. #ifdef TRACE
  1218.  trace_return();
  1219. #endif
  1220.  return(RC_OK);
  1221. }
  1222. /*man***************************************************************************
  1223. NAME
  1224.      find_prefix_synonym
  1225.  
  1226. SYNOPSIS
  1227.      char *find_prefix_synonym(synonym)
  1228.      char *synonym;
  1229.  
  1230. DESCRIPTION
  1231.      The find_prefix_synonym function finds a synonym for 'synonym'
  1232.      and returns that value. If no synonym exists, the 'synonym' is
  1233.      returned unchanged.
  1234.  
  1235.      This function is only available if REXX support is available.
  1236.      
  1237. RETURN VALUE
  1238.      Either the macroname associated with 'synonym' or 'synonym'.
  1239. *******************************************************************************/
  1240. #ifdef PROTO
  1241. char *find_prefix_synonym(char *synonym)
  1242. #else
  1243. char *find_prefix_synonym(synonym)
  1244. char *synonym;
  1245. #endif
  1246. /***********************************************************************/
  1247. {
  1248. /*-------------------------- external data ----------------------------*/
  1249. /*--------------------------- local data ------------------------------*/
  1250.  LINE *curr;
  1251. /*--------------------------- processing ------------------------------*/
  1252. #ifdef TRACE
  1253.  trace_function("prefix.c:  find_prefix_synonym");
  1254. #endif
  1255.  curr = first_prefix_synonym;
  1256.  while(curr != NULL)
  1257.    {
  1258.     if (strcmp(synonym,curr->name) == 0)
  1259.       {
  1260. #ifdef TRACE
  1261.        trace_return();
  1262. #endif
  1263.        return(curr->line);
  1264.       }
  1265.     curr = curr->next;
  1266.    }
  1267. #ifdef TRACE
  1268.  trace_return();
  1269. #endif
  1270.  return(synonym);
  1271. }
  1272. /*man***************************************************************************
  1273. NAME
  1274.      find_prefix_oldname
  1275.  
  1276. SYNOPSIS
  1277.      char *find_prefix_oldname(oldname)
  1278.      char *oldname;
  1279.  
  1280. DESCRIPTION
  1281.      The find_prefix_oldname function finds the synonym for
  1282.      'oldname' and returns that value. If no synonym exists, the 
  1283.      'oldname' is returned unchanged.
  1284.  
  1285.      This function is only available if REXX support is available.
  1286.      
  1287. RETURN VALUE
  1288.      Either the synonym associated with 'oldname' or 'oldname'.
  1289. *******************************************************************************/
  1290. #ifdef PROTO
  1291. char *find_prefix_oldname(char *oldname)
  1292. #else
  1293. char *find_prefix_oldname(oldname)
  1294. char *oldname;
  1295. #endif
  1296. /***********************************************************************/
  1297. {
  1298. /*-------------------------- external data ----------------------------*/
  1299. /*--------------------------- local data ------------------------------*/
  1300.  LINE *curr;
  1301. /*--------------------------- processing ------------------------------*/
  1302. #ifdef TRACE
  1303.  trace_function("prefix.c:  find_prefix_oldname");
  1304. #endif
  1305.  curr = first_prefix_synonym;
  1306.  while(curr != NULL)
  1307.    {
  1308.     if (strcmp(oldname,curr->line) == 0)
  1309.       {
  1310. #ifdef TRACE
  1311.        trace_return();
  1312. #endif
  1313.        return(curr->name);
  1314.       }
  1315.     curr = curr->next;
  1316.    }
  1317. #ifdef TRACE
  1318.  trace_return();
  1319. #endif
  1320.  return(oldname);
  1321. }
  1322.