home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / thesrc15.zip / commutil.c < prev    next >
C/C++ Source or Header  |  1993-11-30  |  90KB  |  2,871 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-1993 Mark Hessling
  9.  *
  10.  * This program is free software; you can redistribute it and/or
  11.  * modify it under the terms of the GNU General Public License as
  12.  * published by the Free Software Foundation; either version 2 of
  13.  * the License, or any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18.  * General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to:
  22.  *
  23.  *    The Free Software Foundation, Inc.
  24.  *    675 Mass Ave,
  25.  *    Cambridge, MA 02139 USA.
  26.  *
  27.  *
  28.  * If you make modifications to this software that you feel increases
  29.  * it usefulness for the rest of the community, please email the
  30.  * changes, enhancements, bug fixes as well as any and all ideas to me.
  31.  * This software is going to be maintained and enhanced as deemed
  32.  * necessary by the community.
  33.  *
  34.  * Mark Hessling                     email: M.Hessling@gu.edu.au
  35.  * 36 David Road                     Phone: +61 7 849 7731
  36.  * Holland Park                      Fax:   +61 7 875 5314
  37.  * QLD 4121
  38.  * Australia
  39.  */
  40.  
  41. /*
  42. $Header: C:\THE\RCS\commutil.c 1.4 1993/09/01 16:25:58 MH Interim MH $
  43. */
  44.  
  45. #include <stdio.h>
  46.  
  47. #include "the.h"
  48. #include "key.h"
  49. #include "command.h"
  50. #include "proto.h"
  51.  
  52. /*#define DEBUG 1*/
  53.  
  54.  
  55. #define NUMBER_VALID_TARGETS 32
  56. #define NUMBER_SEARCH_TARGETS 9
  57.  static SEARCH_TARGET st[NUMBER_VALID_TARGETS] =
  58.   {
  59.    {(char *)"\\",1,'\\',DIRECTION_FORWARD},
  60.    {(char *)"+\\",2,'\\',DIRECTION_FORWARD},
  61.    {(char *)"-\\",2,'\\',DIRECTION_BACKWARD},
  62.  
  63.    {(char *)"/",1,'/',DIRECTION_FORWARD},
  64.    {(char *)"+/",2,'/',DIRECTION_FORWARD},
  65.    {(char *)"-/",2,'/',DIRECTION_BACKWARD},
  66.  
  67.    {(char *)"@",1,'@',DIRECTION_FORWARD},
  68.    {(char *)"+@",2,'@',DIRECTION_FORWARD},
  69.    {(char *)"-@",2,'@',DIRECTION_BACKWARD},
  70.  
  71.    {(char *)":",1,0,0},
  72.    {(char *)"*",1,0,0},
  73.    {(char *)"-*",2,0,0},
  74.    {(char *)"0",1,0,0},
  75.    {(char *)"1",1,0,0},
  76.    {(char *)"2",1,0,0},
  77.    {(char *)"3",1,0,0},
  78.    {(char *)"4",1,0,0},
  79.    {(char *)"5",1,0,0},
  80.    {(char *)"6",1,0,0},
  81.    {(char *)"7",1,0,0},
  82.    {(char *)"8",1,0,0},
  83.    {(char *)"9",1,0,0},
  84.    {(char *)"-0",1,0,0},
  85.    {(char *)"-1",1,0,0},
  86.    {(char *)"-2",1,0,0},
  87.    {(char *)"-3",1,0,0},
  88.    {(char *)"-4",1,0,0},
  89.    {(char *)"-5",1,0,0},
  90.    {(char *)"-6",1,0,0},
  91.    {(char *)"-7",1,0,0},
  92.    {(char *)"-8",1,0,0},
  93.    {(char *)"-9",1,0,0}
  94.   };
  95.  
  96. #define MAX_CMDS 15
  97.  static char cmd[MAX_CMDS][80];
  98.  static short last_cmd=(-1),current_cmd=0,number_cmds=0,offset_cmd=0;
  99.  
  100. /*---------------------------------------------------------------------*/
  101. /* The following two static variables are for reserving space for the  */
  102. /* parameters of a command. Space for temp_params is allocated and     */
  103. /* freed in the.c. If the size of the string to be placed into         */
  104. /* temp_params is > length_temp_params, reallocate a larger area and   */
  105. /* set the value of length_temp_params to reflect the new size.        */
  106. /*---------------------------------------------------------------------*/
  107.  static char *temp_params=NULL;
  108.  static unsigned int length_temp_params=0;
  109. /*---------------------------------------------------------------------*/
  110. /* The following two static variables are for reserving space for the  */
  111. /* directories in a macro path. Space for temp_macros is allocated and */
  112. /* freed in the.c. If the size of the string to be placed into         */
  113. /* temp_macros is > length_temp_macros  reallocate a larger area and   */
  114. /* set the value of length_temp_macros to reflect the new size.        */
  115. /*---------------------------------------------------------------------*/
  116.  static char *temp_macros=NULL;
  117.  static unsigned int length_temp_macros=0;
  118. /*---------------------------------------------------------------------*/
  119. /* The following two static variables are for reserving space for the  */
  120. /* contents of   a command. Space for tmp_cmd     is allocated and     */
  121. /* freed in the.c. If the size of the string to be placed into         */
  122. /* tmp_cmd     is > length_tmp_cmd    , reallocate a larger area and   */
  123. /* set the value of length_tmp_cmd     to reflect the new size.        */
  124. /*---------------------------------------------------------------------*/
  125.  static char *tmp_cmd=NULL;
  126.  static unsigned int length_tmp_cmd=0;
  127. /*---------------------------------------------------------------------*/
  128. /* The following two        variables are for reserving space for the  */
  129. /* contents of   a command. Space for temp_cmd    is allocated and     */
  130. /* freed in the.c. If the size of the string to be placed into         */
  131. /* temp_cmd    is > length_temp_cmd   , reallocate a larger area and   */
  132. /* set the value of length_temp_cmd    to reflect the new size.        */
  133. /*---------------------------------------------------------------------*/
  134.  char *temp_cmd=NULL;
  135.  static unsigned int length_temp_cmd=0;
  136.  
  137. /*---------------------------------------------------------------------*/
  138. /* The following two are to specify the first and last items in the    */
  139. /* linked list for key definitions.                                    */
  140. /*---------------------------------------------------------------------*/
  141. DEFINE *first_define=NULL;
  142. DEFINE *last_define=NULL;
  143.  
  144.  bool clear_command=TRUE;
  145. /*-------------------------- external data ----------------------------*/
  146. extern LINE *next_line,*curr_line;
  147. extern VIEW_DETAILS *vd_current,*vd_first,*vd_mark;
  148. extern char current_screen;
  149. extern SCREEN_DETAILS screen[MAX_SCREENS];        /* screen structures */
  150. extern char number_of_views;
  151. extern WINDOW *foot,*error_window;
  152. extern bool error_on_screen;
  153. extern char in_profile;    /* indicates if processing profile */
  154. extern char file_read;  /* indicates if we have read the file */
  155. extern char *last_target;
  156. extern char curr_path[MAX_FILE_NAME+1] ;
  157. extern char sp_path[MAX_FILE_NAME+1] ;
  158. extern char sp_fname[MAX_FILE_NAME+1] ;
  159. /***********************************************************************/
  160. #ifdef PROTO
  161. char *get_key_definition(unsigned short key)
  162. #else
  163. char *get_key_definition(key)
  164. unsigned short key;
  165. #endif
  166. /***********************************************************************/
  167. {
  168. /*--------------------------- local data ------------------------------*/
  169.  register int i;
  170.  DEFINE *curr;
  171.  char delim[2];
  172.  bool key_defined=FALSE;
  173.  bool valid_key=FALSE;
  174.  bool first_time=TRUE;
  175.  bool locate_command;
  176. /*--------------------------- processing ------------------------------*/
  177. #ifdef TRACE
  178.  trace_function("commutil.c:get_key_definition");
  179. #endif
  180. /*---------------------------------------------------------------------*/
  181. /* First determine if the key is a named key.                          */
  182. /*---------------------------------------------------------------------*/
  183.  for (i=0;i<MAX_NUMBER_KEYS && valid_key == FALSE;i++)
  184.     {
  185.      if (key == key_table[i].key_value)
  186.        {
  187.         strcpy(temp_cmd,"Key: ");
  188.         valid_key = TRUE;
  189.         strcat(temp_cmd,key_table[i].mnemonic);
  190.        }
  191.     }
  192. /*---------------------------------------------------------------------*/
  193. /* If key is invalid,  show it as a character and decimal; provided it */
  194. /* is an ASCII or extended character.                                  */
  195. /*---------------------------------------------------------------------*/
  196.  if (!valid_key && key <256)
  197.     sprintf(temp_cmd,"Key: %c \\%d",(char)key,key);
  198. /*---------------------------------------------------------------------*/
  199. /* Next check to see if the key has been "defined".                    */
  200. /*---------------------------------------------------------------------*/
  201.  delim[1] = '\0';
  202.  curr = first_define;
  203.  while(curr != NULL)
  204.   {
  205.    if (key == curr->def_funkey)
  206.      {
  207.       key_defined = TRUE;
  208.       if (first_time)
  209.          strcat(temp_cmd," - assigned to '");
  210.       else
  211.         {
  212.          delim[0] = curr->def_delim;
  213.          strcat(temp_cmd,delim);
  214.         }
  215. /*---------------------------------------------------------------------*/
  216. /* If command is 'locate' do not append to string.                     */
  217. /*---------------------------------------------------------------------*/
  218.       locate_command = FALSE;
  219.       if (strcmp(command[curr->def_command].text,"locate") != 0)
  220.          strcat(temp_cmd,command[curr->def_command].text);
  221.       else
  222.          locate_command = TRUE;
  223. /*---------------------------------------------------------------------*/
  224. /* Append any parameters.                                              */
  225. /*---------------------------------------------------------------------*/
  226.       if (strcmp(curr->def_params,"") != 0)
  227.         {
  228.          if (!locate_command)
  229.             strcat(temp_cmd," ");
  230.          strcat(temp_cmd,curr->def_params);
  231.         }
  232.       first_time = FALSE;
  233.      }
  234.    curr = curr->next;
  235.   }
  236.  if (key_defined)
  237.    {
  238.     strcat(temp_cmd,"'");
  239. #ifdef TRACE
  240.     trace_return();
  241. #endif
  242.     return(temp_cmd);
  243.    }
  244. /*---------------------------------------------------------------------*/
  245. /* If not, check for the default function key values.                  */
  246. /*---------------------------------------------------------------------*/
  247.  for (i=0;command[i].text != NULL;i++)
  248.     {
  249.       if (key == command[i].funkey)
  250.         {
  251.          strcat(temp_cmd," - assigned to '");
  252. /*---------------------------------------------------------------------*/
  253. /* If a SET command, prefix with 'set'                                 */
  254. /*---------------------------------------------------------------------*/
  255.          if (command[i].set_command)
  256.             strcat(temp_cmd,"set ");
  257. /*---------------------------------------------------------------------*/
  258. /* If a SOS command, prefix with 'sos'                                 */
  259. /*---------------------------------------------------------------------*/
  260.          if (command[i].sos_command)
  261.             strcat(temp_cmd,"sos ");
  262. /*---------------------------------------------------------------------*/
  263. /* Append the command name.                                            */
  264. /*---------------------------------------------------------------------*/
  265.          strcat(temp_cmd,command[i].text);
  266. /*---------------------------------------------------------------------*/
  267. /* Append any parameters.                                              */
  268. /*---------------------------------------------------------------------*/
  269.          if (strcmp(command[i].params,"") != 0)
  270.            {
  271.             strcat(temp_cmd," ");
  272.             strcat(temp_cmd,command[i].params);
  273.            }
  274.          strcat(temp_cmd,"'");
  275. #ifdef TRACE
  276.          trace_return();
  277. #endif
  278.          return(temp_cmd);
  279.         }
  280.     }
  281. /*---------------------------------------------------------------------*/
  282. /* If none of the above, it is unassigned                              */
  283. /*---------------------------------------------------------------------*/
  284.  strcat(temp_cmd," - unassigned");
  285. #ifdef TRACE
  286.  trace_return();
  287. #endif
  288.  return(temp_cmd);
  289. }
  290. /***********************************************************************/
  291. #ifdef PROTO
  292. int function_key(int key)
  293. #else
  294. int function_key(key)
  295. int key;
  296. #endif
  297. /***********************************************************************/
  298. {
  299. /*--------------------------- local data ------------------------------*/
  300.  unsigned short x,y;
  301.  register int i;
  302.  DEFINE *curr;
  303.  char cmd[81];
  304.  bool key_defined = FALSE;
  305.  int rc;
  306. /*--------------------------- processing ------------------------------*/
  307. #ifdef TRACE
  308.  trace_function("commutil.c:function_key");
  309. #endif
  310. /*---------------------------------------------------------------------*/
  311. /* First check to see if the function key has been redefined.          */
  312. /*---------------------------------------------------------------------*/
  313.  curr = first_define;
  314.  while(curr != NULL)
  315.   {
  316.    if (key == curr->def_funkey)
  317.      {
  318.       key_defined = TRUE;
  319.       rc = (*command[curr->def_command].function)(curr->def_params);
  320.       if (rc != RC_OK
  321.       &&  rc != RC_TOF_EOF_REACHED
  322.       &&  rc != RC_NO_LINES_CHANGED
  323.       &&  rc != RC_TARGET_NOT_FOUND)
  324.          break;
  325.      }
  326.    curr = curr->next;
  327.   }
  328.  if (key_defined)
  329.    {
  330. #ifdef TRACE
  331.     trace_return();
  332. #endif
  333.     return(rc);
  334.    }
  335. /*---------------------------------------------------------------------*/
  336. /* If not, check for the default function key values.                  */
  337. /*---------------------------------------------------------------------*/
  338.  for (i=0;command[i].text != NULL;i++)
  339.       if (key == command[i].funkey)
  340.         {
  341.          i = (*command[i].function)(command[i].params);
  342. #ifdef TRACE
  343.          trace_return();
  344. #endif
  345.          return(i);
  346.         }
  347. #ifdef TRACE
  348.  trace_return();
  349. #endif
  350.  return(RAW_KEY);
  351. }
  352. /***********************************************************************/
  353. #ifdef PROTO
  354. int command_line(char *cmd_line,bool command_only)
  355. #else
  356. int command_line(cmd_line,command_only)
  357. char *cmd_line;
  358. bool command_only;
  359. #endif
  360. /***********************************************************************/
  361. {
  362. /*------------------------- external data -----------------------------*/
  363.  extern char in_macro;
  364.  extern char number_of_files;
  365.  extern int lastrc;
  366. /*--------------------------- local data ------------------------------*/
  367.  bool valid_command=FALSE;
  368.  unsigned short x,y;
  369.  register int i,j;
  370.  int rc,pos;
  371.  long num_lines;
  372.  char *cmd[MAX_COMMANDS+1];
  373.  unsigned short num_commands;
  374.  char command_delim[2];
  375.  char define_test[7];
  376.  char *command_entered;
  377.  char *cl_cmd;
  378.  char *cl_param;
  379. /*--------------------------- processing ------------------------------*/
  380. #ifdef TRACE
  381.  trace_function("commutil.c:command_line");
  382. #endif
  383. /*---------------------------------------------------------------------*/
  384. /* If the command is being issued from a macro and there are no more   */
  385. /* files in the ring, ignore the command and exit.                     */
  386. /*---------------------------------------------------------------------*/
  387.  if (in_macro && number_of_files == 0)
  388.    {
  389. #ifdef TRACE
  390.     trace_return();
  391. #endif
  392.     return(RC_COMMAND_NO_FILES);
  393.    }
  394. /*---------------------------------------------------------------------*/
  395. /* If the command line is blank, just return.                          */
  396. /*---------------------------------------------------------------------*/
  397.  if (strlen(cmd_line) == 0)
  398.    {
  399.     if (!in_profile)
  400.        wmove(CURRENT_WINDOW_COMMAND,0,0);
  401. #ifdef TRACE
  402.     trace_return();
  403. #endif
  404.     return(RC_OK);
  405.    }
  406. /*---------------------------------------------------------------------*/
  407. /* If the command is to be kept displayed on the command line...       */
  408. /*---------------------------------------------------------------------*/
  409.  if (*(cmd_line) == '&')
  410.    {
  411.     cmd_line++;
  412.     clear_command = FALSE;
  413.    }
  414.  else
  415.     if (!(in_macro && !clear_command))
  416.        clear_command = TRUE;
  417. /*---------------------------------------------------------------------*/
  418. /* Get the command to see if it is the DEFINE command. This is done so */
  419. /* that it is possible to assign multiple commands to a key.           */
  420. /*---------------------------------------------------------------------*/
  421.  for (i=0;i<7;i++)
  422.     define_test[i] = '\0';
  423.  pos = min(6,strlen(cmd_line));
  424.  memcpy(define_test,cmd_line,pos);
  425.  for (i=0;i<7;i++)
  426.     if (define_test[i] == ' ')
  427.        define_test[i] = '\0';
  428. /*---------------------------------------------------------------------*/
  429. /* Copy the incoming cmd_line, so we can play with it.                 */
  430. /*---------------------------------------------------------------------*/
  431.  if ((command_entered = strdup(cmd_line)) == NULL)
  432.    {
  433.     display_error(30,(char *)"");
  434. #ifdef TRACE
  435.     trace_return();
  436. #endif
  437.     return(RC_OUT_OF_MEMORY);
  438.    }
  439. /*---------------------------------------------------------------------*/
  440. /* Allocate some space to cl_cmd and cl_param for the a command when   */
  441. /* it is split into a command and its parameters.                      */
  442. /*---------------------------------------------------------------------*/
  443.  if ((cl_cmd = (char *)malloc((strlen(cmd_line)+1)*sizeof(char))) == NULL)
  444.    {
  445.     display_error(30,(char *)"");
  446. #ifdef TRACE
  447.     trace_return();
  448. #endif
  449.     return(RC_OUT_OF_MEMORY);
  450.    }
  451.  if ((cl_param = (char *)malloc((strlen(cmd_line)+1)*sizeof(char))) == NULL)
  452.    {
  453.     display_error(30,(char *)"");
  454. #ifdef TRACE
  455.     trace_return();
  456. #endif
  457.     return(RC_OUT_OF_MEMORY);
  458.    }
  459. /*---------------------------------------------------------------------*/
  460. /* If [SET] LINENd is set to ON, split the line up into a number of    */
  461. /* individual commands.                                                */
  462. /*---------------------------------------------------------------------*/
  463.  if (CURRENT_VIEW->linend_status
  464.  && !equal("define",define_test,3))
  465.    {
  466.     command_delim[0] = CURRENT_VIEW->linend_value;
  467.     command_delim[1] = '\0';
  468.     num_commands = command_split(cmd_line,cmd,MAX_COMMANDS,command_delim,command_entered);
  469.    }
  470.  else
  471.    {
  472.     cmd[0] = command_entered;
  473.     num_commands = 1;
  474.    }
  475. /*---------------------------------------------------------------------*/
  476. /* For each command entered, split it up into command and params, and  */
  477. /* process it...                                                       */
  478. /*---------------------------------------------------------------------*/
  479.  for (j=0;j<num_commands;j++)
  480.    {
  481.     valid_command = FALSE;
  482.     split_command(cmd[j],cl_cmd,cl_param);
  483. /*---------------------------------------------------------------------*/
  484. /* Here is where we could check for synonyms first.                    */
  485. /*---------------------------------------------------------------------*/
  486.     if (!command_only)
  487.        ;       /* get synonym for entered command */
  488. /*---------------------------------------------------------------------*/
  489. /* Look up the command in the command array in command.h               */
  490. /*---------------------------------------------------------------------*/
  491.     for (i=0;command[i].text != NULL;i++)
  492.       {
  493. /*---------------------------------------------------------------------*/
  494. /* If no command text, continue.                                       */
  495. /*---------------------------------------------------------------------*/
  496.        if (strcmp(command[i].text,"") == 0)
  497.          continue;
  498.        rc = RC_OK;
  499. /*---------------------------------------------------------------------*/
  500. /* Check that the supplied command matches the command for the length  */
  501. /* of the command and that the length is at least as long as the       */
  502. /* necessary significance.                                             */
  503. /*---------------------------------------------------------------------*/
  504.        if (equal(command[i].text,cl_cmd,command[i].min_len)
  505.        && command[i].min_len != 0
  506.        && !command[i].sos_command)
  507.          {
  508.           if (in_profile
  509.           && !command[i].valid_profile_command)
  510.             {
  511.              display_error(24,command[i].text);
  512.              lastrc = rc = RC_INVALID_ENVIRON;
  513.              break;
  514.             }
  515.           valid_command = TRUE;
  516. /*---------------------------------------------------------------------*/
  517. /* Here is a big kludge. Because only a few commands need leading      */
  518. /* spaces to be present in temp_params and all other commands barf at  */
  519. /* leading spaces, we need to left truncate temp_params for most       */
  520. /* commands.                                                           */
  521. /*---------------------------------------------------------------------*/
  522.           if (command[i].strip_param)
  523.             {
  524.              pos = strzne(cl_param,' ');
  525.              if (pos == (-1))
  526.                 pos = 0;
  527.             }
  528.           else
  529.              pos = 0;
  530. /*---------------------------------------------------------------------*/
  531. /* Now call the function associated with the supplied command string   */
  532. /* and the possibly stripped parameters.                               */
  533. /*---------------------------------------------------------------------*/
  534.           lastrc = rc = (*command[i].function)(cl_param+pos);
  535.           break;
  536.          }
  537.       }
  538. /*---------------------------------------------------------------------*/
  539. /* If an error occurred while executing a command above, break.        */
  540. /*---------------------------------------------------------------------*/
  541.     if (rc != RC_OK
  542.     &&  rc != RC_TOF_EOF_REACHED)
  543.        break;
  544. /*---------------------------------------------------------------------*/
  545. /* If we found and successfully executed a command above, process the  */
  546. /* next command.                                                       */
  547. /*---------------------------------------------------------------------*/
  548.     if (valid_command)
  549.        continue;
  550. /*---------------------------------------------------------------------*/
  551. /* To get here the command was not a 'command'.                        */
  552. /*---------------------------------------------------------------------*/
  553.     num_lines = valid_target(cl_cmd,get_true_line());
  554. /*---------------------------------------------------------------------*/
  555. /* If TARGET_NOT_FOUND error, then the 'command' was a valid target but*/
  556. /* the target could not be found. continue or break ????????           */
  557. /*---------------------------------------------------------------------*/
  558.     if (num_lines == TARGET_NOT_FOUND)
  559.       {
  560.        display_error(17,(char *)command_entered);
  561.        lastrc = rc = RC_TARGET_NOT_FOUND;
  562.        continue;
  563.       }
  564. /*---------------------------------------------------------------------*/
  565. /* If not TARGET_ERROR, execute Next commnad.                          */
  566. /*---------------------------------------------------------------------*/
  567.     if (num_lines != TARGET_ERROR)
  568.       {
  569.        char n[PREFIX_WIDTH+1];
  570.        sprintf(n,"%-ld",num_lines);
  571.        lastrc = rc = Next(n);
  572.        continue;
  573.       }
  574. /*---------------------------------------------------------------------*/
  575. /* If return is TARGET_ERROR, check if command is OS command...        */
  576. /*---------------------------------------------------------------------*/
  577.     if (cmd[j][0] == '!')
  578.       {
  579.        strcpy(command_entered,cmd[j]);
  580.        lastrc = rc = Os(command_entered+1);
  581.        continue;
  582.       }
  583. /*---------------------------------------------------------------------*/
  584. /* ...or if command is a macro command (as long as IMPMACRO is ON) and */
  585. /* command_only is FALSE...                                            */
  586. /*---------------------------------------------------------------------*/
  587.     if (CURRENT_VIEW->imp_macro
  588.     && !command_only)
  589.       {
  590.        strcpy(command_entered,cmd[j]);
  591.        if (CURRENT_VIEW->imp_os)
  592.          {
  593.           rc = execute_macro(command_entered,FALSE);
  594.           if (rc != RC_FILE_NOT_FOUND)
  595.             {
  596.              lastrc = rc;
  597.              continue;
  598.             }
  599.          }
  600.        else
  601.          {
  602.           rc = execute_macro(command_entered,TRUE);
  603.           if (rc == RC_FILE_NOT_FOUND)
  604.             {
  605.              lastrc = rc = RC_NOT_COMMAND;
  606.              break;
  607.             }
  608.           else
  609.             {
  610.              lastrc = rc;
  611.              continue;
  612.             }
  613.          }
  614.       }
  615. /*---------------------------------------------------------------------*/
  616. /* ...or if command is an OS command (as long as IMPOS is ON).         */
  617. /*---------------------------------------------------------------------*/
  618.     if (CURRENT_VIEW->imp_os)
  619.       {
  620.        strcpy(command_entered,cmd[j]);
  621.        rc = Os(command_entered);
  622.       }
  623.     else
  624.       {
  625.        display_error(21,cmd[j]);
  626.        rc = RC_NOT_COMMAND;
  627.       }
  628. /*---------------------------------------------------------------------*/
  629. /* If the 'command' is not a command then do not process any more.     */
  630. /*---------------------------------------------------------------------*/
  631.     lastrc = rc;
  632.     if (rc == RC_NOT_COMMAND)
  633.        break;
  634.    }
  635.  cleanup_command_line();
  636.  free(command_entered);
  637.  free(cl_cmd);
  638.  free(cl_param);
  639.  
  640. #ifdef TRACE
  641.  trace_return();
  642. #endif
  643.  return(rc);
  644. }
  645. /***********************************************************************/
  646. #ifdef PROTO
  647. void cleanup_command_line(void)
  648. #else
  649. void cleanup_command_line()
  650. #endif
  651. /***********************************************************************/
  652. {
  653. /*-------------------------- external data ----------------------------*/
  654.  extern char *cmd_rec;
  655.  extern unsigned short cmd_rec_len;
  656.  extern char in_macro;
  657. /*--------------------------- local data ------------------------------*/
  658.  register int i;
  659. /*--------------------------- processing ------------------------------*/
  660. #ifdef TRACE
  661.  trace_function("commutil.c:cleanup_command_line");
  662. #endif
  663.  if (in_profile || in_macro || number_of_views == 0)
  664.    {
  665. #ifdef TRACE
  666.     trace_return();
  667. #endif
  668.     return;
  669.    }
  670.  if (clear_command)
  671.    {
  672.     wmove(CURRENT_WINDOW_COMMAND,0,0);
  673.     my_wclrtoeol(CURRENT_WINDOW_COMMAND);
  674.     memset(cmd_rec,' ',COLS);
  675.     cmd_rec_len = 0;
  676.    }
  677.  wmove(CURRENT_WINDOW_COMMAND,0,0);
  678. #ifdef TRACE
  679.  trace_return();
  680. #endif
  681.  return;
  682. }
  683. /***********************************************************************/
  684. #ifdef PROTO
  685. void split_command(char *cmd_line,char *cmd,char *param)
  686. #else
  687. void split_command(cmd_line,cmd,param)
  688. char *cmd_line,*cmd,*param;
  689. #endif
  690. /***********************************************************************/
  691. /*---------------------------------------------------------------------*/
  692. {
  693. /*--------------------------- local data ------------------------------*/
  694.  short pos;
  695.  char *param_ptr;
  696. /*--------------------------- processing ------------------------------*/
  697. #ifdef TRACE
  698.  trace_function("commutil.c:split_command");
  699. #endif
  700.  strcpy(cmd,cmd_line);
  701.  strtrunc(cmd);
  702.  if ((param_ptr = (char *)strpbrk(cmd," \\/-+@")) == NULL)
  703.     {
  704.      strcpy(param,"");
  705. #ifdef TRACE
  706.      trace_return();
  707. #endif
  708.      return;
  709.     }
  710.  pos = strzne(param_ptr,' ');
  711.  if (param_ptr == cmd
  712.  || pos == (-1))
  713.     {
  714.      strcpy(param,"");
  715. #ifdef TRACE
  716.      trace_return();
  717. #endif
  718.      return;
  719.     }
  720.  strcpy(param,param_ptr+(*(param_ptr) == ' ' ? 1 : 0));
  721.  *(param_ptr) = '\0';
  722. #ifdef TRACE
  723.  trace_return();
  724. #endif
  725.  return;
  726. }
  727. /***********************************************************************/
  728. #ifdef PROTO
  729. int param_split(char *params,char *word[],int words,
  730.                 char *delims,char param_type)
  731. #else
  732. int param_split(params,word,words,delims,param_type)
  733. char *params;
  734. char *word[];
  735. int words;
  736. char *delims;
  737. char param_type;
  738. #endif
  739. /***********************************************************************/
  740. {
  741. /*--------------------------- local data ------------------------------*/
  742.  register int i,k;
  743.  unsigned short len;
  744.  char j;
  745.  bool end_of_string,end_of_word;
  746.  char *param_ptr;
  747. /*--------------------------- processing ------------------------------*/
  748. #ifdef TRACE
  749.  trace_function("commutil.c:param_split");
  750. #endif
  751. /*---------------------------------------------------------------------*/
  752. /* Allocate some memory to the temporary area.                         */
  753. /*---------------------------------------------------------------------*/
  754.  if (params != (char *)NULL)
  755.    {
  756.     if (allocate_temp_space(strlen(params),param_type) != RC_OK)
  757.       {
  758. #ifdef TRACE
  759.       trace_return();
  760. #endif
  761.       return(-1);
  762.       }
  763.    }
  764. /*---------------------------------------------------------------------*/
  765. /* Based on param_type, point param_ptr to appropriate buffer.         */
  766. /*---------------------------------------------------------------------*/
  767.  switch(param_type)
  768.    {
  769.     case TEMP_PARAM:
  770.          param_ptr = temp_params;
  771.          break;
  772.     case TEMP_MACRO:
  773.          param_ptr = temp_macros;
  774.          break;
  775.     case TEMP_TEMP_CMD:
  776.          param_ptr = temp_cmd;
  777.          break;
  778.     default:
  779.          return(-1);
  780.          break;
  781.    }
  782. /*---------------------------------------------------------------------*/
  783. /* In case params is NULL, copy an empty string into param_ptr...      */
  784. /*---------------------------------------------------------------------*/
  785.  if (params == (char *)NULL)
  786.     strcpy(param_ptr,"");
  787.  else
  788.     strcpy(param_ptr,params);
  789.  
  790.  for (i=0;i<words;i++)
  791.      word[i] = (char *)"";
  792.  j = 0;
  793.  end_of_string = YES;
  794.  len = strlen(param_ptr);
  795.  for (i=0;i<len && j<words;i++)
  796.    {
  797.     end_of_word = FALSE;
  798.     for (k=0;k<strlen(delims);k++)
  799.       {
  800.        if (*(param_ptr+i) == *(delims+k))
  801.           end_of_word = TRUE;
  802.       }
  803.     if (end_of_word)
  804.       {
  805.        *(param_ptr+i) = '\0';
  806.        end_of_string = YES;
  807.       }
  808.     else
  809.        if (end_of_string == YES)
  810.          {
  811.           word[j++] = param_ptr+i;
  812.           end_of_string = NO;
  813.          }
  814.    }
  815. #ifdef TRACE
  816.  trace_return();
  817. #endif
  818.  return(j);
  819. }
  820. /***********************************************************************/
  821. #ifdef PROTO
  822. int command_split(char *params,char *word[],int words,
  823.                 char *delims,char *buffer)
  824. #else
  825. int command_split(params,word,words,delims,buffer)
  826. char *params;
  827. char *word[];
  828. int words;
  829. char *delims;
  830. char *buffer;
  831. #endif
  832. /***********************************************************************/
  833. {
  834. /*--------------------------- local data ------------------------------*/
  835.  register int i,k;
  836.  unsigned short len;
  837.  char j;
  838.  bool end_of_string,end_of_word;
  839. /*--------------------------- processing ------------------------------*/
  840. #ifdef TRACE
  841.  trace_function("commutil.c:command_split");
  842. #endif
  843. /*---------------------------------------------------------------------*/
  844. /* In case params is NULL, copy an empty string into buffer...         */
  845. /*---------------------------------------------------------------------*/
  846.  if (params == (char *)NULL)
  847.     strcpy(buffer,"");
  848.  else
  849.     strcpy(buffer,params);
  850.  
  851.  for (i=0;i<words;i++)
  852.      word[i] = (char *)"";
  853.  j = 0;
  854.  end_of_string = YES;
  855.  len = strlen(buffer);
  856.  for (i=0;i<len && j<words;i++)
  857.    {
  858.     end_of_word = FALSE;
  859.     for (k=0;k<strlen(delims);k++)
  860.       {
  861.        if (*(buffer+i) == *(delims+k))
  862.           end_of_word = TRUE;
  863.       }
  864.     if (end_of_word)
  865.       {
  866.        *(buffer+i) = '\0';
  867.        end_of_string = YES;
  868.       }
  869.     else
  870.        if (end_of_string == YES)
  871.          {
  872.           word[j++] = buffer+i;
  873.           end_of_string = NO;
  874.          }
  875.    }
  876. #ifdef TRACE
  877.  trace_return();
  878. #endif
  879.  return(j);
  880. }
  881. /***********************************************************************/
  882. #ifdef PROTO
  883. long valid_target(char *target,long true_line)
  884. #else
  885. long valid_target(target,true_line)
  886. char *target;
  887. long true_line;
  888. #endif
  889. /***********************************************************************/
  890. /*---------------------------------------------------------------------*/
  891. /* This returns TARGET_ERROR if the target value is invalid. Otherwise */
  892. /* it returns the number of lines to the target from the 'true_line'.  */
  893. /*---------------------------------------------------------------------*/
  894. {
  895. /*--------------------------- local data ------------------------------*/
  896.  long num_target;
  897.  register int i;
  898.  LINE *curr;
  899. /*--------------------------- processing ------------------------------*/
  900. #ifdef TRACE
  901.  trace_function("commutil.c:valid_target");
  902. #endif
  903. /*---------------------------------------------------------------------*/
  904. /* Check for 'ALL'.   This means from first line to last line.         */
  905. /*---------------------------------------------------------------------*/
  906.  if (equal((char *)"all",target,3))
  907.    {
  908. #ifdef TRACE
  909.     trace_return();
  910. #endif
  911.     return(CURRENT_FILE->number_lines);
  912.    }
  913. /*---------------------------------------------------------------------*/
  914. /* Check for 'BLOCK'. This just returns 0 so that BLOCK is valid.      */
  915. /*---------------------------------------------------------------------*/
  916.  if (equal((char *)"block",target,5))
  917.    {
  918. #ifdef TRACE
  919.     trace_return();
  920. #endif
  921.     return(0);
  922.    }
  923. /*---------------------------------------------------------------------*/
  924. /* Check for named line; target beginning with '.' and 2nd char is     */
  925. /* alphabetic.                                                         */
  926. /*---------------------------------------------------------------------*/
  927.  if (*(target) == '.' && isalpha(*(target+1)))
  928.    {
  929.     if ((curr = find_named_line(target,&num_target)) == (LINE *)NULL)
  930.       {
  931. #ifdef TRACE
  932.        trace_return();
  933. #endif
  934.        return(TARGET_NOT_FOUND);
  935.       }
  936.     if (num_target >= true_line)
  937.        num_target = min((num_target - true_line),
  938.                      (CURRENT_FILE->number_lines - true_line+1));
  939.     else
  940.        num_target = (true_line - num_target)*(-1);
  941. #ifdef TRACE
  942.     trace_return();
  943. #endif
  944.     return(num_target);
  945.    }
  946. /*---------------------------------------------------------------------*/
  947. /* Check for '*'.     This means to the end of file.                   */
  948. /*---------------------------------------------------------------------*/
  949.  if (*(target) == '*')
  950.    {
  951. #ifdef TRACE
  952.     trace_return();
  953. #endif
  954.     return(CURRENT_FILE->number_lines - true_line+1);
  955.    }
  956. /*---------------------------------------------------------------------*/
  957. /* Check for '-*'.    This means to the top of file.                   */
  958. /*---------------------------------------------------------------------*/
  959.  if (strncmp(target,"-*",2) == 0)
  960.    {
  961. #ifdef TRACE
  962.     trace_return();
  963. #endif
  964.     return(true_line*(-1));
  965.    }
  966. /*---------------------------------------------------------------------*/
  967. /* Check for search targets. These are delimited by one of '/\@' and   */
  968. /* may be positive or negative.                                        */
  969. /*---------------------------------------------------------------------*/
  970.  for (i=0;i<NUMBER_SEARCH_TARGETS;i++)
  971.     if (strncmp(target,st[i].prefix,st[i].length) == 0)
  972.       {
  973. /*---------------------------------------------------------------------*/
  974. /* Save valid target for later retrieval.                              */
  975. /*---------------------------------------------------------------------*/
  976.         if (strcmp(target+st[i].length,"") != 0)
  977.            strcpy(last_target,target);
  978.         num_target = search_target((target+st[i].length),st[i].delim,
  979.                              true_line,st[i].direction);
  980. #ifdef TRACE
  981.         trace_return();
  982. #endif
  983.         return(num_target);
  984.       }
  985. /*---------------------------------------------------------------------*/
  986. /* Check for ':' or ';' - absolute line number target.                 */
  987. /*---------------------------------------------------------------------*/
  988.  if (*(target) == ':'
  989.  ||  *(target) == ';')
  990.    {
  991.     target++;
  992.     if (!valid_integer(target))
  993.       {
  994. #ifdef TRACE
  995.        trace_return();
  996. #endif
  997.        return(TARGET_ERROR);
  998.       }
  999.     num_target = atol(target);
  1000.     if (num_target < 0L)              /* invalid if negative */
  1001.       {
  1002. #ifdef TRACE
  1003.        trace_return();
  1004. #endif
  1005.        return(TARGET_ERROR);
  1006.       }
  1007.     if (num_target >= true_line)
  1008.        num_target = min((num_target - true_line),
  1009.                      (CURRENT_FILE->number_lines - true_line+1));
  1010.     else
  1011.        num_target = (true_line - num_target)*(-1);
  1012. #ifdef TRACE
  1013.     trace_return();
  1014. #endif
  1015.     return(num_target);
  1016.    }
  1017. /*---------------------------------------------------------------------*/
  1018. /* Lastly, check for valid integers, +ve or -ve.                       */
  1019. /*---------------------------------------------------------------------*/
  1020.  if (!valid_integer(target))
  1021.    {
  1022. #ifdef TRACE
  1023.     trace_return();
  1024. #endif
  1025.     return(TARGET_ERROR);
  1026.    }
  1027.  num_target = atol(target);
  1028.  if (num_target >= 0)
  1029.     num_target = min(num_target,(CURRENT_FILE->number_lines - true_line+1));
  1030.  else
  1031.     num_target = max((num_target),(true_line == 0) ? (0) : (int)(true_line*(-1)));
  1032. #ifdef TRACE
  1033.  trace_return();
  1034. #endif
  1035.  return(num_target);
  1036. }
  1037. /***********************************************************************/
  1038. #ifdef PROTO
  1039. long get_true_line(void)
  1040. #else
  1041. long get_true_line()
  1042. #endif
  1043. /***********************************************************************/
  1044. {
  1045. /*-------------------------- external data ----------------------------*/
  1046. /*--------------------------- local data ------------------------------*/
  1047.  long true_line;
  1048. /*--------------------------- processing ------------------------------*/
  1049. #ifdef TRACE
  1050.  trace_function("commutil.c:get_true_line");
  1051. #endif
  1052. /*---------------------------------------------------------------------*/
  1053. /* Determine 'true_line'.                                              */
  1054. /*---------------------------------------------------------------------*/
  1055.  if (in_profile)
  1056.     true_line = CURRENT_VIEW->current_line;
  1057.  else
  1058.     if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
  1059.        true_line = CURRENT_VIEW->current_line;
  1060.     else
  1061.        true_line = CURRENT_VIEW->focus_line;
  1062. #ifdef TRACE
  1063.  trace_return();
  1064. #endif
  1065.  return(true_line);
  1066. }
  1067. /***********************************************************************/
  1068. #ifdef PROTO
  1069. LINE *find_named_line(char *name,long *retline)
  1070. #else
  1071. LINE *find_named_line(name,retline)
  1072. char *name;
  1073. long *retline;
  1074. #endif
  1075. /***********************************************************************/
  1076. {
  1077. /*--------------------------- local data ------------------------------*/
  1078.  long lineno=0;
  1079.  LINE *curr;
  1080. /*--------------------------- processing ------------------------------*/
  1081. #ifdef TRACE
  1082.  trace_function("commutil.c:find_named_line");
  1083. #endif
  1084. /*---------------------------------------------------------------------*/
  1085. /* Find the line number in the current file of the named line specified*/
  1086. /*---------------------------------------------------------------------*/
  1087.  curr = CURRENT_FILE->first_line;
  1088.  while(curr->next != (LINE *)NULL)
  1089.    {
  1090.     if (curr->name != (char *)NULL)
  1091.        if (strcmp(curr->name,name) == 0)
  1092.          {
  1093. #ifdef TRACE
  1094.           trace_return();
  1095. #endif
  1096.           *retline = lineno;
  1097.           return(curr);
  1098.          }
  1099.     lineno++;
  1100.     curr = curr->next;
  1101.    }
  1102. #ifdef TRACE
  1103.  trace_return();
  1104. #endif
  1105.  return((LINE *)NULL);
  1106. }
  1107. /***********************************************************************/
  1108. #ifdef PROTO
  1109. long search_target(char *target,char delim,
  1110.                    long true_line,int direction)
  1111. #else
  1112. long search_target(target,delim,true_line,direction)
  1113. char *target;
  1114. char delim;
  1115. long true_line;
  1116. int direction;
  1117. #endif
  1118. /***********************************************************************/
  1119. {
  1120. /*--------------------------- local data ------------------------------*/
  1121.  short start_col=0;
  1122.  long rc;
  1123.  int len_target;
  1124. /*--------------------------- processing ------------------------------*/
  1125. #ifdef TRACE
  1126.  trace_function("commutil.c:search_target");
  1127. #endif
  1128.  if (*(target+strlen(target)-1) == delim)
  1129.     *(target+strlen(target)-1) = '\0';
  1130.  if (CURRENT_VIEW->hex == ON)
  1131.    {
  1132.     if ((len_target = convert_hex_strings(target)) == (-1))
  1133.       {
  1134.        display_error(32,(char *)"");
  1135. #ifdef TRACE
  1136.        trace_return();
  1137. #endif
  1138.        return(RC_INVALID_OPERAND);
  1139.       }
  1140.    }
  1141.  else
  1142.    len_target = strlen(target);
  1143.  rc = find_string(true_line,&start_col,target,len_target,
  1144.         direction,direction,CURRENT_VIEW->case_locate);
  1145. #ifdef TRACE
  1146.  trace_return();
  1147. #endif
  1148.  return(rc);
  1149. }
  1150. /***********************************************************************/
  1151. #ifdef PROTO
  1152. int get_row_for_focus_line(int cr,long fl,long cl)
  1153. #else
  1154. int get_row_for_focus_line(cr,fl,cl)
  1155. int cr;
  1156. long fl,cl;
  1157. #endif
  1158. /***********************************************************************/
  1159. /*---------------------------------------------------------------------*/
  1160. /* Returns the row within the main window where the focus line is      */
  1161. /* placed. If the focus line is off the screen, or out of bounds of the*/
  1162. /* current size of the file; <0 or >number_lines, this returns the     */
  1163. /* current row.                                                        */
  1164. /*---------------------------------------------------------------------*/
  1165. {
  1166. /*--------------------------- local data ------------------------------*/
  1167.  register int row;
  1168. /*--------------------------- processing ------------------------------*/
  1169. #ifdef TRACE
  1170.  trace_function("commutil.c:get_row_for_focus_line");
  1171. #endif
  1172.  row = (cr + (int)(fl - cl));
  1173.  if (fl <= row)
  1174.    {
  1175. #ifdef TRACE
  1176.     trace_return();
  1177. #endif
  1178.     return(row);
  1179.    }
  1180.  if (row < 0 || row > min(CURRENT_SCREEN.rows - 1,CURRENT_FILE->number_lines+1))
  1181.    {
  1182. #ifdef TRACE
  1183.     trace_return();
  1184. #endif
  1185.     return(cr);
  1186.    }
  1187. #ifdef TRACE
  1188.  trace_return();
  1189. #endif
  1190.  return(row);
  1191. }
  1192. /***********************************************************************/
  1193. #ifdef PROTO
  1194. int calculate_focus_line(int cr,long fl,long cl)
  1195. #else
  1196. int calculate_focus_line(cr,fl,cl)
  1197. int cr;
  1198. long fl,cl;
  1199. #endif
  1200. /***********************************************************************/
  1201. /*---------------------------------------------------------------------*/
  1202. /* Returns the new focus line. If the focus line is still in the       */
  1203. /* window, it stays as is. If not,the focus   line becomes the current */
  1204. /* line.                                                               */
  1205. /*---------------------------------------------------------------------*/
  1206. {
  1207. /*--------------------------- local data ------------------------------*/
  1208.  register int max_top,max_bot;
  1209. /*--------------------------- processing ------------------------------*/
  1210. #ifdef TRACE
  1211.  trace_function("commutil.c:calculate_focus_line");
  1212. #endif
  1213.  max_top = max(0,cl-CURRENT_VIEW->current_row);
  1214.  max_bot = min(CURRENT_FILE->number_lines+1,
  1215.                cl+(CURRENT_SCREEN.rows - CURRENT_VIEW->current_row)-1);
  1216.  if (fl >= max_top && fl <= max_bot)
  1217.    {
  1218. #ifdef TRACE
  1219.     trace_return();
  1220. #endif
  1221.     return(fl);
  1222.    }
  1223. #ifdef TRACE
  1224.  trace_return();
  1225. #endif
  1226.  return(cl);
  1227. }
  1228. /***********************************************************************/
  1229. #ifdef PROTO
  1230. void print_line(char close_spooler,long num_lines,short pagesize,
  1231.                 char *text,char *line_term,bool all)
  1232. #else
  1233. void print_line(close_spooler,num_lines,pagesize,text,line_term,all)
  1234. char close_spooler;
  1235. long num_lines;
  1236. short pagesize;
  1237. char *text;
  1238. char *line_term;
  1239. bool all;
  1240. #endif
  1241. /***********************************************************************/
  1242. {
  1243. /*------------------------- external data -----------------------------*/
  1244. #if defined(UNIX) || defined(OS2)
  1245.  extern char *spooler_name;
  1246. #endif
  1247. /*--------------------------- local data ------------------------------*/
  1248. #if defined(UNIX) || defined(OS2)
  1249.  static char spooler_open=NO;
  1250. #ifdef OS2
  1251.  HFILE Lpt;
  1252. #ifdef __32BIT__
  1253.  ULONG Action;
  1254.  ULONG NoWritten;
  1255. #else
  1256.  USHORT Action;
  1257.  USHORT NoWritten;
  1258. #endif
  1259. #endif
  1260. #endif
  1261.  static FILE *pp;
  1262.  register int i;
  1263.  long j,true_line;
  1264.  LINE *curr;
  1265.  char c;
  1266.  unsigned short line_number=0;
  1267. /*--------------------------- processing ------------------------------*/
  1268. #ifdef TRACE
  1269.  trace_function("commutil.c:print_line");
  1270. #endif
  1271. #if defined(DOS)
  1272.  pp = stdprn;
  1273. #endif
  1274. #if defined(UNIX) || defined(OS2)
  1275.  if (close_spooler == YES)
  1276.    {
  1277.     if (spooler_open == YES)
  1278.       {
  1279.        spooler_open = NO;
  1280. #if defined(OS2)
  1281.        DosClose(Lpt);
  1282. #else
  1283.        pclose(pp);
  1284. #endif
  1285.       }
  1286. #ifdef TRACE
  1287.     trace_return();
  1288. #endif
  1289.     return;
  1290.    }
  1291. #endif
  1292. #if defined(UNIX)
  1293.  if (spooler_open == NO)
  1294.    {
  1295.     pp = popen(spooler_name,"w");
  1296.     spooler_open = YES;
  1297.    }
  1298. #endif
  1299. #if defined(OS2)
  1300.  if (spooler_open == NO)
  1301.    {
  1302. #ifdef __32BIT__
  1303.    if (DosOpen(spooler_name, &Lpt, &Action, 0,FILE_NORMAL,FILE_OPEN,
  1304.                OPEN_ACCESS_READWRITE|OPEN_SHARE_DENYNONE,(PEAOP2)NULL) != 0)
  1305. #else
  1306.    if (DosOpen(spooler_name, &Lpt, &Action, 0,FILE_NORMAL,FILE_OPEN,
  1307.                OPEN_ACCESS_WRITEONLY|OPEN_SHARE_DENYWRITE,NULL) != 0)
  1308. #endif
  1309.      {
  1310. #ifdef TRACE
  1311.       trace_return();
  1312. #endif
  1313.       return;
  1314.      }
  1315.     spooler_open = YES;
  1316.    }
  1317. #endif
  1318.  
  1319.  if (num_lines == 0L)
  1320.    {
  1321. #if defined(OS2)
  1322.     DosWrite(Lpt,text,strlen(text),&NoWritten);
  1323. #else
  1324.     fprintf(pp,"%s%s",text,line_term);
  1325. #endif
  1326. #ifdef TRACE
  1327.     trace_return();
  1328. #endif
  1329.     return;
  1330.    }
  1331. /*---------------------------------------------------------------------*/
  1332. /* Determine where to start writing from in the linked list.           */
  1333. /* If target is ALL, start with first line...                          */
  1334. /* If on command line or in profile, use current_line...               */
  1335. /* Else, use focus line.                                               */
  1336. /*---------------------------------------------------------------------*/
  1337.  if (all)
  1338.     true_line = 1;
  1339.  else
  1340.     true_line = get_true_line();
  1341. #ifdef USE_VOID
  1342.  curr = (LINE *)ll_find((void *)CURRENT_FILE->first_line,true_line);
  1343. #else
  1344.  curr = lll_find(CURRENT_FILE->first_line,true_line);
  1345. #endif
  1346. /*---------------------------------------------------------------------*/
  1347. /* Now write out the contents of the file array to the printer.        */
  1348. /*---------------------------------------------------------------------*/
  1349.  for (j=0L;j<num_lines && curr->next != NULL;j++)
  1350.    {
  1351.     if (curr->prev != NULL)  /* not first line */
  1352.       {
  1353. #if defined(OS2)
  1354.        DosWrite(Lpt,curr->line,curr->length,&NoWritten);
  1355.        DosWrite(Lpt,line_term,strlen(line_term),&NoWritten);
  1356. #else
  1357.        for (i=0;i<curr->length;i++)
  1358.            fputc(*(curr->line+i) & A_CHARTEXT,pp);
  1359.        fprintf(pp,"%s",line_term);
  1360. #endif
  1361.        line_number++;
  1362.        if (line_number == pagesize
  1363.        && pagesize != 0)
  1364.          {
  1365. #if defined(OS2)
  1366.           DosWrite(Lpt,"\f",1,&NoWritten);
  1367. #else
  1368.           fputc('\f',pp);
  1369. #endif
  1370.           line_number = 0;
  1371.          }
  1372.       }
  1373.     curr = curr->next;
  1374.    }
  1375. #ifdef TRACE
  1376.  trace_return();
  1377. #endif
  1378.  return;
  1379. }
  1380. /***********************************************************************/
  1381. #ifdef PROTO
  1382. char next_char(LINE *curr,short *off,int end_col)
  1383. #else
  1384. char next_char(curr,off,end_col)
  1385. LINE *curr;
  1386. short *off;
  1387. int end_col;
  1388. #endif
  1389. /***********************************************************************/
  1390. {
  1391. /*--------------------------- local data ------------------------------*/
  1392. /*--------------------------- processing ------------------------------*/
  1393. #ifdef TRACE
  1394.  trace_function("commutil.c:next_char");
  1395. #endif
  1396.  if (*(off) < min(curr->length,end_col))
  1397.    {
  1398.     (*(off))++;
  1399. #ifdef TRACE
  1400.     trace_return();
  1401. #endif
  1402.     return(*(curr->line+((*(off))-1)));
  1403.    }
  1404.  *(off) = (-1);
  1405. #ifdef TRACE
  1406.  trace_return();
  1407. #endif
  1408.  return(0);
  1409. }
  1410. /***********************************************************************/
  1411. #ifdef PROTO
  1412. int add_define(int key_value,char *commands)
  1413. #else
  1414. int add_define(key_value,commands)
  1415. int key_value;
  1416. char *commands;
  1417. #endif
  1418. /***********************************************************************/
  1419. /* Parameters:                                                         */
  1420. /*  key_value: numeric representation of function key                  */
  1421. /*   commands: commands and parameters                                 */
  1422. /***********************************************************************/
  1423. {
  1424. /*--------------------------- local data ------------------------------*/
  1425.  register int j;
  1426.  short cmd_nr;
  1427.  char *word[MAX_COMMANDS+1];
  1428.  unsigned short num_commands;
  1429.  char command_delim[2];
  1430.  int rc;
  1431.  char *command_entered,*cl_cmd,*cl_param;
  1432. /*--------------------------- processing ------------------------------*/
  1433. #ifdef TRACE
  1434.  trace_function("commutil.c:add_define");
  1435. #endif
  1436. /*---------------------------------------------------------------------*/
  1437. /* First thing is to delete any definitions that may exist for the     */
  1438. /* supplied key_value;                                                 */
  1439. /*---------------------------------------------------------------------*/
  1440.  remove_define(key_value);
  1441. /*---------------------------------------------------------------------*/
  1442. /* If the commands argument is empty, then we have already deleted any */
  1443. /* definitions for the key, so just return.                            */
  1444. /*---------------------------------------------------------------------*/
  1445.  if (strcmp(commands,"") == 0)
  1446.    {
  1447. #ifdef TRACE
  1448.     trace_return();
  1449. #endif
  1450.     return(RC_OK);
  1451.    }
  1452. /*---------------------------------------------------------------------*/
  1453. /* Copy the incoming commands, so we can play with it.                 */
  1454. /*---------------------------------------------------------------------*/
  1455.  if ((command_entered = strdup(commands)) == NULL)
  1456.    {
  1457.     display_error(30,(char *)"");
  1458. #ifdef TRACE
  1459.     trace_return();
  1460. #endif
  1461.     return(RC_OUT_OF_MEMORY);
  1462.    }
  1463. /*---------------------------------------------------------------------*/
  1464. /* Allocate some space to cl_cmd and cl_param for the a command when   */
  1465. /* it is split into a command and its parameters.                      */
  1466. /*---------------------------------------------------------------------*/
  1467.  if ((cl_cmd = (char *)malloc((strlen(commands)+1)*sizeof(char))) == NULL)
  1468.    {
  1469.     display_error(30,(char *)"");
  1470. #ifdef TRACE
  1471.     trace_return();
  1472. #endif
  1473.     return(RC_OUT_OF_MEMORY);
  1474.    }
  1475.  if ((cl_param = (char *)malloc((strlen(commands)+1)*sizeof(char))) == NULL)
  1476.    {
  1477.     display_error(30,(char *)"");
  1478. #ifdef TRACE
  1479.     trace_return();
  1480. #endif
  1481.     return(RC_OUT_OF_MEMORY);
  1482.    }
  1483. /*---------------------------------------------------------------------*/
  1484. /* If [SET] LINENd is set to ON, split the args up into a number of    */
  1485. /* individual commands.                                                */
  1486. /*---------------------------------------------------------------------*/
  1487.  if (CURRENT_VIEW->linend_status)
  1488.    {
  1489.     command_delim[0] = CURRENT_VIEW->linend_value;
  1490.     command_delim[1] = '\0';
  1491.     num_commands = command_split(commands,word,MAX_COMMANDS,command_delim,command_entered);
  1492.    }
  1493.  else
  1494.    {
  1495.     word[0] = command_entered;
  1496.     num_commands = 1;
  1497.    }
  1498. /*---------------------------------------------------------------------*/
  1499. /* For each command entered, split it up into command and params, and  */
  1500. /* process it...                                                       */
  1501. /*---------------------------------------------------------------------*/
  1502.  for (j=0;j<num_commands;j++)
  1503.    {
  1504.     split_command(word[j],cl_cmd,cl_param);
  1505.     if ((cmd_nr = find_command(cl_cmd)) == (-1))
  1506.       {
  1507.        display_error(21,cl_cmd);
  1508.        rc = RC_INVALID_OPERAND;
  1509.        break;
  1510.       }
  1511.     if ((rc = append_define(key_value,cmd_nr,cl_param)) != RC_OK)
  1512.        break;
  1513.    }
  1514.  free(command_entered);
  1515.  free(cl_cmd);
  1516.  free(cl_param);
  1517. #ifdef TRACE
  1518.  trace_return();
  1519. #endif
  1520.  return(rc);
  1521. }
  1522. /***********************************************************************/
  1523. #ifdef PROTO
  1524. int remove_define(int key_value)
  1525. #else
  1526. int remove_define(key_value)
  1527. int key_value;
  1528. #endif
  1529. /***********************************************************************/
  1530. /* Parameters:                                                         */
  1531. /*  key_value: numeric representation of function key                  */
  1532. /***********************************************************************/
  1533. {
  1534. /*--------------------------- local data ------------------------------*/
  1535.  DEFINE *curr;
  1536. /*--------------------------- processing ------------------------------*/
  1537. #ifdef TRACE
  1538.  trace_function("commutil.c:remove_define");
  1539. #endif
  1540. /*---------------------------------------------------------------------*/
  1541. /* Find all items in the linked list for the key_value and remove them */
  1542. /* from the list.                                                      */
  1543. /*---------------------------------------------------------------------*/
  1544.  curr = first_define;
  1545.  while(curr != NULL)
  1546.    {
  1547.     if (curr->def_funkey == key_value)
  1548.       {
  1549.        if (curr->def_params != NULL)
  1550.           free(curr->def_params);
  1551. #ifdef USE_VOID
  1552.        curr = (DEFINE *)ll_del((void *)first_define,(void *)curr,DIRECTION_FORWARD);
  1553. #else
  1554.        curr = dll_del(&first_define,&last_define,curr,DIRECTION_FORWARD);
  1555. #endif
  1556.       }
  1557.     else
  1558.        curr = curr->next;
  1559.    }
  1560. #ifdef TRACE
  1561.  trace_return();
  1562. #endif
  1563.  return(RC_OK);
  1564. }
  1565. /***********************************************************************/
  1566. #ifdef PROTO
  1567. int append_define(int key_value,int cmd,char *prm)
  1568. #else
  1569. int append_define(key_value,cmd,prm)
  1570. int key_value,cmd;
  1571. char *prm;
  1572. #endif
  1573. /***********************************************************************/
  1574. /* Parameters:                                                         */
  1575. /*  key_value: numeric representation of function key                  */
  1576. /***********************************************************************/
  1577. {
  1578. /*--------------------------- local data ------------------------------*/
  1579.  DEFINE *curr,*next;
  1580. /*--------------------------- processing ------------------------------*/
  1581. #ifdef TRACE
  1582.  trace_function("commutil.c:append_define");
  1583. #endif
  1584. /*---------------------------------------------------------------------*/
  1585. /* Find all items in the linked list for the key_value and remove them */
  1586. /* from the list.                                                      */
  1587. /*---------------------------------------------------------------------*/
  1588. #ifdef USE_VOID
  1589.  curr = (DEFINE *)ll_add((void *)first_define,(void *)last_define,sizeof(DEFINE));
  1590. #else
  1591.  curr = dll_add(first_define,last_define,sizeof(DEFINE));
  1592. #endif
  1593.  if (curr == NULL)
  1594.    {
  1595.     display_error(30,(char *)"");
  1596. #ifdef TRACE
  1597.     trace_return();
  1598. #endif
  1599.     return(RC_OUT_OF_MEMORY);
  1600.    }
  1601.  curr->def_params = (char *)malloc((strlen(prm)+1)*sizeof(char));
  1602.  if (curr->def_params == NULL)
  1603.    {
  1604.     display_error(30,(char *)"");
  1605. #ifdef TRACE
  1606.     trace_return();
  1607. #endif
  1608.     return(RC_OUT_OF_MEMORY);
  1609.    }
  1610.  strcpy(curr->def_params,prm);
  1611.  curr->def_funkey = key_value;
  1612.  curr->def_command = cmd;
  1613.  curr->def_delim = CURRENT_VIEW->linend_value;
  1614.  last_define = curr;
  1615.  if (first_define == NULL)
  1616.     first_define = last_define;
  1617. #ifdef TRACE
  1618.  trace_return();
  1619. #endif
  1620.  return(RC_OK);
  1621. }
  1622. /***********************************************************************/
  1623. #ifdef PROTO
  1624. int find_key_value(char *mnemonic)
  1625. #else
  1626. int find_key_value(mnemonic)
  1627. char *mnemonic;
  1628. #endif
  1629. /***********************************************************************/
  1630. /*   Function: find the matching key value for the supplied key name   */
  1631. /* Parameters:                                                         */
  1632. /*   mnemonic: the key name to be matched                              */
  1633. /***********************************************************************/
  1634. {
  1635. /*--------------------------- local data ------------------------------*/
  1636.  register short i;
  1637. /*--------------------------- processing ------------------------------*/
  1638. #ifdef TRACE
  1639.  trace_function("commutil.c:find_key_value");
  1640. #endif
  1641.  for (i=0;i<MAX_NUMBER_KEYS;i++)
  1642.     if (strcmp(mnemonic,key_table[i].mnemonic) == 0)
  1643.       {
  1644. #ifdef TRACE
  1645.        trace_return();
  1646. #endif
  1647.        return(key_table[i].key_value);
  1648.       }
  1649. #ifdef TRACE
  1650.  trace_return();
  1651. #endif
  1652.  return(-1);
  1653. }
  1654. /***********************************************************************/
  1655. #ifdef PROTO
  1656. short find_command(char *cmd)
  1657. #else
  1658. short find_command(cmd)
  1659. char *cmd;
  1660. #endif
  1661. /***********************************************************************/
  1662. /*   Function: determine if the string supplied is a valid abbrev for  */
  1663. /*             a command.                                              */
  1664. /* Parameters:                                                         */
  1665. /*        cmd: the string to be matched                                */
  1666. /*        prm: any parameters (only used if target supplied)           */
  1667. /***********************************************************************/
  1668. {
  1669. /*--------------------------- local data ------------------------------*/
  1670.  register short i;
  1671.  long num_lines;
  1672. /*--------------------------- processing ------------------------------*/
  1673. #ifdef TRACE
  1674.  trace_function("commutil.c:find_command");
  1675. #endif
  1676.  for (i=0;command[i].text != NULL;i++)
  1677.     if (equal(command[i].text,cmd,(command[i].min_len == 0) ? strlen(command[i].text) : command[i].min_len)
  1678.     &&  !command[i].sos_command)
  1679.       {
  1680. #ifdef TRACE
  1681.        trace_return();
  1682. #endif
  1683.        return(i);
  1684.       }
  1685. /*---------------------------------------------------------------------*/
  1686. /* To get here the command was not a 'command'.                        */
  1687. /*---------------------------------------------------------------------*/
  1688.  num_lines = valid_target(cmd,get_true_line());
  1689. /*---------------------------------------------------------------------*/
  1690. /* If not TARGET_ERROR, find 'LOCATE' command and set temp_params to   */
  1691. /* cmd.                                                                */
  1692. /*---------------------------------------------------------------------*/
  1693.  if (num_lines != TARGET_ERROR)
  1694.    {
  1695.     strcpy(temp_params,cmd);
  1696.     for (i=0;command[i].text != NULL;i++)
  1697.       {
  1698.        if (strcmp(command[i].text,"locate") == 0)
  1699.           break;
  1700.       }
  1701. #ifdef TRACE
  1702.     trace_return();
  1703. #endif
  1704.     return(i);
  1705.    }
  1706. #ifdef TRACE
  1707.  trace_return();
  1708. #endif
  1709.   return(-1);
  1710. }
  1711. /***********************************************************************/
  1712. #ifdef PROTO
  1713. short split_change_params(char *cmd_line,char *old_str,char *new_str,char *target,
  1714.                           char *num,char *occ)
  1715. #else
  1716. short split_change_params(cmd_line,old_str,new_str,target,num,occ)
  1717. char *cmd_line,*old_str,*new_str,*target,*num,*occ;
  1718. #endif
  1719. /***********************************************************************/
  1720. {
  1721.  register short i;
  1722.  short off1,off2,off3,eos_old,eos_new,target_start;
  1723.  char cmmand_line[80],str3[20];
  1724.  
  1725.  char *cmd=cmmand_line;
  1726.  
  1727. #define SPLT_PARAMS  3
  1728.  char *word[SPLT_PARAMS];
  1729.  char parm[SPLT_PARAMS];
  1730.  unsigned short num_params;
  1731.  unsigned short x,y;
  1732.  short rc;
  1733. /*--------------------------- processing ------------------------------*/
  1734. #ifdef TRACE
  1735.  trace_function("commutil.c:split_change_params");
  1736. #endif
  1737.  
  1738.  strcpy(cmd,cmd_line);
  1739.  for (i=0;i<NUMBER_SEARCH_TARGETS;i++)
  1740.     if (*(cmd) == st[i].delim)
  1741.       break;
  1742.  if (i == NUMBER_SEARCH_TARGETS)
  1743.    {
  1744. #ifdef TRACE
  1745.     trace_return();
  1746. #endif
  1747.     return(-1);
  1748.    }
  1749. /*---------------------------------------------------------------------*/
  1750. /* Obtain the old string to change.                                    */
  1751. /*---------------------------------------------------------------------*/
  1752.  if ((off1 = strzeq(cmd+1,st[i].delim)) == (-1))
  1753.    {
  1754. #ifdef TRACE
  1755.     trace_return();
  1756. #endif
  1757.     return(-1);
  1758.    }
  1759.  eos_old = off1+1;
  1760.  *(cmd+eos_old) = '\0';
  1761.  strcpy(old_str,cmd+1);
  1762. /*---------------------------------------------------------------------*/
  1763. /* Obtain the new string to change to.                                 */
  1764. /*---------------------------------------------------------------------*/
  1765.  if ((off2 = strzeq(cmd+eos_old+1,st[i].delim)) == (-1))
  1766.    {
  1767. #ifdef TRACE
  1768.     trace_return();
  1769. #endif
  1770.     return(-1);
  1771.    }
  1772.  eos_new = eos_old+off2+1;
  1773.  *(cmd+eos_new) = '\0';
  1774.  strcpy(new_str,cmd+eos_old+1);
  1775. /*---------------------------------------------------------------------*/
  1776. /* Determine if there are any more parameters. If not, then return with*/
  1777. /* parameters of 1,1,1.                                                */
  1778. /*---------------------------------------------------------------------*/
  1779.  off1 = strzne(cmd+eos_new+1,' ');
  1780.  if (off1 == (-1))
  1781.    {
  1782.     strcpy(target,"1");
  1783.     strcpy(num,"1");
  1784.     strcpy(occ,"1");
  1785. #ifdef TRACE
  1786.     trace_return();
  1787. #endif
  1788.     return(RC_OK);
  1789.    }
  1790.  target_start = eos_new+off1+1;
  1791.  for (i=0;i<NUMBER_SEARCH_TARGETS;i++)
  1792.     if (strncmp(cmd+target_start,st[i].prefix,st[i].length) == 0)
  1793.       break;
  1794.  if (i == NUMBER_SEARCH_TARGETS)
  1795.    {                                            /* not a string target */
  1796.     num_params = param_split(cmd+target_start,word,SPLT_PARAMS,WORD_DELIMS,TEMP_PARAM);
  1797.     if (strcmp(word[0],"") == 0)
  1798.        strcpy(target,"1");
  1799.     else
  1800.        strcpy(target,word[0]);
  1801.     if (strcmp(word[1],"") == 0)
  1802.        strcpy(num,"1");
  1803.     else
  1804.        strcpy(num,word[1]);
  1805.     if (strcmp(word[2],"") == 0)
  1806.        strcpy(occ,"1");
  1807.     else
  1808.        strcpy(occ,word[2]);
  1809. #ifdef TRACE
  1810.     trace_return();
  1811. #endif
  1812.     return(RC_OK);
  1813.    }
  1814. /* to get here it is a valid start to a string target */
  1815.  off1 = strzeq(cmd+target_start+st[i].length,st[i].delim);
  1816.  if (off1 == (-1))
  1817.    {
  1818. #ifdef TRACE
  1819.     trace_return();
  1820. #endif
  1821.     return(-1);
  1822.    }
  1823.  off2 = off1+1+st[i].length;
  1824.  for (i=0;i<off2;i++)
  1825.      str3[i] = *(cmd+target_start+i);
  1826.  
  1827.  str3[off2] = '\0';
  1828.  strcpy(target,str3);
  1829.  num_params = param_split(cmd+target_start+off2+1,word,2,WORD_DELIMS,TEMP_PARAM);
  1830.  if (strcmp(word[0],"") == 0)
  1831.     strcpy(num,"1");
  1832.  else
  1833.     strcpy(num,word[0]);
  1834.  if (strcmp(word[1],"") == 0)
  1835.     strcpy(occ,"1");
  1836.  else
  1837.     strcpy(occ,word[1]);
  1838.  
  1839. #ifdef TRACE
  1840.  trace_return();
  1841. #endif
  1842.  return(RC_OK);
  1843.  
  1844. }
  1845. /***********************************************************************/
  1846. #ifdef PROTO
  1847. void init_command(void)
  1848. #else
  1849. void init_command()
  1850. #endif
  1851. /***********************************************************************/
  1852. {
  1853. /*--------------------------- local data ------------------------------*/
  1854.  register int i;
  1855. /*--------------------------- processing ------------------------------*/
  1856. #ifdef TRACE
  1857.  trace_function("commutil.c:init_command");
  1858. #endif
  1859.  for (i=0;i<MAX_CMDS;i++)
  1860.      strcpy(cmd[i],"");
  1861. #ifdef TRACE
  1862.  trace_return();
  1863. #endif
  1864.  return;
  1865. }
  1866. /***********************************************************************/
  1867. #ifdef PROTO
  1868. void add_command(char *new_cmd)
  1869. #else
  1870. void add_command(new_cmd)
  1871. char *new_cmd;
  1872. #endif
  1873. /***********************************************************************/
  1874. {
  1875. /*--------------------------- local data ------------------------------*/
  1876. /*--------------------------- processing ------------------------------*/
  1877. #ifdef TRACE
  1878.  trace_function("commutil.c:add_command");
  1879. #endif
  1880.  offset_cmd = 0;
  1881. /*---------------------------------------------------------------------*/
  1882. /* If the command to be added is the same as the current command or if */
  1883. /* the command line is empty or if the command is "=", return without  */
  1884. /* adding command to array.                                            */
  1885. /*---------------------------------------------------------------------*/
  1886.  if (strcmp(new_cmd,cmd[current_cmd]) == 0
  1887.  || strcmp(new_cmd,"") == 0
  1888.  || strcmp(new_cmd,"=") == 0)
  1889.    {
  1890. #ifdef TRACE
  1891.     trace_return();
  1892. #endif
  1893.     return;
  1894.    }
  1895.  if (number_cmds == MAX_CMDS)
  1896.     current_cmd = last_cmd = (last_cmd == MAX_CMDS-1) ? 0 : ++last_cmd;
  1897.  else
  1898.     current_cmd = ++last_cmd;
  1899.  strcpy(cmd[current_cmd],new_cmd);
  1900.  number_cmds++;
  1901.  if (number_cmds > MAX_CMDS)
  1902.     number_cmds = MAX_CMDS;
  1903. #ifdef TRACE
  1904.  trace_return();
  1905. #endif
  1906.  return;
  1907. }
  1908. /***********************************************************************/
  1909. #ifdef PROTO
  1910. char *get_next_command( int direction)
  1911. #else
  1912. char *get_next_command(direction)
  1913. int direction;
  1914. #endif
  1915. /***********************************************************************/
  1916. {
  1917. /*--------------------------- local data ------------------------------*/
  1918.  char *cmd_to_return;
  1919. /*--------------------------- processing ------------------------------*/
  1920. #ifdef TRACE
  1921.  trace_function("commutil.c:get_next_command");
  1922. #endif
  1923.  if (number_cmds == 0)
  1924.    {
  1925. #ifdef TRACE
  1926.     trace_return();
  1927. #endif
  1928.     return((char *)NULL);
  1929.    }
  1930.  switch(direction)
  1931.    {
  1932.     case DIRECTION_BACKWARD:
  1933.          if (current_cmd+1 == number_cmds)
  1934.            {
  1935.             current_cmd = 0;
  1936.             cmd_to_return = cmd[current_cmd];
  1937.            }
  1938.          else
  1939.             cmd_to_return = cmd[++current_cmd];
  1940.          break;
  1941.     case DIRECTION_FORWARD:
  1942.          if (current_cmd+offset_cmd < 0)
  1943.            {
  1944.             current_cmd = number_cmds-1;
  1945.             cmd_to_return = cmd[current_cmd];
  1946.            }
  1947.          else
  1948.            {
  1949.             current_cmd = current_cmd+offset_cmd;
  1950.             cmd_to_return = cmd[current_cmd];
  1951.            }
  1952.          offset_cmd = (-1);
  1953.          break;
  1954.     case DIRECTION_NONE:
  1955.          cmd_to_return = cmd[current_cmd];
  1956.          break;
  1957.    }
  1958. #ifdef TRACE
  1959.  trace_return();
  1960. #endif
  1961.  return(cmd_to_return);
  1962. }
  1963. /***********************************************************************/
  1964. #ifdef PROTO
  1965. int parse_colours(char *attrib,chtype *pfg,chtype *pbg,chtype *pmod)
  1966. #else
  1967. int parse_colours(attrib,pfg,pbg,pmod)
  1968. char *attrib;
  1969. chtype *pfg;
  1970. chtype *pbg;
  1971. chtype *pmod;
  1972. #endif
  1973. /***********************************************************************/
  1974. {
  1975. /*------------------------- external data -----------------------------*/
  1976. extern bool colour_support;
  1977. /*--------------------------- local data ------------------------------*/
  1978.  struct attributes
  1979.  {
  1980.   char *attrib;
  1981.   short attrib_min_len;
  1982.   chtype actual_attrib;
  1983.   bool attrib_modifier;
  1984.   bool attrib_allowed_on_mono;
  1985.  };
  1986.  typedef struct attributes ATTRIBS;
  1987. #define NO_ATTRIBS 15
  1988.  static ATTRIBS valid_attribs[NO_ATTRIBS]=
  1989.  {
  1990. #ifdef A_COLOR
  1991.   {(char *)"black",3,COLOR_BLACK,FALSE,FALSE},
  1992.   {(char *)"blue",3,COLOR_BLUE,FALSE,FALSE},
  1993.   {(char *)"green",1,COLOR_GREEN,FALSE,FALSE},
  1994.   {(char *)"cyan",1,COLOR_CYAN,FALSE,FALSE},
  1995.   {(char *)"red",3,COLOR_RED,FALSE,FALSE},
  1996.   {(char *)"magenta",1,COLOR_MAGENTA,FALSE,FALSE},
  1997.   {(char *)"yellow",1,COLOR_YELLOW,FALSE,FALSE},
  1998.   {(char *)"white",1,COLOR_WHITE,FALSE,FALSE},
  1999. #else
  2000.   {(char *)"black",3,A_BOLD,TRUE,FALSE},
  2001.   {(char *)"blue",3,A_BOLD,TRUE,FALSE},
  2002.   {(char *)"green",1,A_BOLD,TRUE,FALSE},
  2003.   {(char *)"cyan",1,A_NORMAL,TRUE,FALSE},
  2004.   {(char *)"red",3,A_BOLD,TRUE,FALSE},
  2005.   {(char *)"magenta",1,A_NORMAL,TRUE,FALSE},
  2006.   {(char *)"yellow",1,A_NORMAL,TRUE,FALSE},
  2007.   {(char *)"white",1,A_NORMAL,TRUE,FALSE},
  2008. #endif
  2009.   {(char *)"normal",3,A_NORMAL,TRUE,TRUE},
  2010.   {(char *)"blink",3,A_BLINK,TRUE,TRUE},
  2011.   {(char *)"bold",2,A_BOLD,TRUE,TRUE},
  2012.   {(char *)"bright",3,A_BOLD,TRUE,TRUE},
  2013.   {(char *)"high",1,A_BOLD,TRUE,TRUE},
  2014.   {(char *)"reverse",3,A_REVERSE,TRUE,TRUE},
  2015.   {(char *)"underline",1,A_UNDERLINE,TRUE,TRUE},
  2016.  };
  2017.  
  2018.  register int i;
  2019.  
  2020.  int num_colours = 0;
  2021.  chtype fg  = (chtype)0;
  2022.  chtype bg  = (chtype)0;
  2023.  chtype mod = (chtype)0;
  2024.  char *p;
  2025.  bool found;
  2026. /*--------------------------- processing ------------------------------*/
  2027. #ifdef TRACE
  2028.  trace_function("commutil.c:parse_colours");
  2029. #endif
  2030.  
  2031.  p = (char *)strtok(attrib," ");
  2032.  while(p != NULL)
  2033.    {
  2034.     found = FALSE;
  2035.     for (i=0;i<NO_ATTRIBS;i++)
  2036.        {
  2037.         if (equal(valid_attribs[i].attrib,p,valid_attribs[i].attrib_min_len))
  2038.           {
  2039.            found = TRUE;
  2040.            if (!valid_attribs[i].attrib_allowed_on_mono
  2041.            &&  !colour_support)
  2042.              {
  2043.               display_error(61,(char *)p);
  2044. #ifdef TRACE
  2045.               trace_return();
  2046. #endif
  2047.               return(RC_INVALID_OPERAND);
  2048.              }
  2049.            if (valid_attribs[i].attrib_modifier)
  2050.              {
  2051.               mod |= valid_attribs[i].actual_attrib;
  2052.               break;
  2053.              }
  2054.            else
  2055.               switch(num_colours)
  2056.                 {
  2057.                  case 0: fg = valid_attribs[i].actual_attrib;
  2058.                          num_colours++;
  2059.                          break;
  2060.                  case 1: bg = valid_attribs[i].actual_attrib;
  2061.                          num_colours++;
  2062.                          break;
  2063.                  default:display_error(1,(char *)p);
  2064. #ifdef TRACE
  2065.                          trace_return();
  2066. #endif
  2067.                          return(RC_INVALID_OPERAND);
  2068.                          break;
  2069.                 }
  2070.            break;
  2071.           }
  2072.        }
  2073.     if (!found)
  2074.       {
  2075.        display_error(1,(char *)p);
  2076. #ifdef TRACE
  2077.        trace_return();
  2078. #endif
  2079.        return(RC_INVALID_OPERAND);
  2080.       }
  2081.     p = (char *)strtok(NULL," ");
  2082.    }
  2083.  *pfg = fg;
  2084.  *pbg = bg;
  2085.  *pmod = mod;
  2086. #ifdef TRACE
  2087.  trace_return();
  2088. #endif
  2089.  return(RC_OK);
  2090. }
  2091.  
  2092. /***********************************************************************/
  2093. #ifdef PROTO
  2094. void set_colour(int area,chtype fg,chtype bg,chtype mod)
  2095. #else
  2096. void set_colour(area,fg,bg,mod)
  2097. int area;
  2098. chtype fg;
  2099. chtype bg;
  2100. chtype mod;
  2101. #endif
  2102. /***********************************************************************/
  2103. {                  
  2104. /*------------------------- external data -----------------------------*/
  2105. extern bool colour_support;
  2106. /*--------------------------- processing ------------------------------*/
  2107. #ifdef TRACE
  2108.  trace_function("commutil.c:set_colour");
  2109. #endif
  2110.  
  2111. #ifdef A_COLOR
  2112.  if (colour_support)
  2113.    {
  2114.     init_pair(area+1,fg,bg);
  2115.     colour[area] = COLOR_PAIR(area+1) | mod;
  2116.    }
  2117.  else
  2118.     colour[area] = mod;
  2119. #else
  2120.  colour[area] = mod;
  2121. #endif
  2122.  
  2123. #ifdef TRACE
  2124.  trace_return();
  2125. #endif
  2126.  return;
  2127. }
  2128. /***********************************************************************/
  2129. #ifdef PROTO
  2130. int tabs_convert(LINE *curr,bool expand_tabs)
  2131. #else
  2132. int tabs_convert(curr,expand_tabs)
  2133. LINE *curr;
  2134. bool expand_tabs;
  2135. #endif
  2136. /***********************************************************************/
  2137. {
  2138. /*-------------------------- external data ----------------------------*/
  2139. extern char *rec;
  2140. extern char TABI_Nx;
  2141. /*--------------------------- local data ------------------------------*/
  2142.  register int i,j;
  2143.  bool expanded = FALSE;
  2144.  int rc;
  2145. /*--------------------------- processing ------------------------------*/
  2146. #ifdef TRACE
  2147.  trace_function("commutil.c:tabs_convert");
  2148. #endif
  2149. /*---------------------------------------------------------------------*/
  2150. /* If we are expanding tabs to spaces, do the following...             */
  2151. /*---------------------------------------------------------------------*/
  2152.  if (expand_tabs)
  2153.    {
  2154.     for (i=0,j=0;i<curr->length;i++)
  2155.      {
  2156.       if (curr->line[i] == '\t')
  2157.         {
  2158.          do
  2159.           {
  2160.            rec[j++] = ' ';
  2161.            if (j >= max_line_length)
  2162.              break;
  2163.           }
  2164.          while ((j % TABI_Nx) != 0);
  2165.          expanded = TRUE;
  2166.         }
  2167.       else
  2168.         {
  2169.          rec[j++] = curr->line[i];
  2170.          if (j >= max_line_length)
  2171.            break;
  2172.         }
  2173.      }
  2174. /*---------------------------------------------------------------------*/
  2175. /* If we expanded tabs, we need to reallocate memory for the line.     */
  2176. /*---------------------------------------------------------------------*/
  2177.   if (expanded)
  2178.     {
  2179.      curr->line = (char *)realloc((void *)curr->line,(j+1)*sizeof(char));
  2180.      if (curr->line == (char *)NULL)
  2181.        {
  2182.         display_error(30,(char *)"");
  2183. #ifdef TRACE
  2184.         trace_return();
  2185. #endif
  2186.         return(RC_OUT_OF_MEMORY);
  2187.        }
  2188. /*---------------------------------------------------------------------*/
  2189. /* Copy the contents of rec into the line.                             */
  2190. /*---------------------------------------------------------------------*/
  2191.     memcpy(curr->line,rec,j);
  2192.     curr->length = j;
  2193.     *(curr->line+j) = '\0';
  2194. /*---------------------------------------------------------------------*/
  2195. /* Increment the number of alterations count.                          */
  2196. /*---------------------------------------------------------------------*/
  2197.     if ((rc = increment_alt(CURRENT_FILE)) != RC_OK)
  2198.       {
  2199. #ifdef TRACE
  2200.        trace_return();
  2201. #endif
  2202.        return(rc);
  2203.       }
  2204.     }
  2205.  }
  2206.  
  2207. #ifdef TRACE
  2208.  trace_return();
  2209. #endif
  2210.  return(RC_OK);
  2211. }
  2212. /***********************************************************************/
  2213. #ifdef PROTO
  2214. int convert_hex_strings(char *str)
  2215. #else
  2216. int convert_hex_strings(str)
  2217. char *str;
  2218. #endif
  2219. /***********************************************************************/
  2220. {
  2221. /*--------------------------- local data ------------------------------*/
  2222.  register int i=0;
  2223.  char *p;
  2224.  bool dec_char;
  2225.  char temp_str[80];
  2226.  int num;
  2227.  char ch1,ch2;
  2228. /*--------------------------- processing ------------------------------*/
  2229. #ifdef TRACE
  2230.  trace_function("commutil.c:convert_hex_strings");
  2231. #endif
  2232. /*---------------------------------------------------------------------*/
  2233. /* Check if the string begins with d',D',x' or X'. If not return the   */
  2234. /* string unchanged.                                                   */
  2235. /*---------------------------------------------------------------------*/
  2236.  if ((*(str) == 'd'
  2237.  ||   *(str) == 'D'
  2238.  ||   *(str) == 'x'
  2239.  ||   *(str) == 'X')
  2240.  &&   *(str+1) == '\'')
  2241.     ;
  2242.  else
  2243.    {
  2244. #ifdef TRACE
  2245.     trace_return();
  2246. #endif
  2247.     return(strlen(str));
  2248.    }
  2249. /*---------------------------------------------------------------------*/
  2250. /* Check if the last character is a single quote. If not return (-1)   */
  2251. /* to indicate an error.                                               */
  2252. /*---------------------------------------------------------------------*/
  2253.  if (*(str+strlen(str)-1) != '\'')
  2254.    {
  2255. #ifdef TRACE
  2256.     trace_return();
  2257. #endif
  2258.     return((-1));
  2259.    }
  2260. /*---------------------------------------------------------------------*/
  2261. /* If we got here we can validate the contents of the string.          */
  2262. /*---------------------------------------------------------------------*/
  2263.  *(str+strlen(str)-1) = '\0';
  2264.  if (*(str) == 'd'
  2265.  ||  *(str) == 'D')
  2266.     dec_char = TRUE;
  2267.  else
  2268.     dec_char = FALSE;
  2269.  p = (char *)strtok(str+2," ");
  2270.  while(p != NULL)
  2271.    {
  2272.     switch(dec_char)
  2273.       {
  2274.        case TRUE: /* parse decimal number */
  2275.                   if (equal((char *)"000000",p,1))
  2276.                      temp_str[i++] = (char)0;
  2277.                   else
  2278.                     {
  2279.                      num = atoi(p);
  2280.                      if (num < 1 || num > 255)
  2281.                        {
  2282. #ifdef TRACE
  2283.                         trace_return();
  2284. #endif
  2285.                         return((-1));
  2286.                        }
  2287.                      temp_str[i++] = (char)num;
  2288.                     }
  2289.                   break;
  2290.        case FALSE: /* parse hexidecimal number */
  2291.                   ch1 = *(p);
  2292.                   ch2 = *(p+1);
  2293.                   if (strlen(p) != 2
  2294.                   || !isxdigit(ch1)
  2295.                   || !isxdigit(ch2))
  2296.                     {
  2297. #ifdef TRACE
  2298.                      trace_return();
  2299. #endif
  2300.                      return((-1));
  2301.                     }
  2302.                   if (isupper(ch1)!=0)
  2303.                      ch1 = tolower(ch1);
  2304.                   if (isupper(ch2)!=0)
  2305.                      ch2 = tolower(ch2);
  2306.                   num =  ((isdigit(ch1)!=0) ? ch1-48 : ch1-87) * 16;
  2307.                   num += ((isdigit(ch2)!=0) ? ch2-48 : ch2-87);
  2308.                   temp_str[i++] = (char)num;
  2309.                   break;
  2310.       }
  2311.     p = (char *)strtok(NULL," ");
  2312.    }
  2313. /*
  2314.  temp_str[i] = '\0';
  2315.  memcpy(str,temp_str,i+1);
  2316. */
  2317.  memcpy(str,temp_str,i);
  2318. #ifdef TRACE
  2319.  trace_return();
  2320. #endif
  2321.  return(i);
  2322. }
  2323. /***********************************************************************/
  2324. #ifdef PROTO
  2325. int marked_block(bool in_current_view)
  2326. #else
  2327. int marked_block(in_current_view)
  2328. bool in_current_view;
  2329. #endif
  2330. /***********************************************************************/
  2331. {
  2332. /*--------------------------- local data ------------------------------*/
  2333. /*--------------------------- processing ------------------------------*/
  2334. #ifdef TRACE
  2335.  trace_function("commutil.c:marked_block");
  2336. #endif
  2337.  if (in_profile)                  /* block commands invalid in profile */
  2338.    {
  2339.     display_error(24,(char *)"");
  2340. #ifdef TRACE
  2341.     trace_return();
  2342. #endif
  2343.     return(RC_INVALID_ENVIRON);
  2344.    }
  2345.  if (MARK_VIEW == (VIEW_DETAILS *)NULL)             /* no marked block */
  2346.    {
  2347.     display_error(44,(char *)"");
  2348. #ifdef TRACE
  2349.     trace_return();
  2350. #endif
  2351.     return(RC_INVALID_ENVIRON);
  2352.    }
  2353.  if (MARK_VIEW != CURRENT_VIEW     /* marked block not in current view */
  2354.  && in_current_view)
  2355.    {
  2356.     display_error(45,(char *)"");
  2357. #ifdef TRACE
  2358.     trace_return();
  2359. #endif
  2360.     return(RC_INVALID_ENVIRON);
  2361.    }
  2362. #ifdef TRACE
  2363.  trace_return();
  2364. #endif
  2365.  return(RC_OK);
  2366. }
  2367. /***********************************************************************/
  2368. #ifdef PROTO
  2369. int suspend_curses(void)
  2370. #else
  2371. int suspend_curses()
  2372. #endif
  2373. /***********************************************************************/
  2374. {
  2375. /*--------------------------- local data ------------------------------*/
  2376. /*--------------------------- processing ------------------------------*/
  2377. #ifdef TRACE
  2378.  trace_function("commutil.c:suspend_curses");
  2379. #endif
  2380. #ifdef UNIX
  2381.  reset_shell_mode();
  2382. # ifdef BSD
  2383.  noraw();
  2384.  nl();
  2385.  echo();
  2386.  nocbreak();
  2387. # endif
  2388. #endif
  2389. #ifdef TRACE
  2390.  trace_return();
  2391. #endif
  2392.  return(RC_OK);
  2393. }
  2394. /***********************************************************************/
  2395. #ifdef PROTO
  2396. int resume_curses(void)
  2397. #else
  2398. int resume_curses()
  2399. #endif
  2400. /***********************************************************************/
  2401. {
  2402. /*--------------------------- local data ------------------------------*/
  2403. /*--------------------------- processing ------------------------------*/
  2404. #ifdef TRACE
  2405.  trace_function("commutil.c:resume_curses");
  2406. #endif
  2407. #ifdef UNIX
  2408.  reset_prog_mode();
  2409. # ifdef BSD
  2410.  raw();
  2411.  nonl();
  2412.  noecho();
  2413.  cbreak();
  2414. # endif
  2415. #endif
  2416. #ifdef TRACE
  2417.  trace_return();
  2418. #endif
  2419.  return(RC_OK);
  2420. }
  2421. /***********************************************************************/
  2422. #ifdef PROTO
  2423. int restore_THE(void)
  2424. #else
  2425. int restore_THE()
  2426. #endif
  2427. /***********************************************************************/
  2428. {
  2429. /*--------------------------- local data ------------------------------*/
  2430.  unsigned short y,x;
  2431. /*--------------------------- processing ------------------------------*/
  2432. #ifdef TRACE
  2433.  trace_function("commutil.c:restore_THE");
  2434. #endif
  2435.  getyx(CURRENT_WINDOW,y,x);
  2436.  wclear(stdscr);
  2437.  refresh();
  2438.  if (CURRENT_VIEW->prefix)
  2439.     touchwin(CURRENT_WINDOW_PREFIX);
  2440.  touchwin(CURRENT_WINDOW_COMMAND);
  2441.  touchwin(CURRENT_WINDOW_MAIN);
  2442.  touchwin(CURRENT_WINDOW_IDLINE);
  2443.  touchwin(foot);
  2444.  wmove(CURRENT_WINDOW,y,x);
  2445. #ifdef TRACE
  2446.  trace_return();
  2447. #endif
  2448.  return(RC_OK);
  2449. }
  2450. /***********************************************************************/
  2451. #ifdef PROTO
  2452. int execute_set_sos_command(bool set_command,char *params)
  2453. #else
  2454. int execute_set_sos_command(set_command,params)
  2455. bool set_command;
  2456. char *params;
  2457. #endif
  2458. /***********************************************************************/
  2459. {
  2460. /*--------------------------- local data ------------------------------*/
  2461.  register int i;
  2462. #define SETSOS_PARAMS  2
  2463.  char *word[SETSOS_PARAMS+1];
  2464.  unsigned short num_params;
  2465.  int rc,command_index;
  2466. /*--------------------------- processing ------------------------------*/
  2467. #ifdef TRACE
  2468.  trace_function("commutil.c:execute_set_sos_command");
  2469. #endif
  2470.  num_params = param_split(params,word,SETSOS_PARAMS,WORD_DELIMS,TEMP_PARAM);
  2471.  if (num_params < 1)
  2472.    {
  2473.     display_error(1,(char *)"");
  2474. #ifdef TRACE
  2475.     trace_return();
  2476. #endif
  2477.     return(RC_INVALID_OPERAND);
  2478.    }
  2479.  if ((command_index = valid_command_type(set_command,word[0])) == RC_NOT_COMMAND)
  2480.    {
  2481.     display_error(set_command ? 42 : 41,word[0]);
  2482. #ifdef TRACE
  2483.     trace_return();
  2484. #endif
  2485.     return(RC_INVALID_OPERAND);
  2486.    }
  2487.  rc = (*command[command_index].function)(word[1]);
  2488. #ifdef TRACE
  2489.  trace_return();
  2490. #endif
  2491.  return(rc);
  2492. }
  2493. /***********************************************************************/
  2494. #ifdef PROTO
  2495. int valid_command_type(bool set_command,char *cmd_line)
  2496. #else
  2497. int valid_command_type(set_command,cmd_line)
  2498. bool set_command;
  2499. char *cmd_line;
  2500. #endif
  2501. /***********************************************************************/
  2502. {
  2503. /*--------------------------- local data ------------------------------*/
  2504.  register int i;
  2505. /*--------------------------- processing ------------------------------*/
  2506. #ifdef TRACE
  2507.  trace_function("commutil.c:valid_command_type");
  2508. #endif
  2509.  for (i=0;command[i].text != NULL;i++)
  2510.     {
  2511. /*---------------------------------------------------------------------*/
  2512. /* If no command text, continue.                                       */
  2513. /*---------------------------------------------------------------------*/
  2514.      if (strcmp(command[i].text,"") == 0)
  2515.         continue;
  2516. /*---------------------------------------------------------------------*/
  2517. /* Check that the supplied command matches the command for the length  */
  2518. /* of the command and that the length is at least as long as the       */
  2519. /* necessary significance.                                             */
  2520. /*---------------------------------------------------------------------*/
  2521.      if (equal(command[i].text,cmd_line,command[i].min_len)
  2522.      && command[i].min_len != 0)
  2523.        {
  2524. #ifdef TRACE
  2525.         trace_return();
  2526. #endif
  2527.         if (set_command && command[i].set_command)
  2528.            return(i);
  2529.         if (!set_command && command[i].sos_command)
  2530.            return(i);
  2531.        }
  2532.     }
  2533. #ifdef TRACE
  2534.  trace_return();
  2535. #endif
  2536.  return(RC_NOT_COMMAND);
  2537. }
  2538. /***********************************************************************/
  2539. #ifdef PROTO
  2540. int allocate_temp_space(unsigned int length,char param_type)
  2541. #else
  2542. int allocate_temp_space(length,param_type)
  2543. unsigned int length;
  2544. char param_type;
  2545. #endif
  2546. /***********************************************************************/
  2547. {
  2548. /*--------------------------- local data ------------------------------*/
  2549.  char *temp_ptr;
  2550.  unsigned int *temp_length;
  2551. /*--------------------------- processing ------------------------------*/
  2552. #ifdef TRACE
  2553.  trace_function("commutil.c:allocate_temp_space");
  2554. #endif
  2555. /*---------------------------------------------------------------------*/
  2556. /* Based on param_type, point param_ptr to appropriate buffer.         */
  2557. /*---------------------------------------------------------------------*/
  2558.  switch(param_type)
  2559.    {
  2560.     case TEMP_PARAM:
  2561.          temp_ptr = temp_params;
  2562.          temp_length = &length_temp_params;
  2563.          break;
  2564.     case TEMP_MACRO:
  2565.          temp_ptr = temp_macros;
  2566.          temp_length = &length_temp_macros;
  2567.          break;
  2568.     case TEMP_TMP_CMD:
  2569.          temp_ptr = tmp_cmd;
  2570.          temp_length = &length_tmp_cmd;
  2571.          break;
  2572.     case TEMP_TEMP_CMD:
  2573.          temp_ptr = temp_cmd;
  2574.          temp_length = &length_temp_cmd;
  2575.          break;
  2576.     default:
  2577.          return(-1);
  2578.          break;
  2579.    }
  2580.  if (*temp_length >= length)
  2581.    {
  2582. #ifdef TRACE
  2583.     trace_return();
  2584. #endif
  2585.     return(RC_OK);
  2586.    }
  2587.  if (temp_ptr == NULL)
  2588.     temp_ptr = (char *)malloc(sizeof(char)*(length+1));
  2589.  else
  2590.     temp_ptr = (char *)realloc(temp_ptr,sizeof(char)*(length+1));
  2591.  if (temp_ptr == NULL)
  2592.    {
  2593.     display_error(30,(char *)"");
  2594. #ifdef TRACE
  2595.     trace_return();
  2596. #endif
  2597.     return(RC_OUT_OF_MEMORY);
  2598.    }
  2599. /*---------------------------------------------------------------------*/
  2600. /* Based on param_type, point param_ptr to appropriate buffer.         */
  2601. /*---------------------------------------------------------------------*/
  2602.  switch(param_type)
  2603.    {
  2604.     case TEMP_PARAM:
  2605.          temp_params = temp_ptr;
  2606.          break;
  2607.     case TEMP_MACRO:
  2608.          temp_macros = temp_ptr;
  2609.          break;
  2610.     case TEMP_TMP_CMD:
  2611.          tmp_cmd = temp_ptr;
  2612.          break;
  2613.     case TEMP_TEMP_CMD:
  2614.          temp_cmd = temp_ptr;
  2615.          break;
  2616.     default:
  2617.          return(-1);
  2618.          break;
  2619.    }
  2620.  *temp_length = length;
  2621. #ifdef TRACE
  2622.  trace_return();
  2623. #endif
  2624.  return(RC_OK);
  2625. }
  2626. /***********************************************************************/
  2627. #ifdef PROTO
  2628. void free_temp_space(char param_type)
  2629. #else
  2630. void free_temp_space(param_type)
  2631. char param_type;
  2632. #endif
  2633. /***********************************************************************/
  2634. {
  2635. /*--------------------------- local data ------------------------------*/
  2636.  char *temp_ptr;
  2637.  unsigned int *temp_length;
  2638. /*--------------------------- processing ------------------------------*/
  2639. #ifdef TRACE
  2640.  trace_function("commutil.c:free_temp_space");
  2641. #endif
  2642. /*---------------------------------------------------------------------*/
  2643. /* Based on param_type, point param_ptr to appropriate buffer.         */
  2644. /*---------------------------------------------------------------------*/
  2645.  switch(param_type)
  2646.    {
  2647.     case TEMP_PARAM:
  2648.          temp_ptr = temp_params;
  2649.          temp_length = &length_temp_params;
  2650.          break;
  2651.     case TEMP_MACRO:
  2652.          temp_ptr = temp_macros;
  2653.          temp_length = &length_temp_macros;
  2654.          break;
  2655.     case TEMP_TMP_CMD:
  2656.          temp_ptr = tmp_cmd;
  2657.          temp_length = &length_tmp_cmd;
  2658.          break;
  2659.     case TEMP_TEMP_CMD:
  2660.          temp_ptr = temp_cmd;
  2661.          temp_length = &length_temp_cmd;
  2662.          break;
  2663.     default:
  2664.          return;
  2665.          break;
  2666.    }
  2667.  free(temp_ptr);
  2668.  *temp_length = 0;
  2669. #ifdef TRACE
  2670.  trace_return();
  2671. #endif
  2672.  return;
  2673. }
  2674. /***********************************************************************/
  2675. #ifdef PROTO
  2676. char calculate_current_row(char base,char off,char rows)
  2677. #else
  2678. char calculate_current_row(base,off,rows)
  2679. char base,rows;
  2680. char off;
  2681. #endif
  2682. /***********************************************************************/
  2683. {
  2684. /*--------------------------- local data ------------------------------*/
  2685.  int row;
  2686. /*--------------------------- processing ------------------------------*/
  2687. #ifdef TRACE
  2688.  trace_function("commutil.c:calculate_current_row");
  2689. #endif
  2690.  switch(base)
  2691.    {
  2692.     case CURLINE_TOP:
  2693.                      row = off;
  2694.                      break;
  2695.     case CURLINE_MIDDLE:
  2696.                      row = (rows /2 ) + off;
  2697.                      break;
  2698.     case CURLINE_BOTTOM:
  2699.                      row = rows+off+1;
  2700.                      break;
  2701.    }
  2702. /*---------------------------------------------------------------------*/
  2703. /* If the calculated row is outside the screen size, default to middle.*/
  2704. /*---------------------------------------------------------------------*/
  2705.  if (row < 0 || row > rows)
  2706.     row = rows / 2;
  2707. #ifdef TRACE
  2708.  trace_return();
  2709. #endif
  2710.  return((char)row-1);
  2711. }
  2712. /*man***************************************************************************
  2713. NAME
  2714.      get_valid_macro_file_name 
  2715.  
  2716. SYNOPSIS
  2717.      int get_valid_macro_file_name(macroname,filename,errnum)
  2718.      char *macroname;
  2719.      char *filename;
  2720.      int *errnum;
  2721.  
  2722. DESCRIPTION
  2723.      The get_valid_macro_file_name function determines the fully qualified
  2724.      file name for the supplied macroname.
  2725.  
  2726.      If the macroname contains any path specifiers, then the macro name
  2727.      is used as the filename and a check is made to ensure that the file
  2728.      exists and is readable.
  2729.  
  2730.      If the macroname does not contain any path specifiers, each
  2731.      directory in the MACROPATH variable is searched for a file that
  2732.      consists of the macroname appended with the current value for
  2733.      MACROEXT. If a file is found, it is checked to ensure it is
  2734.      readable.
  2735.      
  2736. RETURN VALUE
  2737.      If a file is found based on the above matching process, the fully
  2738.      qualified file name is copied into filename, errnum is set to 0
  2739.      and the function returns with RC_OK.
  2740.  
  2741.      If a file is not found, the macroname is copied into filename, the
  2742.      error number of the error message is copied into errnum and the
  2743.      function returns with RC_FILE_NOT_FOUND.
  2744.  
  2745.      If a file is found but the file is not readable, the macroname is 
  2746.      copied into filename, the error number of the error message is 
  2747.      copied into errnum and the function returns with RC_ACCESS_DENIED.
  2748. *******************************************************************************/
  2749. #ifdef PROTO
  2750. int get_valid_macro_file_name(char *macroname,char *filename,int *errnum)
  2751. #else
  2752. int get_valid_macro_file_name(macroname,filename,errnum)
  2753. char *macroname,*filename;
  2754. int *errnum;
  2755. #endif
  2756. /***********************************************************************/
  2757. {
  2758. #if defined(UNIX)
  2759. #   define PATH_DELIM ":"
  2760. #else
  2761. #   define PATH_DELIM ";"
  2762. #endif
  2763. /*-------------------------- external data ----------------------------*/
  2764.  extern char the_macro_path[MAX_FILE_NAME+1] ;
  2765.  extern char sp_path[MAX_FILE_NAME+1] ;
  2766.  extern char sp_fname[MAX_FILE_NAME+1] ;
  2767.  extern char macro_suffix[12];
  2768. /*--------------------------- local data ------------------------------*/
  2769.  register int i;
  2770.  char delims[3];
  2771.  bool file_found;
  2772.  char *path[MAX_MACRO_DIRS+1];    /* max number of macro dirs */
  2773.  unsigned short num_params;
  2774. /*--------------------------- processing ------------------------------*/
  2775. #ifdef TRACE
  2776.  trace_function("commutil.c:get_valid_macro_file_name");
  2777. #endif
  2778. /*---------------------------------------------------------------------*/
  2779. /* Create the full name of the macro file by prepending the default    */
  2780. /* macropath provided the filename does not already contain a path.    */
  2781. /*---------------------------------------------------------------------*/
  2782.  (void *)strtrans(macroname,OSLASH,ISLASH);
  2783. #ifdef UNIX
  2784.  strcpy(delims,ISTR_SLASH);
  2785.  if (strpbrk(macroname,delims) == NULL
  2786.  && *(macroname) != '~')
  2787. #endif
  2788. #if defined(DOS) || defined(OS2)
  2789.  strcpy(delims,ISTR_SLASH);
  2790.  strcat(delims,":");
  2791.  if (strpbrk(macroname,delims) == NULL)
  2792. #endif
  2793. /*---------------------------------------------------------------------*/
  2794. /* The supplied macro file name does not contain a path...so for each  */
  2795. /* directory in the_macro_path, try to find the supplied file in that  */
  2796. /* directory.                                                          */
  2797. /*---------------------------------------------------------------------*/
  2798.    {
  2799.     strcpy(filename,the_macro_path);
  2800.     num_params = param_split(filename,path,MAX_MACRO_DIRS,PATH_DELIM,TEMP_MACRO);
  2801.     file_found = FALSE;
  2802.     for (i=0;i<num_params;i++)
  2803.       {
  2804.        strcpy(filename,path[i]);
  2805.        if (strlen(filename) == 0)
  2806.           continue;
  2807.        if (*(filename+strlen(filename)-1) != ISLASH)
  2808.           strcat(filename,ISTR_SLASH);
  2809.        strcat(filename,macroname);               /* append the file name */
  2810.        strcat(filename,macro_suffix);         /* append default suffix */
  2811.        if (file_exists(filename))           /* check if file exists... */
  2812.          {
  2813.           file_found = TRUE;
  2814.           break;
  2815.          }
  2816.       }
  2817.     if (!file_found)
  2818.       {
  2819.        strcpy(filename,macroname);
  2820.        strcat(filename,macro_suffix);
  2821.        *errnum = 11;
  2822. #ifdef TRACE
  2823.        trace_return();
  2824. #endif
  2825.        return(RC_FILE_NOT_FOUND);
  2826.       }
  2827.    }
  2828.  else                                /* file contains a path specifier */
  2829. /*---------------------------------------------------------------------*/
  2830. /* The supplied macro file name does contain a path...so just check to */
  2831. /* ensure that the file exists.                                        */
  2832. /*---------------------------------------------------------------------*/
  2833.    {
  2834.     if (splitpath(macroname) != RC_OK)
  2835.       {
  2836.        *errnum = 9;
  2837. #ifdef TRACE
  2838.        trace_return();
  2839. #endif
  2840.        return(RC_FILE_NOT_FOUND);
  2841.       }
  2842.     strcpy(filename,sp_path);
  2843.     strcat(filename,sp_fname);
  2844.     if (!file_exists(filename)
  2845.     ||  strcmp(sp_fname,"") == 0)
  2846.       {
  2847.        *errnum = 9;
  2848. #ifdef TRACE
  2849.        trace_return();
  2850. #endif
  2851.        return(RC_FILE_NOT_FOUND);
  2852.       }
  2853.    }
  2854. /*---------------------------------------------------------------------*/
  2855. /* If the file is not readable, error.                                 */
  2856. /*---------------------------------------------------------------------*/
  2857.  if (!file_readable(filename))
  2858.    {
  2859.     *errnum = 8;
  2860. #ifdef TRACE
  2861.     trace_return();
  2862. #endif
  2863.     return(RC_ACCESS_DENIED);
  2864.    }
  2865. #ifdef TRACE
  2866.  trace_return();
  2867. #endif
  2868.  *errnum = 0;
  2869.  return(RC_OK);
  2870. }
  2871.