home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / the25.zip / thesrc251.zip / commutil.c < prev    next >
C/C++ Source or Header  |  1998-07-28  |  134KB  |  3,984 lines

  1. /***********************************************************************/
  2. /* COMMUTIL.C -                                                        */
  3. /* This file contains all utility functions used when processing       */
  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: commutil.c 2.1 1995/06/24 16:29:18 MH Rel MH $
  43. */
  44.  
  45. #include <the.h>
  46. #include <proto.h>
  47. #include <key.h>
  48. #include <command.h>
  49.  
  50. #ifdef HAVE_PROTO
  51. static CHARTYPE *build_defined_key_definition(int, CHARTYPE *,DEFINE *,bool);
  52. static void save_last_command(CHARTYPE *,CHARTYPE *);
  53. #else
  54. static CHARTYPE *build_defined_key_definition();
  55. static void save_last_command();
  56. #endif
  57.  
  58.  static CHARTYPE cmd_history[MAX_SAVED_COMMANDS][MAX_COMMAND_LENGTH];
  59.  static short last_cmd=(-1),current_cmd=0,number_cmds=0,offset_cmd=0;
  60.  CHARTYPE last_command_for_reexecute[MAX_COMMAND_LENGTH];
  61.  CHARTYPE last_command_for_repeat[MAX_COMMAND_LENGTH];
  62.  CHARTYPE last_change_command[MAX_COMMAND_LENGTH];
  63.  CHARTYPE last_target[MAX_COMMAND_LENGTH];
  64.  
  65. #define KEY_REDEF "/* Key re-definitions */"
  66. #define KEY_DEFAULT "/* Default key definitions */"
  67. #define KEY_MOUSE_REDEF "/* Mouse definitions */"
  68. /*---------------------------------------------------------------------*/
  69. /* The following two static variables are for reserving space for the  */
  70. /* parameters of a command. Space for temp_params is allocated and     */
  71. /* freed in the.c. If the size of the string to be placed into         */
  72. /* temp_params is > length_temp_params, reallocate a larger area and   */
  73. /* set the value of length_temp_params to reflect the new size.        */
  74. /*---------------------------------------------------------------------*/
  75.  static CHARTYPE *temp_params=NULL;
  76.  static unsigned short length_temp_params=0;
  77. /*---------------------------------------------------------------------*/
  78. /* The following two static variables are for reserving space for the  */
  79. /* directories in a macro path. Space for temp_macros is allocated and */
  80. /* freed in the.c. If the size of the string to be placed into         */
  81. /* temp_macros is > length_temp_macros  reallocate a larger area and   */
  82. /* set the value of length_temp_macros to reflect the new size.        */
  83. /*---------------------------------------------------------------------*/
  84.  static CHARTYPE *temp_macros=NULL;
  85.  static unsigned short length_temp_macros=0;
  86. /*---------------------------------------------------------------------*/
  87. /* The following two static variables are for reserving space for the  */
  88. /* contents of   a command. Space for tmp_cmd     is allocated and     */
  89. /* freed in the.c. If the size of the string to be placed into         */
  90. /* tmp_cmd     is > length_tmp_cmd    , reallocate a larger area and   */
  91. /* set the value of length_tmp_cmd     to reflect the new size.        */
  92. /*---------------------------------------------------------------------*/
  93.  static CHARTYPE *tmp_cmd=NULL;
  94.  static unsigned short length_tmp_cmd=0;
  95. /*---------------------------------------------------------------------*/
  96. /* The following two        variables are for reserving space for the  */
  97. /* contents of   a command. Space for temp_cmd    is allocated and     */
  98. /* freed in the.c. If the size of the string to be placed into         */
  99. /* temp_cmd    is > length_temp_cmd   , reallocate a larger area and   */
  100. /* set the value of length_temp_cmd    to reflect the new size.        */
  101. /*---------------------------------------------------------------------*/
  102.  CHARTYPE *temp_cmd=NULL;
  103.  static unsigned short length_temp_cmd=0;
  104. /*---------------------------------------------------------------------*/
  105. /* The following two are to specify the first and last items in the    */
  106. /* linked list for key definitions.                                    */
  107. /*---------------------------------------------------------------------*/
  108. DEFINE *first_define=NULL;
  109. DEFINE *last_define=NULL;
  110. /*---------------------------------------------------------------------*/
  111. /* The following two are to specify the first and last items in the    */
  112. /* linked list for mouse button defintions.                            */
  113. /*---------------------------------------------------------------------*/
  114. DEFINE *first_mouse_define=NULL;
  115. DEFINE *last_mouse_define=NULL;
  116.  
  117. bool clear_command=TRUE;
  118.  
  119. /*---------------------------------------------------------------------*/
  120. /* Key re-definition pseudo files.                                     */
  121. /*---------------------------------------------------------------------*/
  122. LINE *key_first_line=NULL;
  123. LINE *key_last_line=NULL;
  124. LINETYPE key_number_lines=0L;
  125.  
  126. AREAS valid_areas[ATTR_MAX]=
  127.  {
  128.   {(CHARTYPE *)"FILEAREA",1,WINDOW_FILEAREA,TRUE},
  129.   {(CHARTYPE *)"CURLINE",2,WINDOW_FILEAREA,FALSE},
  130.   {(CHARTYPE *)"BLOCK",1,WINDOW_FILEAREA,FALSE},
  131.   {(CHARTYPE *)"CBLOCK",2,WINDOW_FILEAREA,FALSE},
  132.   {(CHARTYPE *)"CMDLINE",1,WINDOW_COMMAND,TRUE},
  133.   {(CHARTYPE *)"IDLINE",1,WINDOW_IDLINE,TRUE},
  134.   {(CHARTYPE *)"MSGLINE",1,WINDOW_ERROR,FALSE},
  135.   {(CHARTYPE *)"ARROW",1,WINDOW_ARROW,TRUE},
  136.   {(CHARTYPE *)"PREFIX",2,WINDOW_PREFIX,TRUE},
  137.   {(CHARTYPE *)"PENDING",1,WINDOW_PREFIX,FALSE},
  138.   {(CHARTYPE *)"SCALE",1,WINDOW_FILEAREA,FALSE},
  139.   {(CHARTYPE *)"TOFEOF",2,WINDOW_FILEAREA,FALSE},
  140.   {(CHARTYPE *)"CTOFEOF",2,WINDOW_FILEAREA,FALSE},
  141.   {(CHARTYPE *)"TABLINE",1,WINDOW_FILEAREA,FALSE},
  142.   {(CHARTYPE *)"SHADOW",2,WINDOW_FILEAREA,FALSE},
  143.   {(CHARTYPE *)"STATAREA",2,WINDOW_STATAREA,TRUE},
  144.   {(CHARTYPE *)"DIVIDER",1,WINDOW_DIVIDER,TRUE},
  145.   {(CHARTYPE *)"RESERVED",1,WINDOW_RESERVED,FALSE},
  146.   {(CHARTYPE *)"NONDISP",1,WINDOW_FILEAREA,FALSE},
  147.   {(CHARTYPE *)"HIGHLIGHT",2,WINDOW_FILEAREA,FALSE},
  148.   {(CHARTYPE *)"CHIGHLIGHT",3,WINDOW_FILEAREA,FALSE},
  149.   {(CHARTYPE *)"SLK",3,WINDOW_SLK,FALSE},
  150.   {(CHARTYPE *)"GAP",3,WINDOW_PREFIX,FALSE},
  151.  };
  152.  
  153. /***********************************************************************/
  154. #ifdef HAVE_PROTO
  155. CHARTYPE *get_key_name(int key)
  156. #else
  157. CHARTYPE *get_key_name(key)
  158. int key;
  159. #endif
  160. /***********************************************************************/
  161. {
  162. /*--------------------------- local data ------------------------------*/
  163.  register short i=0;
  164.  CHARTYPE *keyname=NULL;
  165. /*--------------------------- processing ------------------------------*/
  166. #ifdef TRACE
  167.  trace_function("commutil.c:get_key_name");
  168. #endif
  169. /*---------------------------------------------------------------------*/
  170. /* Get name of key...                                                  */
  171. /*---------------------------------------------------------------------*/
  172.  for (i=0;key_table[i].mnemonic!=NULL;i++)
  173.     {
  174.      if (key == key_table[i].key_value)
  175.        {
  176.         keyname = key_table[i].mnemonic;
  177.         break;
  178.        }
  179.     }
  180. #ifdef TRACE
  181.  trace_return();
  182. #endif
  183.  return(keyname);
  184. }
  185. /***********************************************************************/
  186. #ifdef HAVE_PROTO
  187. CHARTYPE *get_key_definition(int key,bool define_format,bool default_keys,bool mouse_key)
  188. #else
  189. CHARTYPE *get_key_definition(key,define_format,default_keys,mouse_key)
  190. int key;
  191. bool define_format,default_keys,mouse_key;
  192. #endif
  193. /***********************************************************************/
  194. {
  195. /*--------------------------- local data ------------------------------*/
  196.  register short i=0;
  197.  DEFINE *curr=NULL;
  198.  bool check_redefined=TRUE;
  199.  bool check_default=TRUE;
  200.  CHARTYPE *keyname=NULL;
  201.  CHARTYPE key_buf[50];
  202. /*--------------------------- processing ------------------------------*/
  203. #ifdef TRACE
  204.  trace_function("commutil.c:get_key_definition");
  205. #endif
  206. /*---------------------------------------------------------------------*/
  207. /* First determine if the key is a named key.                          */
  208. /*---------------------------------------------------------------------*/
  209.  if (mouse_key)
  210.     keyname = mouse_key_number_to_name(key,key_buf);
  211.  else
  212.     keyname = get_key_name(key);
  213. /*---------------------------------------------------------------------*/
  214. /* If key is invalid,  show it as a character and decimal; provided it */
  215. /* is an ASCII or extended character.                                  */
  216. /*---------------------------------------------------------------------*/
  217.  if (keyname == NULL)
  218.    {
  219.     if (define_format)
  220.        sprintf((DEFCHAR *)temp_cmd,"\"define \\%d ",key);
  221.     else
  222.        sprintf((DEFCHAR *)temp_cmd,"Key: \\%d",key);
  223.    }
  224.  else
  225.    {
  226.     if (define_format)
  227.        strcpy((DEFCHAR *)temp_cmd,"\"define ");
  228.     else
  229.        strcpy((DEFCHAR *)temp_cmd,"Key: ");
  230.     strcat((DEFCHAR *)temp_cmd,(DEFCHAR *)keyname);
  231.    }
  232.  
  233.  if (mouse_key)
  234.     check_default = check_redefined = FALSE;
  235.  else
  236.    {
  237.     if (define_format)
  238.       {
  239.        check_default = (default_keys) ? TRUE : FALSE;
  240.        check_redefined = (default_keys) ? FALSE : TRUE;
  241.       }
  242.    }
  243. /*---------------------------------------------------------------------*/
  244. /* If we want to first check redefined keys...                         */
  245. /*---------------------------------------------------------------------*/
  246.  if (check_redefined)
  247.    {
  248. /*---------------------------------------------------------------------*/
  249. /* Next check to see if the key has been "defined".                    */
  250. /*---------------------------------------------------------------------*/
  251.     curr = first_define;
  252.     if (build_defined_key_definition(key,temp_cmd,curr,define_format) != (CHARTYPE *)NULL)
  253.       {
  254.        strcat((DEFCHAR *)temp_cmd,"\"");
  255. #ifdef TRACE
  256.        trace_return();
  257. #endif
  258.        return(temp_cmd);
  259.       }
  260.    }
  261. /*---------------------------------------------------------------------*/
  262. /* If not, check for the default function key values.                  */
  263. /*---------------------------------------------------------------------*/
  264.  if (check_default)
  265.    {
  266.     for (i=0;command[i].text != NULL;i++)
  267.        {
  268.          if (key == command[i].funkey)
  269.            {
  270.             if (define_format)
  271.                strcat((DEFCHAR *)temp_cmd," ");
  272.             else
  273.                strcat((DEFCHAR *)temp_cmd," - assigned to \"");
  274.             build_default_key_definition(i,temp_cmd);
  275.             strcat((DEFCHAR *)temp_cmd,"\"");
  276. #ifdef TRACE
  277.             trace_return();
  278. #endif
  279.             return(temp_cmd);
  280.            }
  281.        }
  282.    }
  283. /*---------------------------------------------------------------------*/
  284. /* If we want to check mouse key definitions.                          */
  285. /*---------------------------------------------------------------------*/
  286.  if (mouse_key)
  287.    {
  288. /*---------------------------------------------------------------------*/
  289. /* Next check to see if the key has been "defined".                    */
  290. /*---------------------------------------------------------------------*/
  291.     curr = first_mouse_define;
  292.     if (build_defined_key_definition(key,temp_cmd,curr,define_format) != (CHARTYPE *)NULL)
  293.       {
  294.        strcat((DEFCHAR *)temp_cmd,"\"");
  295. #ifdef TRACE
  296.        trace_return();
  297. #endif
  298.        return(temp_cmd);
  299.       }
  300.    }
  301. /*---------------------------------------------------------------------*/
  302. /* If none of the above, it is unassigned. We should never get here if */
  303. /* define_format is TRUE.                                              */
  304. /*---------------------------------------------------------------------*/
  305.  strcat((DEFCHAR *)temp_cmd," - unassigned");
  306. #ifdef TRACE
  307.  trace_return();
  308. #endif
  309.  return(temp_cmd);
  310. }
  311. /***********************************************************************/
  312. #ifdef HAVE_PROTO
  313. short function_key(int key,int option)
  314. #else
  315. short function_key(key,option)
  316. int key;
  317. int option;
  318. #endif
  319. /***********************************************************************/
  320. {
  321. /*------------------------- external data -----------------------------*/
  322.  extern CHARTYPE number_of_files;
  323.  extern CHARTYPE display_screens;
  324.  extern bool readonly;
  325. /*--------------------------- local data ------------------------------*/
  326.  register short i=0;
  327.  DEFINE *curr=(DEFINE *)NULL;
  328.  DEFINE *first_save=(DEFINE *)NULL,*last_save=(DEFINE *)NULL;
  329.  short rc=RC_OK;
  330.  short len=0,num_cmds=0;
  331.  CHARTYPE *key_cmd=NULL;
  332.  CHARTYPE tmpnum[5];
  333.  short macrorc=0;
  334. /*--------------------------- processing ------------------------------*/
  335. #ifdef TRACE
  336.  trace_function("commutil.c:function_key");
  337. #endif
  338. /*---------------------------------------------------------------------*/
  339. /* First check to see if the function key has been redefined and save  */
  340. /* all key redefinitions.  This is because we may be redefining a      */
  341. /* function key in the middle of its redefinition. eg ENTER key        */
  342. /*---------------------------------------------------------------------*/
  343.  curr = first_define;
  344.  while(curr != (DEFINE *)NULL)
  345.    {
  346.     if (key == curr->def_funkey)
  347.       {
  348.        rc = append_define(&first_save,&last_save,key,curr->def_command,curr->def_params);
  349.        if (rc != RC_OK)
  350.          {
  351. #ifdef TRACE
  352.           trace_return();
  353. #endif
  354.           return(rc);
  355.           }
  356.       }
  357.     curr = curr->next;
  358.    }
  359. /*---------------------------------------------------------------------*/
  360. /* Now we have saved any current definition of the function key, use   */
  361. /* these definitions to drive the following...                         */
  362. /*---------------------------------------------------------------------*/
  363.  curr = first_save;
  364.  while(curr != (DEFINE *)NULL)
  365.    {
  366.     switch(option)
  367.       {
  368.       case OPTION_NORMAL:
  369. /*---------------------------------------------------------------------*/
  370. /* If running in read-only mode and the function selected is not valid */
  371. /* display an error.                                                   */
  372. /*---------------------------------------------------------------------*/
  373.            if (curr->def_command != (-1)
  374.            && readonly 
  375.            && !command[curr->def_command].valid_in_readonly)
  376.              {
  377.               display_error(56,(CHARTYPE *)"",FALSE);
  378.               rc = RC_INVALID_ENVIRON;
  379.               curr = NULL;
  380.               break;
  381.              }
  382. /*---------------------------------------------------------------------*/
  383. /* If there are no more files in the ring, and the command is not a    */
  384. /* command to edit a new file, then ignore the command.                */
  385. /*---------------------------------------------------------------------*/
  386.            if (curr->def_command != (-1)
  387.            &&  number_of_files == 0
  388.            &&  !command[curr->def_command].edit_command)
  389.              {
  390.               rc = RC_OK;
  391.               curr = NULL;
  392.               break;
  393.              }
  394.            if ((key_cmd = (CHARTYPE *)my_strdup(curr->def_params)) == NULL)
  395.              {
  396.               display_error(30,(CHARTYPE *)"",FALSE);
  397.               rc = RC_OUT_OF_MEMORY;
  398.               curr = NULL;
  399.               break;
  400.              }
  401.            if (curr->def_command == (-1))
  402.              {
  403.               rc = execute_macro_instore(key_cmd,¯orc);
  404.               if (number_of_files > 0)
  405.                 {
  406.                  if (display_screens > 1)
  407.                    {
  408.                     build_screen(other_screen);
  409.                     display_screen(other_screen);
  410.                    }
  411.                  build_screen(current_screen);
  412.                  display_screen(current_screen);
  413.                 }
  414.              }
  415.            else
  416.               rc = (*command[curr->def_command].function)((CHARTYPE *)key_cmd);
  417.            (*the_free)(key_cmd);
  418.            if (rc != RC_OK
  419.            &&  rc != RC_TOF_EOF_REACHED
  420.            &&  rc != RC_NO_LINES_CHANGED
  421.            &&  rc != RC_TARGET_NOT_FOUND)
  422.              {
  423.               curr = NULL;
  424.               break;
  425.              }
  426.            break;
  427.        case OPTION_EXTRACT:
  428. /*---------------------------------------------------------------------*/
  429. /* If the request is to extract a keys commands, set a REXX variable   */
  430. /* for each command associated with the function key.                  */
  431. /*---------------------------------------------------------------------*/
  432.             len = strlen((DEFCHAR *)command[curr->def_command].text) +
  433.                   strlen((DEFCHAR *)curr->def_params) + 2;
  434.             if ((key_cmd = (CHARTYPE *)(*the_malloc)(len)) == NULL)
  435.               {
  436.                display_error(30,(CHARTYPE *)"",FALSE);
  437.                curr = NULL;
  438.                rc = RC_OUT_OF_MEMORY;
  439.                break;
  440.               }
  441.             strcpy((DEFCHAR *)key_cmd,(DEFCHAR *)command[curr->def_command].text);
  442.             strcat((DEFCHAR *)key_cmd," ");
  443.             strcat((DEFCHAR *)key_cmd,(DEFCHAR *)curr->def_params);
  444.             rc = set_rexx_variable((CHARTYPE *)"SHOWKEY",key_cmd,strlen((DEFCHAR *)key_cmd),++num_cmds);
  445.             (*the_free)(key_cmd);
  446.             break;
  447.       case OPTION_READV:
  448. /*---------------------------------------------------------------------*/
  449. /* If the key hit is KEY_ENTER, KEY_RETURN or KEY_NUMENTER, terminate  */
  450. /* the READV CMDLINE command.                                          */
  451. /*---------------------------------------------------------------------*/
  452.            if (key == KEY_RETURN
  453.            ||  key == KEY_ENTER
  454.            ||  key == KEY_C_m
  455.            ||  key == KEY_NUMENTER)
  456.              {
  457.               rc = RC_READV_TERM;
  458.               curr = NULL;
  459.               break;
  460.              }
  461. /*---------------------------------------------------------------------*/
  462. /* If the command is not allowed in READV CMDLINE, or a REXX macro is  */
  463. /* assigned to the key, return with an error.                          */
  464. /*---------------------------------------------------------------------*/
  465.            if (curr->def_command == (-1))
  466.              {
  467.               rc = RC_INVALID_ENVIRON;
  468.               curr = NULL;
  469.               break;
  470.              }
  471.            if (!command[curr->def_command].valid_readv)
  472.              {
  473.               rc = RC_INVALID_ENVIRON;
  474.               curr = NULL;
  475.               break;
  476.              }
  477. /*---------------------------------------------------------------------*/
  478. /* To get here, a valid READV CMDLINE command is present; execute it.  */
  479. /*---------------------------------------------------------------------*/
  480.            if ((key_cmd = (CHARTYPE *)my_strdup(curr->def_params)) == NULL)
  481.              {
  482.               display_error(30,(CHARTYPE *)"",FALSE);
  483.               rc = RC_OUT_OF_MEMORY;
  484.               curr = NULL;
  485.               break;
  486.              }
  487.            rc = (*command[curr->def_command].function)((CHARTYPE *)key_cmd);
  488.            (*the_free)(key_cmd);
  489.            if (rc != RC_OK
  490.            &&  rc != RC_TOF_EOF_REACHED
  491.            &&  rc != RC_NO_LINES_CHANGED
  492.            &&  rc != RC_TARGET_NOT_FOUND)
  493.              {
  494.               curr = NULL;
  495.               break;
  496.              }
  497.            break;
  498.        default:
  499.            break;
  500.       }
  501.     if (curr == NULL)
  502.        break;
  503.     curr = curr->next;
  504.    }
  505. /*---------------------------------------------------------------------*/
  506. /* If the key has been redefined, exit here...                         */
  507. /*---------------------------------------------------------------------*/
  508.  if (first_save)
  509.    {
  510.     if (option == OPTION_EXTRACT)
  511.       {
  512.        sprintf((DEFCHAR *)tmpnum,"%d",num_cmds);
  513.        rc = set_rexx_variable((CHARTYPE *)"SHOWKEY",tmpnum,strlen((DEFCHAR *)tmpnum),0);
  514.        rc = num_cmds;
  515.       }
  516.     dll_free(first_save);
  517. #ifdef TRACE
  518.     trace_return();
  519. #endif
  520.     return(rc);
  521.    }
  522. /*---------------------------------------------------------------------*/
  523. /* If not, check for the default function key values.                  */
  524. /*---------------------------------------------------------------------*/
  525.  for (i=0;command[i].text != NULL;i++)
  526.     {
  527.       if (key == command[i].funkey)
  528.         {
  529.          switch(option)
  530.            {
  531.             case OPTION_NORMAL:
  532. /*---------------------------------------------------------------------*/
  533. /* If running in read-only mode and the function selected is not valid */
  534. /* display an error.                                                   */
  535. /*---------------------------------------------------------------------*/
  536.                  if (readonly && !command[i].valid_in_readonly)
  537.                    {
  538.                     display_error(56,(CHARTYPE *)"",FALSE);
  539.                     rc = RC_INVALID_ENVIRON;
  540.                     break;
  541.                    }
  542.                  if ((key_cmd = (CHARTYPE *)my_strdup(command[i].params)) == NULL)
  543.                    {
  544.                     display_error(30,(CHARTYPE *)"",FALSE);
  545.                     rc = RC_OUT_OF_MEMORY;
  546.                     break;
  547.                    }
  548.                  rc = (*command[i].function)((CHARTYPE *)key_cmd);
  549.                  (*the_free)(key_cmd);
  550.                  break;
  551.             case OPTION_EXTRACT:
  552.                  len = strlen((DEFCHAR *)command[i].text) +
  553.                        strlen((DEFCHAR *)command[i].params) + 10;
  554.                  if ((key_cmd = (CHARTYPE *)(*the_malloc)(len)) == NULL)
  555.                    {
  556.                     display_error(30,(CHARTYPE *)"",FALSE);
  557.                     rc = RC_OUT_OF_MEMORY;
  558.                     break;
  559.                    }
  560.                  strcpy((DEFCHAR *)key_cmd,"");
  561.                  key_cmd = build_default_key_definition(i,key_cmd);
  562.                  rc = set_rexx_variable((CHARTYPE *)"SHOWKEY",key_cmd,strlen((DEFCHAR *)key_cmd),1);
  563.                  (*the_free)(key_cmd);
  564.                  rc = set_rexx_variable((CHARTYPE *)"SHOWKEY",(CHARTYPE *)"1",1,0);
  565.                  break;
  566.             case OPTION_READV:
  567. /*---------------------------------------------------------------------*/
  568. /* If the key hit is KEY_ENTER, KEY_RETURN or KEY_NUMENTER, terminate  */
  569. /* the READV CMDLINE command.                                          */
  570. /*---------------------------------------------------------------------*/
  571.                  if (key == KEY_RETURN
  572.                  ||  key == KEY_ENTER
  573.                  ||  key == KEY_C_m
  574.                  ||  key == KEY_NUMENTER)
  575.                    {
  576.                     rc = RC_READV_TERM;
  577.                     break;
  578.                    }
  579. /*---------------------------------------------------------------------*/
  580. /* If the command is not allowed in READV CMDLINE, return with an error*/
  581. /*---------------------------------------------------------------------*/
  582.                  if (!command[i].valid_readv)
  583.                    {
  584.                     rc = RC_INVALID_ENVIRON;
  585.                     break;
  586.                    }
  587. /*---------------------------------------------------------------------*/
  588. /* To get here, a valid READV CMDLINE command is present; execute it.  */
  589. /*---------------------------------------------------------------------*/
  590.                  if ((key_cmd = (CHARTYPE *)my_strdup(command[i].params)) == NULL)
  591.                    {
  592.                     display_error(30,(CHARTYPE *)"",FALSE);
  593.                     rc = RC_OUT_OF_MEMORY;
  594.                     break;
  595.                    }
  596.                  rc = (*command[i].function)((CHARTYPE *)key_cmd);
  597.                  (*the_free)(key_cmd);
  598.                  break;
  599.            }
  600. #ifdef TRACE
  601.          trace_return();
  602. #endif
  603.          return(rc);
  604.         }
  605.     }
  606.  if (option == OPTION_EXTRACT)
  607.     rc = set_rexx_variable((CHARTYPE *)"SHOWKEY",(CHARTYPE *)"0",1,0);
  608. #ifdef TRACE
  609.  trace_return();
  610. #endif
  611.  return(RAW_KEY);
  612. }
  613. /***********************************************************************/
  614. #ifdef HAVE_PROTO
  615. CHARTYPE *build_default_key_definition(int key, CHARTYPE *buf)
  616. #else
  617. CHARTYPE *build_default_key_definition(key, buf)
  618. int key;
  619. CHARTYPE *buf;
  620. #endif
  621. /***********************************************************************/
  622. {
  623. /*------------------------- external data -----------------------------*/
  624. /*--------------------------- local data ------------------------------*/
  625. /*--------------------------- processing ------------------------------*/
  626. #ifdef TRACE
  627.  trace_function("commutil.c:build_default_key_definition");
  628. #endif
  629. /*---------------------------------------------------------------------*/
  630. /* The argument, buf, MUST be long enough to to accept the full command*/
  631. /* and arguments and MUST have be nul terminated before this function  */
  632. /* is called.                                                          */
  633. /*---------------------------------------------------------------------*/
  634. /* If a SET command, prefix with 'set'                                 */
  635. /*---------------------------------------------------------------------*/
  636.  if (command[key].set_command)
  637.     strcat((DEFCHAR *)buf,"set ");
  638. /*---------------------------------------------------------------------*/
  639. /* If a SOS command, prefix with 'sos'                                 */
  640. /*---------------------------------------------------------------------*/
  641.  if (command[key].sos_command)
  642.     strcat((DEFCHAR *)buf,"sos ");
  643. /*---------------------------------------------------------------------*/
  644. /* Append the command name.                                            */
  645. /*---------------------------------------------------------------------*/
  646.  strcat((DEFCHAR *)buf,(DEFCHAR *)command[key].text);
  647. /*---------------------------------------------------------------------*/
  648. /* Append any parameters.                                              */
  649. /*---------------------------------------------------------------------*/
  650.  if (strcmp((DEFCHAR *)command[key].params,"") != 0)
  651.    {
  652.     strcat((DEFCHAR *)buf," ");
  653.     strcat((DEFCHAR *)buf,(DEFCHAR *)command[key].params);
  654.    }
  655. #ifdef TRACE
  656.  trace_return();
  657. #endif
  658.  return(buf);
  659. }
  660. /***********************************************************************/
  661. #ifdef HAVE_PROTO
  662. static CHARTYPE *build_defined_key_definition(int key, CHARTYPE *buf,DEFINE *curr,bool define_format)
  663. #else
  664. static CHARTYPE *build_defined_key_definition(key, buf,curr,define_format)
  665. int key;
  666. CHARTYPE *buf;
  667. DEFINE *curr;
  668. bool define_format;
  669. #endif
  670. /***********************************************************************/
  671. {
  672. /*------------------------- external data -----------------------------*/
  673. /*--------------------------- local data ------------------------------*/
  674.  bool key_defined=FALSE;
  675.  bool first_time=TRUE;
  676.  CHARTYPE delim[2];
  677. /*--------------------------- processing ------------------------------*/
  678. #ifdef TRACE
  679.  trace_function("commutil.c:build_defined_key_definition");
  680. #endif
  681. /*---------------------------------------------------------------------*/
  682. /* The argument, buf, MUST be long enough to to accept the full command*/
  683. /* and arguments and MUST have be nul terminated before this function  */
  684. /* is called.                                                          */
  685. /*---------------------------------------------------------------------*/
  686.  delim[1] = '\0';
  687.  delim[0] = CURRENT_VIEW->linend_value;
  688.  while(curr != NULL)
  689.   {
  690.    if (key == curr->def_funkey)
  691.      {
  692.       key_defined = TRUE;
  693.       if (first_time)
  694.         {
  695.          if (define_format)
  696.             strcat((DEFCHAR *)buf," ");
  697.          else
  698.             strcat((DEFCHAR *)buf," - assigned to \"");
  699.         }
  700.       else
  701.         {
  702.          strcat((DEFCHAR *)buf,(DEFCHAR *)delim);
  703.         }
  704. /*---------------------------------------------------------------------*/
  705. /* Append the command to the string.                                   */
  706. /*---------------------------------------------------------------------*/
  707.       if (curr->def_command == (-1))  /* definition is REXX instore */
  708.          strcat((DEFCHAR *)buf,(DEFCHAR *)"REXX");
  709.       else
  710.          strcat((DEFCHAR *)buf,(DEFCHAR *)command[curr->def_command].text);
  711. /*---------------------------------------------------------------------*/
  712. /* Append any parameters.                                              */
  713. /*---------------------------------------------------------------------*/
  714.       if (strcmp((DEFCHAR *)curr->def_params,"") != 0)
  715.         {
  716.          strcat((DEFCHAR *)buf," ");
  717.          strcat((DEFCHAR *)buf,(DEFCHAR *)curr->def_params);
  718.         }
  719.       first_time = FALSE;
  720.      }
  721.    curr = curr->next;
  722.   }
  723. #ifdef TRACE
  724.  trace_return();
  725. #endif
  726.  return((key_defined)?buf:(CHARTYPE *)NULL);
  727. }
  728. /***********************************************************************/
  729. #ifdef HAVE_PROTO
  730. short display_all_keys(void)
  731. #else
  732. short display_all_keys()
  733. #endif
  734. /***********************************************************************/
  735. {
  736. /*------------------------- external data -----------------------------*/
  737. #if !defined(MULTIPLE_PSEUDO_FILES)
  738.  extern CHARTYPE key_filename[10];
  739.  extern CHARTYPE key_pathname[MAX_FILE_NAME+1];
  740. #endif
  741. /*--------------------------- local data ------------------------------*/
  742.  LINE *curr=NULL;
  743.  DEFINE *curr_define=NULL;
  744.  int key=0,save_funkey=0;
  745.  register int i=0;
  746.  CHARTYPE *keydef=NULL;
  747.  VIEW_DETAILS *found_view=NULL;
  748. /*--------------------------- processing ------------------------------*/
  749. #ifdef TRACE
  750.  trace_function("commutil.c:display_all_keys");
  751. #endif
  752. /*---------------------------------------------------------------------*/
  753. /* Free up the existing linked list (if any)                           */
  754. /*---------------------------------------------------------------------*/
  755. #if !defined(MULTIPLE_PSEUDO_FILES)
  756.  key_first_line = key_last_line = lll_free(key_first_line);
  757.  key_number_lines = 0L;
  758.  if ((found_view = find_file(key_pathname,key_filename)) != (VIEW_DETAILS *)NULL)
  759.    {
  760.     found_view->file_for_view->first_line = found_view->file_for_view->last_line = NULL;
  761.     found_view->file_for_view->number_lines = 0L;
  762.    }
  763. #endif
  764. /*---------------------------------------------------------------------*/
  765. /* first_line is set to "Top of File"                                  */
  766. /*---------------------------------------------------------------------*/
  767.  if ((key_first_line = add_line(key_first_line,NULL,TOP_OF_FILE,
  768.      strlen((DEFCHAR *)TOP_OF_FILE),0,FALSE)) == NULL)
  769.    {
  770. #ifdef TRACE
  771.     trace_return();
  772. #endif
  773.     return(RC_OUT_OF_MEMORY);
  774.    }
  775. /*---------------------------------------------------------------------*/
  776. /* last line is set to "Bottom of File"                                */
  777. /*---------------------------------------------------------------------*/
  778.  if ((key_last_line = add_line(key_first_line,key_first_line,BOTTOM_OF_FILE,
  779.      strlen((DEFCHAR *)BOTTOM_OF_FILE),0,FALSE)) == NULL)
  780.    {
  781. #ifdef TRACE
  782.     trace_return();
  783. #endif
  784.     return(RC_OUT_OF_MEMORY);
  785.    }
  786.  curr = key_first_line;
  787. /*---------------------------------------------------------------------*/
  788. /* First display default key mappings...                               */
  789. /*---------------------------------------------------------------------*/
  790.  if ((curr = add_line(key_first_line,curr,(CHARTYPE *)KEY_DEFAULT,strlen(KEY_DEFAULT),0,FALSE)) == NULL)
  791.    {
  792. #ifdef TRACE
  793.     trace_return();
  794. #endif
  795.     return(RC_OUT_OF_MEMORY);
  796.    }
  797.  key_number_lines++;
  798.  save_funkey = (-1);
  799.  for (i=0;command[i].text != NULL;i++)
  800.    {
  801.     if (command[i].funkey != (-1)
  802.     &&  save_funkey != command[i].funkey)
  803.       {
  804.        save_funkey = command[i].funkey;
  805.        keydef = get_key_definition(command[i].funkey,TRUE,TRUE,FALSE);
  806.        if ((curr = add_line(key_first_line,curr,keydef,strlen((DEFCHAR *)keydef),0,FALSE)) == NULL)
  807.          {
  808. #ifdef TRACE
  809.           trace_return();
  810. #endif
  811.           return(RC_OUT_OF_MEMORY);
  812.          }
  813.        key_number_lines++;
  814.       }
  815.    }
  816. /*---------------------------------------------------------------------*/
  817. /* ...next, display any key redefinitions.                             */
  818. /*---------------------------------------------------------------------*/
  819.  if ((curr = add_line(key_first_line,curr,(CHARTYPE *)KEY_REDEF,strlen(KEY_REDEF),0,FALSE)) == NULL)
  820.    {
  821. #ifdef TRACE
  822.     trace_return();
  823. #endif
  824.     return(RC_OUT_OF_MEMORY);
  825.    }
  826.  key_number_lines++;
  827.  curr_define = first_define;
  828.  while(curr_define != NULL)
  829.   {
  830.    if (key != curr_define->def_funkey)
  831.      {
  832.       keydef = get_key_definition(curr_define->def_funkey,TRUE,FALSE,FALSE);
  833.       if ((curr = add_line(key_first_line,curr,keydef,strlen((DEFCHAR *)keydef),0,FALSE)) == NULL)
  834.         {
  835. #ifdef TRACE
  836.          trace_return();
  837. #endif
  838.          return(RC_OUT_OF_MEMORY);
  839.         }
  840.       key_number_lines++;
  841.      }
  842.    key = curr_define->def_funkey;
  843.    curr_define = curr_define->next;
  844.   }
  845. #if defined(MOUSE_SUPPORT_ENABLED)
  846. /*---------------------------------------------------------------------*/
  847. /* ...last, display any mouse key definitions.                         */
  848. /*---------------------------------------------------------------------*/
  849.  if ((curr = add_line(key_first_line,curr,(CHARTYPE *)KEY_MOUSE_REDEF,strlen(KEY_MOUSE_REDEF),0,FALSE)) == NULL)
  850.    {
  851. #ifdef TRACE
  852.     trace_return();
  853. #endif
  854.     return(RC_OUT_OF_MEMORY);
  855.    }
  856.  key_number_lines++;
  857.  curr_define = first_mouse_define;
  858.  while(curr_define != NULL)
  859.   {
  860.    if (key != curr_define->def_funkey)
  861.      {
  862.       keydef = get_key_definition(curr_define->def_funkey,TRUE,FALSE,TRUE);
  863.       if ((curr = add_line(key_first_line,curr,keydef,strlen((DEFCHAR *)keydef),0,FALSE)) == NULL)
  864.         {
  865. #ifdef TRACE
  866.          trace_return();
  867. #endif
  868.          return(RC_OUT_OF_MEMORY);
  869.         }
  870.       key_number_lines++;
  871.      }
  872.    key = curr_define->def_funkey;
  873.    curr_define = curr_define->next;
  874.   }
  875. #endif
  876. #if defined(MULTIPLE_PSEUDO_FILES)
  877.  Xedit((CHARTYPE *)"***KEY***");
  878. #else
  879.  strcpy((DEFCHAR *)temp_cmd,(DEFCHAR *)key_pathname);
  880.  strcat((DEFCHAR *)temp_cmd,(DEFCHAR *)key_filename);
  881.  Xedit(temp_cmd);
  882. #endif
  883. #ifdef TRACE
  884.  trace_return();
  885. #endif
  886.  return(RC_OK);
  887. }
  888. /***********************************************************************/
  889. #ifdef HAVE_PROTO
  890. short command_line(CHARTYPE *cmd_line,bool command_only)
  891. #else
  892. short command_line(cmd_line,command_only)
  893. CHARTYPE *cmd_line;
  894. bool command_only;
  895. #endif
  896. /***********************************************************************/
  897. {
  898. /*------------------------- external data -----------------------------*/
  899.  extern bool error_on_screen;
  900.  extern bool LINEND_STATUSx;
  901.  extern CHARTYPE LINEND_VALUEx;
  902.  extern bool in_macro;
  903.  extern CHARTYPE number_of_files;
  904.  extern short lastrc;
  905.  extern bool readonly;
  906.  extern bool curses_started;
  907.  extern bool batch_only;
  908.  extern bool in_reprofile;
  909.  extern int profile_file_executions;
  910.  extern short compatible_feel;
  911. /*--------------------------- local data ------------------------------*/
  912.  bool valid_command=FALSE;
  913.  bool linend_status=(number_of_files) ? CURRENT_VIEW->linend_status : LINEND_STATUSx;
  914.  CHARTYPE linend_value=0;
  915.  register short i=0,j=0;
  916.  short rc=RC_OK;
  917.  CHARTYPE *cmd[MAX_COMMANDS+1];
  918.  unsigned short num_commands=0;
  919.  CHARTYPE command_delim[2];
  920.  CHARTYPE *command_entered=NULL;
  921.  CHARTYPE *cl_cmd=NULL;
  922.  CHARTYPE *cl_param=NULL;
  923.  TARGET target;
  924.  short target_type=TARGET_NORMAL|TARGET_SPARE;
  925.  bool display_parse_error=FALSE,wrapped=FALSE;
  926.  short macrorc=0;
  927.  LINETYPE save_focus_line=0L;
  928.  LINETYPE save_current_line=0L;
  929.  LINETYPE true_line=0L;
  930. /*--------------------------- processing ------------------------------*/
  931. #ifdef TRACE
  932.  trace_function("commutil.c:command_line");
  933. #endif
  934. /*---------------------------------------------------------------------*/
  935. /* If the command line is blank, just return.                          */
  936. /*---------------------------------------------------------------------*/
  937.  if (blank_field(cmd_line))
  938. /* if (strlen((DEFCHAR *)cmd_line) == 0) */
  939.    {
  940.     if (curses_started)
  941.        wmove(CURRENT_WINDOW_COMMAND,0,0);
  942. #ifdef TRACE
  943.     trace_return();
  944. #endif
  945.     return(RC_OK);
  946.    }
  947. /*---------------------------------------------------------------------*/
  948. /* Set up values for LINEND for later processing...                    */
  949. /*---------------------------------------------------------------------*/
  950.  if (number_of_files == 0)
  951.    {
  952.     linend_status = LINEND_STATUSx;
  953.     linend_value = LINEND_VALUEx;
  954.    }
  955.  else
  956.    {
  957.     linend_status = CURRENT_VIEW->linend_status;
  958.     linend_value = CURRENT_VIEW->linend_value;
  959.    }
  960. /*---------------------------------------------------------------------*/
  961. /* If the command is to be kept displayed on the command line...       */
  962. /*---------------------------------------------------------------------*/
  963.  if (*(cmd_line) == '&')
  964.    {
  965.     cmd_line++;
  966.     clear_command = FALSE;
  967.    }
  968.  else
  969.     if (!(in_macro && !clear_command))
  970.        clear_command = TRUE;
  971. /*---------------------------------------------------------------------*/
  972. /* Copy the incoming cmd_line, so we can play with it.                 */
  973. /*---------------------------------------------------------------------*/
  974.  if ((command_entered = (CHARTYPE *)my_strdup(cmd_line)) == NULL)
  975.    {
  976.     display_error(30,(CHARTYPE *)"",FALSE);
  977. #ifdef TRACE
  978.     trace_return();
  979. #endif
  980.     return(RC_OUT_OF_MEMORY);
  981.    }
  982. /*---------------------------------------------------------------------*/
  983. /* Allocate some space to cl_cmd and cl_param for the a command when   */
  984. /* it is split into a command and its parameters.                      */
  985. /*---------------------------------------------------------------------*/
  986.  if ((cl_cmd = (CHARTYPE *)(*the_malloc)((strlen((DEFCHAR *)cmd_line)+1)*sizeof(CHARTYPE))) == NULL)
  987.    {
  988.     display_error(30,(CHARTYPE *)"",FALSE);
  989. #ifdef TRACE
  990.     trace_return();
  991. #endif
  992.     return(RC_OUT_OF_MEMORY);
  993.    }
  994.  if ((cl_param = (CHARTYPE *)(*the_malloc)((strlen((DEFCHAR *)cmd_line)+1)*sizeof(CHARTYPE))) == NULL)
  995.    {
  996.     display_error(30,(CHARTYPE *)"",FALSE);
  997. #ifdef TRACE
  998.     trace_return();
  999. #endif
  1000.     return(RC_OUT_OF_MEMORY);
  1001.    }
  1002. /*---------------------------------------------------------------------*/
  1003. /* If [SET] LINENd is set to ON, split the line up into a number of    */
  1004. /* individual commands.                                                */
  1005. /*---------------------------------------------------------------------*/
  1006.  if (linend_status
  1007.  && !define_command(cmd_line))
  1008.    {
  1009.     command_delim[0] = linend_value;
  1010.     command_delim[1] = '\0';
  1011.     num_commands = command_split(cmd_line,cmd,MAX_COMMANDS,command_delim,command_entered);
  1012.    }
  1013.  else
  1014.    {
  1015.     cmd[0] = command_entered;
  1016.     num_commands = 1;
  1017.    }
  1018. /*---------------------------------------------------------------------*/
  1019. /* For each command entered, split it up into command and params, and  */
  1020. /* process it...                                                       */
  1021. /*---------------------------------------------------------------------*/
  1022.  for (j=0;j<num_commands;j++)
  1023.    {
  1024.     valid_command = FALSE;
  1025.     split_command(cmd[j],cl_cmd,cl_param);
  1026.     cl_cmd = MyStrip(cl_cmd,STRIP_BOTH,' ');
  1027. /*---------------------------------------------------------------------*/
  1028. /* Here is where we could check for synonyms first.                    */
  1029. /*---------------------------------------------------------------------*/
  1030.     if (!command_only)
  1031.       {
  1032.       }
  1033.               /* get synonym for entered command */
  1034. /*---------------------------------------------------------------------*/
  1035. /* Before we try the command array, if SET MACRO is ON and IMPMACRO is */
  1036. /* ON and we have not reached here via COMMAND command, try for a      */
  1037. /* macro...                                                            */
  1038. /*---------------------------------------------------------------------*/
  1039.     if (number_of_files > 0
  1040.     &&  CURRENT_VIEW->macro
  1041.     &&  CURRENT_VIEW->imp_macro
  1042.     && !command_only)
  1043.       {
  1044.        strcpy((DEFCHAR *)command_entered,(DEFCHAR *)cmd[j]);
  1045.        rc = execute_macro(command_entered,FALSE,¯orc);
  1046.        if (rc != RC_FILE_NOT_FOUND)
  1047.          {
  1048.           lastrc = (rc==RC_SYSTEM_ERROR)?rc:macrorc;
  1049.           save_last_command(cmd[j],cl_cmd);
  1050.           continue;
  1051.          }
  1052.       }
  1053. /*---------------------------------------------------------------------*/
  1054. /* Look up the command in the command array in command.h               */
  1055. /*---------------------------------------------------------------------*/
  1056.     for (i=0;command[i].text != NULL;i++)
  1057.       {
  1058. /*---------------------------------------------------------------------*/
  1059. /* If no command text, continue.                                       */
  1060. /*---------------------------------------------------------------------*/
  1061.        if (strcmp((DEFCHAR *)command[i].text,"") == 0)
  1062.          continue;
  1063.        rc = RC_OK;
  1064. /*---------------------------------------------------------------------*/
  1065. /* Check that the supplied command matches the command for the length  */
  1066. /* of the command and that the length is at least as long as the       */
  1067. /* necessary significance.                                             */
  1068. /*---------------------------------------------------------------------*/
  1069.        if (equal(command[i].text,cl_cmd,command[i].min_len)
  1070.        && command[i].min_len != 0
  1071.        && !command[i].sos_command)
  1072.          {
  1073.           if (batch_only
  1074.           && !command[i].valid_batch_command)
  1075.             {
  1076.              display_error(24,command[i].text,FALSE);
  1077.              lastrc = rc = RC_INVALID_ENVIRON;
  1078.              break;
  1079.             }
  1080.           valid_command = TRUE;
  1081. /*---------------------------------------------------------------------*/
  1082. /* Here is a big kludge. Because only a few commands need leading      */
  1083. /* spaces to be present in temp_params and all other commands barf at  */
  1084. /* leading spaces, we need to left truncate temp_params for most       */
  1085. /* commands.                                                           */
  1086. /*---------------------------------------------------------------------*/
  1087.           if (command[i].strip_param)
  1088.              cl_param = MyStrip(cl_param,command[i].strip_param,' ');
  1089. /*---------------------------------------------------------------------*/
  1090. /* If running in read-only mode and the function selected is not valid */
  1091. /* display an error.                                                   */
  1092. /*---------------------------------------------------------------------*/
  1093.          if (readonly && !command[i].valid_in_readonly)
  1094.            {
  1095.             display_error(56,(CHARTYPE *)"",FALSE);
  1096.             rc = RC_INVALID_ENVIRON;
  1097.             break;
  1098.            }
  1099. /*---------------------------------------------------------------------*/
  1100. /* If we are currently processing the profile file as a result of      */
  1101. /* reprofile, ignore those commands that are invalid.                  */
  1102. /*---------------------------------------------------------------------*/
  1103.          if (profile_file_executions > 1
  1104.          &&  in_reprofile
  1105.          &&  !command[i].valid_for_reprofile)
  1106.            {
  1107.             rc = RC_OK;
  1108.             break;
  1109.            }
  1110. /*---------------------------------------------------------------------*/
  1111. /* If there are no more files in the ring, and the command is not a    */
  1112. /* command to edit a new file, then ignore the command.                */
  1113. /*---------------------------------------------------------------------*/
  1114.          if (number_of_files == 0
  1115.          &&  !command[i].edit_command)
  1116.            {
  1117.             rc = RC_OK;
  1118.             break;
  1119.            }
  1120. /*---------------------------------------------------------------------*/
  1121. /* Now call the function associated with the supplied command string   */
  1122. /* and the possibly stripped parameters.                               */
  1123. /*---------------------------------------------------------------------*/
  1124.           lastrc = rc = (*command[i].function)(cl_param);
  1125.           break;
  1126.          }
  1127.       }
  1128. /*---------------------------------------------------------------------*/
  1129. /* If an error occurred while executing a command above, break.        */
  1130. /*---------------------------------------------------------------------*/
  1131.     if (rc != RC_OK
  1132.     &&  rc != RC_TOF_EOF_REACHED)
  1133.        break;
  1134. /*---------------------------------------------------------------------*/
  1135. /* If we found and successfully executed a command above, process the  */
  1136. /* next command.                                                       */
  1137. /*---------------------------------------------------------------------*/
  1138.     if (valid_command)
  1139.       {
  1140.        save_last_command(cmd[j],cl_cmd);
  1141.        continue;
  1142.       }
  1143. /*---------------------------------------------------------------------*/
  1144. /* If there are no more files in the ring, then ignore the command.    */
  1145. /*---------------------------------------------------------------------*/
  1146.     if (number_of_files == 0)
  1147.       {
  1148.        save_last_command(cmd[j],cl_cmd);
  1149.        continue;
  1150.       }
  1151. /*---------------------------------------------------------------------*/
  1152. /* To get here the command was not a 'command'; check if a valid target*/
  1153. /*---------------------------------------------------------------------*/
  1154.     save_focus_line=CURRENT_VIEW->focus_line;
  1155.     save_current_line=CURRENT_VIEW->current_line;
  1156.     initialise_target(&target);
  1157.     if (!CURRENT_VIEW->imp_macro
  1158.     &&  !CURRENT_VIEW->imp_os)
  1159.        display_parse_error = TRUE;
  1160.     else
  1161.        display_parse_error = FALSE;
  1162.     rc = validate_target(cmd[j],&target,target_type,get_true_line(TRUE),display_parse_error,(CURRENT_VIEW->wrap)?FALSE:TRUE);
  1163. /*---------------------------------------------------------------------*/
  1164. /* If a valid target, but target not found, continue...                */
  1165. /*---------------------------------------------------------------------*/
  1166.     if (rc == RC_TARGET_NOT_FOUND)
  1167.       {
  1168.        bool negative=FALSE;
  1169.        if (CURRENT_VIEW->wrap)
  1170.          {
  1171.           wrapped = TRUE;
  1172.           negative = target.rt[0].negative;
  1173.           free_target(&target);
  1174.           initialise_target(&target);
  1175.           true_line = (negative ? CURRENT_FILE->number_lines+1 : 0L);
  1176.           CURRENT_VIEW->focus_line = CURRENT_VIEW->current_line = true_line;
  1177.           pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
  1178.           rc = validate_target(cmd[j],&target,target_type,true_line,display_parse_error,TRUE);
  1179.           if (rc != RC_OK)
  1180.             {
  1181.              CURRENT_VIEW->focus_line = save_focus_line;
  1182.              CURRENT_VIEW->current_line = save_current_line;
  1183.             }
  1184.          }
  1185.        if (rc == RC_TARGET_NOT_FOUND)
  1186.          {
  1187.           strcpy((DEFCHAR *)last_target,(DEFCHAR *)target.string);
  1188.           free_target(&target);
  1189.           lastrc = rc = RC_TARGET_NOT_FOUND;
  1190.           save_last_command(cmd[j],cl_cmd);
  1191.           continue;
  1192.          }
  1193.       }
  1194. /*---------------------------------------------------------------------*/
  1195. /* If a valid target and found, go there and execute any following     */
  1196. /* command.                                                            */
  1197. /*---------------------------------------------------------------------*/
  1198.     if (rc == RC_OK)
  1199.       {
  1200.        if (wrapped)
  1201.          {
  1202.           display_error(0,(CHARTYPE*)"Wrapped...",FALSE);
  1203.           CURRENT_VIEW->focus_line = save_focus_line;
  1204.           CURRENT_VIEW->current_line = save_current_line;
  1205.           build_screen(current_screen);
  1206.           if (CURRENT_VIEW->current_window == WINDOW_COMMAND
  1207.           ||  compatible_feel == COMPAT_XEDIT)
  1208.              CURRENT_VIEW->current_line = true_line;
  1209.           else
  1210.              CURRENT_VIEW->focus_line = true_line;
  1211.           pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
  1212.          }
  1213.        strcpy((DEFCHAR *)last_target,(DEFCHAR *)target.string);
  1214.        lastrc = rc = advance_current_or_focus_line(target.num_lines);
  1215.        if ((rc == RC_OK
  1216.            || rc == RC_TOF_EOF_REACHED)
  1217.        &&  target.spare != (-1))
  1218.           rc = lastrc = command_line(MyStrip(target.rt[target.spare].string,STRIP_LEADING,' '),FALSE);
  1219.        free_target(&target);
  1220.        save_last_command(cmd[j],cl_cmd);
  1221.        continue;
  1222.       }
  1223.     free_target(&target);
  1224. /*---------------------------------------------------------------------*/
  1225. /* If return is RC_INVALID_OPERAND, check if command is OS command...  */
  1226. /*---------------------------------------------------------------------*/
  1227.     if (cmd[j][0] == '!')
  1228.       {
  1229.        strcpy((DEFCHAR *)command_entered,(DEFCHAR *)cmd[j]);
  1230.        lastrc = rc = Os(command_entered+1);
  1231.        save_last_command(cmd[j],cl_cmd);
  1232.        continue;
  1233.       }
  1234. /*---------------------------------------------------------------------*/
  1235. /* ...or if command is a macro command (as long as IMPMACRO is ON) and */
  1236. /* command_only is FALSE...                                            */
  1237. /*---------------------------------------------------------------------*/
  1238.     if (CURRENT_VIEW->imp_macro
  1239.     && !command_only)
  1240.       {
  1241.        strcpy((DEFCHAR *)command_entered,(DEFCHAR *)cmd[j]);
  1242.        if (CURRENT_VIEW->imp_os)
  1243.          {
  1244.           rc = execute_macro(command_entered,FALSE,¯orc);
  1245.           if (rc != RC_FILE_NOT_FOUND)
  1246.             {
  1247.              lastrc = (rc==RC_SYSTEM_ERROR)?rc:macrorc;
  1248.              save_last_command(cmd[j],cl_cmd);
  1249.              continue;
  1250.             }
  1251.          }
  1252.        else
  1253.          {
  1254.           rc = execute_macro(command_entered,TRUE,¯orc);
  1255.           if (rc == RC_FILE_NOT_FOUND)
  1256.             {
  1257.              lastrc = rc = RC_NOT_COMMAND;
  1258.              break;
  1259.             }
  1260.           else
  1261.             {
  1262.              lastrc = (rc==RC_SYSTEM_ERROR)?rc:macrorc;
  1263.              save_last_command(cmd[j],cl_cmd);
  1264.              continue;
  1265.             }
  1266.          }
  1267.       }
  1268. /*---------------------------------------------------------------------*/
  1269. /* ...or if command is an OS command (as long as IMPOS is ON).         */
  1270. /*---------------------------------------------------------------------*/
  1271.     if (CURRENT_VIEW->imp_os)
  1272.       {
  1273.        error_on_screen = FALSE;
  1274.        strcpy((DEFCHAR *)command_entered,(DEFCHAR *)cmd[j]);
  1275.        rc = Os(command_entered);
  1276.       }
  1277.     else
  1278.       {
  1279.        display_error(21,cmd[j],FALSE);
  1280.        rc = RC_NOT_COMMAND;
  1281.       }
  1282. /*---------------------------------------------------------------------*/
  1283. /* If the 'command' is not a command then do not process any more.     */
  1284. /*---------------------------------------------------------------------*/
  1285.     lastrc = rc;
  1286.     if (rc == RC_NOT_COMMAND)
  1287.        break;
  1288.     save_last_command(cmd[j],cl_cmd);
  1289.    }
  1290.  cleanup_command_line();
  1291.  (*the_free)(command_entered);
  1292.  (*the_free)(cl_cmd);
  1293.  (*the_free)(cl_param);
  1294.  
  1295. #ifdef TRACE
  1296.  trace_return();
  1297. #endif
  1298.  return(rc);
  1299. }
  1300. /***********************************************************************/
  1301. #ifdef HAVE_PROTO
  1302. void cleanup_command_line(void)
  1303. #else
  1304. void cleanup_command_line()
  1305. #endif
  1306. /***********************************************************************/
  1307. {
  1308. /*-------------------------- external data ----------------------------*/
  1309.  extern CHARTYPE *cmd_rec;
  1310.  extern unsigned short cmd_rec_len;
  1311.  extern bool in_macro;
  1312.  extern CHARTYPE number_of_views;
  1313.  extern bool curses_started;
  1314. /*--------------------------- local data ------------------------------*/
  1315. /*--------------------------- processing ------------------------------*/
  1316. #ifdef TRACE
  1317.  trace_function("commutil.c:cleanup_command_line");
  1318. #endif
  1319.  if (!curses_started || in_macro || number_of_views == 0)
  1320.    {
  1321. #ifdef TRACE
  1322.     trace_return();
  1323. #endif
  1324.     return;
  1325.    }
  1326.  if (clear_command)
  1327.    {
  1328.     if (CURRENT_WINDOW_COMMAND != (WINDOW *)NULL)
  1329.       {
  1330.        wmove(CURRENT_WINDOW_COMMAND,0,0);
  1331.        my_wclrtoeol(CURRENT_WINDOW_COMMAND);
  1332.       }
  1333.     memset(cmd_rec,' ',max_line_length);
  1334.     cmd_rec_len = 0;
  1335.    }
  1336.  if (CURRENT_WINDOW_COMMAND != (WINDOW *)NULL)
  1337.     wmove(CURRENT_WINDOW_COMMAND,0,0);
  1338. #ifdef TRACE
  1339.  trace_return();
  1340. #endif
  1341.  return;
  1342. }
  1343. /***********************************************************************/
  1344. #ifdef HAVE_PROTO
  1345. void split_command(CHARTYPE *cmd_line,CHARTYPE *cmd,CHARTYPE *param)
  1346. #else
  1347. void split_command(cmd_line,cmd,param)
  1348. CHARTYPE *cmd_line,*cmd,*param;
  1349. #endif
  1350. /***********************************************************************/
  1351. /*---------------------------------------------------------------------*/
  1352. {
  1353. /*--------------------------- local data ------------------------------*/
  1354.  short pos=0;
  1355.  CHARTYPE *param_ptr=NULL;
  1356. /*--------------------------- processing ------------------------------*/
  1357. #ifdef TRACE
  1358.  trace_function("commutil.c:split_command");
  1359. #endif
  1360.  strcpy((DEFCHAR *)cmd,(DEFCHAR *)cmd_line);
  1361.  MyStrip(cmd,STRIP_LEADING,' ');
  1362. /*---------------------------------------------------------------------*/
  1363. /* Special test here for ? and = command...                            */
  1364. /*---------------------------------------------------------------------*/
  1365.  if (*cmd == '?')
  1366.    {
  1367.     strcpy((DEFCHAR *)param,(DEFCHAR *)(cmd+1));
  1368.     strcpy((DEFCHAR *)cmd,"?");
  1369. #ifdef TRACE
  1370.      trace_return();
  1371. #endif
  1372.      return;
  1373.    }
  1374.  if (*cmd == '=')
  1375.    {
  1376.     strcpy((DEFCHAR *)param,(DEFCHAR *)(cmd+1));
  1377.     strcpy((DEFCHAR *)cmd,"=");
  1378. #ifdef TRACE
  1379.      trace_return();
  1380. #endif
  1381.      return;
  1382.    }
  1383.  for (param_ptr=cmd;*param_ptr!='\0';param_ptr++)
  1384.    {
  1385.     if (!isalpha(*param_ptr))
  1386.        break;
  1387.    }
  1388.  if (!param_ptr)
  1389.    {
  1390.     strcpy((DEFCHAR *)param,"");
  1391. #ifdef TRACE
  1392.     trace_return();
  1393. #endif
  1394.     return;
  1395.    }
  1396.  if (param_ptr == cmd
  1397.  ||  *param_ptr == '\0')
  1398.    {
  1399.     strcpy((DEFCHAR *)param,"");
  1400. #ifdef TRACE
  1401.     trace_return();
  1402. #endif
  1403.     return;
  1404.    }
  1405.  pos = strzne(param_ptr,' ');
  1406.  if (pos == (-1))   /* parameters are all spaces */
  1407.    {
  1408.     strcpy((DEFCHAR *)param,(DEFCHAR *)param_ptr+1);
  1409. #ifdef TRACE
  1410.      trace_return();
  1411. #endif
  1412.      return;
  1413.    }
  1414.  strcpy((DEFCHAR *)param,(DEFCHAR *)param_ptr+(*(param_ptr) == ' ' ? 1 : 0));
  1415.  *(param_ptr) = '\0';
  1416. #ifdef TRACE
  1417.  trace_return();
  1418. #endif
  1419.  return;
  1420. }
  1421. /***********************************************************************/
  1422. #ifdef HAVE_PROTO
  1423. short param_split(CHARTYPE *params,CHARTYPE *word[],short words,
  1424.                 CHARTYPE *delims,CHARTYPE param_type,CHARTYPE *strip, bool trailing_spaces_is_arg)
  1425. #else
  1426. short param_split(params,word,words,delims,param_type,strip,trailing_spaces_is_arg)
  1427. CHARTYPE *params;
  1428. CHARTYPE *word[];
  1429. short words;
  1430. CHARTYPE *delims;
  1431. CHARTYPE param_type;
  1432. CHARTYPE *strip;
  1433. bool trailing_spaces_is_arg;
  1434. #endif
  1435. /***********************************************************************/
  1436. {
  1437. #define STATE_START    0
  1438. #define STATE_WORD     1
  1439. #define STATE_DELIM    2
  1440. /*--------------------------- local data ------------------------------*/
  1441.  register short i=0,k=0;
  1442.  unsigned short len=0;
  1443.  CHARTYPE j=0;
  1444. #if 0
  1445.  bool end_of_string=FALSE,end_of_word=FALSE;
  1446. #endif
  1447.  CHARTYPE *param_ptr=NULL;
  1448.  CHARTYPE *space_ptr=NULL;
  1449.  CHARTYPE state=STATE_START;
  1450.  short str_start=0,str_end=(-1);
  1451. /*--------------------------- processing ------------------------------*/
  1452. #ifdef TRACE
  1453.  trace_function("commutil.c:param_split");
  1454. #endif
  1455. /*---------------------------------------------------------------------*/
  1456. /* Allocate some memory to the temporary area.                         */
  1457. /*---------------------------------------------------------------------*/
  1458.  if (params != NULL)
  1459.    {
  1460.     if (allocate_temp_space(strlen((DEFCHAR *)params),param_type) != RC_OK)
  1461.       {
  1462. #ifdef TRACE
  1463.       trace_return();
  1464. #endif
  1465.       return(-1);
  1466.       }
  1467.    }
  1468. /*---------------------------------------------------------------------*/
  1469. /* Based on param_type, point param_ptr to appropriate buffer.         */
  1470. /*---------------------------------------------------------------------*/
  1471.  switch(param_type)
  1472.    {
  1473.     case TEMP_PARAM:
  1474.          param_ptr = temp_params;
  1475.          break;
  1476.     case TEMP_MACRO:
  1477.          param_ptr = temp_macros;
  1478.          break;
  1479.     case TEMP_TEMP_CMD:
  1480.          param_ptr = temp_cmd;
  1481.          break;
  1482.     case TEMP_TMP_CMD:
  1483.          param_ptr = tmp_cmd;
  1484.          break;
  1485.     default:
  1486.          return(-1);
  1487.          break;
  1488.    }
  1489. /*---------------------------------------------------------------------*/
  1490. /* In case params is NULL, copy an empty string into param_ptr...      */
  1491. /*---------------------------------------------------------------------*/
  1492.  if (params == NULL)
  1493.     strcpy((DEFCHAR *)param_ptr,"");
  1494.  else
  1495.     strcpy((DEFCHAR *)param_ptr,(DEFCHAR *)params);
  1496.  
  1497.  for (i=0;i<words;i++)
  1498.      word[i] = (CHARTYPE *)"";
  1499.  word[0] = param_ptr;
  1500.  len = strlen((DEFCHAR *)param_ptr);
  1501.  if (trailing_spaces_is_arg)
  1502.    {
  1503.     i = strzrevne(param_ptr,' ');
  1504.     if (i != (-1)
  1505.     &&  (len - i) > 2)
  1506.       {
  1507.        space_ptr = param_ptr+(i+2);
  1508.        param_ptr[i+1] = '\0';
  1509.       }
  1510.    }
  1511. #if 0
  1512.  if (words > 1)
  1513.    {
  1514. #endif
  1515.     j = 0;
  1516.     str_start = 0;
  1517.     for (i=0;i<len && j<words;i++)
  1518.       {
  1519.        switch(state)
  1520.          {
  1521.           case STATE_START:
  1522.                for (k=0;k<strlen((DEFCHAR *)delims);k++)
  1523.                  {
  1524.                   if (*(param_ptr+i) == *(delims+k))
  1525.                     {
  1526.                      state = STATE_DELIM;
  1527.                      break;
  1528.                     }
  1529.                  }
  1530.                if (state == STATE_DELIM)
  1531.                   break;
  1532.                word[j++] = param_ptr+str_start;
  1533.                if (str_end != (-1))
  1534.                  {
  1535.                   *(param_ptr+str_end) = '\0';
  1536.                  }
  1537.                state = STATE_WORD;
  1538.                break;
  1539.           case STATE_WORD:
  1540.                for (k=0;k<strlen((DEFCHAR *)delims);k++)
  1541.                  {
  1542.                   if (*(param_ptr+i) == *(delims+k))
  1543.                     {
  1544.                      state = STATE_DELIM;
  1545.                      break;
  1546.                     }
  1547.                  }
  1548.                if (state == STATE_DELIM)
  1549.                  {
  1550.                   str_end = i;
  1551.                   str_start = str_end + 1;
  1552.                   break;
  1553.                  }
  1554.                break;
  1555.           case STATE_DELIM:
  1556.                state = STATE_WORD;
  1557.                for (k=0;k<strlen((DEFCHAR *)delims);k++)
  1558.                  {
  1559.                   if (*(param_ptr+i) == *(delims+k))
  1560.                     {
  1561.                      state = STATE_DELIM;
  1562.                      break;
  1563.                     }
  1564.                  }
  1565.                if (state == STATE_WORD)
  1566.                  {
  1567.                   word[j++] = param_ptr+str_start;
  1568.                   if (str_end != (-1))
  1569.                     {
  1570.                      *(param_ptr+str_end) = '\0';
  1571.                     }
  1572.                  }
  1573.                break;
  1574.          }
  1575.       }
  1576. #if 0
  1577.    }
  1578.  else
  1579.    j = words;
  1580. #endif
  1581.  for (i=0;i<words;i++)
  1582.    {
  1583.     if (*(strip+i))
  1584.        word[i] = MyStrip(word[i],*(strip+i),' ');
  1585.    }
  1586.  if (space_ptr)
  1587.    {
  1588.     word[j] = space_ptr;
  1589.     j++;
  1590.    }
  1591. #ifdef TRACE
  1592.  trace_return();
  1593. #endif
  1594.  return(j);
  1595. }
  1596. /***********************************************************************/
  1597. #ifdef HAVE_PROTO
  1598. short command_split(CHARTYPE *params,CHARTYPE *word[],short words,
  1599.                 CHARTYPE *delims,CHARTYPE *buffer)
  1600. #else
  1601. short command_split(params,word,words,delims,buffer)
  1602. CHARTYPE *params;
  1603. CHARTYPE *word[];
  1604. short words;
  1605. CHARTYPE *delims;
  1606. CHARTYPE *buffer;
  1607. #endif
  1608. /***********************************************************************/
  1609. {
  1610. /*--------------------------- local data ------------------------------*/
  1611.  register short i=0,k=0;
  1612.  unsigned short len=0;
  1613.  CHARTYPE j=0;
  1614.  bool end_of_string=FALSE,end_of_word=FALSE;
  1615. /*--------------------------- processing ------------------------------*/
  1616. #ifdef TRACE
  1617.  trace_function("commutil.c:command_split");
  1618. #endif
  1619. /*---------------------------------------------------------------------*/
  1620. /* In case params is NULL, copy an empty string into buffer...         */
  1621. /*---------------------------------------------------------------------*/
  1622.  if (params == NULL)
  1623.     strcpy((DEFCHAR *)buffer,"");
  1624.  else
  1625.     strcpy((DEFCHAR *)buffer,(DEFCHAR *)params);
  1626.  
  1627.  for (i=0;i<words;i++)
  1628.      word[i] = (CHARTYPE *)"";
  1629.  j = 0;
  1630.  end_of_string = TRUE;
  1631.  len = strlen((DEFCHAR *)buffer);
  1632.  for (i=0;i<len && j<words;i++)
  1633.    {
  1634.     end_of_word = FALSE;
  1635.     for (k=0;k<strlen((DEFCHAR *)delims);k++)
  1636.       {
  1637.        if (*(buffer+i) == *(delims+k))
  1638.           end_of_word = TRUE;
  1639.       }
  1640.     if (end_of_word)
  1641.       {
  1642.        *(buffer+i) = '\0';
  1643.        end_of_string = TRUE;
  1644.       }
  1645.     else
  1646.        if (end_of_string)
  1647.          {
  1648.           word[j++] = buffer+i;
  1649.           end_of_string = FALSE;
  1650.          }
  1651.    }
  1652. #ifdef TRACE
  1653.  trace_return();
  1654. #endif
  1655.  return(j);
  1656. }
  1657. /***********************************************************************/
  1658. #ifdef HAVE_PROTO
  1659. LINETYPE get_true_line(bool respect_compat)
  1660. #else
  1661. LINETYPE get_true_line(respect_compat)
  1662. bool respect_compat;
  1663. #endif
  1664. /***********************************************************************/
  1665. {
  1666. /*-------------------------- external data ----------------------------*/
  1667.  extern bool batch_only;
  1668.  extern short compatible_feel;
  1669. /*--------------------------- local data ------------------------------*/
  1670.  LINETYPE true_line=0L;
  1671. /*--------------------------- processing ------------------------------*/
  1672. #ifdef TRACE
  1673.  trace_function("commutil.c:get_true_line");
  1674. #endif
  1675. /*---------------------------------------------------------------------*/
  1676. /* Determine 'true_line'.                                              */
  1677. /*---------------------------------------------------------------------*/
  1678.  if (CURRENT_VIEW->current_window == WINDOW_COMMAND
  1679.  ||  (compatible_feel == COMPAT_XEDIT && respect_compat)
  1680.  ||  batch_only)
  1681.     true_line = CURRENT_VIEW->current_line;
  1682.  else
  1683.     true_line = CURRENT_VIEW->focus_line;
  1684. #ifdef TRACE
  1685.  trace_return();
  1686. #endif
  1687.  return(true_line);
  1688. }
  1689. #ifndef MSWIN
  1690. /***********************************************************************/
  1691. #ifdef HAVE_PROTO
  1692. void print_line(bool close_spooler,LINETYPE true_line,LINETYPE num_lines,
  1693.                 short pagesize,CHARTYPE *text,CHARTYPE *line_term,short target_type)
  1694. #else
  1695. void print_line(close_spooler,true_line,num_lines,pagesize,text,line_term,target_type)
  1696. bool close_spooler;
  1697. LINETYPE true_line,num_lines;
  1698. short pagesize;
  1699. CHARTYPE *text;
  1700. CHARTYPE *line_term;
  1701. short target_type;
  1702. #endif
  1703. /***********************************************************************/
  1704. {
  1705. /*------------------------- external data -----------------------------*/
  1706. #if defined(UNIX) || defined(OS2) || defined(EMX)
  1707.  extern CHARTYPE *spooler_name;
  1708. #endif
  1709.  extern bool curses_started;
  1710.  extern VIEW_DETAILS *vd_mark;
  1711.  extern CHARTYPE *rec;
  1712. /*--------------------------- local data ------------------------------*/
  1713. #if defined(UNIX) || defined(OS2)
  1714.  static bool spooler_open=FALSE;
  1715. #  if defined(OS2)
  1716.  HFILE Lpt;
  1717. #    if defined(__32BIT__) || defined(__386__)
  1718.  ULONG Action=0L;
  1719.  ULONG NoWritten=0L;
  1720. #    else
  1721.  USHORT Action=0;
  1722.  USHORT NoWritten=0;
  1723. #    endif
  1724. #  endif
  1725. #endif
  1726.  static FILE *pp;
  1727.  register short i=0;
  1728.  short rc=RC_OK;
  1729.  LINETYPE j=0L;
  1730.  LINE *curr=NULL;
  1731.  short line_number=0;
  1732.  LINETYPE num_excluded=0L;
  1733.  LINETYPE num_actual_lines=0L;
  1734.  LINETYPE abs_num_lines=(num_lines < 0L ? -num_lines : num_lines);
  1735.  short direction=(num_lines < 0L ? DIRECTION_BACKWARD : DIRECTION_FORWARD);
  1736.  unsigned short y=0,x=0;
  1737.  bool lines_based_on_scope=(target_type==TARGET_BLOCK_CURRENT)?FALSE:TRUE;
  1738.  LINETYPE start=0L,end=0L,len=0L;
  1739.  CHARTYPE *ptr=NULL;
  1740. /*--------------------------- processing ------------------------------*/
  1741. #ifdef TRACE
  1742.  trace_function("commutil.c:print_line");
  1743. #endif
  1744. #if defined(DOS)
  1745. #  if defined(EMX)
  1746.  pp = fopen(spooler_name,"wb");
  1747. #  else
  1748.  pp = stdprn;
  1749. #  endif
  1750. #endif
  1751. #if defined(UNIX) || defined(OS2)
  1752.  if (close_spooler)
  1753.    {
  1754.     if (spooler_open)
  1755.       {
  1756.        spooler_open = FALSE;
  1757. #if defined(OS2)
  1758.        DosClose(Lpt);
  1759. #else
  1760.        pclose(pp);
  1761. #endif
  1762.       }
  1763. #ifdef TRACE
  1764.     trace_return();
  1765. #endif
  1766.     return;
  1767.    }
  1768. #endif
  1769. #if defined(UNIX)
  1770.  if (!spooler_open)
  1771.    {
  1772.     pp = popen((DEFCHAR *)spooler_name,"w");
  1773.     spooler_open = TRUE;
  1774.    }
  1775. #endif
  1776. #if defined(OS2)
  1777.  if (!spooler_open)
  1778.    {
  1779. #if defined(__32BIT__) || defined(__386__)
  1780.    if (DosOpen(spooler_name, &Lpt, &Action, 0,FILE_NORMAL,FILE_OPEN,
  1781.                OPEN_ACCESS_READWRITE|OPEN_SHARE_DENYNONE,(PEAOP2)NULL) != 0)
  1782. #else
  1783.    if (DosOpen(spooler_name, &Lpt, &Action, 0,FILE_NORMAL,FILE_OPEN,
  1784.                OPEN_ACCESS_WRITEONLY|OPEN_SHARE_DENYWRITE,NULL) != 0)
  1785. #endif
  1786.      {
  1787. #ifdef TRACE
  1788.       trace_return();
  1789. #endif
  1790.       return;
  1791.      }
  1792.     spooler_open = TRUE;
  1793.    }
  1794. #endif
  1795.  
  1796.  if (num_lines == 0L)
  1797.    {
  1798. #if defined(OS2)
  1799.     DosWrite(Lpt,text,strlen(text),&NoWritten);
  1800. #else
  1801.     fprintf(pp,"%s%s",text,line_term);
  1802. #  if defined(EMX)
  1803.    fclose(pp);
  1804. #  endif
  1805. #endif
  1806. #ifdef TRACE
  1807.     trace_return();
  1808. #endif
  1809.     return;
  1810.    }
  1811. /*---------------------------------------------------------------------*/
  1812. /* Once we get here, we are to print lines from the file.              */
  1813. /*---------------------------------------------------------------------*/
  1814.  post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE);
  1815.  if (curses_started)
  1816.    {
  1817.     if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
  1818.        getyx(CURRENT_WINDOW_FILEAREA,y,x);
  1819.     else
  1820.        getyx(CURRENT_WINDOW,y,x);
  1821.    }
  1822.  curr = lll_find(CURRENT_FILE->first_line,CURRENT_FILE->last_line,true_line,CURRENT_FILE->number_lines);
  1823.  for (j=0L,num_actual_lines=0L;;j++)
  1824.    {
  1825.     if (lines_based_on_scope)
  1826.       {
  1827.        if (num_actual_lines == abs_num_lines)
  1828.           break;
  1829.       }
  1830.     else
  1831.       {
  1832.        if (abs_num_lines == j)
  1833.           break;
  1834.       }
  1835.     rc = processable_line(CURRENT_VIEW,true_line+(LINETYPE)(j*direction),curr);
  1836.     switch(rc)
  1837.       {
  1838.        case LINE_SHADOW:
  1839.             num_excluded++;
  1840.             break;
  1841.        case LINE_TOF:
  1842.        case LINE_EOF:
  1843.             num_actual_lines++;
  1844.             break;
  1845.        default:
  1846.             if (num_excluded != 0)
  1847.               {
  1848. #if defined(OS2) && !defined(__EMX__)
  1849.                print_shadow_line(Lpt,line_term,num_excluded);
  1850. #else
  1851.                print_shadow_line(pp,line_term,num_excluded);
  1852. #endif
  1853.                num_excluded = 0L;
  1854.               }
  1855.             switch(target_type)
  1856.               {
  1857.                case TARGET_BLOCK_CURRENT:
  1858.                     switch(MARK_VIEW->mark_type)
  1859.                       {
  1860.                        case M_LINE:
  1861.                             start = 0;
  1862.                             end = (curr->length)-1;
  1863.                             len = end - start + 1L;
  1864.                             ptr = curr->line;
  1865.                             break;
  1866.                        case M_BOX:
  1867.                        case M_WORD:
  1868.                        case M_COLUMN:
  1869.                             pre_process_line(CURRENT_VIEW,true_line+(LINETYPE)(j*direction),curr);
  1870.                             start = MARK_VIEW->mark_start_col - 1;
  1871.                             end = MARK_VIEW->mark_end_col - 1;
  1872.                             len = end - start + 1L;
  1873.                             ptr = rec+start;
  1874.                             break;
  1875.                        case M_STREAM:
  1876.                             pre_process_line(CURRENT_VIEW,true_line+(LINETYPE)(j*direction),curr);
  1877.                             start = end = (-1L);
  1878.                             if (true_line+(LINETYPE)(j*direction) == MARK_VIEW->mark_start_line)
  1879.                                start = MARK_VIEW->mark_start_col - 1;
  1880.                             if (true_line+(LINETYPE)(j*direction) == MARK_VIEW->mark_end_line)
  1881.                                end = MARK_VIEW->mark_end_col - 1;
  1882.                             if (start == (-1L))
  1883.                                start = 0;
  1884.                             if (end == (-1L))
  1885.                                end = (curr->length)-1;
  1886.                             len = end - start + 1L;
  1887.                             ptr = curr->line+start;
  1888.                             break;
  1889.                       }
  1890.                     break;
  1891.                default:
  1892.                     start = (LINETYPE)CURRENT_VIEW->zone_start-1;
  1893.                     end = (LINETYPE)min((curr->length)-1,CURRENT_VIEW->zone_end-1);
  1894.                     ptr = curr->line+start;
  1895.                     if (start > end)
  1896.                        len = 0L;
  1897.                     else
  1898.                        len = end - start + 1L;
  1899.                     break;
  1900.               }
  1901. #if defined(OS2)
  1902.             DosWrite(Lpt,ptr,len,&NoWritten);
  1903.             DosWrite(Lpt,line_term,strlen(line_term),&NoWritten);
  1904. #else
  1905.             for (i=0;i<len;i++)
  1906.                 fputc(*(ptr+i) & A_CHARTEXT,pp);
  1907.             fprintf(pp,"%s",line_term);
  1908. #endif
  1909.             line_number++;
  1910.             if (line_number == pagesize
  1911.             && pagesize != 0)
  1912.               {
  1913. #if defined(OS2)
  1914.                DosWrite(Lpt,"\f",1,&NoWritten);
  1915. #else
  1916.                fputc('\f',pp);
  1917. #endif
  1918.                line_number = 0;
  1919.               }
  1920.             num_actual_lines++;
  1921.             break;
  1922.       }
  1923. /*---------------------------------------------------------------------*/
  1924. /* Proceed to the next record, even if the current record not in scope.*/
  1925. /*---------------------------------------------------------------------*/
  1926.     if (direction == DIRECTION_BACKWARD)
  1927.        curr = curr->prev;
  1928.     else
  1929.        curr = curr->next;
  1930.      if (curr == NULL)
  1931.         break;
  1932.    }
  1933. /*---------------------------------------------------------------------*/
  1934. /* If we have a shadow line remaining, print it...                     */
  1935. /*---------------------------------------------------------------------*/
  1936.  if (num_excluded != 0)
  1937.    {
  1938. #if defined(OS2) && !defined(__EMX__)
  1939.     print_shadow_line(Lpt,line_term,num_excluded);
  1940. #else
  1941.     print_shadow_line(pp,line_term,num_excluded);
  1942. #endif
  1943.     num_excluded = 0L;
  1944.    }
  1945. /*---------------------------------------------------------------------*/
  1946. /* If STAY is OFF, change the current and focus lines by the number    */
  1947. /* of lines calculated from the target.                                */
  1948. /*---------------------------------------------------------------------*/
  1949.  if (!CURRENT_VIEW->stay)                               /* stay is off */
  1950.    {
  1951.     CURRENT_VIEW->focus_line = min(CURRENT_VIEW->focus_line+num_lines-1L,CURRENT_FILE->number_lines+1L);
  1952.     CURRENT_VIEW->current_line = min(CURRENT_VIEW->current_line+num_lines-1L,CURRENT_FILE->number_lines+1L);
  1953.    }
  1954.  pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
  1955.  build_screen(current_screen);
  1956.  display_screen(current_screen);
  1957.  if (curses_started)
  1958.    {
  1959.     y = get_row_for_focus_line(current_screen,CURRENT_VIEW->focus_line,
  1960.                                CURRENT_VIEW->current_row);
  1961.     if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
  1962.        wmove(CURRENT_WINDOW_FILEAREA,y,x);
  1963.     else
  1964.        wmove(CURRENT_WINDOW,y,x);
  1965.    }
  1966. #ifdef TRACE
  1967.  trace_return();
  1968. #endif
  1969.  return;
  1970. }
  1971. #if defined(OS2) && !defined(__EMX__)
  1972. /***********************************************************************/
  1973. #ifdef HAVE_PROTO
  1974. void print_shadow_line(HFILE Lpt,CHARTYPE *line_term,LINETYPE num_excluded)
  1975. #else
  1976. void print_shadow_line(Lpt,line_term,num_excluded)
  1977. HFILE Lpt;
  1978. CHARTYPE *line_term;
  1979. LINETYPE num_excluded;
  1980. #endif
  1981. /***********************************************************************/
  1982. {
  1983. /*--------------------------- local data ------------------------------*/
  1984.  register short i=0;
  1985.  short num_dashes=0;
  1986.  CHARTYPE temp_buf[7]="";
  1987. #if defined(__32BIT__) || defined(__386__)
  1988.  ULONG NoWritten=0L;
  1989. #else
  1990.  USHORT NoWritten=0;
  1991. #endif
  1992. /*--------------------------- processing ------------------------------*/
  1993. #ifdef TRACE
  1994.  trace_function("commutil.c:print_shadow_line");
  1995. #endif
  1996.  if (CURRENT_VIEW->shadow)
  1997.    {
  1998.     num_dashes = (CURRENT_SCREEN.cols[WINDOW_FILEAREA] - 26) / 2;
  1999.     for (i=0;i<num_dashes;i++)
  2000.        DosWrite(Lpt,"-",1,&NoWritten);
  2001.     sprintf(temp_buf,"%6ld",num_excluded);
  2002.     DosWrite(Lpt,temp_buf,strlen(temp_buf),&NoWritten);
  2003.     DosWrite(Lpt," line(s) not displayed ",23,&NoWritten);
  2004.     for (i=0;i<num_dashes;i++)
  2005.        DosWrite(Lpt,"-",1,&NoWritten);
  2006.     DosWrite(Lpt,line_term,strlen(line_term),&NoWritten);
  2007.    }
  2008. #ifdef TRACE
  2009.  trace_return();
  2010. #endif
  2011.  return;
  2012. }
  2013. #else
  2014. /***********************************************************************/
  2015. #ifdef HAVE_PROTO
  2016. void print_shadow_line(FILE *pp,CHARTYPE *line_term,LINETYPE num_excluded)
  2017. #else
  2018. void print_shadow_line(pp,line_term,num_excluded)
  2019. FILE *pp;
  2020. CHARTYPE *line_term;
  2021. LINETYPE num_excluded;
  2022. #endif
  2023. /***********************************************************************/
  2024. {
  2025. /*--------------------------- local data ------------------------------*/
  2026.  register short i=0;
  2027.  short num_dashes=0;
  2028. /*--------------------------- processing ------------------------------*/
  2029. #ifdef TRACE
  2030.  trace_function("commutil.c:print_shadow_line");
  2031. #endif
  2032.  if (CURRENT_VIEW->shadow)
  2033.    {
  2034.     num_dashes = (CURRENT_SCREEN.cols[WINDOW_FILEAREA] - 26) / 2;
  2035.     for (i=0;i<num_dashes;i++)
  2036.        fputc('-',pp);
  2037.     fprintf(pp,"%6ld line(s) not displayed ",num_excluded);
  2038.     for (i=0;i<num_dashes;i++)
  2039.        fputc('-',pp);
  2040.     fprintf(pp,"%s",line_term);
  2041.    }
  2042. #ifdef TRACE
  2043.  trace_return();
  2044. #endif
  2045.  return;
  2046. }
  2047. #endif
  2048. #endif
  2049. /***********************************************************************/
  2050. #ifdef HAVE_PROTO
  2051. CHARTYPE next_char(LINE *curr,long *off,LENGTHTYPE end_col)
  2052. #else
  2053. CHARTYPE next_char(curr,off,end_col)
  2054. LINE *curr;
  2055. long *off;
  2056. LENGTHTYPE end_col;
  2057. #endif
  2058. /***********************************************************************/
  2059. {
  2060. /*--------------------------- local data ------------------------------*/
  2061. /*--------------------------- processing ------------------------------*/
  2062. #ifdef TRACE
  2063.  trace_function("commutil.c:next_char");
  2064. #endif
  2065.  if (*(off) < (long)min(curr->length,end_col))
  2066.    {
  2067.     (*(off))++;
  2068. #ifdef TRACE
  2069.     trace_return();
  2070. #endif
  2071.     return(*(curr->line+((*(off))-1L)));
  2072.    }
  2073.  *(off) = (-1L);
  2074. #ifdef TRACE
  2075.  trace_return();
  2076. #endif
  2077.  return(0);
  2078. }
  2079. /***********************************************************************/
  2080. #ifdef HAVE_PROTO
  2081. short add_define(DEFINE **first,DEFINE **last,int key_value,CHARTYPE *commands,bool instore)
  2082. #else
  2083. short add_define(first,last,key_value,commands,instore)
  2084. DEFINE **first,**last;
  2085. int key_value;
  2086. CHARTYPE *commands;
  2087. bool instore;
  2088. #endif
  2089. /***********************************************************************/
  2090. /* Parameters:                                                         */
  2091. /*  key_value: numeric representation of function key                  */
  2092. /*   commands: commands and parameters                                 */
  2093. /***********************************************************************/
  2094. {
  2095. /*-------------------------- external data ----------------------------*/
  2096.  extern bool rexx_support;
  2097. /*--------------------------- local data ------------------------------*/
  2098.  register short j=0;
  2099.  short cmd_nr=0;
  2100.  CHARTYPE *word[MAX_COMMANDS+1];
  2101.  unsigned short num_commands=0;
  2102.  CHARTYPE command_delim[2];
  2103.  short rc=RC_OK;
  2104.  CHARTYPE *command_entered=NULL,*cl_cmd=NULL,*cl_param=NULL;
  2105. /*--------------------------- processing ------------------------------*/
  2106. #ifdef TRACE
  2107.  trace_function("commutil.c:add_define");
  2108. #endif
  2109. /*---------------------------------------------------------------------*/
  2110. /* If the commands argument is empty, delete the definition of the key */
  2111. /* definitions for the key, so just return.                            */
  2112. /*---------------------------------------------------------------------*/
  2113.  if (strcmp((DEFCHAR *)commands,"") == 0)
  2114.    {
  2115.     remove_define(first,last,key_value);
  2116. #ifdef TRACE
  2117.     trace_return();
  2118. #endif
  2119.     return(RC_OK);
  2120.    }
  2121.  if (instore)
  2122.    {
  2123.     if (rexx_support)
  2124.       {
  2125.        remove_define(first,last,key_value);
  2126.        rc = append_define(first,last,key_value,(-1),commands);
  2127. #ifdef TRACE
  2128.        trace_return();
  2129. #endif
  2130.        return(rc);
  2131.       }
  2132.     else
  2133.       {
  2134.        display_error(58,(CHARTYPE *)"instore macros",FALSE);
  2135. #ifdef TRACE
  2136.        trace_return();
  2137. #endif
  2138.        return(RC_INVALID_OPERAND);
  2139.       }
  2140.    }
  2141. /*---------------------------------------------------------------------*/
  2142. /* To have reached here we are dealing with "plain" key definitions,   */
  2143. /* rather than instore macros...                                       */
  2144. /* Copy the incoming commands, so we can play with it.                 */
  2145. /*---------------------------------------------------------------------*/
  2146.  if ((command_entered = (CHARTYPE *)my_strdup(commands)) == NULL)
  2147.    {
  2148.     display_error(30,(CHARTYPE *)"",FALSE);
  2149. #ifdef TRACE
  2150.     trace_return();
  2151. #endif
  2152.     return(RC_OUT_OF_MEMORY);
  2153.    }
  2154. /*---------------------------------------------------------------------*/
  2155. /* Allocate some space to cl_cmd and cl_param for the a command when   */
  2156. /* it is split into a command and its parameters.                      */
  2157. /*---------------------------------------------------------------------*/
  2158.  if ((cl_cmd = (CHARTYPE *)(*the_malloc)((strlen((DEFCHAR *)commands)+1)*sizeof(CHARTYPE))) == NULL)
  2159.    {
  2160.     display_error(30,(CHARTYPE *)"",FALSE);
  2161. #ifdef TRACE
  2162.     trace_return();
  2163. #endif
  2164.     return(RC_OUT_OF_MEMORY);
  2165.    }
  2166.  if ((cl_param = (CHARTYPE *)(*the_malloc)((strlen((DEFCHAR *)commands)+1)*sizeof(CHARTYPE))) == NULL)
  2167.    {
  2168.     display_error(30,(CHARTYPE *)"",FALSE);
  2169. #ifdef TRACE
  2170.     trace_return();
  2171. #endif
  2172.     return(RC_OUT_OF_MEMORY);
  2173.    }
  2174. /*---------------------------------------------------------------------*/
  2175. /* If [SET] LINENd is set to ON, split the args up into a number of    */
  2176. /* individual commands.                                                */
  2177. /*---------------------------------------------------------------------*/
  2178.  if (CURRENT_VIEW)
  2179.    {
  2180.     if (CURRENT_VIEW->linend_status)
  2181.       {
  2182.        command_delim[0] = CURRENT_VIEW->linend_value;
  2183.        command_delim[1] = '\0';
  2184.        num_commands = command_split(commands,word,MAX_COMMANDS,command_delim,command_entered);
  2185.       }
  2186.     else
  2187.       {
  2188.        word[0] = command_entered;
  2189.        num_commands = 1;
  2190.       }
  2191.    }
  2192.  else
  2193.    {
  2194.     command_delim[0] = '#';
  2195.     command_delim[1] = '\0';
  2196.     num_commands = command_split(commands,word,MAX_COMMANDS,command_delim,command_entered);
  2197.    }
  2198. /*---------------------------------------------------------------------*/
  2199. /* For each command entered, split it up into command and params, and  */
  2200. /* validate that each command is valid.  The cmd_nr is discarded here. */
  2201. /*---------------------------------------------------------------------*/
  2202.  for (j=0;j<num_commands;j++)
  2203.    {
  2204.     split_command(word[j],cl_cmd,cl_param);
  2205.     if ((cmd_nr = find_command(cl_cmd,FALSE)) == (-1))
  2206.       {
  2207.        display_error(21,cl_cmd,FALSE);
  2208.        rc = RC_INVALID_OPERAND;
  2209.        break;
  2210.       }
  2211.    }
  2212. /*---------------------------------------------------------------------*/
  2213. /* Now we know each command is valid, we can remove any prior          */
  2214. /* definition and assign the new one.                                  */
  2215. /*---------------------------------------------------------------------*/
  2216.  if (rc == RC_OK)
  2217.    {
  2218.     remove_define(first,last,key_value);
  2219.     for (j=0;j<num_commands;j++)
  2220.       {
  2221.        split_command(word[j],cl_cmd,cl_param);
  2222.        if ((cmd_nr = find_command(cl_cmd,FALSE)) == (-1))
  2223.          {
  2224.           display_error(21,cl_cmd,FALSE);      /* this should not be reached */
  2225.           rc = RC_INVALID_OPERAND;
  2226.           break;
  2227.          }
  2228.        rc = append_define(first,last,key_value,cmd_nr,cl_param);
  2229.        if (rc != RC_OK)
  2230.           break;
  2231.       }
  2232.    }
  2233.  (*the_free)(command_entered);
  2234.  (*the_free)(cl_cmd);
  2235.  (*the_free)(cl_param);
  2236. #ifdef TRACE
  2237.  trace_return();
  2238. #endif
  2239.  return(rc);
  2240. }
  2241. /***********************************************************************/
  2242. #ifdef HAVE_PROTO
  2243. short remove_define(DEFINE **first,DEFINE **last,int key_value)
  2244. #else
  2245. short remove_define(first,last,key_value)
  2246. DEFINE **first,**last;
  2247. int key_value;
  2248. #endif
  2249. /***********************************************************************/
  2250. /* Parameters:                                                         */
  2251. /*  key_value: numeric representation of function key                  */
  2252. /***********************************************************************/
  2253. {
  2254. /*--------------------------- local data ------------------------------*/
  2255.  DEFINE *curr=NULL;
  2256. /*--------------------------- processing ------------------------------*/
  2257. #ifdef TRACE
  2258.  trace_function("commutil.c:remove_define");
  2259. #endif
  2260. /*---------------------------------------------------------------------*/
  2261. /* Find all items in the linked list for the key_value and remove them */
  2262. /* from the list.                                                      */
  2263. /*---------------------------------------------------------------------*/
  2264.  curr = *first;
  2265.  while(curr != NULL)
  2266.    {
  2267.     if (curr->def_funkey == key_value)
  2268.       {
  2269.        if (curr->def_params != NULL)
  2270.           (*the_free)(curr->def_params);
  2271.        curr = dll_del(first,last,curr,DIRECTION_FORWARD);
  2272.       }
  2273.     else
  2274.        curr = curr->next;
  2275.    }
  2276. #ifdef TRACE
  2277.  trace_return();
  2278. #endif
  2279.  return(RC_OK);
  2280. }
  2281. /***********************************************************************/
  2282. #ifdef HAVE_PROTO
  2283. short append_define(DEFINE **first,DEFINE **last,int key_value,short cmd,CHARTYPE *prm)
  2284. #else
  2285. short append_define(first,last,key_value,cmd,prm)
  2286. DEFINE **first,**last;
  2287. int key_value;
  2288. short cmd;
  2289. CHARTYPE *prm;
  2290. #endif
  2291. /***********************************************************************/
  2292. /* Parameters:                                                         */
  2293. /*  key_value: numeric representation of function key                  */
  2294. /***********************************************************************/
  2295. {
  2296. /*-------------------------- external data ----------------------------*/
  2297. /*--------------------------- local data ------------------------------*/
  2298.  DEFINE *curr=NULL;
  2299. /*--------------------------- processing ------------------------------*/
  2300. #ifdef TRACE
  2301.  trace_function("commutil.c:append_define");
  2302. #endif
  2303. /*---------------------------------------------------------------------*/
  2304. /* Add the new key definition to the end of the linked list...         */
  2305. /*---------------------------------------------------------------------*/
  2306.  curr = dll_add(*first,*last,sizeof(DEFINE));
  2307.  if (curr == NULL)
  2308.    {
  2309.     display_error(30,(CHARTYPE *)"",FALSE);
  2310. #ifdef TRACE
  2311.     trace_return();
  2312. #endif
  2313.     return(RC_OUT_OF_MEMORY);
  2314.    }
  2315.  curr->def_params = (CHARTYPE *)(*the_malloc)((strlen((DEFCHAR *)prm)+1)*sizeof(CHARTYPE));
  2316.  if (curr->def_params == NULL)
  2317.    {
  2318.     display_error(30,(CHARTYPE *)"",FALSE);
  2319. #ifdef TRACE
  2320.     trace_return();
  2321. #endif
  2322.     return(RC_OUT_OF_MEMORY);
  2323.    }
  2324.  strcpy((DEFCHAR *)curr->def_params,(DEFCHAR *)prm);
  2325.  curr->def_funkey = key_value;
  2326.  curr->def_command = cmd;
  2327.  *last = curr;
  2328.  if (*first == NULL)
  2329.     *first = *last;
  2330. #ifdef TRACE
  2331.  trace_return();
  2332. #endif
  2333.  return(RC_OK);
  2334. }
  2335. /***********************************************************************/
  2336. #ifdef HAVE_PROTO
  2337. int find_key_value(CHARTYPE *mnemonic)
  2338. #else
  2339. int find_key_value(mnemonic)
  2340. CHARTYPE *mnemonic;
  2341. #endif
  2342. /***********************************************************************/
  2343. /*   Function: find the matching key value for the supplied key name   */
  2344. /* Parameters:                                                         */
  2345. /*   mnemonic: the key name to be matched                              */
  2346. /***********************************************************************/
  2347. {
  2348. /*--------------------------- local data ------------------------------*/
  2349.  register short i=0;
  2350. /*--------------------------- processing ------------------------------*/
  2351. #ifdef TRACE
  2352.  trace_function("commutil.c:find_key_value");
  2353. #endif
  2354.  for (i=0;key_table[i].mnemonic!=NULL;i++)
  2355.     if (equal(key_table[i].mnemonic,mnemonic,strlen((DEFCHAR *)key_table[i].mnemonic)))
  2356.       {
  2357. #ifdef TRACE
  2358.        trace_return();
  2359. #endif
  2360.        return(key_table[i].key_value);
  2361.       }
  2362. #ifdef TRACE
  2363.  trace_return();
  2364. #endif
  2365.  return(-1);
  2366. }
  2367. /***********************************************************************/
  2368. #ifdef HAVE_PROTO
  2369. short find_command(CHARTYPE *cmd,bool search_for_target)
  2370. #else
  2371. short find_command(cmd,search_for_target)
  2372. CHARTYPE *cmd;
  2373. bool search_for_target;
  2374. #endif
  2375. /***********************************************************************/
  2376. /*   Function: determine if the string supplied is a valid abbrev for  */
  2377. /*             a command.                                              */
  2378. /* Parameters:                                                         */
  2379. /*        cmd:               the string to be checked                  */
  2380. /*        search_for_target: determine if command is a valid target    */
  2381. /***********************************************************************/
  2382. {
  2383. /*--------------------------- local data ------------------------------*/
  2384.  register short i=0;
  2385.  short rc=RC_OK;
  2386.  TARGET target;
  2387.  short target_type=TARGET_NORMAL|TARGET_BLOCK|TARGET_ALL;
  2388. /*--------------------------- processing ------------------------------*/
  2389. #ifdef TRACE
  2390.  trace_function("commutil.c:find_command");
  2391. #endif
  2392.  for (i=0;command[i].text != NULL;i++)
  2393.     if (equal(command[i].text,cmd,(command[i].min_len == 0) ? strlen((DEFCHAR *)command[i].text) : command[i].min_len)
  2394.     &&  !command[i].sos_command)
  2395.       {
  2396. #ifdef TRACE
  2397.        trace_return();
  2398. #endif
  2399.        return(i);
  2400.       }
  2401. /*---------------------------------------------------------------------*/
  2402. /* To get here the command was not a 'command'. If we don't want to    */
  2403. /* search for targets, exit with (-1).                                 */
  2404. /*---------------------------------------------------------------------*/
  2405.  if (!search_for_target)
  2406.    {
  2407. #ifdef TRACE
  2408.     trace_return();
  2409. #endif
  2410.     return(-1);
  2411.    }
  2412. /*---------------------------------------------------------------------*/
  2413. /* Find if it is a valid target...                                     */
  2414. /*---------------------------------------------------------------------*/
  2415.  initialise_target(&target);
  2416.  rc = validate_target(cmd,&target,target_type,get_true_line(TRUE),TRUE,TRUE);
  2417.  if (rc != RC_OK
  2418.  &&  rc != RC_TARGET_NOT_FOUND)
  2419.    {
  2420.     free_target(&target);
  2421. #ifdef TRACE
  2422.     trace_return();
  2423. #endif
  2424.     return(-1);
  2425.    }
  2426.  free_target(&target);
  2427. /*---------------------------------------------------------------------*/
  2428. /* If a valid target, find 'LOCATE' command and return the index.      */
  2429. /*---------------------------------------------------------------------*/
  2430.  strcpy((DEFCHAR *)temp_params,(DEFCHAR *)cmd);
  2431.  for (i=0;command[i].text != NULL;i++)
  2432.    {
  2433.     if (strcmp((DEFCHAR *)command[i].text,"locate") == 0)
  2434.        break;
  2435.    }
  2436. #ifdef TRACE
  2437.  trace_return();
  2438. #endif
  2439.   return(i);
  2440. }
  2441. /***********************************************************************/
  2442. #ifdef HAVE_PROTO
  2443. void init_command(void)
  2444. #else
  2445. void init_command()
  2446. #endif
  2447. /***********************************************************************/
  2448. {
  2449. /*--------------------------- local data ------------------------------*/
  2450.  register short i=0;
  2451. /*--------------------------- processing ------------------------------*/
  2452. #ifdef TRACE
  2453.  trace_function("commutil.c:init_command");
  2454. #endif
  2455.  strcpy((DEFCHAR *)last_command_for_reexecute,"");
  2456.  strcpy((DEFCHAR *)last_command_for_repeat,"");
  2457.  for (i=0;i<MAX_SAVED_COMMANDS;i++)
  2458.      strcpy((DEFCHAR *)cmd_history[i],"");
  2459. #ifdef TRACE
  2460.  trace_return();
  2461. #endif
  2462.  return;
  2463. }
  2464. /***********************************************************************/
  2465. #ifdef HAVE_PROTO
  2466. void add_command(CHARTYPE *new_cmd)
  2467. #else
  2468. void add_command(new_cmd)
  2469. CHARTYPE *new_cmd;
  2470. #endif
  2471. /***********************************************************************/
  2472. {
  2473. /*-------------------------- external data ----------------------------*/
  2474.  extern bool in_macro;
  2475. /*--------------------------- local data ------------------------------*/
  2476. /*--------------------------- processing ------------------------------*/
  2477. #ifdef TRACE
  2478.  trace_function("commutil.c:add_command");
  2479. #endif
  2480. /*---------------------------------------------------------------------*/
  2481. /* Do not save commands if the commands are issued from a macro.       */
  2482. /*---------------------------------------------------------------------*/
  2483.  if (in_macro)
  2484.     return;
  2485. /*---------------------------------------------------------------------*/
  2486. /* If the command to be added is the same as the current command or if */
  2487. /* the command line is empty or if the command is "=" or "?", return   */
  2488. /* without adding command to array.                                    */
  2489. /*---------------------------------------------------------------------*/
  2490.  if (!valid_command_to_save(new_cmd))
  2491.    {
  2492. #ifdef TRACE
  2493.     trace_return();
  2494. #endif
  2495.     return;
  2496.    }
  2497.  offset_cmd = 0;
  2498.  if (strcmp((DEFCHAR *)new_cmd,(DEFCHAR *)cmd_history[current_cmd]) == 0)
  2499.    {
  2500. #ifdef TRACE
  2501.     trace_return();
  2502. #endif
  2503.     return;
  2504.    }
  2505.  if (number_cmds == MAX_SAVED_COMMANDS)
  2506.     current_cmd = last_cmd = (last_cmd == MAX_SAVED_COMMANDS-1) ? 0 : ++last_cmd;
  2507.  else
  2508.     current_cmd = ++last_cmd;
  2509.  strcpy((DEFCHAR *)cmd_history[current_cmd],(DEFCHAR *)new_cmd);
  2510.  number_cmds++;
  2511.  if (number_cmds > MAX_SAVED_COMMANDS)
  2512.     number_cmds = MAX_SAVED_COMMANDS;
  2513. #ifdef TRACE
  2514.  trace_return();
  2515. #endif
  2516.  return;
  2517. }             
  2518. /***********************************************************************/
  2519. #ifdef HAVE_PROTO
  2520. CHARTYPE *get_next_command( short direction, short num)
  2521. #else
  2522. CHARTYPE *get_next_command(direction,num)
  2523. short direction,num;
  2524. #endif
  2525. /***********************************************************************/
  2526. {
  2527. /*--------------------------- local data ------------------------------*/
  2528.  CHARTYPE *cmd_to_return=NULL;
  2529. /*--------------------------- processing ------------------------------*/
  2530. #ifdef TRACE
  2531.  trace_function("commutil.c:get_next_command");
  2532. #endif
  2533.  if (number_cmds == 0)
  2534.    {
  2535. #ifdef TRACE
  2536.     trace_return();
  2537. #endif
  2538.     return((CHARTYPE *)NULL);
  2539.    }
  2540.  while(num--)
  2541.    {
  2542.     switch(direction)
  2543.       {
  2544.        case DIRECTION_BACKWARD:
  2545.             if (current_cmd+1 == number_cmds)
  2546.               {
  2547.                current_cmd = 0;
  2548.                cmd_to_return = cmd_history[current_cmd];
  2549.               }
  2550.             else
  2551.                cmd_to_return = cmd_history[++current_cmd];
  2552.             break;
  2553.        case DIRECTION_FORWARD:
  2554.             if (current_cmd+offset_cmd < 0)
  2555.               {
  2556.                current_cmd = number_cmds-1;
  2557.                cmd_to_return = cmd_history[current_cmd];
  2558.               }
  2559.             else
  2560.               {
  2561.                current_cmd = current_cmd+offset_cmd;
  2562.                cmd_to_return = cmd_history[current_cmd];
  2563.               }
  2564.             offset_cmd = (-1);
  2565.             break;
  2566.        case DIRECTION_NONE:
  2567.             cmd_to_return = cmd_history[current_cmd];
  2568.             break;
  2569.       }
  2570.    }
  2571. #ifdef TRACE
  2572.  trace_return();
  2573. #endif
  2574.  return(cmd_to_return);
  2575. }
  2576. /***********************************************************************/
  2577. #ifdef HAVE_PROTO
  2578. bool valid_command_to_save(CHARTYPE *save_cmd)
  2579. #else
  2580. bool valid_command_to_save(save_cmd)
  2581. CHARTYPE *save_cmd;
  2582. #endif
  2583. /***********************************************************************/
  2584. {
  2585. /*--------------------------- local data ------------------------------*/
  2586. /*--------------------------- processing ------------------------------*/
  2587. #ifdef TRACE
  2588.  trace_function("commutil.c:valid_command_to_save");
  2589. #endif
  2590. /*---------------------------------------------------------------------*/
  2591. /* If the command to be added is empty or is "=" or starts with "?",   */
  2592. /* return FALSE, otherwise return TRUE.                                */
  2593. /*---------------------------------------------------------------------*/
  2594.  if (save_cmd == NULL
  2595.  ||  strcmp((DEFCHAR *)save_cmd,"") == 0
  2596.  ||  strcmp((DEFCHAR *)save_cmd,"=") == 0
  2597.  ||  save_cmd[0] == '?')
  2598.    {
  2599. #ifdef TRACE
  2600.     trace_return();
  2601. #endif
  2602.     return(FALSE);
  2603.    }
  2604. #ifdef TRACE
  2605.  trace_return();
  2606. #endif
  2607.  return(TRUE);
  2608. }
  2609. /***********************************************************************/
  2610. #ifdef HAVE_PROTO
  2611. static void save_last_command(CHARTYPE *last_cmd,CHARTYPE *cmnd)
  2612. #else
  2613. static void save_last_command(last_cmd,cmnd)
  2614. CHARTYPE *last_cmd,*cmnd;
  2615. #endif
  2616. /***********************************************************************/
  2617. {
  2618. /*-------------------------- external data ----------------------------*/
  2619.  extern bool in_macro;
  2620. /*--------------------------- local data ------------------------------*/
  2621. /*--------------------------- processing ------------------------------*/
  2622. #ifdef TRACE
  2623.  trace_function("commutil.c:save_last_command");
  2624. #endif
  2625. /*---------------------------------------------------------------------*/
  2626. /* Do not save commands if the commands are issued from a macro.       */
  2627. /*---------------------------------------------------------------------*/
  2628.  if (in_macro)
  2629.     return;
  2630. /*---------------------------------------------------------------------*/
  2631. /* If the command to be added is the same as the current command or if */
  2632. /* the command line is empty or if the command is "=" or "?", return   */
  2633. /* without adding command to array.                                    */
  2634. /*---------------------------------------------------------------------*/
  2635.  if (valid_command_to_save(last_cmd))
  2636.    {
  2637.     strcpy((DEFCHAR *)last_command_for_reexecute,(DEFCHAR *)last_cmd);
  2638.     if (!equal((CHARTYPE *)"REPEAT",cmnd,4))
  2639.        strcpy((DEFCHAR *)last_command_for_repeat,(DEFCHAR *)last_cmd);
  2640.    }
  2641. #ifdef TRACE
  2642.  trace_return();
  2643. #endif
  2644.  return;
  2645. }             
  2646. /***********************************************************************/
  2647. #ifdef HAVE_PROTO
  2648. bool is_tab_col(LENGTHTYPE x)
  2649. #else
  2650. bool is_tab_col(x)
  2651. LENGTHTYPE x;
  2652. #endif
  2653. /***********************************************************************/
  2654. {
  2655. /*-------------------------- external data ----------------------------*/
  2656. /*--------------------------- local data ------------------------------*/
  2657.  register short i=0;
  2658.  bool rc=FALSE;
  2659. /*--------------------------- processing ------------------------------*/
  2660. #ifdef TRACE
  2661.  trace_function("commutil.c:is_tab_col");
  2662. #endif
  2663.  for (i=0;i<CURRENT_VIEW->numtabs;i++)
  2664.    {
  2665.     if (CURRENT_VIEW->tabs[i] == x)
  2666.       {
  2667.        rc = TRUE;
  2668.        break;
  2669.       }
  2670.    }
  2671. #ifdef TRACE
  2672.  trace_return();
  2673. #endif
  2674.  return(rc);
  2675. }
  2676. /***********************************************************************/
  2677. #ifdef HAVE_PROTO
  2678. LENGTHTYPE find_next_tab_col(LENGTHTYPE x)
  2679. #else
  2680. LENGTHTYPE find_next_tab_col(x)
  2681. LENGTHTYPE x;
  2682. #endif
  2683. /***********************************************************************/
  2684. {
  2685. /*-------------------------- external data ----------------------------*/
  2686. /*--------------------------- local data ------------------------------*/
  2687.  register short i=0;
  2688.  LENGTHTYPE next_tab_col=0;
  2689. /*--------------------------- processing ------------------------------*/
  2690. #ifdef TRACE
  2691.  trace_function("commutil.c:find_next_tab_col");
  2692. #endif
  2693.  for (i=0;i<CURRENT_VIEW->numtabs;i++)
  2694.    {
  2695.     if (CURRENT_VIEW->tabs[i] > x)
  2696.       {
  2697.        next_tab_col = CURRENT_VIEW->tabs[i];
  2698.        break;
  2699.       }
  2700.    }
  2701. #ifdef TRACE
  2702.  trace_return();
  2703. #endif
  2704.  return(next_tab_col);
  2705. }
  2706. /***********************************************************************/
  2707. #ifdef HAVE_PROTO
  2708. LENGTHTYPE find_prev_tab_col(LENGTHTYPE x)
  2709. #else
  2710. LENGTHTYPE find_prev_tab_col(x)
  2711. LENGTHTYPE x;
  2712. #endif
  2713. /***********************************************************************/
  2714. {
  2715. /*-------------------------- external data ----------------------------*/
  2716. /*--------------------------- local data ------------------------------*/
  2717.  register short i=0;
  2718.  LENGTHTYPE next_tab_col=0;
  2719. /*--------------------------- processing ------------------------------*/
  2720. #ifdef TRACE
  2721.  trace_function("commutil.c:find_prev_tab_col");
  2722. #endif
  2723.  for (i=CURRENT_VIEW->numtabs-1;i>-1;i--)
  2724.    {
  2725.     if (CURRENT_VIEW->tabs[i] < x)
  2726.       {
  2727.        next_tab_col = CURRENT_VIEW->tabs[i];
  2728.        break;
  2729.       }
  2730.    }
  2731. #ifdef TRACE
  2732.  trace_return();
  2733. #endif
  2734.  return(next_tab_col);
  2735. }
  2736. /***********************************************************************/
  2737. #ifdef HAVE_PROTO
  2738. short tabs_convert(LINE *curr,bool expand_tabs,bool use_tabs,
  2739.                    bool add_to_recovery)
  2740. #else
  2741. short tabs_convert(curr,expand_tabs,use_tabs,add_to_recovery)
  2742. LINE *curr;
  2743. bool expand_tabs,use_tabs,add_to_recovery;
  2744. #endif
  2745. /***********************************************************************/
  2746. {
  2747. #define STATE_NORMAL 0
  2748. #define STATE_TAB    1
  2749. /*-------------------------- external data ----------------------------*/
  2750.  extern CHARTYPE *trec;
  2751.  extern CHARTYPE TABI_Nx;
  2752. /*--------------------------- local data ------------------------------*/
  2753.  register short i=0,j=0;
  2754.  bool expanded=FALSE;
  2755.  bool tabs_exhausted=FALSE;
  2756.  bool state=FALSE;
  2757.  LENGTHTYPE tabcol=0;
  2758. /*--------------------------- processing ------------------------------*/
  2759. #ifdef TRACE
  2760.  trace_function("commutil.c:tabs_convert");
  2761. #endif
  2762. /*---------------------------------------------------------------------*/
  2763. /* If we are expanding tabs to spaces, do the following...             */
  2764. /*---------------------------------------------------------------------*/
  2765.  if (expand_tabs)
  2766.    {
  2767.     for (i=0,j=0;i<curr->length;i++)
  2768.       {
  2769.        if (curr->line[i] == '\t')
  2770.          {
  2771.           if (use_tabs)
  2772.             {
  2773.              if (tabs_exhausted)
  2774.                {
  2775.                 trec[j++] = ' ';
  2776.                 if (j >= max_line_length)
  2777.                    break;
  2778.                }
  2779.              else
  2780.                {
  2781.                 tabcol = find_next_tab_col(j+1);
  2782.                 if (tabcol == 0)
  2783.                    tabs_exhausted = TRUE;
  2784.                 else
  2785.                   {
  2786.                    tabcol--;
  2787.                    do
  2788.                      {
  2789.                       trec[j++] = ' ';
  2790.                       if (j >= max_line_length)
  2791.                          break;
  2792.                      }
  2793.                    while (j<tabcol);
  2794.                   }
  2795.                }
  2796.             }
  2797.           else
  2798.             {
  2799.              do
  2800.                {
  2801.                 trec[j++] = ' ';
  2802.                 if (j >= max_line_length)
  2803.                    break;
  2804.                }
  2805.              while ((j % TABI_Nx) != 0);
  2806.             }
  2807.           expanded = TRUE;
  2808.          }
  2809.        else
  2810.          {
  2811.           trec[j++] = curr->line[i];
  2812.           if (j >= max_line_length)
  2813.             break;
  2814.          }
  2815.       }
  2816. /*---------------------------------------------------------------------*/
  2817. /* If we expanded tabs, we need to reallocate memory for the line.     */
  2818. /*---------------------------------------------------------------------*/
  2819.     if (expanded)
  2820.       {
  2821.        if (add_to_recovery)
  2822.           add_to_recovery_list(curr->line,curr->length);
  2823.        curr->line = (CHARTYPE *)(*the_realloc)((void *)curr->line,(j+1)*sizeof(CHARTYPE));
  2824.        if (curr->line == (CHARTYPE *)NULL)
  2825.          {
  2826.           display_error(30,(CHARTYPE *)"",FALSE);
  2827. #ifdef TRACE
  2828.           trace_return();
  2829. #endif
  2830.           return(RC_OUT_OF_MEMORY);
  2831.          }
  2832. /*---------------------------------------------------------------------*/
  2833. /* Copy the contents of rec into the line.                             */
  2834. /*---------------------------------------------------------------------*/
  2835.        memcpy(curr->line,trec,j);
  2836.        curr->length = j;
  2837.        *(curr->line+j) = '\0';
  2838.       }
  2839.    }
  2840.  else
  2841.    {
  2842.     for (i=(curr->length)-1,j=0;i>(-1);i--)
  2843.       {
  2844.        switch(state)
  2845.          {
  2846.           case STATE_NORMAL:
  2847.                trec[j++] = *(curr->line+i);
  2848.                if (is_tab_col(i+1)
  2849.                &&  i != 0)
  2850.                  {
  2851.                   if (*(curr->line+(i-1)) == ' ')
  2852.                     {
  2853.                      trec[j++] = '\t';
  2854.                      state = STATE_TAB;
  2855.                      expanded = TRUE;
  2856.                     }
  2857.                  }
  2858.                break;
  2859.           case STATE_TAB:
  2860. #if 0
  2861.                if (*(curr->line+i) == ' ')
  2862.                  {
  2863.                   if (is_tab_col(i+1)
  2864.                   &&  i != 0)
  2865.                      trec[j++] = '\t';
  2866.                  }
  2867.                else
  2868.                  {
  2869.                   trec[j++] = *(curr->line+i);
  2870.                   state = STATE_NORMAL;
  2871.                  }
  2872. #else
  2873.                if (is_tab_col(i+1)
  2874.                &&  i != 0)
  2875.                  {
  2876.                   if (*(curr->line+i) == ' ')
  2877.                     {
  2878.                      if (*(curr->line+(i-1)) == ' ')
  2879.                         trec[j++] = '\t';
  2880.                     }
  2881.                   else
  2882.                     {
  2883.                      trec[j++] = *(curr->line+i);
  2884.                      state = STATE_NORMAL;
  2885.                     }
  2886.                  }
  2887.                else
  2888.                  {
  2889.                   if (*(curr->line+i) != ' ')
  2890.                     {
  2891.                      trec[j++] = *(curr->line+i);
  2892.                      state = STATE_NORMAL;
  2893.                     }
  2894.                  }
  2895. #endif
  2896.                break;
  2897.          }     
  2898.       }
  2899.     if (expanded)
  2900.       {
  2901.        trec[j] = '\0';
  2902.        curr->length = j;
  2903.        for (i=0,j--;j>(-1);i++,j--)
  2904.           *(curr->line+i) = trec[j];
  2905.        *(curr->line+curr->length) = '\0';
  2906.       }
  2907.    }
  2908. #ifdef TRACE
  2909.  trace_return();
  2910. #endif
  2911.  return((expanded)?RC_FILE_CHANGED:RC_OK);
  2912. }
  2913. /***********************************************************************/
  2914. #ifdef HAVE_PROTO
  2915. short convert_hex_strings(CHARTYPE *str)
  2916. #else
  2917. short convert_hex_strings(str)
  2918. CHARTYPE *str;
  2919. #endif
  2920. /***********************************************************************/
  2921. {
  2922. /*--------------------------- local data ------------------------------*/
  2923.  register short i=0;
  2924.  CHARTYPE *p=NULL;
  2925.  bool dec_char=FALSE;
  2926.  CHARTYPE temp_str[MAX_COMMAND_LENGTH];
  2927.  short num=0;
  2928.  CHARTYPE ch1=0,ch2=0;
  2929. /*--------------------------- processing ------------------------------*/
  2930. #ifdef TRACE
  2931.  trace_function("commutil.c:convert_hex_strings");
  2932. #endif
  2933. /*---------------------------------------------------------------------*/
  2934. /* Check if the string begins with d',D',x' or X'. If not return the   */
  2935. /* string unchanged.                                                   */
  2936. /*---------------------------------------------------------------------*/
  2937.  if ((*(str) == 'd'
  2938.  ||   *(str) == 'D'
  2939.  ||   *(str) == 'x'
  2940.  ||   *(str) == 'X')
  2941.  &&   *(str+1) == '\'')
  2942.     ;
  2943.  else
  2944.    {
  2945. #ifdef TRACE
  2946.     trace_return();
  2947. #endif
  2948.     return(strlen((DEFCHAR *)str));
  2949.    }
  2950. /*---------------------------------------------------------------------*/
  2951. /* Check if the last character is a single quote. If not return (-1)   */
  2952. /* to indicate an error.                                               */
  2953. /*---------------------------------------------------------------------*/
  2954.  if (*(str+strlen((DEFCHAR *)str)-1) != '\'')
  2955.    {
  2956. #ifdef TRACE
  2957.     trace_return();
  2958. #endif
  2959.     return((-1));
  2960.    }
  2961. /*---------------------------------------------------------------------*/
  2962. /* If we got here we can validate the contents of the string.          */
  2963. /*---------------------------------------------------------------------*/
  2964.  *(str+strlen((DEFCHAR *)str)-1) = '\0';
  2965.  if (*(str) == 'd'
  2966.  ||  *(str) == 'D')
  2967.     dec_char = TRUE;
  2968.  else
  2969.     dec_char = FALSE;
  2970.  p = (CHARTYPE *)strtok((DEFCHAR *)str+2," ");
  2971.  while(p != NULL)
  2972.    {
  2973.     switch(dec_char)
  2974.       {
  2975.        case TRUE: /* parse decimal number */
  2976.                   if (equal((CHARTYPE *)"000000",p,1))
  2977.                      temp_str[i++] = (CHARTYPE)0;
  2978.                   else
  2979.                     {
  2980.                      num = atoi((DEFCHAR *)p);
  2981.                      if (num < 1 || num > 255)
  2982.                        {
  2983. #ifdef TRACE
  2984.                         trace_return();
  2985. #endif
  2986.                         return((-1));
  2987.                        }
  2988.                      temp_str[i++] = (CHARTYPE)num;
  2989.                     }
  2990.                   break;
  2991.        case FALSE: /* parse hexidecimal number */
  2992.                   ch1 = *(p);
  2993.                   ch2 = *(p+1);
  2994.                   if (strlen((DEFCHAR *)p) != 2
  2995.                   || !isxdigit(ch1)
  2996.                   || !isxdigit(ch2))
  2997.                     {
  2998. #ifdef TRACE
  2999.                      trace_return();
  3000. #endif
  3001.                      return((-1));
  3002.                     }
  3003.                   if (isupper(ch1)!=0)
  3004.                      ch1 = tolower(ch1);
  3005.                   if (isupper(ch2)!=0)
  3006.                      ch2 = tolower(ch2);
  3007.                   num =  ((isdigit(ch1)!=0) ? ch1-48 : ch1-87) * 16;
  3008.                   num += ((isdigit(ch2)!=0) ? ch2-48 : ch2-87);
  3009.                   temp_str[i++] = (CHARTYPE)num;
  3010.                   break;
  3011.       }
  3012.     p = (CHARTYPE *)strtok(NULL," ");
  3013.    }
  3014. /*
  3015.  temp_str[i] = '\0';
  3016.  memcpy(str,temp_str,i+1);
  3017. */
  3018.  memcpy(str,temp_str,i);
  3019. #ifdef TRACE
  3020.  trace_return();
  3021. #endif
  3022.  return(i);
  3023. }
  3024. /***********************************************************************/
  3025. #ifdef HAVE_PROTO
  3026. short marked_block(bool in_current_view)
  3027. #else
  3028. short marked_block(in_current_view)
  3029. bool in_current_view;
  3030. #endif
  3031. /***********************************************************************/
  3032. {
  3033. /*-------------------------- external data ----------------------------*/
  3034.  extern VIEW_DETAILS *vd_mark;
  3035.  extern bool batch_only;
  3036. /*--------------------------- local data ------------------------------*/
  3037. /*--------------------------- processing ------------------------------*/
  3038. #ifdef TRACE
  3039.  trace_function("commutil.c:marked_block");
  3040. #endif
  3041.  if (batch_only)                    /* block commands invalid in batch */
  3042.    {
  3043.     display_error(24,(CHARTYPE *)"",FALSE);
  3044. #ifdef TRACE
  3045.     trace_return();
  3046. #endif
  3047.     return(RC_INVALID_ENVIRON);
  3048.    }
  3049.  if (MARK_VIEW == (VIEW_DETAILS *)NULL)             /* no marked block */
  3050.    {
  3051.     display_error(44,(CHARTYPE *)"",FALSE);
  3052. #ifdef TRACE
  3053.     trace_return();
  3054. #endif
  3055.     return(RC_INVALID_ENVIRON);
  3056.    }
  3057.  if (MARK_VIEW != CURRENT_VIEW     /* marked block not in current view */
  3058.  && in_current_view)
  3059.    {
  3060.     display_error(45,(CHARTYPE *)"",FALSE);
  3061. #ifdef TRACE
  3062.     trace_return();
  3063. #endif
  3064.     return(RC_INVALID_ENVIRON);
  3065.    }
  3066. #ifdef TRACE
  3067.  trace_return();
  3068. #endif
  3069.  return(RC_OK);
  3070. }
  3071. /***********************************************************************/
  3072. #ifdef HAVE_PROTO
  3073. short suspend_curses(void)
  3074. #else
  3075. short suspend_curses()
  3076. #endif
  3077. /***********************************************************************/
  3078. {
  3079. /*--------------------------- local data ------------------------------*/
  3080. /*--------------------------- processing ------------------------------*/
  3081. #ifdef TRACE
  3082.  trace_function("commutil.c:suspend_curses");
  3083. #endif
  3084.  
  3085. #ifdef UNIX
  3086. # if defined(USE_EXTCURSES)
  3087.  csavetty(FALSE);
  3088.  reset_shell_mode();
  3089. # else
  3090.  endwin();
  3091. # endif
  3092. #endif
  3093.  
  3094. #if WAS_HAVE_BSD_CURSES
  3095.  noraw();
  3096.  nl();
  3097.  echo();
  3098.  nocbreak();
  3099. #endif
  3100.  
  3101. #ifdef TRACE
  3102.  trace_return();
  3103. #endif
  3104.  return(RC_OK);
  3105. }
  3106. /***********************************************************************/
  3107. #ifdef HAVE_PROTO
  3108. short resume_curses(void)
  3109. #else
  3110. short resume_curses()
  3111. #endif
  3112. /***********************************************************************/
  3113. {
  3114. /*--------------------------- local data ------------------------------*/
  3115. /*--------------------------- processing ------------------------------*/
  3116. #ifdef TRACE
  3117.  trace_function("commutil.c:resume_curses");
  3118. #endif
  3119. #ifdef WIN32
  3120.  reset_prog_mode();
  3121. #endif
  3122. #ifdef UNIX
  3123. # if defined(USE_EXTCURSES)
  3124.  cresetty(FALSE);
  3125. # else
  3126.  reset_prog_mode();
  3127. #  ifdef HAVE_BSD_CURSES
  3128.  raw();
  3129.  nonl();
  3130.  noecho();
  3131.  cbreak();
  3132. #  endif
  3133. # endif
  3134. #endif
  3135.  
  3136. #ifdef TRACE
  3137.  trace_return();
  3138. #endif
  3139.  return(RC_OK);
  3140. }
  3141. /***********************************************************************/
  3142. #ifdef HAVE_PROTO
  3143. short restore_THE(void)
  3144. #else
  3145. short restore_THE()
  3146. #endif
  3147. /***********************************************************************/
  3148. {
  3149. /*-------------------------- external data ----------------------------*/
  3150.  extern WINDOW *divider;
  3151.  extern WINDOW *statarea;
  3152.  extern CHARTYPE display_screens;
  3153.  extern bool horizontal;
  3154.  extern bool curses_started;
  3155. /*--------------------------- local data ------------------------------*/
  3156.  unsigned short y=0,x=0;
  3157. /*--------------------------- processing ------------------------------*/
  3158. #ifdef TRACE
  3159.  trace_function("commutil.c:restore_THE");
  3160. #endif
  3161. /*---------------------------------------------------------------------*/
  3162. /* If curses hasn't started, no point in doing anything...             */
  3163. /*---------------------------------------------------------------------*/
  3164.  if (!curses_started)
  3165.    {
  3166. #ifdef TRACE
  3167.     trace_return();
  3168. #endif
  3169.     return(RC_OK);
  3170.    }
  3171.  getyx(CURRENT_WINDOW,y,x);
  3172.  
  3173. #if 0
  3174.  wclear(stdscr);
  3175.  refresh();
  3176. #endif
  3177.  
  3178.  if (display_screens > 1)
  3179.    {
  3180.     touch_screen(other_screen);
  3181.     refresh_screen(other_screen);
  3182.     if (!horizontal)
  3183.       {
  3184.        touchwin(divider);
  3185.        wnoutrefresh(divider);
  3186.       }
  3187.    }
  3188.  touch_screen(current_screen);
  3189.  if (statarea != (WINDOW *)NULL)
  3190.     touchwin(statarea);
  3191.  wmove(CURRENT_WINDOW,y,x);
  3192. #ifdef TRACE
  3193.  trace_return();
  3194. #endif
  3195.  return(RC_OK);
  3196. }
  3197. /***********************************************************************/
  3198. #ifdef HAVE_PROTO
  3199. short execute_set_sos_command(bool set_command,CHARTYPE *params)
  3200. #else
  3201. short execute_set_sos_command(set_command,params)
  3202. bool set_command;
  3203. CHARTYPE *params;
  3204. #endif
  3205. /***********************************************************************/
  3206. {
  3207. /*-------------------------- external data ----------------------------*/
  3208.  extern bool in_readv;
  3209. /*--------------------------- local data ------------------------------*/
  3210. #define SETSOS_PARAMS  2
  3211.  CHARTYPE *word[SETSOS_PARAMS+1];
  3212.  CHARTYPE strip[SETSOS_PARAMS];
  3213.  unsigned short num_params=0;
  3214.  short rc=RC_OK,command_index=0;
  3215. /*--------------------------- processing ------------------------------*/
  3216. #ifdef TRACE
  3217.  trace_function("commutil.c:execute_set_sos_command");
  3218. #endif
  3219.  strip[0]=STRIP_BOTH;
  3220.  strip[1]=STRIP_NONE;
  3221.  num_params = param_split(params,word,SETSOS_PARAMS,WORD_DELIMS,TEMP_PARAM,strip,FALSE);
  3222.  if (num_params < 1)
  3223.    {
  3224.     display_error(1,(CHARTYPE *)"",FALSE);
  3225. #ifdef TRACE
  3226.     trace_return();
  3227. #endif
  3228.     return(RC_INVALID_OPERAND);
  3229.    }
  3230.  if ((command_index = valid_command_type(set_command,word[0])) == RC_NOT_COMMAND)
  3231.    {
  3232.     display_error(set_command ? 42 : 41,word[0],FALSE);
  3233. #ifdef TRACE
  3234.     trace_return();
  3235. #endif
  3236.     return(RC_INVALID_OPERAND);
  3237.    }
  3238. /*---------------------------------------------------------------------*/
  3239. /* If the SOS command is being executed while in READV CMDLINE, only   */
  3240. /* execute those commands that are allowed...                          */
  3241. /*---------------------------------------------------------------------*/
  3242.  if (in_readv)
  3243.    {
  3244.     if (command[command_index].valid_readv)
  3245.        rc = (*command[command_index].function)(word[1]);
  3246.    }
  3247.  else
  3248.     rc = (*command[command_index].function)(word[1]);
  3249. #ifdef TRACE
  3250.  trace_return();
  3251. #endif
  3252.  return(rc);
  3253. }
  3254. /***********************************************************************/
  3255. #ifdef HAVE_PROTO
  3256. short valid_command_type(bool set_command,CHARTYPE *cmd_line)
  3257. #else
  3258. short valid_command_type(set_command,cmd_line)
  3259. bool set_command;
  3260. CHARTYPE *cmd_line;
  3261. #endif
  3262. /***********************************************************************/
  3263. {
  3264. /*--------------------------- local data ------------------------------*/
  3265.  register short i=0;
  3266. /*--------------------------- processing ------------------------------*/
  3267. #ifdef TRACE
  3268.  trace_function("commutil.c:valid_command_type");
  3269. #endif
  3270.  for (i=0;command[i].text != NULL;i++)
  3271.     {
  3272. /*---------------------------------------------------------------------*/
  3273. /* If no command text, continue.                                       */
  3274. /*---------------------------------------------------------------------*/
  3275.      if (strcmp((DEFCHAR *)command[i].text,"") == 0)
  3276.         continue;
  3277. /*---------------------------------------------------------------------*/
  3278. /* Check that the supplied command matches the command for the length  */
  3279. /* of the command and that the length is at least as long as the       */
  3280. /* necessary significance.                                             */
  3281. /*---------------------------------------------------------------------*/
  3282.      if (equal(command[i].text,cmd_line,command[i].min_len)
  3283.      && command[i].min_len != 0)
  3284.        {
  3285. #ifdef TRACE
  3286.         trace_return();
  3287. #endif
  3288.         if (set_command && command[i].set_command)
  3289.            return(i);
  3290.         if (!set_command && command[i].sos_command)
  3291.            return(i);
  3292.        }
  3293.     }
  3294. #ifdef TRACE
  3295.  trace_return();
  3296. #endif
  3297.  return(RC_NOT_COMMAND);
  3298. }
  3299. /***********************************************************************/
  3300. #ifdef HAVE_PROTO
  3301. short allocate_temp_space(unsigned short length,CHARTYPE param_type)
  3302. #else
  3303. short allocate_temp_space(length,param_type)
  3304. unsigned short length;
  3305. CHARTYPE param_type;
  3306. #endif
  3307. /***********************************************************************/
  3308. {
  3309. /*--------------------------- local data ------------------------------*/
  3310.  CHARTYPE *temp_ptr=NULL;
  3311.  unsigned short *temp_length=NULL;
  3312. /*--------------------------- processing ------------------------------*/
  3313. #ifdef TRACE
  3314.  trace_function("commutil.c:allocate_temp_space");
  3315. #endif
  3316. /*---------------------------------------------------------------------*/
  3317. /* Based on param_type, point param_ptr to appropriate buffer.         */
  3318. /*---------------------------------------------------------------------*/
  3319.  switch(param_type)
  3320.    {
  3321.     case TEMP_PARAM:
  3322.          temp_ptr = temp_params;
  3323.          temp_length = &length_temp_params;
  3324.          break;
  3325.     case TEMP_MACRO:
  3326.          temp_ptr = temp_macros;
  3327.          temp_length = &length_temp_macros;
  3328.          break;
  3329.     case TEMP_TMP_CMD:
  3330.          temp_ptr = tmp_cmd;
  3331.          temp_length = &length_tmp_cmd;
  3332.          break;
  3333.     case TEMP_TEMP_CMD:
  3334.          temp_ptr = temp_cmd;
  3335.          temp_length = &length_temp_cmd;
  3336.          break;
  3337.     default:
  3338.          return(-1);
  3339.          break;
  3340.    }
  3341.  if (*temp_length >= length)
  3342.    {
  3343. #ifdef TRACE
  3344.     trace_return();
  3345. #endif
  3346.     return(RC_OK);
  3347.    }
  3348.  if (temp_ptr == NULL)
  3349.     temp_ptr = (CHARTYPE *)(*the_malloc)(sizeof(CHARTYPE)*(length+1));
  3350.  else
  3351.     temp_ptr = (CHARTYPE *)(*the_realloc)(temp_ptr,sizeof(CHARTYPE)*(length+1));
  3352.  if (temp_ptr == NULL)
  3353.    {
  3354.     display_error(30,(CHARTYPE *)"",FALSE);
  3355. #ifdef TRACE
  3356.     trace_return();
  3357. #endif
  3358.     return(RC_OUT_OF_MEMORY);
  3359.    }
  3360. /*---------------------------------------------------------------------*/
  3361. /* Based on param_type, point param_ptr to appropriate buffer.         */
  3362. /*---------------------------------------------------------------------*/
  3363.  switch(param_type)
  3364.    {
  3365.     case TEMP_PARAM:
  3366.          temp_params = temp_ptr;
  3367.          break;
  3368.     case TEMP_MACRO:
  3369.          temp_macros = temp_ptr;
  3370.          break;
  3371.     case TEMP_TMP_CMD:
  3372.          tmp_cmd = temp_ptr;
  3373.          break;
  3374.     case TEMP_TEMP_CMD:
  3375.          temp_cmd = temp_ptr;
  3376.          break;
  3377.     default:
  3378.          return(-1);
  3379.          break;
  3380.    }
  3381.  *temp_length = length;
  3382. #ifdef TRACE
  3383.  trace_return();
  3384. #endif
  3385.  return(RC_OK);
  3386. }
  3387. /***********************************************************************/
  3388. #ifdef HAVE_PROTO
  3389. void free_temp_space(CHARTYPE param_type)
  3390. #else
  3391. void free_temp_space(param_type)
  3392. CHARTYPE param_type;
  3393. #endif
  3394. /***********************************************************************/
  3395. {
  3396. /*--------------------------- local data ------------------------------*/
  3397.  CHARTYPE *temp_ptr=NULL;
  3398.  unsigned short *temp_length=0;
  3399. /*--------------------------- processing ------------------------------*/
  3400. #ifdef TRACE
  3401.  trace_function("commutil.c:free_temp_space");
  3402. #endif
  3403. /*---------------------------------------------------------------------*/
  3404. /* Based on param_type, point param_ptr to appropriate buffer.         */
  3405. /*---------------------------------------------------------------------*/
  3406.  switch(param_type)
  3407.    {
  3408.     case TEMP_PARAM:
  3409.          temp_ptr    = temp_params;
  3410.          temp_params = NULL;
  3411.          temp_length = &length_temp_params;
  3412.          break;
  3413.     case TEMP_MACRO:
  3414.          temp_ptr    = temp_macros;
  3415.          temp_macros = NULL;
  3416.          temp_length = &length_temp_macros;
  3417.          break;
  3418.     case TEMP_TMP_CMD:
  3419.          temp_ptr = tmp_cmd;
  3420.          tmp_cmd  = NULL;
  3421.          temp_length = &length_tmp_cmd;
  3422.          break;
  3423.     case TEMP_TEMP_CMD:
  3424.          temp_ptr    = temp_cmd;
  3425.          temp_cmd    = NULL;
  3426.          temp_length = &length_temp_cmd;
  3427.          break;
  3428.     default:
  3429.          return;
  3430.          break;
  3431.    }
  3432.  (*the_free)(temp_ptr);
  3433.  *temp_length = 0;
  3434. #ifdef TRACE
  3435.  trace_return();
  3436. #endif
  3437.  return;
  3438. }
  3439. /***********************************************************************/
  3440. #ifdef HAVE_PROTO
  3441. CHARTYPE calculate_actual_row(CHARTYPE base,short off,CHARTYPE rows,bool force_in_view)
  3442. #else
  3443. CHARTYPE calculate_actual_row(base,off,rows,force_in_view)
  3444. CHARTYPE base,rows;
  3445. short off;
  3446. bool force_in_view;
  3447. #endif
  3448. /***********************************************************************/
  3449. {
  3450. /*--------------------------- local data ------------------------------*/
  3451.  short row=0;
  3452. /*--------------------------- processing ------------------------------*/
  3453. #ifdef TRACE
  3454.  trace_function("commutil.c:calculate_actual_row");
  3455. #endif
  3456.  switch(base)
  3457.    {
  3458.     case POSITION_TOP:
  3459.                      row = off;
  3460.                      break;
  3461.     case POSITION_MIDDLE:
  3462.                      row = (rows /2 ) + off;
  3463.                      break;
  3464.     case POSITION_BOTTOM:
  3465.                      row = rows+off+1;
  3466.                      break;
  3467.    }
  3468. /*---------------------------------------------------------------------*/
  3469. /* If the calculated row is outside the screen size, default to middle.*/
  3470. /*---------------------------------------------------------------------*/
  3471.  if ((row < 0 || row > rows)
  3472.  && force_in_view)
  3473.     row = rows / 2;
  3474. #ifdef TRACE
  3475.  trace_return();
  3476. #endif
  3477.  return((CHARTYPE)row-1);
  3478. }
  3479. /*man***************************************************************************
  3480. NAME
  3481.      get_valid_macro_file_name
  3482.  
  3483. SYNOPSIS
  3484.      short get_valid_macro_file_name(macroname,filename,errnum)
  3485.      CHARTYPE *macroname;
  3486.      CHARTYPE *filename;
  3487.      short *errnum;
  3488.  
  3489. DESCRIPTION
  3490.      The get_valid_macro_file_name function determines the fully qualified
  3491.      file name for the supplied macroname.
  3492.  
  3493.      If the macroname contains any path specifiers, then the macro name
  3494.      is used as the filename and a check is made to ensure that the file
  3495.      exists and is readable.
  3496.  
  3497.      If the macroname does not contain any path specifiers, each
  3498.      directory in the MACROPATH variable is searched for a file that
  3499.      consists of the macroname appended with the current value for
  3500.      MACROEXT. If a file is found, it is checked to ensure it is
  3501.      readable.
  3502.  
  3503. RETURN VALUE
  3504.      If a file is found based on the above matching process, the fully
  3505.      qualified file name is copied into filename, errnum is set to 0
  3506.      and the function returns with RC_OK.
  3507.  
  3508.      If a file is not found, the macroname is copied into filename, the
  3509.      error number of the error message is copied into errnum and the
  3510.      function returns with RC_FILE_NOT_FOUND.
  3511.  
  3512.      If a file is found but the file is not readable, the macroname is
  3513.      copied into filename, the error number of the error message is
  3514.      copied into errnum and the function returns with RC_ACCESS_DENIED.
  3515. *******************************************************************************/
  3516. #ifdef HAVE_PROTO
  3517. short get_valid_macro_file_name(CHARTYPE *inmacroname,CHARTYPE *filename,short *errnum)
  3518. #else
  3519. short get_valid_macro_file_name(inmacroname,filename,errnum)
  3520. CHARTYPE *inmacroname,*filename;
  3521. short *errnum;
  3522. #endif
  3523. /***********************************************************************/
  3524. {
  3525. /*-------------------------- external data ----------------------------*/
  3526.  extern CHARTYPE the_macro_path_buf[MAX_FILE_NAME+1];
  3527.  extern CHARTYPE *the_macro_dir[MAX_MACRO_DIRS];
  3528.  extern int max_macro_dirs;
  3529.  extern CHARTYPE sp_path[MAX_FILE_NAME+1] ;
  3530.  extern CHARTYPE sp_fname[MAX_FILE_NAME+1] ;
  3531.  extern CHARTYPE macro_suffix[12];
  3532. /*--------------------------- local data ------------------------------*/
  3533.  register short i=0;
  3534.  CHARTYPE delims[3];
  3535.  bool file_found=FALSE;
  3536.  CHARTYPE macroname[MAX_FILE_NAME+1] ;
  3537.  unsigned short num_params=0;
  3538.  int len_macroname=strlen((DEFCHAR*)inmacroname);
  3539.  int len_macro_suffix=strlen((DEFCHAR*)macro_suffix);
  3540.  bool append_suffix=TRUE;
  3541. /*--------------------------- processing ------------------------------*/
  3542. #ifdef TRACE
  3543.  trace_function("commutil.c:get_valid_macro_file_name");
  3544. #endif
  3545. /*---------------------------------------------------------------------*/
  3546. /* Create the full name of the macro file by prepending the default    */
  3547. /* macropath provided the filename does not already contain a path.    */
  3548. /*---------------------------------------------------------------------*/
  3549.  strcpy( (DEFCHAR*)macroname, (DEFCHAR*)inmacroname );
  3550.  (void *)strrmdup(strtrans(macroname,OSLASH,ISLASH),ISLASH);
  3551. #ifdef UNIX
  3552.  strcpy((DEFCHAR *)delims,(DEFCHAR *)ISTR_SLASH);
  3553.  if (strpbrk((DEFCHAR *)macroname,(DEFCHAR *)delims) == NULL
  3554.  && *(macroname) != '~')
  3555. #endif
  3556. #if defined(DOS) || defined(OS2) || defined(WIN32)
  3557.  strcpy((DEFCHAR *)delims,ISTR_SLASH);
  3558.  strcat((DEFCHAR *)delims,":");
  3559.  if (strpbrk((DEFCHAR *)macroname,(DEFCHAR *)delims) == NULL)
  3560. #endif
  3561. /*---------------------------------------------------------------------*/
  3562. /* The supplied macro file name does not contain a path...so for each  */
  3563. /* directory in the_macro_path, try to find the supplied file in that  */
  3564. /* directory.                                                          */
  3565. /*---------------------------------------------------------------------*/
  3566.    {
  3567.     if (len_macroname > len_macro_suffix)
  3568.       {
  3569.        if (strcmp((DEFCHAR*)macroname+(len_macroname-len_macro_suffix),(DEFCHAR*)macro_suffix) == 0)
  3570.           append_suffix = FALSE;
  3571.        else
  3572.           append_suffix = TRUE;
  3573.       }
  3574.     file_found = FALSE;
  3575.     for (i=0;i<max_macro_dirs;i++)
  3576.       {
  3577.        strcpy((DEFCHAR *)filename,(DEFCHAR *)the_macro_dir[i]);
  3578.        if (strlen((DEFCHAR *)filename) == 0)
  3579.           continue;
  3580.        if (*(filename+strlen((DEFCHAR *)filename)-1) != ISLASH)
  3581.           strcat((DEFCHAR *)filename,(DEFCHAR *)ISTR_SLASH);
  3582.        strcat((DEFCHAR *)filename,(DEFCHAR *)macroname);     /* append the file name */
  3583.        if (append_suffix)
  3584.           strcat((DEFCHAR *)filename,(DEFCHAR *)macro_suffix); /* append default suffix */
  3585.        if (file_exists(filename))           /* check if file exists... */
  3586.          {
  3587.           file_found = TRUE;
  3588.           break;
  3589.          }
  3590.       }
  3591.     if (!file_found)
  3592.       {
  3593.        strcpy((DEFCHAR *)filename,(DEFCHAR *)macroname);
  3594.        if (append_suffix)
  3595.           strcat((DEFCHAR *)filename,(DEFCHAR *)macro_suffix);
  3596.        *errnum = 11;
  3597. #ifdef TRACE
  3598.        trace_return();
  3599. #endif
  3600.        return(RC_FILE_NOT_FOUND);
  3601.       }
  3602.    }
  3603.  else                                /* file contains a path specifier */
  3604. /*---------------------------------------------------------------------*/
  3605. /* The supplied macro file name does contain a path...so just check to */
  3606. /* ensure that the file exists.                                        */
  3607. /*---------------------------------------------------------------------*/
  3608.    {
  3609.     if (splitpath(macroname) != RC_OK)
  3610.       {
  3611.        *errnum = 9;
  3612. #ifdef TRACE
  3613.        trace_return();
  3614. #endif
  3615.        return(RC_FILE_NOT_FOUND);
  3616.       }
  3617.     strcpy((DEFCHAR *)filename,(DEFCHAR *)sp_path);
  3618.     strcat((DEFCHAR *)filename,(DEFCHAR *)sp_fname);
  3619.     if (!file_exists(filename)
  3620.     ||  strcmp((DEFCHAR *)sp_fname,"") == 0)
  3621.       {
  3622.        *errnum = 9;
  3623. #ifdef TRACE
  3624.        trace_return();
  3625. #endif
  3626.        return(RC_FILE_NOT_FOUND);
  3627.       }
  3628.    }
  3629. /*---------------------------------------------------------------------*/
  3630. /* If the file is not readable, error.                                 */
  3631. /*---------------------------------------------------------------------*/
  3632.  if (!file_readable(filename))
  3633.    {
  3634.     *errnum = 8;
  3635. #ifdef TRACE
  3636.     trace_return();
  3637. #endif
  3638.     return(RC_ACCESS_DENIED);
  3639.    }
  3640. #ifdef TRACE
  3641.  trace_return();
  3642. #endif
  3643.  *errnum = 0;
  3644.  return(RC_OK);
  3645. }
  3646. /***********************************************************************/
  3647. #ifdef HAVE_PROTO
  3648. bool define_command(CHARTYPE *cmd_line)
  3649. #else
  3650. bool define_command(cmd_line)
  3651. CHARTYPE *cmd_line;
  3652. #endif
  3653. /***********************************************************************/
  3654. {
  3655. /*-------------------------- external data ----------------------------*/
  3656. /*--------------------------- local data ------------------------------*/
  3657.  register short i=0;
  3658.  CHARTYPE buf[7];
  3659. /*--------------------------- processing ------------------------------*/
  3660. #ifdef TRACE
  3661.  trace_function("commutil.c:define_command");
  3662. #endif
  3663. /*---------------------------------------------------------------------*/
  3664. /* First check if the command is a synonym, and use the real name to   */
  3665. /* search the command array.                                           */
  3666. /*---------------------------------------------------------------------*/
  3667.  
  3668.  memset(buf,'\0',7);
  3669.  memcpy(buf,cmd_line,min(6,strlen((DEFCHAR *)cmd_line)));
  3670.  for (i=0;i<7;i++)
  3671.    {
  3672.     if (buf[i] == ' ')
  3673.        buf[i] = '\0';
  3674.    }
  3675.  if ((i = find_command(buf,FALSE)) == (-1))
  3676.    {
  3677. #ifdef TRACE
  3678.     trace_return();
  3679. #endif
  3680.     return(FALSE);
  3681.    }
  3682.  if (strcmp("define",(DEFCHAR *)command[i].text) == 0)
  3683.    {
  3684. #ifdef TRACE
  3685.     trace_return();
  3686. #endif
  3687.     return(TRUE);
  3688.    }
  3689. #ifdef TRACE
  3690.  trace_return();
  3691. #endif
  3692.  return(FALSE);
  3693. }
  3694. /***********************************************************************/
  3695. #ifdef HAVE_PROTO
  3696. int find_key_name(CHARTYPE *keyname)
  3697. #else
  3698. int find_key_name(keyname)
  3699. CHARTYPE *keyname;
  3700. #endif
  3701. /***********************************************************************/
  3702. {
  3703. /*-------------------------- external data ----------------------------*/
  3704. /*--------------------------- local data ------------------------------*/
  3705.  register int i=0;
  3706.  int key=(-1);
  3707. /*--------------------------- processing ------------------------------*/
  3708. #ifdef TRACE
  3709.  trace_function("commutil.c:find_key_name");
  3710. #endif
  3711.  for (i=0;key_table[i].mnemonic != NULL;i++)
  3712.    {
  3713.     if (memcmpi(keyname,key_table[i].mnemonic,strlen((DEFCHAR *)keyname)) == 0)
  3714.       {
  3715.        key = key_table[i].key_value;
  3716.        break;
  3717.       }
  3718.    }
  3719. #ifdef TRACE
  3720.  trace_return();
  3721. #endif
  3722.  return(key);
  3723. }
  3724. /***********************************************************************/
  3725. #ifdef HAVE_PROTO
  3726. int readv_cmdline(CHARTYPE *initial)
  3727. #else
  3728. int readv_cmdline(initial)
  3729. CHARTYPE *initial;
  3730. #endif
  3731. /***********************************************************************/
  3732. {
  3733. /*-------------------------- external data ----------------------------*/
  3734.  extern CHARTYPE *cmd_rec;
  3735.  extern unsigned short cmd_rec_len;
  3736.  extern bool in_readv;
  3737. /*--------------------------- local data ------------------------------*/
  3738.  int key=0;
  3739.  short rc=RC_OK;
  3740.  bool cursor_on_cmdline=FALSE;
  3741.  CHARTYPE buf[3];
  3742. /*--------------------------- processing ------------------------------*/
  3743. #ifdef TRACE
  3744.  trace_function("commutil.c:readv_cmdline");
  3745. #endif
  3746.  if (CURRENT_WINDOW_COMMAND == (WINDOW *)NULL)
  3747.    {
  3748.     display_error(86,(CHARTYPE *)"",FALSE);
  3749. #ifdef TRACE
  3750.     trace_return();
  3751. #endif
  3752.     return(RC_INVALID_OPERAND);
  3753.    }
  3754.  buf[1] = '\0';
  3755.  if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
  3756.     cursor_on_cmdline = TRUE;
  3757.  Cmsg(initial);
  3758.  cursor_cmdline(strlen((DEFCHAR *)initial)+1);
  3759.  in_readv = TRUE; /* this MUST go here to allow cursor_cmdline() to work */
  3760.  wrefresh(CURRENT_WINDOW_COMMAND);
  3761.  while(1)
  3762.    {
  3763.     key = my_getch(stdscr);
  3764. #if defined(XCURSES)
  3765.     if (key == KEY_SF || key == KEY_SR)
  3766.        continue;
  3767. #endif
  3768.     rc = function_key(key,OPTION_READV);
  3769.     switch(rc)
  3770.       {
  3771.        case RC_READV_TERM:
  3772. /*            cmd_rec[cmd_rec_len] = '\0';*/
  3773.             set_rexx_variable((CHARTYPE *)"READV",cmd_rec,cmd_rec_len,1);
  3774.             set_rexx_variable((CHARTYPE *)"READV",(CHARTYPE *)"1",1,0);
  3775.             wmove(CURRENT_WINDOW_COMMAND,0,0);
  3776.             my_wclrtoeol(CURRENT_WINDOW_COMMAND);
  3777.             memset(cmd_rec,' ',max_line_length);
  3778.             cmd_rec_len = 0;
  3779.             wmove(CURRENT_WINDOW_COMMAND,0,0);
  3780.             break;
  3781.        case RAW_KEY:
  3782.             if (rc >= RAW_KEY)
  3783.               {
  3784.                if (rc > RAW_KEY)
  3785.                key = rc - (RAW_KEY*2);
  3786.                if (key < 256 && key >= 0)
  3787.                  {
  3788.                   buf[0] = (CHARTYPE)key;
  3789.                   rc = Text(buf);
  3790.                  }
  3791.               }
  3792.             break;
  3793.        default:
  3794.             break;
  3795.       }
  3796.     show_statarea();
  3797.     wrefresh(CURRENT_WINDOW_COMMAND);
  3798.     if (rc == RC_READV_TERM)
  3799.        break;
  3800.    }
  3801. /*---------------------------------------------------------------------*/
  3802. /* If we were NOT on the command line, go back to where we were.       */
  3803. /*---------------------------------------------------------------------*/
  3804.  in_readv = FALSE; /* this MUST go here to allow cursor_home() to work */
  3805.  if (!cursor_on_cmdline)
  3806.     cursor_home(TRUE);
  3807. #ifdef TRACE
  3808.  trace_return();
  3809. #endif
  3810.  return(rc);
  3811. }
  3812. /***********************************************************************/
  3813. #ifdef HAVE_PROTO
  3814. short execute_mouse_commands(int key)
  3815. #else
  3816. short execute_mouse_commands(key)
  3817. int key;
  3818. #endif
  3819. /***********************************************************************/
  3820. {
  3821. /*------------------------- external data -----------------------------*/
  3822.  extern DEFINE *first_mouse_define;
  3823.  extern CHARTYPE number_of_files;
  3824.  extern bool readonly;
  3825. /*--------------------------- local data ------------------------------*/
  3826.  register short i=0;
  3827.  DEFINE *curr=(DEFINE *)NULL;
  3828.  CHARTYPE *key_cmd=NULL;
  3829.  short rc=RC_OK;
  3830.  short macrorc=0;
  3831. /*--------------------------- processing ------------------------------*/
  3832. #ifdef TRACE
  3833.  trace_function("commutil.c:execute_mouse_commands");
  3834. #endif
  3835.  curr = first_mouse_define;
  3836.  while(curr != (DEFINE *)NULL)
  3837.    {
  3838.     if (key == curr->def_funkey)
  3839.       {
  3840. /*---------------------------------------------------------------------*/
  3841. /* If running in read-only mode and the function selected is not valid */
  3842. /* display an error.                                                   */
  3843. /*---------------------------------------------------------------------*/
  3844.        if (curr->def_command != (-1)
  3845.        && readonly
  3846.        && !command[curr->def_command].valid_in_readonly)
  3847.          {
  3848.           display_error(56,(CHARTYPE *)"",FALSE);
  3849.           rc = RC_INVALID_ENVIRON;
  3850.           curr = NULL;
  3851.           break;
  3852.          }
  3853. /*---------------------------------------------------------------------*/
  3854. /* If there are no more files in the ring, and the command is not a    */
  3855. /* command to edit a new file, then ignore the command.                */
  3856. /*---------------------------------------------------------------------*/
  3857.        if (curr->def_command != (-1)
  3858.        &&  number_of_files == 0
  3859.        &&  !command[curr->def_command].edit_command)
  3860.          {
  3861.           rc = RC_OK;
  3862.           curr = NULL;
  3863.           break;
  3864.          }
  3865.        if ((key_cmd = (CHARTYPE *)my_strdup(curr->def_params)) == NULL)
  3866.          {
  3867.           display_error(30,(CHARTYPE *)"",FALSE);
  3868.           rc = RC_OUT_OF_MEMORY;
  3869.           curr = NULL;
  3870.           break;
  3871.          }
  3872.        if (curr->def_command == (-1))
  3873.           rc = execute_macro_instore(key_cmd,¯orc);
  3874.        else
  3875.           rc = (*command[curr->def_command].function)((CHARTYPE *)key_cmd);
  3876.        (*the_free)(key_cmd);
  3877.        if (rc != RC_OK
  3878.        &&  rc != RC_TOF_EOF_REACHED
  3879.        &&  rc != RC_NO_LINES_CHANGED
  3880.        &&  rc != RC_TARGET_NOT_FOUND)
  3881.          {
  3882.           curr = NULL;
  3883.           break;
  3884.          }
  3885.       }
  3886.     if (curr == NULL)
  3887.        break;
  3888.     curr = curr->next;
  3889.    }
  3890. #ifdef TRACE
  3891.  trace_return();
  3892. #endif
  3893.  return(rc);
  3894. }
  3895. /***********************************************************************/
  3896. #ifdef HAVE_PROTO
  3897. short validate_n_m(CHARTYPE *params,short *col1,short *col2)
  3898. #else
  3899. short validate_n_m(params,col1,col2)
  3900. CHARTYPE *params;
  3901. short *col1,*col2;
  3902. #endif
  3903. /***********************************************************************/
  3904. {
  3905. /*------------------------- external data -----------------------------*/
  3906. /*--------------------------- local data ------------------------------*/
  3907. #define NM_PARAMS  2
  3908.  CHARTYPE *word[NM_PARAMS+1];
  3909.  CHARTYPE strip[NM_PARAMS];
  3910.  unsigned short num_params=0;
  3911.  short rc=RC_OK;
  3912. /*--------------------------- processing ------------------------------*/
  3913. #ifdef TRACE
  3914.  trace_function("commutil.c:validate_n_m");
  3915. #endif
  3916. /*---------------------------------------------------------------------*/
  3917. /* Validate the parameters that have been supplied. One only           */
  3918. /* parameter MUST be supplied. The first parameter MUST be a positive  */
  3919. /* integer. The second can be a positive integer or '*'. If no second  */
  3920. /* parameter is supplied, defaults to p1. The second parameter MUST be */
  3921. /* >= first parameter. '*' is regarded as the biggest number and is    */
  3922. /* literally 255.                                                      */
  3923. /*---------------------------------------------------------------------*/
  3924.  strip[0]=STRIP_BOTH;
  3925.  strip[1]=STRIP_BOTH;
  3926.  num_params = param_split(params,word,NM_PARAMS,WORD_DELIMS,TEMP_PARAM,strip,FALSE);
  3927.  if (num_params < 1)
  3928.    {
  3929.     display_error(3,(CHARTYPE *)"",FALSE);
  3930. #ifdef TRACE
  3931.     trace_return();
  3932. #endif
  3933.     return(RC_INVALID_OPERAND);
  3934.    }
  3935.  if (num_params > 2)
  3936.    {
  3937.     display_error(2,(CHARTYPE *)"",FALSE);
  3938. #ifdef TRACE
  3939.     trace_return();
  3940. #endif
  3941.     return(RC_INVALID_OPERAND);
  3942.    }
  3943.  if (!valid_positive_integer(word[0]))
  3944.    {
  3945.     display_error(4,word[0],FALSE);
  3946. #ifdef TRACE
  3947.     trace_return();
  3948. #endif
  3949.     return(RC_INVALID_OPERAND);
  3950.    }
  3951.  *col1 = atoi((DEFCHAR *)word[0]);
  3952.  if (strcmp((DEFCHAR *)word[1],"*") == 0)
  3953.     *col2 = 255;
  3954.  else
  3955.     if (num_params == 1)      /* no second parameter, default to first */
  3956.        *col2 = *col1;
  3957.     else
  3958.        if (!valid_positive_integer(word[1]))
  3959.          {
  3960.           display_error(4,word[1],FALSE);
  3961. #ifdef TRACE
  3962.           trace_return();
  3963. #endif
  3964.           return(RC_INVALID_OPERAND);
  3965.          }
  3966.        else
  3967.           *col2 = atoi((DEFCHAR *)word[1]);
  3968.  
  3969.  if (*col2 > 255)
  3970.     *col2 = 255;
  3971.  if (*col1 > *col2)
  3972.    {
  3973.     display_error(6,word[0],FALSE);
  3974. #ifdef TRACE
  3975.     trace_return();
  3976. #endif
  3977.     return(RC_INVALID_OPERAND);
  3978.    }
  3979. #ifdef TRACE
  3980.  trace_return();
  3981. #endif
  3982.  return(rc);
  3983. }
  3984.