home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
thesrc15.zip
/
commutil.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-30
|
90KB
|
2,871 lines
/***********************************************************************/
/* COMMUTIL.C - */
/* This file contains all utility functions used when processing */
/* commands. */
/***********************************************************************/
/*
* THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
* Copyright (C) 1991-1993 Mark Hessling
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
*
* The Free Software Foundation, Inc.
* 675 Mass Ave,
* Cambridge, MA 02139 USA.
*
*
* If you make modifications to this software that you feel increases
* it usefulness for the rest of the community, please email the
* changes, enhancements, bug fixes as well as any and all ideas to me.
* This software is going to be maintained and enhanced as deemed
* necessary by the community.
*
* Mark Hessling email: M.Hessling@gu.edu.au
* 36 David Road Phone: +61 7 849 7731
* Holland Park Fax: +61 7 875 5314
* QLD 4121
* Australia
*/
/*
$Header: C:\THE\RCS\commutil.c 1.4 1993/09/01 16:25:58 MH Interim MH $
*/
#include <stdio.h>
#include "the.h"
#include "key.h"
#include "command.h"
#include "proto.h"
/*#define DEBUG 1*/
#define NUMBER_VALID_TARGETS 32
#define NUMBER_SEARCH_TARGETS 9
static SEARCH_TARGET st[NUMBER_VALID_TARGETS] =
{
{(char *)"\\",1,'\\',DIRECTION_FORWARD},
{(char *)"+\\",2,'\\',DIRECTION_FORWARD},
{(char *)"-\\",2,'\\',DIRECTION_BACKWARD},
{(char *)"/",1,'/',DIRECTION_FORWARD},
{(char *)"+/",2,'/',DIRECTION_FORWARD},
{(char *)"-/",2,'/',DIRECTION_BACKWARD},
{(char *)"@",1,'@',DIRECTION_FORWARD},
{(char *)"+@",2,'@',DIRECTION_FORWARD},
{(char *)"-@",2,'@',DIRECTION_BACKWARD},
{(char *)":",1,0,0},
{(char *)"*",1,0,0},
{(char *)"-*",2,0,0},
{(char *)"0",1,0,0},
{(char *)"1",1,0,0},
{(char *)"2",1,0,0},
{(char *)"3",1,0,0},
{(char *)"4",1,0,0},
{(char *)"5",1,0,0},
{(char *)"6",1,0,0},
{(char *)"7",1,0,0},
{(char *)"8",1,0,0},
{(char *)"9",1,0,0},
{(char *)"-0",1,0,0},
{(char *)"-1",1,0,0},
{(char *)"-2",1,0,0},
{(char *)"-3",1,0,0},
{(char *)"-4",1,0,0},
{(char *)"-5",1,0,0},
{(char *)"-6",1,0,0},
{(char *)"-7",1,0,0},
{(char *)"-8",1,0,0},
{(char *)"-9",1,0,0}
};
#define MAX_CMDS 15
static char cmd[MAX_CMDS][80];
static short last_cmd=(-1),current_cmd=0,number_cmds=0,offset_cmd=0;
/*---------------------------------------------------------------------*/
/* The following two static variables are for reserving space for the */
/* parameters of a command. Space for temp_params is allocated and */
/* freed in the.c. If the size of the string to be placed into */
/* temp_params is > length_temp_params, reallocate a larger area and */
/* set the value of length_temp_params to reflect the new size. */
/*---------------------------------------------------------------------*/
static char *temp_params=NULL;
static unsigned int length_temp_params=0;
/*---------------------------------------------------------------------*/
/* The following two static variables are for reserving space for the */
/* directories in a macro path. Space for temp_macros is allocated and */
/* freed in the.c. If the size of the string to be placed into */
/* temp_macros is > length_temp_macros reallocate a larger area and */
/* set the value of length_temp_macros to reflect the new size. */
/*---------------------------------------------------------------------*/
static char *temp_macros=NULL;
static unsigned int length_temp_macros=0;
/*---------------------------------------------------------------------*/
/* The following two static variables are for reserving space for the */
/* contents of a command. Space for tmp_cmd is allocated and */
/* freed in the.c. If the size of the string to be placed into */
/* tmp_cmd is > length_tmp_cmd , reallocate a larger area and */
/* set the value of length_tmp_cmd to reflect the new size. */
/*---------------------------------------------------------------------*/
static char *tmp_cmd=NULL;
static unsigned int length_tmp_cmd=0;
/*---------------------------------------------------------------------*/
/* The following two variables are for reserving space for the */
/* contents of a command. Space for temp_cmd is allocated and */
/* freed in the.c. If the size of the string to be placed into */
/* temp_cmd is > length_temp_cmd , reallocate a larger area and */
/* set the value of length_temp_cmd to reflect the new size. */
/*---------------------------------------------------------------------*/
char *temp_cmd=NULL;
static unsigned int length_temp_cmd=0;
/*---------------------------------------------------------------------*/
/* The following two are to specify the first and last items in the */
/* linked list for key definitions. */
/*---------------------------------------------------------------------*/
DEFINE *first_define=NULL;
DEFINE *last_define=NULL;
bool clear_command=TRUE;
/*-------------------------- external data ----------------------------*/
extern LINE *next_line,*curr_line;
extern VIEW_DETAILS *vd_current,*vd_first,*vd_mark;
extern char current_screen;
extern SCREEN_DETAILS screen[MAX_SCREENS]; /* screen structures */
extern char number_of_views;
extern WINDOW *foot,*error_window;
extern bool error_on_screen;
extern char in_profile; /* indicates if processing profile */
extern char file_read; /* indicates if we have read the file */
extern char *last_target;
extern char curr_path[MAX_FILE_NAME+1] ;
extern char sp_path[MAX_FILE_NAME+1] ;
extern char sp_fname[MAX_FILE_NAME+1] ;
/***********************************************************************/
#ifdef PROTO
char *get_key_definition(unsigned short key)
#else
char *get_key_definition(key)
unsigned short key;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i;
DEFINE *curr;
char delim[2];
bool key_defined=FALSE;
bool valid_key=FALSE;
bool first_time=TRUE;
bool locate_command;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:get_key_definition");
#endif
/*---------------------------------------------------------------------*/
/* First determine if the key is a named key. */
/*---------------------------------------------------------------------*/
for (i=0;i<MAX_NUMBER_KEYS && valid_key == FALSE;i++)
{
if (key == key_table[i].key_value)
{
strcpy(temp_cmd,"Key: ");
valid_key = TRUE;
strcat(temp_cmd,key_table[i].mnemonic);
}
}
/*---------------------------------------------------------------------*/
/* If key is invalid, show it as a character and decimal; provided it */
/* is an ASCII or extended character. */
/*---------------------------------------------------------------------*/
if (!valid_key && key <256)
sprintf(temp_cmd,"Key: %c \\%d",(char)key,key);
/*---------------------------------------------------------------------*/
/* Next check to see if the key has been "defined". */
/*---------------------------------------------------------------------*/
delim[1] = '\0';
curr = first_define;
while(curr != NULL)
{
if (key == curr->def_funkey)
{
key_defined = TRUE;
if (first_time)
strcat(temp_cmd," - assigned to '");
else
{
delim[0] = curr->def_delim;
strcat(temp_cmd,delim);
}
/*---------------------------------------------------------------------*/
/* If command is 'locate' do not append to string. */
/*---------------------------------------------------------------------*/
locate_command = FALSE;
if (strcmp(command[curr->def_command].text,"locate") != 0)
strcat(temp_cmd,command[curr->def_command].text);
else
locate_command = TRUE;
/*---------------------------------------------------------------------*/
/* Append any parameters. */
/*---------------------------------------------------------------------*/
if (strcmp(curr->def_params,"") != 0)
{
if (!locate_command)
strcat(temp_cmd," ");
strcat(temp_cmd,curr->def_params);
}
first_time = FALSE;
}
curr = curr->next;
}
if (key_defined)
{
strcat(temp_cmd,"'");
#ifdef TRACE
trace_return();
#endif
return(temp_cmd);
}
/*---------------------------------------------------------------------*/
/* If not, check for the default function key values. */
/*---------------------------------------------------------------------*/
for (i=0;command[i].text != NULL;i++)
{
if (key == command[i].funkey)
{
strcat(temp_cmd," - assigned to '");
/*---------------------------------------------------------------------*/
/* If a SET command, prefix with 'set' */
/*---------------------------------------------------------------------*/
if (command[i].set_command)
strcat(temp_cmd,"set ");
/*---------------------------------------------------------------------*/
/* If a SOS command, prefix with 'sos' */
/*---------------------------------------------------------------------*/
if (command[i].sos_command)
strcat(temp_cmd,"sos ");
/*---------------------------------------------------------------------*/
/* Append the command name. */
/*---------------------------------------------------------------------*/
strcat(temp_cmd,command[i].text);
/*---------------------------------------------------------------------*/
/* Append any parameters. */
/*---------------------------------------------------------------------*/
if (strcmp(command[i].params,"") != 0)
{
strcat(temp_cmd," ");
strcat(temp_cmd,command[i].params);
}
strcat(temp_cmd,"'");
#ifdef TRACE
trace_return();
#endif
return(temp_cmd);
}
}
/*---------------------------------------------------------------------*/
/* If none of the above, it is unassigned */
/*---------------------------------------------------------------------*/
strcat(temp_cmd," - unassigned");
#ifdef TRACE
trace_return();
#endif
return(temp_cmd);
}
/***********************************************************************/
#ifdef PROTO
int function_key(int key)
#else
int function_key(key)
int key;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
unsigned short x,y;
register int i;
DEFINE *curr;
char cmd[81];
bool key_defined = FALSE;
int rc;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:function_key");
#endif
/*---------------------------------------------------------------------*/
/* First check to see if the function key has been redefined. */
/*---------------------------------------------------------------------*/
curr = first_define;
while(curr != NULL)
{
if (key == curr->def_funkey)
{
key_defined = TRUE;
rc = (*command[curr->def_command].function)(curr->def_params);
if (rc != RC_OK
&& rc != RC_TOF_EOF_REACHED
&& rc != RC_NO_LINES_CHANGED
&& rc != RC_TARGET_NOT_FOUND)
break;
}
curr = curr->next;
}
if (key_defined)
{
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/*---------------------------------------------------------------------*/
/* If not, check for the default function key values. */
/*---------------------------------------------------------------------*/
for (i=0;command[i].text != NULL;i++)
if (key == command[i].funkey)
{
i = (*command[i].function)(command[i].params);
#ifdef TRACE
trace_return();
#endif
return(i);
}
#ifdef TRACE
trace_return();
#endif
return(RAW_KEY);
}
/***********************************************************************/
#ifdef PROTO
int command_line(char *cmd_line,bool command_only)
#else
int command_line(cmd_line,command_only)
char *cmd_line;
bool command_only;
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
extern char in_macro;
extern char number_of_files;
extern int lastrc;
/*--------------------------- local data ------------------------------*/
bool valid_command=FALSE;
unsigned short x,y;
register int i,j;
int rc,pos;
long num_lines;
char *cmd[MAX_COMMANDS+1];
unsigned short num_commands;
char command_delim[2];
char define_test[7];
char *command_entered;
char *cl_cmd;
char *cl_param;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:command_line");
#endif
/*---------------------------------------------------------------------*/
/* If the command is being issued from a macro and there are no more */
/* files in the ring, ignore the command and exit. */
/*---------------------------------------------------------------------*/
if (in_macro && number_of_files == 0)
{
#ifdef TRACE
trace_return();
#endif
return(RC_COMMAND_NO_FILES);
}
/*---------------------------------------------------------------------*/
/* If the command line is blank, just return. */
/*---------------------------------------------------------------------*/
if (strlen(cmd_line) == 0)
{
if (!in_profile)
wmove(CURRENT_WINDOW_COMMAND,0,0);
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/*---------------------------------------------------------------------*/
/* If the command is to be kept displayed on the command line... */
/*---------------------------------------------------------------------*/
if (*(cmd_line) == '&')
{
cmd_line++;
clear_command = FALSE;
}
else
if (!(in_macro && !clear_command))
clear_command = TRUE;
/*---------------------------------------------------------------------*/
/* Get the command to see if it is the DEFINE command. This is done so */
/* that it is possible to assign multiple commands to a key. */
/*---------------------------------------------------------------------*/
for (i=0;i<7;i++)
define_test[i] = '\0';
pos = min(6,strlen(cmd_line));
memcpy(define_test,cmd_line,pos);
for (i=0;i<7;i++)
if (define_test[i] == ' ')
define_test[i] = '\0';
/*---------------------------------------------------------------------*/
/* Copy the incoming cmd_line, so we can play with it. */
/*---------------------------------------------------------------------*/
if ((command_entered = strdup(cmd_line)) == NULL)
{
display_error(30,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
/*---------------------------------------------------------------------*/
/* Allocate some space to cl_cmd and cl_param for the a command when */
/* it is split into a command and its parameters. */
/*---------------------------------------------------------------------*/
if ((cl_cmd = (char *)malloc((strlen(cmd_line)+1)*sizeof(char))) == NULL)
{
display_error(30,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
if ((cl_param = (char *)malloc((strlen(cmd_line)+1)*sizeof(char))) == NULL)
{
display_error(30,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
/*---------------------------------------------------------------------*/
/* If [SET] LINENd is set to ON, split the line up into a number of */
/* individual commands. */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->linend_status
&& !equal("define",define_test,3))
{
command_delim[0] = CURRENT_VIEW->linend_value;
command_delim[1] = '\0';
num_commands = command_split(cmd_line,cmd,MAX_COMMANDS,command_delim,command_entered);
}
else
{
cmd[0] = command_entered;
num_commands = 1;
}
/*---------------------------------------------------------------------*/
/* For each command entered, split it up into command and params, and */
/* process it... */
/*---------------------------------------------------------------------*/
for (j=0;j<num_commands;j++)
{
valid_command = FALSE;
split_command(cmd[j],cl_cmd,cl_param);
/*---------------------------------------------------------------------*/
/* Here is where we could check for synonyms first. */
/*---------------------------------------------------------------------*/
if (!command_only)
; /* get synonym for entered command */
/*---------------------------------------------------------------------*/
/* Look up the command in the command array in command.h */
/*---------------------------------------------------------------------*/
for (i=0;command[i].text != NULL;i++)
{
/*---------------------------------------------------------------------*/
/* If no command text, continue. */
/*---------------------------------------------------------------------*/
if (strcmp(command[i].text,"") == 0)
continue;
rc = RC_OK;
/*---------------------------------------------------------------------*/
/* Check that the supplied command matches the command for the length */
/* of the command and that the length is at least as long as the */
/* necessary significance. */
/*---------------------------------------------------------------------*/
if (equal(command[i].text,cl_cmd,command[i].min_len)
&& command[i].min_len != 0
&& !command[i].sos_command)
{
if (in_profile
&& !command[i].valid_profile_command)
{
display_error(24,command[i].text);
lastrc = rc = RC_INVALID_ENVIRON;
break;
}
valid_command = TRUE;
/*---------------------------------------------------------------------*/
/* Here is a big kludge. Because only a few commands need leading */
/* spaces to be present in temp_params and all other commands barf at */
/* leading spaces, we need to left truncate temp_params for most */
/* commands. */
/*---------------------------------------------------------------------*/
if (command[i].strip_param)
{
pos = strzne(cl_param,' ');
if (pos == (-1))
pos = 0;
}
else
pos = 0;
/*---------------------------------------------------------------------*/
/* Now call the function associated with the supplied command string */
/* and the possibly stripped parameters. */
/*---------------------------------------------------------------------*/
lastrc = rc = (*command[i].function)(cl_param+pos);
break;
}
}
/*---------------------------------------------------------------------*/
/* If an error occurred while executing a command above, break. */
/*---------------------------------------------------------------------*/
if (rc != RC_OK
&& rc != RC_TOF_EOF_REACHED)
break;
/*---------------------------------------------------------------------*/
/* If we found and successfully executed a command above, process the */
/* next command. */
/*---------------------------------------------------------------------*/
if (valid_command)
continue;
/*---------------------------------------------------------------------*/
/* To get here the command was not a 'command'. */
/*---------------------------------------------------------------------*/
num_lines = valid_target(cl_cmd,get_true_line());
/*---------------------------------------------------------------------*/
/* If TARGET_NOT_FOUND error, then the 'command' was a valid target but*/
/* the target could not be found. continue or break ???????? */
/*---------------------------------------------------------------------*/
if (num_lines == TARGET_NOT_FOUND)
{
display_error(17,(char *)command_entered);
lastrc = rc = RC_TARGET_NOT_FOUND;
continue;
}
/*---------------------------------------------------------------------*/
/* If not TARGET_ERROR, execute Next commnad. */
/*---------------------------------------------------------------------*/
if (num_lines != TARGET_ERROR)
{
char n[PREFIX_WIDTH+1];
sprintf(n,"%-ld",num_lines);
lastrc = rc = Next(n);
continue;
}
/*---------------------------------------------------------------------*/
/* If return is TARGET_ERROR, check if command is OS command... */
/*---------------------------------------------------------------------*/
if (cmd[j][0] == '!')
{
strcpy(command_entered,cmd[j]);
lastrc = rc = Os(command_entered+1);
continue;
}
/*---------------------------------------------------------------------*/
/* ...or if command is a macro command (as long as IMPMACRO is ON) and */
/* command_only is FALSE... */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->imp_macro
&& !command_only)
{
strcpy(command_entered,cmd[j]);
if (CURRENT_VIEW->imp_os)
{
rc = execute_macro(command_entered,FALSE);
if (rc != RC_FILE_NOT_FOUND)
{
lastrc = rc;
continue;
}
}
else
{
rc = execute_macro(command_entered,TRUE);
if (rc == RC_FILE_NOT_FOUND)
{
lastrc = rc = RC_NOT_COMMAND;
break;
}
else
{
lastrc = rc;
continue;
}
}
}
/*---------------------------------------------------------------------*/
/* ...or if command is an OS command (as long as IMPOS is ON). */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->imp_os)
{
strcpy(command_entered,cmd[j]);
rc = Os(command_entered);
}
else
{
display_error(21,cmd[j]);
rc = RC_NOT_COMMAND;
}
/*---------------------------------------------------------------------*/
/* If the 'command' is not a command then do not process any more. */
/*---------------------------------------------------------------------*/
lastrc = rc;
if (rc == RC_NOT_COMMAND)
break;
}
cleanup_command_line();
free(command_entered);
free(cl_cmd);
free(cl_param);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/***********************************************************************/
#ifdef PROTO
void cleanup_command_line(void)
#else
void cleanup_command_line()
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern char *cmd_rec;
extern unsigned short cmd_rec_len;
extern char in_macro;
/*--------------------------- local data ------------------------------*/
register int i;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:cleanup_command_line");
#endif
if (in_profile || in_macro || number_of_views == 0)
{
#ifdef TRACE
trace_return();
#endif
return;
}
if (clear_command)
{
wmove(CURRENT_WINDOW_COMMAND,0,0);
my_wclrtoeol(CURRENT_WINDOW_COMMAND);
memset(cmd_rec,' ',COLS);
cmd_rec_len = 0;
}
wmove(CURRENT_WINDOW_COMMAND,0,0);
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef PROTO
void split_command(char *cmd_line,char *cmd,char *param)
#else
void split_command(cmd_line,cmd,param)
char *cmd_line,*cmd,*param;
#endif
/***********************************************************************/
/*---------------------------------------------------------------------*/
{
/*--------------------------- local data ------------------------------*/
short pos;
char *param_ptr;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:split_command");
#endif
strcpy(cmd,cmd_line);
strtrunc(cmd);
if ((param_ptr = (char *)strpbrk(cmd," \\/-+@")) == NULL)
{
strcpy(param,"");
#ifdef TRACE
trace_return();
#endif
return;
}
pos = strzne(param_ptr,' ');
if (param_ptr == cmd
|| pos == (-1))
{
strcpy(param,"");
#ifdef TRACE
trace_return();
#endif
return;
}
strcpy(param,param_ptr+(*(param_ptr) == ' ' ? 1 : 0));
*(param_ptr) = '\0';
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef PROTO
int param_split(char *params,char *word[],int words,
char *delims,char param_type)
#else
int param_split(params,word,words,delims,param_type)
char *params;
char *word[];
int words;
char *delims;
char param_type;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i,k;
unsigned short len;
char j;
bool end_of_string,end_of_word;
char *param_ptr;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:param_split");
#endif
/*---------------------------------------------------------------------*/
/* Allocate some memory to the temporary area. */
/*---------------------------------------------------------------------*/
if (params != (char *)NULL)
{
if (allocate_temp_space(strlen(params),param_type) != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return(-1);
}
}
/*---------------------------------------------------------------------*/
/* Based on param_type, point param_ptr to appropriate buffer. */
/*---------------------------------------------------------------------*/
switch(param_type)
{
case TEMP_PARAM:
param_ptr = temp_params;
break;
case TEMP_MACRO:
param_ptr = temp_macros;
break;
case TEMP_TEMP_CMD:
param_ptr = temp_cmd;
break;
default:
return(-1);
break;
}
/*---------------------------------------------------------------------*/
/* In case params is NULL, copy an empty string into param_ptr... */
/*---------------------------------------------------------------------*/
if (params == (char *)NULL)
strcpy(param_ptr,"");
else
strcpy(param_ptr,params);
for (i=0;i<words;i++)
word[i] = (char *)"";
j = 0;
end_of_string = YES;
len = strlen(param_ptr);
for (i=0;i<len && j<words;i++)
{
end_of_word = FALSE;
for (k=0;k<strlen(delims);k++)
{
if (*(param_ptr+i) == *(delims+k))
end_of_word = TRUE;
}
if (end_of_word)
{
*(param_ptr+i) = '\0';
end_of_string = YES;
}
else
if (end_of_string == YES)
{
word[j++] = param_ptr+i;
end_of_string = NO;
}
}
#ifdef TRACE
trace_return();
#endif
return(j);
}
/***********************************************************************/
#ifdef PROTO
int command_split(char *params,char *word[],int words,
char *delims,char *buffer)
#else
int command_split(params,word,words,delims,buffer)
char *params;
char *word[];
int words;
char *delims;
char *buffer;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i,k;
unsigned short len;
char j;
bool end_of_string,end_of_word;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:command_split");
#endif
/*---------------------------------------------------------------------*/
/* In case params is NULL, copy an empty string into buffer... */
/*---------------------------------------------------------------------*/
if (params == (char *)NULL)
strcpy(buffer,"");
else
strcpy(buffer,params);
for (i=0;i<words;i++)
word[i] = (char *)"";
j = 0;
end_of_string = YES;
len = strlen(buffer);
for (i=0;i<len && j<words;i++)
{
end_of_word = FALSE;
for (k=0;k<strlen(delims);k++)
{
if (*(buffer+i) == *(delims+k))
end_of_word = TRUE;
}
if (end_of_word)
{
*(buffer+i) = '\0';
end_of_string = YES;
}
else
if (end_of_string == YES)
{
word[j++] = buffer+i;
end_of_string = NO;
}
}
#ifdef TRACE
trace_return();
#endif
return(j);
}
/***********************************************************************/
#ifdef PROTO
long valid_target(char *target,long true_line)
#else
long valid_target(target,true_line)
char *target;
long true_line;
#endif
/***********************************************************************/
/*---------------------------------------------------------------------*/
/* This returns TARGET_ERROR if the target value is invalid. Otherwise */
/* it returns the number of lines to the target from the 'true_line'. */
/*---------------------------------------------------------------------*/
{
/*--------------------------- local data ------------------------------*/
long num_target;
register int i;
LINE *curr;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:valid_target");
#endif
/*---------------------------------------------------------------------*/
/* Check for 'ALL'. This means from first line to last line. */
/*---------------------------------------------------------------------*/
if (equal((char *)"all",target,3))
{
#ifdef TRACE
trace_return();
#endif
return(CURRENT_FILE->number_lines);
}
/*---------------------------------------------------------------------*/
/* Check for 'BLOCK'. This just returns 0 so that BLOCK is valid. */
/*---------------------------------------------------------------------*/
if (equal((char *)"block",target,5))
{
#ifdef TRACE
trace_return();
#endif
return(0);
}
/*---------------------------------------------------------------------*/
/* Check for named line; target beginning with '.' and 2nd char is */
/* alphabetic. */
/*---------------------------------------------------------------------*/
if (*(target) == '.' && isalpha(*(target+1)))
{
if ((curr = find_named_line(target,&num_target)) == (LINE *)NULL)
{
#ifdef TRACE
trace_return();
#endif
return(TARGET_NOT_FOUND);
}
if (num_target >= true_line)
num_target = min((num_target - true_line),
(CURRENT_FILE->number_lines - true_line+1));
else
num_target = (true_line - num_target)*(-1);
#ifdef TRACE
trace_return();
#endif
return(num_target);
}
/*---------------------------------------------------------------------*/
/* Check for '*'. This means to the end of file. */
/*---------------------------------------------------------------------*/
if (*(target) == '*')
{
#ifdef TRACE
trace_return();
#endif
return(CURRENT_FILE->number_lines - true_line+1);
}
/*---------------------------------------------------------------------*/
/* Check for '-*'. This means to the top of file. */
/*---------------------------------------------------------------------*/
if (strncmp(target,"-*",2) == 0)
{
#ifdef TRACE
trace_return();
#endif
return(true_line*(-1));
}
/*---------------------------------------------------------------------*/
/* Check for search targets. These are delimited by one of '/\@' and */
/* may be positive or negative. */
/*---------------------------------------------------------------------*/
for (i=0;i<NUMBER_SEARCH_TARGETS;i++)
if (strncmp(target,st[i].prefix,st[i].length) == 0)
{
/*---------------------------------------------------------------------*/
/* Save valid target for later retrieval. */
/*---------------------------------------------------------------------*/
if (strcmp(target+st[i].length,"") != 0)
strcpy(last_target,target);
num_target = search_target((target+st[i].length),st[i].delim,
true_line,st[i].direction);
#ifdef TRACE
trace_return();
#endif
return(num_target);
}
/*---------------------------------------------------------------------*/
/* Check for ':' or ';' - absolute line number target. */
/*---------------------------------------------------------------------*/
if (*(target) == ':'
|| *(target) == ';')
{
target++;
if (!valid_integer(target))
{
#ifdef TRACE
trace_return();
#endif
return(TARGET_ERROR);
}
num_target = atol(target);
if (num_target < 0L) /* invalid if negative */
{
#ifdef TRACE
trace_return();
#endif
return(TARGET_ERROR);
}
if (num_target >= true_line)
num_target = min((num_target - true_line),
(CURRENT_FILE->number_lines - true_line+1));
else
num_target = (true_line - num_target)*(-1);
#ifdef TRACE
trace_return();
#endif
return(num_target);
}
/*---------------------------------------------------------------------*/
/* Lastly, check for valid integers, +ve or -ve. */
/*---------------------------------------------------------------------*/
if (!valid_integer(target))
{
#ifdef TRACE
trace_return();
#endif
return(TARGET_ERROR);
}
num_target = atol(target);
if (num_target >= 0)
num_target = min(num_target,(CURRENT_FILE->number_lines - true_line+1));
else
num_target = max((num_target),(true_line == 0) ? (0) : (int)(true_line*(-1)));
#ifdef TRACE
trace_return();
#endif
return(num_target);
}
/***********************************************************************/
#ifdef PROTO
long get_true_line(void)
#else
long get_true_line()
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
/*--------------------------- local data ------------------------------*/
long true_line;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:get_true_line");
#endif
/*---------------------------------------------------------------------*/
/* Determine 'true_line'. */
/*---------------------------------------------------------------------*/
if (in_profile)
true_line = CURRENT_VIEW->current_line;
else
if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
true_line = CURRENT_VIEW->current_line;
else
true_line = CURRENT_VIEW->focus_line;
#ifdef TRACE
trace_return();
#endif
return(true_line);
}
/***********************************************************************/
#ifdef PROTO
LINE *find_named_line(char *name,long *retline)
#else
LINE *find_named_line(name,retline)
char *name;
long *retline;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
long lineno=0;
LINE *curr;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:find_named_line");
#endif
/*---------------------------------------------------------------------*/
/* Find the line number in the current file of the named line specified*/
/*---------------------------------------------------------------------*/
curr = CURRENT_FILE->first_line;
while(curr->next != (LINE *)NULL)
{
if (curr->name != (char *)NULL)
if (strcmp(curr->name,name) == 0)
{
#ifdef TRACE
trace_return();
#endif
*retline = lineno;
return(curr);
}
lineno++;
curr = curr->next;
}
#ifdef TRACE
trace_return();
#endif
return((LINE *)NULL);
}
/***********************************************************************/
#ifdef PROTO
long search_target(char *target,char delim,
long true_line,int direction)
#else
long search_target(target,delim,true_line,direction)
char *target;
char delim;
long true_line;
int direction;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
short start_col=0;
long rc;
int len_target;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:search_target");
#endif
if (*(target+strlen(target)-1) == delim)
*(target+strlen(target)-1) = '\0';
if (CURRENT_VIEW->hex == ON)
{
if ((len_target = convert_hex_strings(target)) == (-1))
{
display_error(32,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
}
else
len_target = strlen(target);
rc = find_string(true_line,&start_col,target,len_target,
direction,direction,CURRENT_VIEW->case_locate);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/***********************************************************************/
#ifdef PROTO
int get_row_for_focus_line(int cr,long fl,long cl)
#else
int get_row_for_focus_line(cr,fl,cl)
int cr;
long fl,cl;
#endif
/***********************************************************************/
/*---------------------------------------------------------------------*/
/* Returns the row within the main window where the focus line is */
/* placed. If the focus line is off the screen, or out of bounds of the*/
/* current size of the file; <0 or >number_lines, this returns the */
/* current row. */
/*---------------------------------------------------------------------*/
{
/*--------------------------- local data ------------------------------*/
register int row;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:get_row_for_focus_line");
#endif
row = (cr + (int)(fl - cl));
if (fl <= row)
{
#ifdef TRACE
trace_return();
#endif
return(row);
}
if (row < 0 || row > min(CURRENT_SCREEN.rows - 1,CURRENT_FILE->number_lines+1))
{
#ifdef TRACE
trace_return();
#endif
return(cr);
}
#ifdef TRACE
trace_return();
#endif
return(row);
}
/***********************************************************************/
#ifdef PROTO
int calculate_focus_line(int cr,long fl,long cl)
#else
int calculate_focus_line(cr,fl,cl)
int cr;
long fl,cl;
#endif
/***********************************************************************/
/*---------------------------------------------------------------------*/
/* Returns the new focus line. If the focus line is still in the */
/* window, it stays as is. If not,the focus line becomes the current */
/* line. */
/*---------------------------------------------------------------------*/
{
/*--------------------------- local data ------------------------------*/
register int max_top,max_bot;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:calculate_focus_line");
#endif
max_top = max(0,cl-CURRENT_VIEW->current_row);
max_bot = min(CURRENT_FILE->number_lines+1,
cl+(CURRENT_SCREEN.rows - CURRENT_VIEW->current_row)-1);
if (fl >= max_top && fl <= max_bot)
{
#ifdef TRACE
trace_return();
#endif
return(fl);
}
#ifdef TRACE
trace_return();
#endif
return(cl);
}
/***********************************************************************/
#ifdef PROTO
void print_line(char close_spooler,long num_lines,short pagesize,
char *text,char *line_term,bool all)
#else
void print_line(close_spooler,num_lines,pagesize,text,line_term,all)
char close_spooler;
long num_lines;
short pagesize;
char *text;
char *line_term;
bool all;
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
#if defined(UNIX) || defined(OS2)
extern char *spooler_name;
#endif
/*--------------------------- local data ------------------------------*/
#if defined(UNIX) || defined(OS2)
static char spooler_open=NO;
#ifdef OS2
HFILE Lpt;
#ifdef __32BIT__
ULONG Action;
ULONG NoWritten;
#else
USHORT Action;
USHORT NoWritten;
#endif
#endif
#endif
static FILE *pp;
register int i;
long j,true_line;
LINE *curr;
char c;
unsigned short line_number=0;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:print_line");
#endif
#if defined(DOS)
pp = stdprn;
#endif
#if defined(UNIX) || defined(OS2)
if (close_spooler == YES)
{
if (spooler_open == YES)
{
spooler_open = NO;
#if defined(OS2)
DosClose(Lpt);
#else
pclose(pp);
#endif
}
#ifdef TRACE
trace_return();
#endif
return;
}
#endif
#if defined(UNIX)
if (spooler_open == NO)
{
pp = popen(spooler_name,"w");
spooler_open = YES;
}
#endif
#if defined(OS2)
if (spooler_open == NO)
{
#ifdef __32BIT__
if (DosOpen(spooler_name, &Lpt, &Action, 0,FILE_NORMAL,FILE_OPEN,
OPEN_ACCESS_READWRITE|OPEN_SHARE_DENYNONE,(PEAOP2)NULL) != 0)
#else
if (DosOpen(spooler_name, &Lpt, &Action, 0,FILE_NORMAL,FILE_OPEN,
OPEN_ACCESS_WRITEONLY|OPEN_SHARE_DENYWRITE,NULL) != 0)
#endif
{
#ifdef TRACE
trace_return();
#endif
return;
}
spooler_open = YES;
}
#endif
if (num_lines == 0L)
{
#if defined(OS2)
DosWrite(Lpt,text,strlen(text),&NoWritten);
#else
fprintf(pp,"%s%s",text,line_term);
#endif
#ifdef TRACE
trace_return();
#endif
return;
}
/*---------------------------------------------------------------------*/
/* Determine where to start writing from in the linked list. */
/* If target is ALL, start with first line... */
/* If on command line or in profile, use current_line... */
/* Else, use focus line. */
/*---------------------------------------------------------------------*/
if (all)
true_line = 1;
else
true_line = get_true_line();
#ifdef USE_VOID
curr = (LINE *)ll_find((void *)CURRENT_FILE->first_line,true_line);
#else
curr = lll_find(CURRENT_FILE->first_line,true_line);
#endif
/*---------------------------------------------------------------------*/
/* Now write out the contents of the file array to the printer. */
/*---------------------------------------------------------------------*/
for (j=0L;j<num_lines && curr->next != NULL;j++)
{
if (curr->prev != NULL) /* not first line */
{
#if defined(OS2)
DosWrite(Lpt,curr->line,curr->length,&NoWritten);
DosWrite(Lpt,line_term,strlen(line_term),&NoWritten);
#else
for (i=0;i<curr->length;i++)
fputc(*(curr->line+i) & A_CHARTEXT,pp);
fprintf(pp,"%s",line_term);
#endif
line_number++;
if (line_number == pagesize
&& pagesize != 0)
{
#if defined(OS2)
DosWrite(Lpt,"\f",1,&NoWritten);
#else
fputc('\f',pp);
#endif
line_number = 0;
}
}
curr = curr->next;
}
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef PROTO
char next_char(LINE *curr,short *off,int end_col)
#else
char next_char(curr,off,end_col)
LINE *curr;
short *off;
int end_col;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:next_char");
#endif
if (*(off) < min(curr->length,end_col))
{
(*(off))++;
#ifdef TRACE
trace_return();
#endif
return(*(curr->line+((*(off))-1)));
}
*(off) = (-1);
#ifdef TRACE
trace_return();
#endif
return(0);
}
/***********************************************************************/
#ifdef PROTO
int add_define(int key_value,char *commands)
#else
int add_define(key_value,commands)
int key_value;
char *commands;
#endif
/***********************************************************************/
/* Parameters: */
/* key_value: numeric representation of function key */
/* commands: commands and parameters */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int j;
short cmd_nr;
char *word[MAX_COMMANDS+1];
unsigned short num_commands;
char command_delim[2];
int rc;
char *command_entered,*cl_cmd,*cl_param;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:add_define");
#endif
/*---------------------------------------------------------------------*/
/* First thing is to delete any definitions that may exist for the */
/* supplied key_value; */
/*---------------------------------------------------------------------*/
remove_define(key_value);
/*---------------------------------------------------------------------*/
/* If the commands argument is empty, then we have already deleted any */
/* definitions for the key, so just return. */
/*---------------------------------------------------------------------*/
if (strcmp(commands,"") == 0)
{
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/*---------------------------------------------------------------------*/
/* Copy the incoming commands, so we can play with it. */
/*---------------------------------------------------------------------*/
if ((command_entered = strdup(commands)) == NULL)
{
display_error(30,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
/*---------------------------------------------------------------------*/
/* Allocate some space to cl_cmd and cl_param for the a command when */
/* it is split into a command and its parameters. */
/*---------------------------------------------------------------------*/
if ((cl_cmd = (char *)malloc((strlen(commands)+1)*sizeof(char))) == NULL)
{
display_error(30,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
if ((cl_param = (char *)malloc((strlen(commands)+1)*sizeof(char))) == NULL)
{
display_error(30,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
/*---------------------------------------------------------------------*/
/* If [SET] LINENd is set to ON, split the args up into a number of */
/* individual commands. */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->linend_status)
{
command_delim[0] = CURRENT_VIEW->linend_value;
command_delim[1] = '\0';
num_commands = command_split(commands,word,MAX_COMMANDS,command_delim,command_entered);
}
else
{
word[0] = command_entered;
num_commands = 1;
}
/*---------------------------------------------------------------------*/
/* For each command entered, split it up into command and params, and */
/* process it... */
/*---------------------------------------------------------------------*/
for (j=0;j<num_commands;j++)
{
split_command(word[j],cl_cmd,cl_param);
if ((cmd_nr = find_command(cl_cmd)) == (-1))
{
display_error(21,cl_cmd);
rc = RC_INVALID_OPERAND;
break;
}
if ((rc = append_define(key_value,cmd_nr,cl_param)) != RC_OK)
break;
}
free(command_entered);
free(cl_cmd);
free(cl_param);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/***********************************************************************/
#ifdef PROTO
int remove_define(int key_value)
#else
int remove_define(key_value)
int key_value;
#endif
/***********************************************************************/
/* Parameters: */
/* key_value: numeric representation of function key */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
DEFINE *curr;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:remove_define");
#endif
/*---------------------------------------------------------------------*/
/* Find all items in the linked list for the key_value and remove them */
/* from the list. */
/*---------------------------------------------------------------------*/
curr = first_define;
while(curr != NULL)
{
if (curr->def_funkey == key_value)
{
if (curr->def_params != NULL)
free(curr->def_params);
#ifdef USE_VOID
curr = (DEFINE *)ll_del((void *)first_define,(void *)curr,DIRECTION_FORWARD);
#else
curr = dll_del(&first_define,&last_define,curr,DIRECTION_FORWARD);
#endif
}
else
curr = curr->next;
}
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
int append_define(int key_value,int cmd,char *prm)
#else
int append_define(key_value,cmd,prm)
int key_value,cmd;
char *prm;
#endif
/***********************************************************************/
/* Parameters: */
/* key_value: numeric representation of function key */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
DEFINE *curr,*next;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:append_define");
#endif
/*---------------------------------------------------------------------*/
/* Find all items in the linked list for the key_value and remove them */
/* from the list. */
/*---------------------------------------------------------------------*/
#ifdef USE_VOID
curr = (DEFINE *)ll_add((void *)first_define,(void *)last_define,sizeof(DEFINE));
#else
curr = dll_add(first_define,last_define,sizeof(DEFINE));
#endif
if (curr == NULL)
{
display_error(30,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
curr->def_params = (char *)malloc((strlen(prm)+1)*sizeof(char));
if (curr->def_params == NULL)
{
display_error(30,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
strcpy(curr->def_params,prm);
curr->def_funkey = key_value;
curr->def_command = cmd;
curr->def_delim = CURRENT_VIEW->linend_value;
last_define = curr;
if (first_define == NULL)
first_define = last_define;
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
int find_key_value(char *mnemonic)
#else
int find_key_value(mnemonic)
char *mnemonic;
#endif
/***********************************************************************/
/* Function: find the matching key value for the supplied key name */
/* Parameters: */
/* mnemonic: the key name to be matched */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register short i;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:find_key_value");
#endif
for (i=0;i<MAX_NUMBER_KEYS;i++)
if (strcmp(mnemonic,key_table[i].mnemonic) == 0)
{
#ifdef TRACE
trace_return();
#endif
return(key_table[i].key_value);
}
#ifdef TRACE
trace_return();
#endif
return(-1);
}
/***********************************************************************/
#ifdef PROTO
short find_command(char *cmd)
#else
short find_command(cmd)
char *cmd;
#endif
/***********************************************************************/
/* Function: determine if the string supplied is a valid abbrev for */
/* a command. */
/* Parameters: */
/* cmd: the string to be matched */
/* prm: any parameters (only used if target supplied) */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register short i;
long num_lines;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:find_command");
#endif
for (i=0;command[i].text != NULL;i++)
if (equal(command[i].text,cmd,(command[i].min_len == 0) ? strlen(command[i].text) : command[i].min_len)
&& !command[i].sos_command)
{
#ifdef TRACE
trace_return();
#endif
return(i);
}
/*---------------------------------------------------------------------*/
/* To get here the command was not a 'command'. */
/*---------------------------------------------------------------------*/
num_lines = valid_target(cmd,get_true_line());
/*---------------------------------------------------------------------*/
/* If not TARGET_ERROR, find 'LOCATE' command and set temp_params to */
/* cmd. */
/*---------------------------------------------------------------------*/
if (num_lines != TARGET_ERROR)
{
strcpy(temp_params,cmd);
for (i=0;command[i].text != NULL;i++)
{
if (strcmp(command[i].text,"locate") == 0)
break;
}
#ifdef TRACE
trace_return();
#endif
return(i);
}
#ifdef TRACE
trace_return();
#endif
return(-1);
}
/***********************************************************************/
#ifdef PROTO
short split_change_params(char *cmd_line,char *old_str,char *new_str,char *target,
char *num,char *occ)
#else
short split_change_params(cmd_line,old_str,new_str,target,num,occ)
char *cmd_line,*old_str,*new_str,*target,*num,*occ;
#endif
/***********************************************************************/
{
register short i;
short off1,off2,off3,eos_old,eos_new,target_start;
char cmmand_line[80],str3[20];
char *cmd=cmmand_line;
#define SPLT_PARAMS 3
char *word[SPLT_PARAMS];
char parm[SPLT_PARAMS];
unsigned short num_params;
unsigned short x,y;
short rc;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:split_change_params");
#endif
strcpy(cmd,cmd_line);
for (i=0;i<NUMBER_SEARCH_TARGETS;i++)
if (*(cmd) == st[i].delim)
break;
if (i == NUMBER_SEARCH_TARGETS)
{
#ifdef TRACE
trace_return();
#endif
return(-1);
}
/*---------------------------------------------------------------------*/
/* Obtain the old string to change. */
/*---------------------------------------------------------------------*/
if ((off1 = strzeq(cmd+1,st[i].delim)) == (-1))
{
#ifdef TRACE
trace_return();
#endif
return(-1);
}
eos_old = off1+1;
*(cmd+eos_old) = '\0';
strcpy(old_str,cmd+1);
/*---------------------------------------------------------------------*/
/* Obtain the new string to change to. */
/*---------------------------------------------------------------------*/
if ((off2 = strzeq(cmd+eos_old+1,st[i].delim)) == (-1))
{
#ifdef TRACE
trace_return();
#endif
return(-1);
}
eos_new = eos_old+off2+1;
*(cmd+eos_new) = '\0';
strcpy(new_str,cmd+eos_old+1);
/*---------------------------------------------------------------------*/
/* Determine if there are any more parameters. If not, then return with*/
/* parameters of 1,1,1. */
/*---------------------------------------------------------------------*/
off1 = strzne(cmd+eos_new+1,' ');
if (off1 == (-1))
{
strcpy(target,"1");
strcpy(num,"1");
strcpy(occ,"1");
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
target_start = eos_new+off1+1;
for (i=0;i<NUMBER_SEARCH_TARGETS;i++)
if (strncmp(cmd+target_start,st[i].prefix,st[i].length) == 0)
break;
if (i == NUMBER_SEARCH_TARGETS)
{ /* not a string target */
num_params = param_split(cmd+target_start,word,SPLT_PARAMS,WORD_DELIMS,TEMP_PARAM);
if (strcmp(word[0],"") == 0)
strcpy(target,"1");
else
strcpy(target,word[0]);
if (strcmp(word[1],"") == 0)
strcpy(num,"1");
else
strcpy(num,word[1]);
if (strcmp(word[2],"") == 0)
strcpy(occ,"1");
else
strcpy(occ,word[2]);
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/* to get here it is a valid start to a string target */
off1 = strzeq(cmd+target_start+st[i].length,st[i].delim);
if (off1 == (-1))
{
#ifdef TRACE
trace_return();
#endif
return(-1);
}
off2 = off1+1+st[i].length;
for (i=0;i<off2;i++)
str3[i] = *(cmd+target_start+i);
str3[off2] = '\0';
strcpy(target,str3);
num_params = param_split(cmd+target_start+off2+1,word,2,WORD_DELIMS,TEMP_PARAM);
if (strcmp(word[0],"") == 0)
strcpy(num,"1");
else
strcpy(num,word[0]);
if (strcmp(word[1],"") == 0)
strcpy(occ,"1");
else
strcpy(occ,word[1]);
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
void init_command(void)
#else
void init_command()
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:init_command");
#endif
for (i=0;i<MAX_CMDS;i++)
strcpy(cmd[i],"");
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef PROTO
void add_command(char *new_cmd)
#else
void add_command(new_cmd)
char *new_cmd;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:add_command");
#endif
offset_cmd = 0;
/*---------------------------------------------------------------------*/
/* If the command to be added is the same as the current command or if */
/* the command line is empty or if the command is "=", return without */
/* adding command to array. */
/*---------------------------------------------------------------------*/
if (strcmp(new_cmd,cmd[current_cmd]) == 0
|| strcmp(new_cmd,"") == 0
|| strcmp(new_cmd,"=") == 0)
{
#ifdef TRACE
trace_return();
#endif
return;
}
if (number_cmds == MAX_CMDS)
current_cmd = last_cmd = (last_cmd == MAX_CMDS-1) ? 0 : ++last_cmd;
else
current_cmd = ++last_cmd;
strcpy(cmd[current_cmd],new_cmd);
number_cmds++;
if (number_cmds > MAX_CMDS)
number_cmds = MAX_CMDS;
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef PROTO
char *get_next_command( int direction)
#else
char *get_next_command(direction)
int direction;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
char *cmd_to_return;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:get_next_command");
#endif
if (number_cmds == 0)
{
#ifdef TRACE
trace_return();
#endif
return((char *)NULL);
}
switch(direction)
{
case DIRECTION_BACKWARD:
if (current_cmd+1 == number_cmds)
{
current_cmd = 0;
cmd_to_return = cmd[current_cmd];
}
else
cmd_to_return = cmd[++current_cmd];
break;
case DIRECTION_FORWARD:
if (current_cmd+offset_cmd < 0)
{
current_cmd = number_cmds-1;
cmd_to_return = cmd[current_cmd];
}
else
{
current_cmd = current_cmd+offset_cmd;
cmd_to_return = cmd[current_cmd];
}
offset_cmd = (-1);
break;
case DIRECTION_NONE:
cmd_to_return = cmd[current_cmd];
break;
}
#ifdef TRACE
trace_return();
#endif
return(cmd_to_return);
}
/***********************************************************************/
#ifdef PROTO
int parse_colours(char *attrib,chtype *pfg,chtype *pbg,chtype *pmod)
#else
int parse_colours(attrib,pfg,pbg,pmod)
char *attrib;
chtype *pfg;
chtype *pbg;
chtype *pmod;
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
extern bool colour_support;
/*--------------------------- local data ------------------------------*/
struct attributes
{
char *attrib;
short attrib_min_len;
chtype actual_attrib;
bool attrib_modifier;
bool attrib_allowed_on_mono;
};
typedef struct attributes ATTRIBS;
#define NO_ATTRIBS 15
static ATTRIBS valid_attribs[NO_ATTRIBS]=
{
#ifdef A_COLOR
{(char *)"black",3,COLOR_BLACK,FALSE,FALSE},
{(char *)"blue",3,COLOR_BLUE,FALSE,FALSE},
{(char *)"green",1,COLOR_GREEN,FALSE,FALSE},
{(char *)"cyan",1,COLOR_CYAN,FALSE,FALSE},
{(char *)"red",3,COLOR_RED,FALSE,FALSE},
{(char *)"magenta",1,COLOR_MAGENTA,FALSE,FALSE},
{(char *)"yellow",1,COLOR_YELLOW,FALSE,FALSE},
{(char *)"white",1,COLOR_WHITE,FALSE,FALSE},
#else
{(char *)"black",3,A_BOLD,TRUE,FALSE},
{(char *)"blue",3,A_BOLD,TRUE,FALSE},
{(char *)"green",1,A_BOLD,TRUE,FALSE},
{(char *)"cyan",1,A_NORMAL,TRUE,FALSE},
{(char *)"red",3,A_BOLD,TRUE,FALSE},
{(char *)"magenta",1,A_NORMAL,TRUE,FALSE},
{(char *)"yellow",1,A_NORMAL,TRUE,FALSE},
{(char *)"white",1,A_NORMAL,TRUE,FALSE},
#endif
{(char *)"normal",3,A_NORMAL,TRUE,TRUE},
{(char *)"blink",3,A_BLINK,TRUE,TRUE},
{(char *)"bold",2,A_BOLD,TRUE,TRUE},
{(char *)"bright",3,A_BOLD,TRUE,TRUE},
{(char *)"high",1,A_BOLD,TRUE,TRUE},
{(char *)"reverse",3,A_REVERSE,TRUE,TRUE},
{(char *)"underline",1,A_UNDERLINE,TRUE,TRUE},
};
register int i;
int num_colours = 0;
chtype fg = (chtype)0;
chtype bg = (chtype)0;
chtype mod = (chtype)0;
char *p;
bool found;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:parse_colours");
#endif
p = (char *)strtok(attrib," ");
while(p != NULL)
{
found = FALSE;
for (i=0;i<NO_ATTRIBS;i++)
{
if (equal(valid_attribs[i].attrib,p,valid_attribs[i].attrib_min_len))
{
found = TRUE;
if (!valid_attribs[i].attrib_allowed_on_mono
&& !colour_support)
{
display_error(61,(char *)p);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
if (valid_attribs[i].attrib_modifier)
{
mod |= valid_attribs[i].actual_attrib;
break;
}
else
switch(num_colours)
{
case 0: fg = valid_attribs[i].actual_attrib;
num_colours++;
break;
case 1: bg = valid_attribs[i].actual_attrib;
num_colours++;
break;
default:display_error(1,(char *)p);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
break;
}
break;
}
}
if (!found)
{
display_error(1,(char *)p);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
p = (char *)strtok(NULL," ");
}
*pfg = fg;
*pbg = bg;
*pmod = mod;
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
void set_colour(int area,chtype fg,chtype bg,chtype mod)
#else
void set_colour(area,fg,bg,mod)
int area;
chtype fg;
chtype bg;
chtype mod;
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
extern bool colour_support;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:set_colour");
#endif
#ifdef A_COLOR
if (colour_support)
{
init_pair(area+1,fg,bg);
colour[area] = COLOR_PAIR(area+1) | mod;
}
else
colour[area] = mod;
#else
colour[area] = mod;
#endif
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef PROTO
int tabs_convert(LINE *curr,bool expand_tabs)
#else
int tabs_convert(curr,expand_tabs)
LINE *curr;
bool expand_tabs;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern char *rec;
extern char TABI_Nx;
/*--------------------------- local data ------------------------------*/
register int i,j;
bool expanded = FALSE;
int rc;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:tabs_convert");
#endif
/*---------------------------------------------------------------------*/
/* If we are expanding tabs to spaces, do the following... */
/*---------------------------------------------------------------------*/
if (expand_tabs)
{
for (i=0,j=0;i<curr->length;i++)
{
if (curr->line[i] == '\t')
{
do
{
rec[j++] = ' ';
if (j >= max_line_length)
break;
}
while ((j % TABI_Nx) != 0);
expanded = TRUE;
}
else
{
rec[j++] = curr->line[i];
if (j >= max_line_length)
break;
}
}
/*---------------------------------------------------------------------*/
/* If we expanded tabs, we need to reallocate memory for the line. */
/*---------------------------------------------------------------------*/
if (expanded)
{
curr->line = (char *)realloc((void *)curr->line,(j+1)*sizeof(char));
if (curr->line == (char *)NULL)
{
display_error(30,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
/*---------------------------------------------------------------------*/
/* Copy the contents of rec into the line. */
/*---------------------------------------------------------------------*/
memcpy(curr->line,rec,j);
curr->length = j;
*(curr->line+j) = '\0';
/*---------------------------------------------------------------------*/
/* Increment the number of alterations count. */
/*---------------------------------------------------------------------*/
if ((rc = increment_alt(CURRENT_FILE)) != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return(rc);
}
}
}
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
int convert_hex_strings(char *str)
#else
int convert_hex_strings(str)
char *str;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i=0;
char *p;
bool dec_char;
char temp_str[80];
int num;
char ch1,ch2;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:convert_hex_strings");
#endif
/*---------------------------------------------------------------------*/
/* Check if the string begins with d',D',x' or X'. If not return the */
/* string unchanged. */
/*---------------------------------------------------------------------*/
if ((*(str) == 'd'
|| *(str) == 'D'
|| *(str) == 'x'
|| *(str) == 'X')
&& *(str+1) == '\'')
;
else
{
#ifdef TRACE
trace_return();
#endif
return(strlen(str));
}
/*---------------------------------------------------------------------*/
/* Check if the last character is a single quote. If not return (-1) */
/* to indicate an error. */
/*---------------------------------------------------------------------*/
if (*(str+strlen(str)-1) != '\'')
{
#ifdef TRACE
trace_return();
#endif
return((-1));
}
/*---------------------------------------------------------------------*/
/* If we got here we can validate the contents of the string. */
/*---------------------------------------------------------------------*/
*(str+strlen(str)-1) = '\0';
if (*(str) == 'd'
|| *(str) == 'D')
dec_char = TRUE;
else
dec_char = FALSE;
p = (char *)strtok(str+2," ");
while(p != NULL)
{
switch(dec_char)
{
case TRUE: /* parse decimal number */
if (equal((char *)"000000",p,1))
temp_str[i++] = (char)0;
else
{
num = atoi(p);
if (num < 1 || num > 255)
{
#ifdef TRACE
trace_return();
#endif
return((-1));
}
temp_str[i++] = (char)num;
}
break;
case FALSE: /* parse hexidecimal number */
ch1 = *(p);
ch2 = *(p+1);
if (strlen(p) != 2
|| !isxdigit(ch1)
|| !isxdigit(ch2))
{
#ifdef TRACE
trace_return();
#endif
return((-1));
}
if (isupper(ch1)!=0)
ch1 = tolower(ch1);
if (isupper(ch2)!=0)
ch2 = tolower(ch2);
num = ((isdigit(ch1)!=0) ? ch1-48 : ch1-87) * 16;
num += ((isdigit(ch2)!=0) ? ch2-48 : ch2-87);
temp_str[i++] = (char)num;
break;
}
p = (char *)strtok(NULL," ");
}
/*
temp_str[i] = '\0';
memcpy(str,temp_str,i+1);
*/
memcpy(str,temp_str,i);
#ifdef TRACE
trace_return();
#endif
return(i);
}
/***********************************************************************/
#ifdef PROTO
int marked_block(bool in_current_view)
#else
int marked_block(in_current_view)
bool in_current_view;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:marked_block");
#endif
if (in_profile) /* block commands invalid in profile */
{
display_error(24,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_ENVIRON);
}
if (MARK_VIEW == (VIEW_DETAILS *)NULL) /* no marked block */
{
display_error(44,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_ENVIRON);
}
if (MARK_VIEW != CURRENT_VIEW /* marked block not in current view */
&& in_current_view)
{
display_error(45,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_ENVIRON);
}
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
int suspend_curses(void)
#else
int suspend_curses()
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:suspend_curses");
#endif
#ifdef UNIX
reset_shell_mode();
# ifdef BSD
noraw();
nl();
echo();
nocbreak();
# endif
#endif
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
int resume_curses(void)
#else
int resume_curses()
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:resume_curses");
#endif
#ifdef UNIX
reset_prog_mode();
# ifdef BSD
raw();
nonl();
noecho();
cbreak();
# endif
#endif
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
int restore_THE(void)
#else
int restore_THE()
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
unsigned short y,x;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:restore_THE");
#endif
getyx(CURRENT_WINDOW,y,x);
wclear(stdscr);
refresh();
if (CURRENT_VIEW->prefix)
touchwin(CURRENT_WINDOW_PREFIX);
touchwin(CURRENT_WINDOW_COMMAND);
touchwin(CURRENT_WINDOW_MAIN);
touchwin(CURRENT_WINDOW_IDLINE);
touchwin(foot);
wmove(CURRENT_WINDOW,y,x);
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
int execute_set_sos_command(bool set_command,char *params)
#else
int execute_set_sos_command(set_command,params)
bool set_command;
char *params;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i;
#define SETSOS_PARAMS 2
char *word[SETSOS_PARAMS+1];
unsigned short num_params;
int rc,command_index;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:execute_set_sos_command");
#endif
num_params = param_split(params,word,SETSOS_PARAMS,WORD_DELIMS,TEMP_PARAM);
if (num_params < 1)
{
display_error(1,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
if ((command_index = valid_command_type(set_command,word[0])) == RC_NOT_COMMAND)
{
display_error(set_command ? 42 : 41,word[0]);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
rc = (*command[command_index].function)(word[1]);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/***********************************************************************/
#ifdef PROTO
int valid_command_type(bool set_command,char *cmd_line)
#else
int valid_command_type(set_command,cmd_line)
bool set_command;
char *cmd_line;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:valid_command_type");
#endif
for (i=0;command[i].text != NULL;i++)
{
/*---------------------------------------------------------------------*/
/* If no command text, continue. */
/*---------------------------------------------------------------------*/
if (strcmp(command[i].text,"") == 0)
continue;
/*---------------------------------------------------------------------*/
/* Check that the supplied command matches the command for the length */
/* of the command and that the length is at least as long as the */
/* necessary significance. */
/*---------------------------------------------------------------------*/
if (equal(command[i].text,cmd_line,command[i].min_len)
&& command[i].min_len != 0)
{
#ifdef TRACE
trace_return();
#endif
if (set_command && command[i].set_command)
return(i);
if (!set_command && command[i].sos_command)
return(i);
}
}
#ifdef TRACE
trace_return();
#endif
return(RC_NOT_COMMAND);
}
/***********************************************************************/
#ifdef PROTO
int allocate_temp_space(unsigned int length,char param_type)
#else
int allocate_temp_space(length,param_type)
unsigned int length;
char param_type;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
char *temp_ptr;
unsigned int *temp_length;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:allocate_temp_space");
#endif
/*---------------------------------------------------------------------*/
/* Based on param_type, point param_ptr to appropriate buffer. */
/*---------------------------------------------------------------------*/
switch(param_type)
{
case TEMP_PARAM:
temp_ptr = temp_params;
temp_length = &length_temp_params;
break;
case TEMP_MACRO:
temp_ptr = temp_macros;
temp_length = &length_temp_macros;
break;
case TEMP_TMP_CMD:
temp_ptr = tmp_cmd;
temp_length = &length_tmp_cmd;
break;
case TEMP_TEMP_CMD:
temp_ptr = temp_cmd;
temp_length = &length_temp_cmd;
break;
default:
return(-1);
break;
}
if (*temp_length >= length)
{
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
if (temp_ptr == NULL)
temp_ptr = (char *)malloc(sizeof(char)*(length+1));
else
temp_ptr = (char *)realloc(temp_ptr,sizeof(char)*(length+1));
if (temp_ptr == NULL)
{
display_error(30,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
/*---------------------------------------------------------------------*/
/* Based on param_type, point param_ptr to appropriate buffer. */
/*---------------------------------------------------------------------*/
switch(param_type)
{
case TEMP_PARAM:
temp_params = temp_ptr;
break;
case TEMP_MACRO:
temp_macros = temp_ptr;
break;
case TEMP_TMP_CMD:
tmp_cmd = temp_ptr;
break;
case TEMP_TEMP_CMD:
temp_cmd = temp_ptr;
break;
default:
return(-1);
break;
}
*temp_length = length;
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
void free_temp_space(char param_type)
#else
void free_temp_space(param_type)
char param_type;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
char *temp_ptr;
unsigned int *temp_length;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:free_temp_space");
#endif
/*---------------------------------------------------------------------*/
/* Based on param_type, point param_ptr to appropriate buffer. */
/*---------------------------------------------------------------------*/
switch(param_type)
{
case TEMP_PARAM:
temp_ptr = temp_params;
temp_length = &length_temp_params;
break;
case TEMP_MACRO:
temp_ptr = temp_macros;
temp_length = &length_temp_macros;
break;
case TEMP_TMP_CMD:
temp_ptr = tmp_cmd;
temp_length = &length_tmp_cmd;
break;
case TEMP_TEMP_CMD:
temp_ptr = temp_cmd;
temp_length = &length_temp_cmd;
break;
default:
return;
break;
}
free(temp_ptr);
*temp_length = 0;
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef PROTO
char calculate_current_row(char base,char off,char rows)
#else
char calculate_current_row(base,off,rows)
char base,rows;
char off;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
int row;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:calculate_current_row");
#endif
switch(base)
{
case CURLINE_TOP:
row = off;
break;
case CURLINE_MIDDLE:
row = (rows /2 ) + off;
break;
case CURLINE_BOTTOM:
row = rows+off+1;
break;
}
/*---------------------------------------------------------------------*/
/* If the calculated row is outside the screen size, default to middle.*/
/*---------------------------------------------------------------------*/
if (row < 0 || row > rows)
row = rows / 2;
#ifdef TRACE
trace_return();
#endif
return((char)row-1);
}
/*man***************************************************************************
NAME
get_valid_macro_file_name
SYNOPSIS
int get_valid_macro_file_name(macroname,filename,errnum)
char *macroname;
char *filename;
int *errnum;
DESCRIPTION
The get_valid_macro_file_name function determines the fully qualified
file name for the supplied macroname.
If the macroname contains any path specifiers, then the macro name
is used as the filename and a check is made to ensure that the file
exists and is readable.
If the macroname does not contain any path specifiers, each
directory in the MACROPATH variable is searched for a file that
consists of the macroname appended with the current value for
MACROEXT. If a file is found, it is checked to ensure it is
readable.
RETURN VALUE
If a file is found based on the above matching process, the fully
qualified file name is copied into filename, errnum is set to 0
and the function returns with RC_OK.
If a file is not found, the macroname is copied into filename, the
error number of the error message is copied into errnum and the
function returns with RC_FILE_NOT_FOUND.
If a file is found but the file is not readable, the macroname is
copied into filename, the error number of the error message is
copied into errnum and the function returns with RC_ACCESS_DENIED.
*******************************************************************************/
#ifdef PROTO
int get_valid_macro_file_name(char *macroname,char *filename,int *errnum)
#else
int get_valid_macro_file_name(macroname,filename,errnum)
char *macroname,*filename;
int *errnum;
#endif
/***********************************************************************/
{
#if defined(UNIX)
# define PATH_DELIM ":"
#else
# define PATH_DELIM ";"
#endif
/*-------------------------- external data ----------------------------*/
extern char the_macro_path[MAX_FILE_NAME+1] ;
extern char sp_path[MAX_FILE_NAME+1] ;
extern char sp_fname[MAX_FILE_NAME+1] ;
extern char macro_suffix[12];
/*--------------------------- local data ------------------------------*/
register int i;
char delims[3];
bool file_found;
char *path[MAX_MACRO_DIRS+1]; /* max number of macro dirs */
unsigned short num_params;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:get_valid_macro_file_name");
#endif
/*---------------------------------------------------------------------*/
/* Create the full name of the macro file by prepending the default */
/* macropath provided the filename does not already contain a path. */
/*---------------------------------------------------------------------*/
(void *)strtrans(macroname,OSLASH,ISLASH);
#ifdef UNIX
strcpy(delims,ISTR_SLASH);
if (strpbrk(macroname,delims) == NULL
&& *(macroname) != '~')
#endif
#if defined(DOS) || defined(OS2)
strcpy(delims,ISTR_SLASH);
strcat(delims,":");
if (strpbrk(macroname,delims) == NULL)
#endif
/*---------------------------------------------------------------------*/
/* The supplied macro file name does not contain a path...so for each */
/* directory in the_macro_path, try to find the supplied file in that */
/* directory. */
/*---------------------------------------------------------------------*/
{
strcpy(filename,the_macro_path);
num_params = param_split(filename,path,MAX_MACRO_DIRS,PATH_DELIM,TEMP_MACRO);
file_found = FALSE;
for (i=0;i<num_params;i++)
{
strcpy(filename,path[i]);
if (strlen(filename) == 0)
continue;
if (*(filename+strlen(filename)-1) != ISLASH)
strcat(filename,ISTR_SLASH);
strcat(filename,macroname); /* append the file name */
strcat(filename,macro_suffix); /* append default suffix */
if (file_exists(filename)) /* check if file exists... */
{
file_found = TRUE;
break;
}
}
if (!file_found)
{
strcpy(filename,macroname);
strcat(filename,macro_suffix);
*errnum = 11;
#ifdef TRACE
trace_return();
#endif
return(RC_FILE_NOT_FOUND);
}
}
else /* file contains a path specifier */
/*---------------------------------------------------------------------*/
/* The supplied macro file name does contain a path...so just check to */
/* ensure that the file exists. */
/*---------------------------------------------------------------------*/
{
if (splitpath(macroname) != RC_OK)
{
*errnum = 9;
#ifdef TRACE
trace_return();
#endif
return(RC_FILE_NOT_FOUND);
}
strcpy(filename,sp_path);
strcat(filename,sp_fname);
if (!file_exists(filename)
|| strcmp(sp_fname,"") == 0)
{
*errnum = 9;
#ifdef TRACE
trace_return();
#endif
return(RC_FILE_NOT_FOUND);
}
}
/*---------------------------------------------------------------------*/
/* If the file is not readable, error. */
/*---------------------------------------------------------------------*/
if (!file_readable(filename))
{
*errnum = 8;
#ifdef TRACE
trace_return();
#endif
return(RC_ACCESS_DENIED);
}
#ifdef TRACE
trace_return();
#endif
*errnum = 0;
return(RC_OK);
}