home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
the25.zip
/
thesrc251.zip
/
commutil.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-07-28
|
134KB
|
3,984 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-1997 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@qut.edu.au
* PO Box 203 Phone: +617 3802 0800
* Bellara http://www.gu.edu.au/gext/the/markh.html
* QLD 4507 **** Maintainer PDCurses & REXX/SQL ****
* Australia ************* Author of THE ************
*/
/*
$Id: commutil.c 2.1 1995/06/24 16:29:18 MH Rel MH $
*/
#include <the.h>
#include <proto.h>
#include <key.h>
#include <command.h>
#ifdef HAVE_PROTO
static CHARTYPE *build_defined_key_definition(int, CHARTYPE *,DEFINE *,bool);
static void save_last_command(CHARTYPE *,CHARTYPE *);
#else
static CHARTYPE *build_defined_key_definition();
static void save_last_command();
#endif
static CHARTYPE cmd_history[MAX_SAVED_COMMANDS][MAX_COMMAND_LENGTH];
static short last_cmd=(-1),current_cmd=0,number_cmds=0,offset_cmd=0;
CHARTYPE last_command_for_reexecute[MAX_COMMAND_LENGTH];
CHARTYPE last_command_for_repeat[MAX_COMMAND_LENGTH];
CHARTYPE last_change_command[MAX_COMMAND_LENGTH];
CHARTYPE last_target[MAX_COMMAND_LENGTH];
#define KEY_REDEF "/* Key re-definitions */"
#define KEY_DEFAULT "/* Default key definitions */"
#define KEY_MOUSE_REDEF "/* Mouse definitions */"
/*---------------------------------------------------------------------*/
/* 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 CHARTYPE *temp_params=NULL;
static unsigned short 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 CHARTYPE *temp_macros=NULL;
static unsigned short 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 CHARTYPE *tmp_cmd=NULL;
static unsigned short 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. */
/*---------------------------------------------------------------------*/
CHARTYPE *temp_cmd=NULL;
static unsigned short 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;
/*---------------------------------------------------------------------*/
/* The following two are to specify the first and last items in the */
/* linked list for mouse button defintions. */
/*---------------------------------------------------------------------*/
DEFINE *first_mouse_define=NULL;
DEFINE *last_mouse_define=NULL;
bool clear_command=TRUE;
/*---------------------------------------------------------------------*/
/* Key re-definition pseudo files. */
/*---------------------------------------------------------------------*/
LINE *key_first_line=NULL;
LINE *key_last_line=NULL;
LINETYPE key_number_lines=0L;
AREAS valid_areas[ATTR_MAX]=
{
{(CHARTYPE *)"FILEAREA",1,WINDOW_FILEAREA,TRUE},
{(CHARTYPE *)"CURLINE",2,WINDOW_FILEAREA,FALSE},
{(CHARTYPE *)"BLOCK",1,WINDOW_FILEAREA,FALSE},
{(CHARTYPE *)"CBLOCK",2,WINDOW_FILEAREA,FALSE},
{(CHARTYPE *)"CMDLINE",1,WINDOW_COMMAND,TRUE},
{(CHARTYPE *)"IDLINE",1,WINDOW_IDLINE,TRUE},
{(CHARTYPE *)"MSGLINE",1,WINDOW_ERROR,FALSE},
{(CHARTYPE *)"ARROW",1,WINDOW_ARROW,TRUE},
{(CHARTYPE *)"PREFIX",2,WINDOW_PREFIX,TRUE},
{(CHARTYPE *)"PENDING",1,WINDOW_PREFIX,FALSE},
{(CHARTYPE *)"SCALE",1,WINDOW_FILEAREA,FALSE},
{(CHARTYPE *)"TOFEOF",2,WINDOW_FILEAREA,FALSE},
{(CHARTYPE *)"CTOFEOF",2,WINDOW_FILEAREA,FALSE},
{(CHARTYPE *)"TABLINE",1,WINDOW_FILEAREA,FALSE},
{(CHARTYPE *)"SHADOW",2,WINDOW_FILEAREA,FALSE},
{(CHARTYPE *)"STATAREA",2,WINDOW_STATAREA,TRUE},
{(CHARTYPE *)"DIVIDER",1,WINDOW_DIVIDER,TRUE},
{(CHARTYPE *)"RESERVED",1,WINDOW_RESERVED,FALSE},
{(CHARTYPE *)"NONDISP",1,WINDOW_FILEAREA,FALSE},
{(CHARTYPE *)"HIGHLIGHT",2,WINDOW_FILEAREA,FALSE},
{(CHARTYPE *)"CHIGHLIGHT",3,WINDOW_FILEAREA,FALSE},
{(CHARTYPE *)"SLK",3,WINDOW_SLK,FALSE},
{(CHARTYPE *)"GAP",3,WINDOW_PREFIX,FALSE},
};
/***********************************************************************/
#ifdef HAVE_PROTO
CHARTYPE *get_key_name(int key)
#else
CHARTYPE *get_key_name(key)
int key;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register short i=0;
CHARTYPE *keyname=NULL;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:get_key_name");
#endif
/*---------------------------------------------------------------------*/
/* Get name of key... */
/*---------------------------------------------------------------------*/
for (i=0;key_table[i].mnemonic!=NULL;i++)
{
if (key == key_table[i].key_value)
{
keyname = key_table[i].mnemonic;
break;
}
}
#ifdef TRACE
trace_return();
#endif
return(keyname);
}
/***********************************************************************/
#ifdef HAVE_PROTO
CHARTYPE *get_key_definition(int key,bool define_format,bool default_keys,bool mouse_key)
#else
CHARTYPE *get_key_definition(key,define_format,default_keys,mouse_key)
int key;
bool define_format,default_keys,mouse_key;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register short i=0;
DEFINE *curr=NULL;
bool check_redefined=TRUE;
bool check_default=TRUE;
CHARTYPE *keyname=NULL;
CHARTYPE key_buf[50];
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:get_key_definition");
#endif
/*---------------------------------------------------------------------*/
/* First determine if the key is a named key. */
/*---------------------------------------------------------------------*/
if (mouse_key)
keyname = mouse_key_number_to_name(key,key_buf);
else
keyname = get_key_name(key);
/*---------------------------------------------------------------------*/
/* If key is invalid, show it as a character and decimal; provided it */
/* is an ASCII or extended character. */
/*---------------------------------------------------------------------*/
if (keyname == NULL)
{
if (define_format)
sprintf((DEFCHAR *)temp_cmd,"\"define \\%d ",key);
else
sprintf((DEFCHAR *)temp_cmd,"Key: \\%d",key);
}
else
{
if (define_format)
strcpy((DEFCHAR *)temp_cmd,"\"define ");
else
strcpy((DEFCHAR *)temp_cmd,"Key: ");
strcat((DEFCHAR *)temp_cmd,(DEFCHAR *)keyname);
}
if (mouse_key)
check_default = check_redefined = FALSE;
else
{
if (define_format)
{
check_default = (default_keys) ? TRUE : FALSE;
check_redefined = (default_keys) ? FALSE : TRUE;
}
}
/*---------------------------------------------------------------------*/
/* If we want to first check redefined keys... */
/*---------------------------------------------------------------------*/
if (check_redefined)
{
/*---------------------------------------------------------------------*/
/* Next check to see if the key has been "defined". */
/*---------------------------------------------------------------------*/
curr = first_define;
if (build_defined_key_definition(key,temp_cmd,curr,define_format) != (CHARTYPE *)NULL)
{
strcat((DEFCHAR *)temp_cmd,"\"");
#ifdef TRACE
trace_return();
#endif
return(temp_cmd);
}
}
/*---------------------------------------------------------------------*/
/* If not, check for the default function key values. */
/*---------------------------------------------------------------------*/
if (check_default)
{
for (i=0;command[i].text != NULL;i++)
{
if (key == command[i].funkey)
{
if (define_format)
strcat((DEFCHAR *)temp_cmd," ");
else
strcat((DEFCHAR *)temp_cmd," - assigned to \"");
build_default_key_definition(i,temp_cmd);
strcat((DEFCHAR *)temp_cmd,"\"");
#ifdef TRACE
trace_return();
#endif
return(temp_cmd);
}
}
}
/*---------------------------------------------------------------------*/
/* If we want to check mouse key definitions. */
/*---------------------------------------------------------------------*/
if (mouse_key)
{
/*---------------------------------------------------------------------*/
/* Next check to see if the key has been "defined". */
/*---------------------------------------------------------------------*/
curr = first_mouse_define;
if (build_defined_key_definition(key,temp_cmd,curr,define_format) != (CHARTYPE *)NULL)
{
strcat((DEFCHAR *)temp_cmd,"\"");
#ifdef TRACE
trace_return();
#endif
return(temp_cmd);
}
}
/*---------------------------------------------------------------------*/
/* If none of the above, it is unassigned. We should never get here if */
/* define_format is TRUE. */
/*---------------------------------------------------------------------*/
strcat((DEFCHAR *)temp_cmd," - unassigned");
#ifdef TRACE
trace_return();
#endif
return(temp_cmd);
}
/***********************************************************************/
#ifdef HAVE_PROTO
short function_key(int key,int option)
#else
short function_key(key,option)
int key;
int option;
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
extern CHARTYPE number_of_files;
extern CHARTYPE display_screens;
extern bool readonly;
/*--------------------------- local data ------------------------------*/
register short i=0;
DEFINE *curr=(DEFINE *)NULL;
DEFINE *first_save=(DEFINE *)NULL,*last_save=(DEFINE *)NULL;
short rc=RC_OK;
short len=0,num_cmds=0;
CHARTYPE *key_cmd=NULL;
CHARTYPE tmpnum[5];
short macrorc=0;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:function_key");
#endif
/*---------------------------------------------------------------------*/
/* First check to see if the function key has been redefined and save */
/* all key redefinitions. This is because we may be redefining a */
/* function key in the middle of its redefinition. eg ENTER key */
/*---------------------------------------------------------------------*/
curr = first_define;
while(curr != (DEFINE *)NULL)
{
if (key == curr->def_funkey)
{
rc = append_define(&first_save,&last_save,key,curr->def_command,curr->def_params);
if (rc != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return(rc);
}
}
curr = curr->next;
}
/*---------------------------------------------------------------------*/
/* Now we have saved any current definition of the function key, use */
/* these definitions to drive the following... */
/*---------------------------------------------------------------------*/
curr = first_save;
while(curr != (DEFINE *)NULL)
{
switch(option)
{
case OPTION_NORMAL:
/*---------------------------------------------------------------------*/
/* If running in read-only mode and the function selected is not valid */
/* display an error. */
/*---------------------------------------------------------------------*/
if (curr->def_command != (-1)
&& readonly
&& !command[curr->def_command].valid_in_readonly)
{
display_error(56,(CHARTYPE *)"",FALSE);
rc = RC_INVALID_ENVIRON;
curr = NULL;
break;
}
/*---------------------------------------------------------------------*/
/* If there are no more files in the ring, and the command is not a */
/* command to edit a new file, then ignore the command. */
/*---------------------------------------------------------------------*/
if (curr->def_command != (-1)
&& number_of_files == 0
&& !command[curr->def_command].edit_command)
{
rc = RC_OK;
curr = NULL;
break;
}
if ((key_cmd = (CHARTYPE *)my_strdup(curr->def_params)) == NULL)
{
display_error(30,(CHARTYPE *)"",FALSE);
rc = RC_OUT_OF_MEMORY;
curr = NULL;
break;
}
if (curr->def_command == (-1))
{
rc = execute_macro_instore(key_cmd,¯orc);
if (number_of_files > 0)
{
if (display_screens > 1)
{
build_screen(other_screen);
display_screen(other_screen);
}
build_screen(current_screen);
display_screen(current_screen);
}
}
else
rc = (*command[curr->def_command].function)((CHARTYPE *)key_cmd);
(*the_free)(key_cmd);
if (rc != RC_OK
&& rc != RC_TOF_EOF_REACHED
&& rc != RC_NO_LINES_CHANGED
&& rc != RC_TARGET_NOT_FOUND)
{
curr = NULL;
break;
}
break;
case OPTION_EXTRACT:
/*---------------------------------------------------------------------*/
/* If the request is to extract a keys commands, set a REXX variable */
/* for each command associated with the function key. */
/*---------------------------------------------------------------------*/
len = strlen((DEFCHAR *)command[curr->def_command].text) +
strlen((DEFCHAR *)curr->def_params) + 2;
if ((key_cmd = (CHARTYPE *)(*the_malloc)(len)) == NULL)
{
display_error(30,(CHARTYPE *)"",FALSE);
curr = NULL;
rc = RC_OUT_OF_MEMORY;
break;
}
strcpy((DEFCHAR *)key_cmd,(DEFCHAR *)command[curr->def_command].text);
strcat((DEFCHAR *)key_cmd," ");
strcat((DEFCHAR *)key_cmd,(DEFCHAR *)curr->def_params);
rc = set_rexx_variable((CHARTYPE *)"SHOWKEY",key_cmd,strlen((DEFCHAR *)key_cmd),++num_cmds);
(*the_free)(key_cmd);
break;
case OPTION_READV:
/*---------------------------------------------------------------------*/
/* If the key hit is KEY_ENTER, KEY_RETURN or KEY_NUMENTER, terminate */
/* the READV CMDLINE command. */
/*---------------------------------------------------------------------*/
if (key == KEY_RETURN
|| key == KEY_ENTER
|| key == KEY_C_m
|| key == KEY_NUMENTER)
{
rc = RC_READV_TERM;
curr = NULL;
break;
}
/*---------------------------------------------------------------------*/
/* If the command is not allowed in READV CMDLINE, or a REXX macro is */
/* assigned to the key, return with an error. */
/*---------------------------------------------------------------------*/
if (curr->def_command == (-1))
{
rc = RC_INVALID_ENVIRON;
curr = NULL;
break;
}
if (!command[curr->def_command].valid_readv)
{
rc = RC_INVALID_ENVIRON;
curr = NULL;
break;
}
/*---------------------------------------------------------------------*/
/* To get here, a valid READV CMDLINE command is present; execute it. */
/*---------------------------------------------------------------------*/
if ((key_cmd = (CHARTYPE *)my_strdup(curr->def_params)) == NULL)
{
display_error(30,(CHARTYPE *)"",FALSE);
rc = RC_OUT_OF_MEMORY;
curr = NULL;
break;
}
rc = (*command[curr->def_command].function)((CHARTYPE *)key_cmd);
(*the_free)(key_cmd);
if (rc != RC_OK
&& rc != RC_TOF_EOF_REACHED
&& rc != RC_NO_LINES_CHANGED
&& rc != RC_TARGET_NOT_FOUND)
{
curr = NULL;
break;
}
break;
default:
break;
}
if (curr == NULL)
break;
curr = curr->next;
}
/*---------------------------------------------------------------------*/
/* If the key has been redefined, exit here... */
/*---------------------------------------------------------------------*/
if (first_save)
{
if (option == OPTION_EXTRACT)
{
sprintf((DEFCHAR *)tmpnum,"%d",num_cmds);
rc = set_rexx_variable((CHARTYPE *)"SHOWKEY",tmpnum,strlen((DEFCHAR *)tmpnum),0);
rc = num_cmds;
}
dll_free(first_save);
#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)
{
switch(option)
{
case OPTION_NORMAL:
/*---------------------------------------------------------------------*/
/* If running in read-only mode and the function selected is not valid */
/* display an error. */
/*---------------------------------------------------------------------*/
if (readonly && !command[i].valid_in_readonly)
{
display_error(56,(CHARTYPE *)"",FALSE);
rc = RC_INVALID_ENVIRON;
break;
}
if ((key_cmd = (CHARTYPE *)my_strdup(command[i].params)) == NULL)
{
display_error(30,(CHARTYPE *)"",FALSE);
rc = RC_OUT_OF_MEMORY;
break;
}
rc = (*command[i].function)((CHARTYPE *)key_cmd);
(*the_free)(key_cmd);
break;
case OPTION_EXTRACT:
len = strlen((DEFCHAR *)command[i].text) +
strlen((DEFCHAR *)command[i].params) + 10;
if ((key_cmd = (CHARTYPE *)(*the_malloc)(len)) == NULL)
{
display_error(30,(CHARTYPE *)"",FALSE);
rc = RC_OUT_OF_MEMORY;
break;
}
strcpy((DEFCHAR *)key_cmd,"");
key_cmd = build_default_key_definition(i,key_cmd);
rc = set_rexx_variable((CHARTYPE *)"SHOWKEY",key_cmd,strlen((DEFCHAR *)key_cmd),1);
(*the_free)(key_cmd);
rc = set_rexx_variable((CHARTYPE *)"SHOWKEY",(CHARTYPE *)"1",1,0);
break;
case OPTION_READV:
/*---------------------------------------------------------------------*/
/* If the key hit is KEY_ENTER, KEY_RETURN or KEY_NUMENTER, terminate */
/* the READV CMDLINE command. */
/*---------------------------------------------------------------------*/
if (key == KEY_RETURN
|| key == KEY_ENTER
|| key == KEY_C_m
|| key == KEY_NUMENTER)
{
rc = RC_READV_TERM;
break;
}
/*---------------------------------------------------------------------*/
/* If the command is not allowed in READV CMDLINE, return with an error*/
/*---------------------------------------------------------------------*/
if (!command[i].valid_readv)
{
rc = RC_INVALID_ENVIRON;
break;
}
/*---------------------------------------------------------------------*/
/* To get here, a valid READV CMDLINE command is present; execute it. */
/*---------------------------------------------------------------------*/
if ((key_cmd = (CHARTYPE *)my_strdup(command[i].params)) == NULL)
{
display_error(30,(CHARTYPE *)"",FALSE);
rc = RC_OUT_OF_MEMORY;
break;
}
rc = (*command[i].function)((CHARTYPE *)key_cmd);
(*the_free)(key_cmd);
break;
}
#ifdef TRACE
trace_return();
#endif
return(rc);
}
}
if (option == OPTION_EXTRACT)
rc = set_rexx_variable((CHARTYPE *)"SHOWKEY",(CHARTYPE *)"0",1,0);
#ifdef TRACE
trace_return();
#endif
return(RAW_KEY);
}
/***********************************************************************/
#ifdef HAVE_PROTO
CHARTYPE *build_default_key_definition(int key, CHARTYPE *buf)
#else
CHARTYPE *build_default_key_definition(key, buf)
int key;
CHARTYPE *buf;
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:build_default_key_definition");
#endif
/*---------------------------------------------------------------------*/
/* The argument, buf, MUST be long enough to to accept the full command*/
/* and arguments and MUST have be nul terminated before this function */
/* is called. */
/*---------------------------------------------------------------------*/
/* If a SET command, prefix with 'set' */
/*---------------------------------------------------------------------*/
if (command[key].set_command)
strcat((DEFCHAR *)buf,"set ");
/*---------------------------------------------------------------------*/
/* If a SOS command, prefix with 'sos' */
/*---------------------------------------------------------------------*/
if (command[key].sos_command)
strcat((DEFCHAR *)buf,"sos ");
/*---------------------------------------------------------------------*/
/* Append the command name. */
/*---------------------------------------------------------------------*/
strcat((DEFCHAR *)buf,(DEFCHAR *)command[key].text);
/*---------------------------------------------------------------------*/
/* Append any parameters. */
/*---------------------------------------------------------------------*/
if (strcmp((DEFCHAR *)command[key].params,"") != 0)
{
strcat((DEFCHAR *)buf," ");
strcat((DEFCHAR *)buf,(DEFCHAR *)command[key].params);
}
#ifdef TRACE
trace_return();
#endif
return(buf);
}
/***********************************************************************/
#ifdef HAVE_PROTO
static CHARTYPE *build_defined_key_definition(int key, CHARTYPE *buf,DEFINE *curr,bool define_format)
#else
static CHARTYPE *build_defined_key_definition(key, buf,curr,define_format)
int key;
CHARTYPE *buf;
DEFINE *curr;
bool define_format;
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
/*--------------------------- local data ------------------------------*/
bool key_defined=FALSE;
bool first_time=TRUE;
CHARTYPE delim[2];
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:build_defined_key_definition");
#endif
/*---------------------------------------------------------------------*/
/* The argument, buf, MUST be long enough to to accept the full command*/
/* and arguments and MUST have be nul terminated before this function */
/* is called. */
/*---------------------------------------------------------------------*/
delim[1] = '\0';
delim[0] = CURRENT_VIEW->linend_value;
while(curr != NULL)
{
if (key == curr->def_funkey)
{
key_defined = TRUE;
if (first_time)
{
if (define_format)
strcat((DEFCHAR *)buf," ");
else
strcat((DEFCHAR *)buf," - assigned to \"");
}
else
{
strcat((DEFCHAR *)buf,(DEFCHAR *)delim);
}
/*---------------------------------------------------------------------*/
/* Append the command to the string. */
/*---------------------------------------------------------------------*/
if (curr->def_command == (-1)) /* definition is REXX instore */
strcat((DEFCHAR *)buf,(DEFCHAR *)"REXX");
else
strcat((DEFCHAR *)buf,(DEFCHAR *)command[curr->def_command].text);
/*---------------------------------------------------------------------*/
/* Append any parameters. */
/*---------------------------------------------------------------------*/
if (strcmp((DEFCHAR *)curr->def_params,"") != 0)
{
strcat((DEFCHAR *)buf," ");
strcat((DEFCHAR *)buf,(DEFCHAR *)curr->def_params);
}
first_time = FALSE;
}
curr = curr->next;
}
#ifdef TRACE
trace_return();
#endif
return((key_defined)?buf:(CHARTYPE *)NULL);
}
/***********************************************************************/
#ifdef HAVE_PROTO
short display_all_keys(void)
#else
short display_all_keys()
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
#if !defined(MULTIPLE_PSEUDO_FILES)
extern CHARTYPE key_filename[10];
extern CHARTYPE key_pathname[MAX_FILE_NAME+1];
#endif
/*--------------------------- local data ------------------------------*/
LINE *curr=NULL;
DEFINE *curr_define=NULL;
int key=0,save_funkey=0;
register int i=0;
CHARTYPE *keydef=NULL;
VIEW_DETAILS *found_view=NULL;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:display_all_keys");
#endif
/*---------------------------------------------------------------------*/
/* Free up the existing linked list (if any) */
/*---------------------------------------------------------------------*/
#if !defined(MULTIPLE_PSEUDO_FILES)
key_first_line = key_last_line = lll_free(key_first_line);
key_number_lines = 0L;
if ((found_view = find_file(key_pathname,key_filename)) != (VIEW_DETAILS *)NULL)
{
found_view->file_for_view->first_line = found_view->file_for_view->last_line = NULL;
found_view->file_for_view->number_lines = 0L;
}
#endif
/*---------------------------------------------------------------------*/
/* first_line is set to "Top of File" */
/*---------------------------------------------------------------------*/
if ((key_first_line = add_line(key_first_line,NULL,TOP_OF_FILE,
strlen((DEFCHAR *)TOP_OF_FILE),0,FALSE)) == NULL)
{
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
/*---------------------------------------------------------------------*/
/* last line is set to "Bottom of File" */
/*---------------------------------------------------------------------*/
if ((key_last_line = add_line(key_first_line,key_first_line,BOTTOM_OF_FILE,
strlen((DEFCHAR *)BOTTOM_OF_FILE),0,FALSE)) == NULL)
{
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
curr = key_first_line;
/*---------------------------------------------------------------------*/
/* First display default key mappings... */
/*---------------------------------------------------------------------*/
if ((curr = add_line(key_first_line,curr,(CHARTYPE *)KEY_DEFAULT,strlen(KEY_DEFAULT),0,FALSE)) == NULL)
{
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
key_number_lines++;
save_funkey = (-1);
for (i=0;command[i].text != NULL;i++)
{
if (command[i].funkey != (-1)
&& save_funkey != command[i].funkey)
{
save_funkey = command[i].funkey;
keydef = get_key_definition(command[i].funkey,TRUE,TRUE,FALSE);
if ((curr = add_line(key_first_line,curr,keydef,strlen((DEFCHAR *)keydef),0,FALSE)) == NULL)
{
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
key_number_lines++;
}
}
/*---------------------------------------------------------------------*/
/* ...next, display any key redefinitions. */
/*---------------------------------------------------------------------*/
if ((curr = add_line(key_first_line,curr,(CHARTYPE *)KEY_REDEF,strlen(KEY_REDEF),0,FALSE)) == NULL)
{
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
key_number_lines++;
curr_define = first_define;
while(curr_define != NULL)
{
if (key != curr_define->def_funkey)
{
keydef = get_key_definition(curr_define->def_funkey,TRUE,FALSE,FALSE);
if ((curr = add_line(key_first_line,curr,keydef,strlen((DEFCHAR *)keydef),0,FALSE)) == NULL)
{
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
key_number_lines++;
}
key = curr_define->def_funkey;
curr_define = curr_define->next;
}
#if defined(MOUSE_SUPPORT_ENABLED)
/*---------------------------------------------------------------------*/
/* ...last, display any mouse key definitions. */
/*---------------------------------------------------------------------*/
if ((curr = add_line(key_first_line,curr,(CHARTYPE *)KEY_MOUSE_REDEF,strlen(KEY_MOUSE_REDEF),0,FALSE)) == NULL)
{
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
key_number_lines++;
curr_define = first_mouse_define;
while(curr_define != NULL)
{
if (key != curr_define->def_funkey)
{
keydef = get_key_definition(curr_define->def_funkey,TRUE,FALSE,TRUE);
if ((curr = add_line(key_first_line,curr,keydef,strlen((DEFCHAR *)keydef),0,FALSE)) == NULL)
{
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
key_number_lines++;
}
key = curr_define->def_funkey;
curr_define = curr_define->next;
}
#endif
#if defined(MULTIPLE_PSEUDO_FILES)
Xedit((CHARTYPE *)"***KEY***");
#else
strcpy((DEFCHAR *)temp_cmd,(DEFCHAR *)key_pathname);
strcat((DEFCHAR *)temp_cmd,(DEFCHAR *)key_filename);
Xedit(temp_cmd);
#endif
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef HAVE_PROTO
short command_line(CHARTYPE *cmd_line,bool command_only)
#else
short command_line(cmd_line,command_only)
CHARTYPE *cmd_line;
bool command_only;
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
extern bool error_on_screen;
extern bool LINEND_STATUSx;
extern CHARTYPE LINEND_VALUEx;
extern bool in_macro;
extern CHARTYPE number_of_files;
extern short lastrc;
extern bool readonly;
extern bool curses_started;
extern bool batch_only;
extern bool in_reprofile;
extern int profile_file_executions;
extern short compatible_feel;
/*--------------------------- local data ------------------------------*/
bool valid_command=FALSE;
bool linend_status=(number_of_files) ? CURRENT_VIEW->linend_status : LINEND_STATUSx;
CHARTYPE linend_value=0;
register short i=0,j=0;
short rc=RC_OK;
CHARTYPE *cmd[MAX_COMMANDS+1];
unsigned short num_commands=0;
CHARTYPE command_delim[2];
CHARTYPE *command_entered=NULL;
CHARTYPE *cl_cmd=NULL;
CHARTYPE *cl_param=NULL;
TARGET target;
short target_type=TARGET_NORMAL|TARGET_SPARE;
bool display_parse_error=FALSE,wrapped=FALSE;
short macrorc=0;
LINETYPE save_focus_line=0L;
LINETYPE save_current_line=0L;
LINETYPE true_line=0L;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:command_line");
#endif
/*---------------------------------------------------------------------*/
/* If the command line is blank, just return. */
/*---------------------------------------------------------------------*/
if (blank_field(cmd_line))
/* if (strlen((DEFCHAR *)cmd_line) == 0) */
{
if (curses_started)
wmove(CURRENT_WINDOW_COMMAND,0,0);
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/*---------------------------------------------------------------------*/
/* Set up values for LINEND for later processing... */
/*---------------------------------------------------------------------*/
if (number_of_files == 0)
{
linend_status = LINEND_STATUSx;
linend_value = LINEND_VALUEx;
}
else
{
linend_status = CURRENT_VIEW->linend_status;
linend_value = CURRENT_VIEW->linend_value;
}
/*---------------------------------------------------------------------*/
/* 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;
/*---------------------------------------------------------------------*/
/* Copy the incoming cmd_line, so we can play with it. */
/*---------------------------------------------------------------------*/
if ((command_entered = (CHARTYPE *)my_strdup(cmd_line)) == NULL)
{
display_error(30,(CHARTYPE *)"",FALSE);
#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 = (CHARTYPE *)(*the_malloc)((strlen((DEFCHAR *)cmd_line)+1)*sizeof(CHARTYPE))) == NULL)
{
display_error(30,(CHARTYPE *)"",FALSE);
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
if ((cl_param = (CHARTYPE *)(*the_malloc)((strlen((DEFCHAR *)cmd_line)+1)*sizeof(CHARTYPE))) == NULL)
{
display_error(30,(CHARTYPE *)"",FALSE);
#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 (linend_status
&& !define_command(cmd_line))
{
command_delim[0] = 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);
cl_cmd = MyStrip(cl_cmd,STRIP_BOTH,' ');
/*---------------------------------------------------------------------*/
/* Here is where we could check for synonyms first. */
/*---------------------------------------------------------------------*/
if (!command_only)
{
}
/* get synonym for entered command */
/*---------------------------------------------------------------------*/
/* Before we try the command array, if SET MACRO is ON and IMPMACRO is */
/* ON and we have not reached here via COMMAND command, try for a */
/* macro... */
/*---------------------------------------------------------------------*/
if (number_of_files > 0
&& CURRENT_VIEW->macro
&& CURRENT_VIEW->imp_macro
&& !command_only)
{
strcpy((DEFCHAR *)command_entered,(DEFCHAR *)cmd[j]);
rc = execute_macro(command_entered,FALSE,¯orc);
if (rc != RC_FILE_NOT_FOUND)
{
lastrc = (rc==RC_SYSTEM_ERROR)?rc:macrorc;
save_last_command(cmd[j],cl_cmd);
continue;
}
}
/*---------------------------------------------------------------------*/
/* 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((DEFCHAR *)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 (batch_only
&& !command[i].valid_batch_command)
{
display_error(24,command[i].text,FALSE);
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)
cl_param = MyStrip(cl_param,command[i].strip_param,' ');
/*---------------------------------------------------------------------*/
/* If running in read-only mode and the function selected is not valid */
/* display an error. */
/*---------------------------------------------------------------------*/
if (readonly && !command[i].valid_in_readonly)
{
display_error(56,(CHARTYPE *)"",FALSE);
rc = RC_INVALID_ENVIRON;
break;
}
/*---------------------------------------------------------------------*/
/* If we are currently processing the profile file as a result of */
/* reprofile, ignore those commands that are invalid. */
/*---------------------------------------------------------------------*/
if (profile_file_executions > 1
&& in_reprofile
&& !command[i].valid_for_reprofile)
{
rc = RC_OK;
break;
}
/*---------------------------------------------------------------------*/
/* If there are no more files in the ring, and the command is not a */
/* command to edit a new file, then ignore the command. */
/*---------------------------------------------------------------------*/
if (number_of_files == 0
&& !command[i].edit_command)
{
rc = RC_OK;
break;
}
/*---------------------------------------------------------------------*/
/* Now call the function associated with the supplied command string */
/* and the possibly stripped parameters. */
/*---------------------------------------------------------------------*/
lastrc = rc = (*command[i].function)(cl_param);
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)
{
save_last_command(cmd[j],cl_cmd);
continue;
}
/*---------------------------------------------------------------------*/
/* If there are no more files in the ring, then ignore the command. */
/*---------------------------------------------------------------------*/
if (number_of_files == 0)
{
save_last_command(cmd[j],cl_cmd);
continue;
}
/*---------------------------------------------------------------------*/
/* To get here the command was not a 'command'; check if a valid target*/
/*---------------------------------------------------------------------*/
save_focus_line=CURRENT_VIEW->focus_line;
save_current_line=CURRENT_VIEW->current_line;
initialise_target(&target);
if (!CURRENT_VIEW->imp_macro
&& !CURRENT_VIEW->imp_os)
display_parse_error = TRUE;
else
display_parse_error = FALSE;
rc = validate_target(cmd[j],&target,target_type,get_true_line(TRUE),display_parse_error,(CURRENT_VIEW->wrap)?FALSE:TRUE);
/*---------------------------------------------------------------------*/
/* If a valid target, but target not found, continue... */
/*---------------------------------------------------------------------*/
if (rc == RC_TARGET_NOT_FOUND)
{
bool negative=FALSE;
if (CURRENT_VIEW->wrap)
{
wrapped = TRUE;
negative = target.rt[0].negative;
free_target(&target);
initialise_target(&target);
true_line = (negative ? CURRENT_FILE->number_lines+1 : 0L);
CURRENT_VIEW->focus_line = CURRENT_VIEW->current_line = true_line;
pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
rc = validate_target(cmd[j],&target,target_type,true_line,display_parse_error,TRUE);
if (rc != RC_OK)
{
CURRENT_VIEW->focus_line = save_focus_line;
CURRENT_VIEW->current_line = save_current_line;
}
}
if (rc == RC_TARGET_NOT_FOUND)
{
strcpy((DEFCHAR *)last_target,(DEFCHAR *)target.string);
free_target(&target);
lastrc = rc = RC_TARGET_NOT_FOUND;
save_last_command(cmd[j],cl_cmd);
continue;
}
}
/*---------------------------------------------------------------------*/
/* If a valid target and found, go there and execute any following */
/* command. */
/*---------------------------------------------------------------------*/
if (rc == RC_OK)
{
if (wrapped)
{
display_error(0,(CHARTYPE*)"Wrapped...",FALSE);
CURRENT_VIEW->focus_line = save_focus_line;
CURRENT_VIEW->current_line = save_current_line;
build_screen(current_screen);
if (CURRENT_VIEW->current_window == WINDOW_COMMAND
|| compatible_feel == COMPAT_XEDIT)
CURRENT_VIEW->current_line = true_line;
else
CURRENT_VIEW->focus_line = true_line;
pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
}
strcpy((DEFCHAR *)last_target,(DEFCHAR *)target.string);
lastrc = rc = advance_current_or_focus_line(target.num_lines);
if ((rc == RC_OK
|| rc == RC_TOF_EOF_REACHED)
&& target.spare != (-1))
rc = lastrc = command_line(MyStrip(target.rt[target.spare].string,STRIP_LEADING,' '),FALSE);
free_target(&target);
save_last_command(cmd[j],cl_cmd);
continue;
}
free_target(&target);
/*---------------------------------------------------------------------*/
/* If return is RC_INVALID_OPERAND, check if command is OS command... */
/*---------------------------------------------------------------------*/
if (cmd[j][0] == '!')
{
strcpy((DEFCHAR *)command_entered,(DEFCHAR *)cmd[j]);
lastrc = rc = Os(command_entered+1);
save_last_command(cmd[j],cl_cmd);
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((DEFCHAR *)command_entered,(DEFCHAR *)cmd[j]);
if (CURRENT_VIEW->imp_os)
{
rc = execute_macro(command_entered,FALSE,¯orc);
if (rc != RC_FILE_NOT_FOUND)
{
lastrc = (rc==RC_SYSTEM_ERROR)?rc:macrorc;
save_last_command(cmd[j],cl_cmd);
continue;
}
}
else
{
rc = execute_macro(command_entered,TRUE,¯orc);
if (rc == RC_FILE_NOT_FOUND)
{
lastrc = rc = RC_NOT_COMMAND;
break;
}
else
{
lastrc = (rc==RC_SYSTEM_ERROR)?rc:macrorc;
save_last_command(cmd[j],cl_cmd);
continue;
}
}
}
/*---------------------------------------------------------------------*/
/* ...or if command is an OS command (as long as IMPOS is ON). */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->imp_os)
{
error_on_screen = FALSE;
strcpy((DEFCHAR *)command_entered,(DEFCHAR *)cmd[j]);
rc = Os(command_entered);
}
else
{
display_error(21,cmd[j],FALSE);
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;
save_last_command(cmd[j],cl_cmd);
}
cleanup_command_line();
(*the_free)(command_entered);
(*the_free)(cl_cmd);
(*the_free)(cl_param);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/***********************************************************************/
#ifdef HAVE_PROTO
void cleanup_command_line(void)
#else
void cleanup_command_line()
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern CHARTYPE *cmd_rec;
extern unsigned short cmd_rec_len;
extern bool in_macro;
extern CHARTYPE number_of_views;
extern bool curses_started;
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:cleanup_command_line");
#endif
if (!curses_started || in_macro || number_of_views == 0)
{
#ifdef TRACE
trace_return();
#endif
return;
}
if (clear_command)
{
if (CURRENT_WINDOW_COMMAND != (WINDOW *)NULL)
{
wmove(CURRENT_WINDOW_COMMAND,0,0);
my_wclrtoeol(CURRENT_WINDOW_COMMAND);
}
memset(cmd_rec,' ',max_line_length);
cmd_rec_len = 0;
}
if (CURRENT_WINDOW_COMMAND != (WINDOW *)NULL)
wmove(CURRENT_WINDOW_COMMAND,0,0);
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef HAVE_PROTO
void split_command(CHARTYPE *cmd_line,CHARTYPE *cmd,CHARTYPE *param)
#else
void split_command(cmd_line,cmd,param)
CHARTYPE *cmd_line,*cmd,*param;
#endif
/***********************************************************************/
/*---------------------------------------------------------------------*/
{
/*--------------------------- local data ------------------------------*/
short pos=0;
CHARTYPE *param_ptr=NULL;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:split_command");
#endif
strcpy((DEFCHAR *)cmd,(DEFCHAR *)cmd_line);
MyStrip(cmd,STRIP_LEADING,' ');
/*---------------------------------------------------------------------*/
/* Special test here for ? and = command... */
/*---------------------------------------------------------------------*/
if (*cmd == '?')
{
strcpy((DEFCHAR *)param,(DEFCHAR *)(cmd+1));
strcpy((DEFCHAR *)cmd,"?");
#ifdef TRACE
trace_return();
#endif
return;
}
if (*cmd == '=')
{
strcpy((DEFCHAR *)param,(DEFCHAR *)(cmd+1));
strcpy((DEFCHAR *)cmd,"=");
#ifdef TRACE
trace_return();
#endif
return;
}
for (param_ptr=cmd;*param_ptr!='\0';param_ptr++)
{
if (!isalpha(*param_ptr))
break;
}
if (!param_ptr)
{
strcpy((DEFCHAR *)param,"");
#ifdef TRACE
trace_return();
#endif
return;
}
if (param_ptr == cmd
|| *param_ptr == '\0')
{
strcpy((DEFCHAR *)param,"");
#ifdef TRACE
trace_return();
#endif
return;
}
pos = strzne(param_ptr,' ');
if (pos == (-1)) /* parameters are all spaces */
{
strcpy((DEFCHAR *)param,(DEFCHAR *)param_ptr+1);
#ifdef TRACE
trace_return();
#endif
return;
}
strcpy((DEFCHAR *)param,(DEFCHAR *)param_ptr+(*(param_ptr) == ' ' ? 1 : 0));
*(param_ptr) = '\0';
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef HAVE_PROTO
short param_split(CHARTYPE *params,CHARTYPE *word[],short words,
CHARTYPE *delims,CHARTYPE param_type,CHARTYPE *strip, bool trailing_spaces_is_arg)
#else
short param_split(params,word,words,delims,param_type,strip,trailing_spaces_is_arg)
CHARTYPE *params;
CHARTYPE *word[];
short words;
CHARTYPE *delims;
CHARTYPE param_type;
CHARTYPE *strip;
bool trailing_spaces_is_arg;
#endif
/***********************************************************************/
{
#define STATE_START 0
#define STATE_WORD 1
#define STATE_DELIM 2
/*--------------------------- local data ------------------------------*/
register short i=0,k=0;
unsigned short len=0;
CHARTYPE j=0;
#if 0
bool end_of_string=FALSE,end_of_word=FALSE;
#endif
CHARTYPE *param_ptr=NULL;
CHARTYPE *space_ptr=NULL;
CHARTYPE state=STATE_START;
short str_start=0,str_end=(-1);
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:param_split");
#endif
/*---------------------------------------------------------------------*/
/* Allocate some memory to the temporary area. */
/*---------------------------------------------------------------------*/
if (params != NULL)
{
if (allocate_temp_space(strlen((DEFCHAR *)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;
case TEMP_TMP_CMD:
param_ptr = tmp_cmd;
break;
default:
return(-1);
break;
}
/*---------------------------------------------------------------------*/
/* In case params is NULL, copy an empty string into param_ptr... */
/*---------------------------------------------------------------------*/
if (params == NULL)
strcpy((DEFCHAR *)param_ptr,"");
else
strcpy((DEFCHAR *)param_ptr,(DEFCHAR *)params);
for (i=0;i<words;i++)
word[i] = (CHARTYPE *)"";
word[0] = param_ptr;
len = strlen((DEFCHAR *)param_ptr);
if (trailing_spaces_is_arg)
{
i = strzrevne(param_ptr,' ');
if (i != (-1)
&& (len - i) > 2)
{
space_ptr = param_ptr+(i+2);
param_ptr[i+1] = '\0';
}
}
#if 0
if (words > 1)
{
#endif
j = 0;
str_start = 0;
for (i=0;i<len && j<words;i++)
{
switch(state)
{
case STATE_START:
for (k=0;k<strlen((DEFCHAR *)delims);k++)
{
if (*(param_ptr+i) == *(delims+k))
{
state = STATE_DELIM;
break;
}
}
if (state == STATE_DELIM)
break;
word[j++] = param_ptr+str_start;
if (str_end != (-1))
{
*(param_ptr+str_end) = '\0';
}
state = STATE_WORD;
break;
case STATE_WORD:
for (k=0;k<strlen((DEFCHAR *)delims);k++)
{
if (*(param_ptr+i) == *(delims+k))
{
state = STATE_DELIM;
break;
}
}
if (state == STATE_DELIM)
{
str_end = i;
str_start = str_end + 1;
break;
}
break;
case STATE_DELIM:
state = STATE_WORD;
for (k=0;k<strlen((DEFCHAR *)delims);k++)
{
if (*(param_ptr+i) == *(delims+k))
{
state = STATE_DELIM;
break;
}
}
if (state == STATE_WORD)
{
word[j++] = param_ptr+str_start;
if (str_end != (-1))
{
*(param_ptr+str_end) = '\0';
}
}
break;
}
}
#if 0
}
else
j = words;
#endif
for (i=0;i<words;i++)
{
if (*(strip+i))
word[i] = MyStrip(word[i],*(strip+i),' ');
}
if (space_ptr)
{
word[j] = space_ptr;
j++;
}
#ifdef TRACE
trace_return();
#endif
return(j);
}
/***********************************************************************/
#ifdef HAVE_PROTO
short command_split(CHARTYPE *params,CHARTYPE *word[],short words,
CHARTYPE *delims,CHARTYPE *buffer)
#else
short command_split(params,word,words,delims,buffer)
CHARTYPE *params;
CHARTYPE *word[];
short words;
CHARTYPE *delims;
CHARTYPE *buffer;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register short i=0,k=0;
unsigned short len=0;
CHARTYPE j=0;
bool end_of_string=FALSE,end_of_word=FALSE;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:command_split");
#endif
/*---------------------------------------------------------------------*/
/* In case params is NULL, copy an empty string into buffer... */
/*---------------------------------------------------------------------*/
if (params == NULL)
strcpy((DEFCHAR *)buffer,"");
else
strcpy((DEFCHAR *)buffer,(DEFCHAR *)params);
for (i=0;i<words;i++)
word[i] = (CHARTYPE *)"";
j = 0;
end_of_string = TRUE;
len = strlen((DEFCHAR *)buffer);
for (i=0;i<len && j<words;i++)
{
end_of_word = FALSE;
for (k=0;k<strlen((DEFCHAR *)delims);k++)
{
if (*(buffer+i) == *(delims+k))
end_of_word = TRUE;
}
if (end_of_word)
{
*(buffer+i) = '\0';
end_of_string = TRUE;
}
else
if (end_of_string)
{
word[j++] = buffer+i;
end_of_string = FALSE;
}
}
#ifdef TRACE
trace_return();
#endif
return(j);
}
/***********************************************************************/
#ifdef HAVE_PROTO
LINETYPE get_true_line(bool respect_compat)
#else
LINETYPE get_true_line(respect_compat)
bool respect_compat;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern bool batch_only;
extern short compatible_feel;
/*--------------------------- local data ------------------------------*/
LINETYPE true_line=0L;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:get_true_line");
#endif
/*---------------------------------------------------------------------*/
/* Determine 'true_line'. */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->current_window == WINDOW_COMMAND
|| (compatible_feel == COMPAT_XEDIT && respect_compat)
|| batch_only)
true_line = CURRENT_VIEW->current_line;
else
true_line = CURRENT_VIEW->focus_line;
#ifdef TRACE
trace_return();
#endif
return(true_line);
}
#ifndef MSWIN
/***********************************************************************/
#ifdef HAVE_PROTO
void print_line(bool close_spooler,LINETYPE true_line,LINETYPE num_lines,
short pagesize,CHARTYPE *text,CHARTYPE *line_term,short target_type)
#else
void print_line(close_spooler,true_line,num_lines,pagesize,text,line_term,target_type)
bool close_spooler;
LINETYPE true_line,num_lines;
short pagesize;
CHARTYPE *text;
CHARTYPE *line_term;
short target_type;
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
#if defined(UNIX) || defined(OS2) || defined(EMX)
extern CHARTYPE *spooler_name;
#endif
extern bool curses_started;
extern VIEW_DETAILS *vd_mark;
extern CHARTYPE *rec;
/*--------------------------- local data ------------------------------*/
#if defined(UNIX) || defined(OS2)
static bool spooler_open=FALSE;
# if defined(OS2)
HFILE Lpt;
# if defined(__32BIT__) || defined(__386__)
ULONG Action=0L;
ULONG NoWritten=0L;
# else
USHORT Action=0;
USHORT NoWritten=0;
# endif
# endif
#endif
static FILE *pp;
register short i=0;
short rc=RC_OK;
LINETYPE j=0L;
LINE *curr=NULL;
short line_number=0;
LINETYPE num_excluded=0L;
LINETYPE num_actual_lines=0L;
LINETYPE abs_num_lines=(num_lines < 0L ? -num_lines : num_lines);
short direction=(num_lines < 0L ? DIRECTION_BACKWARD : DIRECTION_FORWARD);
unsigned short y=0,x=0;
bool lines_based_on_scope=(target_type==TARGET_BLOCK_CURRENT)?FALSE:TRUE;
LINETYPE start=0L,end=0L,len=0L;
CHARTYPE *ptr=NULL;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:print_line");
#endif
#if defined(DOS)
# if defined(EMX)
pp = fopen(spooler_name,"wb");
# else
pp = stdprn;
# endif
#endif
#if defined(UNIX) || defined(OS2)
if (close_spooler)
{
if (spooler_open)
{
spooler_open = FALSE;
#if defined(OS2)
DosClose(Lpt);
#else
pclose(pp);
#endif
}
#ifdef TRACE
trace_return();
#endif
return;
}
#endif
#if defined(UNIX)
if (!spooler_open)
{
pp = popen((DEFCHAR *)spooler_name,"w");
spooler_open = TRUE;
}
#endif
#if defined(OS2)
if (!spooler_open)
{
#if defined(__32BIT__) || defined(__386__)
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 = TRUE;
}
#endif
if (num_lines == 0L)
{
#if defined(OS2)
DosWrite(Lpt,text,strlen(text),&NoWritten);
#else
fprintf(pp,"%s%s",text,line_term);
# if defined(EMX)
fclose(pp);
# endif
#endif
#ifdef TRACE
trace_return();
#endif
return;
}
/*---------------------------------------------------------------------*/
/* Once we get here, we are to print lines from the file. */
/*---------------------------------------------------------------------*/
post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE);
if (curses_started)
{
if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
getyx(CURRENT_WINDOW_FILEAREA,y,x);
else
getyx(CURRENT_WINDOW,y,x);
}
curr = lll_find(CURRENT_FILE->first_line,CURRENT_FILE->last_line,true_line,CURRENT_FILE->number_lines);
for (j=0L,num_actual_lines=0L;;j++)
{
if (lines_based_on_scope)
{
if (num_actual_lines == abs_num_lines)
break;
}
else
{
if (abs_num_lines == j)
break;
}
rc = processable_line(CURRENT_VIEW,true_line+(LINETYPE)(j*direction),curr);
switch(rc)
{
case LINE_SHADOW:
num_excluded++;
break;
case LINE_TOF:
case LINE_EOF:
num_actual_lines++;
break;
default:
if (num_excluded != 0)
{
#if defined(OS2) && !defined(__EMX__)
print_shadow_line(Lpt,line_term,num_excluded);
#else
print_shadow_line(pp,line_term,num_excluded);
#endif
num_excluded = 0L;
}
switch(target_type)
{
case TARGET_BLOCK_CURRENT:
switch(MARK_VIEW->mark_type)
{
case M_LINE:
start = 0;
end = (curr->length)-1;
len = end - start + 1L;
ptr = curr->line;
break;
case M_BOX:
case M_WORD:
case M_COLUMN:
pre_process_line(CURRENT_VIEW,true_line+(LINETYPE)(j*direction),curr);
start = MARK_VIEW->mark_start_col - 1;
end = MARK_VIEW->mark_end_col - 1;
len = end - start + 1L;
ptr = rec+start;
break;
case M_STREAM:
pre_process_line(CURRENT_VIEW,true_line+(LINETYPE)(j*direction),curr);
start = end = (-1L);
if (true_line+(LINETYPE)(j*direction) == MARK_VIEW->mark_start_line)
start = MARK_VIEW->mark_start_col - 1;
if (true_line+(LINETYPE)(j*direction) == MARK_VIEW->mark_end_line)
end = MARK_VIEW->mark_end_col - 1;
if (start == (-1L))
start = 0;
if (end == (-1L))
end = (curr->length)-1;
len = end - start + 1L;
ptr = curr->line+start;
break;
}
break;
default:
start = (LINETYPE)CURRENT_VIEW->zone_start-1;
end = (LINETYPE)min((curr->length)-1,CURRENT_VIEW->zone_end-1);
ptr = curr->line+start;
if (start > end)
len = 0L;
else
len = end - start + 1L;
break;
}
#if defined(OS2)
DosWrite(Lpt,ptr,len,&NoWritten);
DosWrite(Lpt,line_term,strlen(line_term),&NoWritten);
#else
for (i=0;i<len;i++)
fputc(*(ptr+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;
}
num_actual_lines++;
break;
}
/*---------------------------------------------------------------------*/
/* Proceed to the next record, even if the current record not in scope.*/
/*---------------------------------------------------------------------*/
if (direction == DIRECTION_BACKWARD)
curr = curr->prev;
else
curr = curr->next;
if (curr == NULL)
break;
}
/*---------------------------------------------------------------------*/
/* If we have a shadow line remaining, print it... */
/*---------------------------------------------------------------------*/
if (num_excluded != 0)
{
#if defined(OS2) && !defined(__EMX__)
print_shadow_line(Lpt,line_term,num_excluded);
#else
print_shadow_line(pp,line_term,num_excluded);
#endif
num_excluded = 0L;
}
/*---------------------------------------------------------------------*/
/* If STAY is OFF, change the current and focus lines by the number */
/* of lines calculated from the target. */
/*---------------------------------------------------------------------*/
if (!CURRENT_VIEW->stay) /* stay is off */
{
CURRENT_VIEW->focus_line = min(CURRENT_VIEW->focus_line+num_lines-1L,CURRENT_FILE->number_lines+1L);
CURRENT_VIEW->current_line = min(CURRENT_VIEW->current_line+num_lines-1L,CURRENT_FILE->number_lines+1L);
}
pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
build_screen(current_screen);
display_screen(current_screen);
if (curses_started)
{
y = get_row_for_focus_line(current_screen,CURRENT_VIEW->focus_line,
CURRENT_VIEW->current_row);
if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
wmove(CURRENT_WINDOW_FILEAREA,y,x);
else
wmove(CURRENT_WINDOW,y,x);
}
#ifdef TRACE
trace_return();
#endif
return;
}
#if defined(OS2) && !defined(__EMX__)
/***********************************************************************/
#ifdef HAVE_PROTO
void print_shadow_line(HFILE Lpt,CHARTYPE *line_term,LINETYPE num_excluded)
#else
void print_shadow_line(Lpt,line_term,num_excluded)
HFILE Lpt;
CHARTYPE *line_term;
LINETYPE num_excluded;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register short i=0;
short num_dashes=0;
CHARTYPE temp_buf[7]="";
#if defined(__32BIT__) || defined(__386__)
ULONG NoWritten=0L;
#else
USHORT NoWritten=0;
#endif
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:print_shadow_line");
#endif
if (CURRENT_VIEW->shadow)
{
num_dashes = (CURRENT_SCREEN.cols[WINDOW_FILEAREA] - 26) / 2;
for (i=0;i<num_dashes;i++)
DosWrite(Lpt,"-",1,&NoWritten);
sprintf(temp_buf,"%6ld",num_excluded);
DosWrite(Lpt,temp_buf,strlen(temp_buf),&NoWritten);
DosWrite(Lpt," line(s) not displayed ",23,&NoWritten);
for (i=0;i<num_dashes;i++)
DosWrite(Lpt,"-",1,&NoWritten);
DosWrite(Lpt,line_term,strlen(line_term),&NoWritten);
}
#ifdef TRACE
trace_return();
#endif
return;
}
#else
/***********************************************************************/
#ifdef HAVE_PROTO
void print_shadow_line(FILE *pp,CHARTYPE *line_term,LINETYPE num_excluded)
#else
void print_shadow_line(pp,line_term,num_excluded)
FILE *pp;
CHARTYPE *line_term;
LINETYPE num_excluded;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register short i=0;
short num_dashes=0;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:print_shadow_line");
#endif
if (CURRENT_VIEW->shadow)
{
num_dashes = (CURRENT_SCREEN.cols[WINDOW_FILEAREA] - 26) / 2;
for (i=0;i<num_dashes;i++)
fputc('-',pp);
fprintf(pp,"%6ld line(s) not displayed ",num_excluded);
for (i=0;i<num_dashes;i++)
fputc('-',pp);
fprintf(pp,"%s",line_term);
}
#ifdef TRACE
trace_return();
#endif
return;
}
#endif
#endif
/***********************************************************************/
#ifdef HAVE_PROTO
CHARTYPE next_char(LINE *curr,long *off,LENGTHTYPE end_col)
#else
CHARTYPE next_char(curr,off,end_col)
LINE *curr;
long *off;
LENGTHTYPE end_col;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:next_char");
#endif
if (*(off) < (long)min(curr->length,end_col))
{
(*(off))++;
#ifdef TRACE
trace_return();
#endif
return(*(curr->line+((*(off))-1L)));
}
*(off) = (-1L);
#ifdef TRACE
trace_return();
#endif
return(0);
}
/***********************************************************************/
#ifdef HAVE_PROTO
short add_define(DEFINE **first,DEFINE **last,int key_value,CHARTYPE *commands,bool instore)
#else
short add_define(first,last,key_value,commands,instore)
DEFINE **first,**last;
int key_value;
CHARTYPE *commands;
bool instore;
#endif
/***********************************************************************/
/* Parameters: */
/* key_value: numeric representation of function key */
/* commands: commands and parameters */
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern bool rexx_support;
/*--------------------------- local data ------------------------------*/
register short j=0;
short cmd_nr=0;
CHARTYPE *word[MAX_COMMANDS+1];
unsigned short num_commands=0;
CHARTYPE command_delim[2];
short rc=RC_OK;
CHARTYPE *command_entered=NULL,*cl_cmd=NULL,*cl_param=NULL;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:add_define");
#endif
/*---------------------------------------------------------------------*/
/* If the commands argument is empty, delete the definition of the key */
/* definitions for the key, so just return. */
/*---------------------------------------------------------------------*/
if (strcmp((DEFCHAR *)commands,"") == 0)
{
remove_define(first,last,key_value);
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
if (instore)
{
if (rexx_support)
{
remove_define(first,last,key_value);
rc = append_define(first,last,key_value,(-1),commands);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
else
{
display_error(58,(CHARTYPE *)"instore macros",FALSE);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
}
/*---------------------------------------------------------------------*/
/* To have reached here we are dealing with "plain" key definitions, */
/* rather than instore macros... */
/* Copy the incoming commands, so we can play with it. */
/*---------------------------------------------------------------------*/
if ((command_entered = (CHARTYPE *)my_strdup(commands)) == NULL)
{
display_error(30,(CHARTYPE *)"",FALSE);
#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 = (CHARTYPE *)(*the_malloc)((strlen((DEFCHAR *)commands)+1)*sizeof(CHARTYPE))) == NULL)
{
display_error(30,(CHARTYPE *)"",FALSE);
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
if ((cl_param = (CHARTYPE *)(*the_malloc)((strlen((DEFCHAR *)commands)+1)*sizeof(CHARTYPE))) == NULL)
{
display_error(30,(CHARTYPE *)"",FALSE);
#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)
{
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;
}
}
else
{
command_delim[0] = '#';
command_delim[1] = '\0';
num_commands = command_split(commands,word,MAX_COMMANDS,command_delim,command_entered);
}
/*---------------------------------------------------------------------*/
/* For each command entered, split it up into command and params, and */
/* validate that each command is valid. The cmd_nr is discarded here. */
/*---------------------------------------------------------------------*/
for (j=0;j<num_commands;j++)
{
split_command(word[j],cl_cmd,cl_param);
if ((cmd_nr = find_command(cl_cmd,FALSE)) == (-1))
{
display_error(21,cl_cmd,FALSE);
rc = RC_INVALID_OPERAND;
break;
}
}
/*---------------------------------------------------------------------*/
/* Now we know each command is valid, we can remove any prior */
/* definition and assign the new one. */
/*---------------------------------------------------------------------*/
if (rc == RC_OK)
{
remove_define(first,last,key_value);
for (j=0;j<num_commands;j++)
{
split_command(word[j],cl_cmd,cl_param);
if ((cmd_nr = find_command(cl_cmd,FALSE)) == (-1))
{
display_error(21,cl_cmd,FALSE); /* this should not be reached */
rc = RC_INVALID_OPERAND;
break;
}
rc = append_define(first,last,key_value,cmd_nr,cl_param);
if (rc != RC_OK)
break;
}
}
(*the_free)(command_entered);
(*the_free)(cl_cmd);
(*the_free)(cl_param);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/***********************************************************************/
#ifdef HAVE_PROTO
short remove_define(DEFINE **first,DEFINE **last,int key_value)
#else
short remove_define(first,last,key_value)
DEFINE **first,**last;
int key_value;
#endif
/***********************************************************************/
/* Parameters: */
/* key_value: numeric representation of function key */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
DEFINE *curr=NULL;
/*--------------------------- 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;
while(curr != NULL)
{
if (curr->def_funkey == key_value)
{
if (curr->def_params != NULL)
(*the_free)(curr->def_params);
curr = dll_del(first,last,curr,DIRECTION_FORWARD);
}
else
curr = curr->next;
}
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef HAVE_PROTO
short append_define(DEFINE **first,DEFINE **last,int key_value,short cmd,CHARTYPE *prm)
#else
short append_define(first,last,key_value,cmd,prm)
DEFINE **first,**last;
int key_value;
short cmd;
CHARTYPE *prm;
#endif
/***********************************************************************/
/* Parameters: */
/* key_value: numeric representation of function key */
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
/*--------------------------- local data ------------------------------*/
DEFINE *curr=NULL;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:append_define");
#endif
/*---------------------------------------------------------------------*/
/* Add the new key definition to the end of the linked list... */
/*---------------------------------------------------------------------*/
curr = dll_add(*first,*last,sizeof(DEFINE));
if (curr == NULL)
{
display_error(30,(CHARTYPE *)"",FALSE);
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
curr->def_params = (CHARTYPE *)(*the_malloc)((strlen((DEFCHAR *)prm)+1)*sizeof(CHARTYPE));
if (curr->def_params == NULL)
{
display_error(30,(CHARTYPE *)"",FALSE);
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
strcpy((DEFCHAR *)curr->def_params,(DEFCHAR *)prm);
curr->def_funkey = key_value;
curr->def_command = cmd;
*last = curr;
if (*first == NULL)
*first = *last;
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef HAVE_PROTO
int find_key_value(CHARTYPE *mnemonic)
#else
int find_key_value(mnemonic)
CHARTYPE *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=0;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:find_key_value");
#endif
for (i=0;key_table[i].mnemonic!=NULL;i++)
if (equal(key_table[i].mnemonic,mnemonic,strlen((DEFCHAR *)key_table[i].mnemonic)))
{
#ifdef TRACE
trace_return();
#endif
return(key_table[i].key_value);
}
#ifdef TRACE
trace_return();
#endif
return(-1);
}
/***********************************************************************/
#ifdef HAVE_PROTO
short find_command(CHARTYPE *cmd,bool search_for_target)
#else
short find_command(cmd,search_for_target)
CHARTYPE *cmd;
bool search_for_target;
#endif
/***********************************************************************/
/* Function: determine if the string supplied is a valid abbrev for */
/* a command. */
/* Parameters: */
/* cmd: the string to be checked */
/* search_for_target: determine if command is a valid target */
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register short i=0;
short rc=RC_OK;
TARGET target;
short target_type=TARGET_NORMAL|TARGET_BLOCK|TARGET_ALL;
/*--------------------------- 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((DEFCHAR *)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'. If we don't want to */
/* search for targets, exit with (-1). */
/*---------------------------------------------------------------------*/
if (!search_for_target)
{
#ifdef TRACE
trace_return();
#endif
return(-1);
}
/*---------------------------------------------------------------------*/
/* Find if it is a valid target... */
/*---------------------------------------------------------------------*/
initialise_target(&target);
rc = validate_target(cmd,&target,target_type,get_true_line(TRUE),TRUE,TRUE);
if (rc != RC_OK
&& rc != RC_TARGET_NOT_FOUND)
{
free_target(&target);
#ifdef TRACE
trace_return();
#endif
return(-1);
}
free_target(&target);
/*---------------------------------------------------------------------*/
/* If a valid target, find 'LOCATE' command and return the index. */
/*---------------------------------------------------------------------*/
strcpy((DEFCHAR *)temp_params,(DEFCHAR *)cmd);
for (i=0;command[i].text != NULL;i++)
{
if (strcmp((DEFCHAR *)command[i].text,"locate") == 0)
break;
}
#ifdef TRACE
trace_return();
#endif
return(i);
}
/***********************************************************************/
#ifdef HAVE_PROTO
void init_command(void)
#else
void init_command()
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register short i=0;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:init_command");
#endif
strcpy((DEFCHAR *)last_command_for_reexecute,"");
strcpy((DEFCHAR *)last_command_for_repeat,"");
for (i=0;i<MAX_SAVED_COMMANDS;i++)
strcpy((DEFCHAR *)cmd_history[i],"");
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef HAVE_PROTO
void add_command(CHARTYPE *new_cmd)
#else
void add_command(new_cmd)
CHARTYPE *new_cmd;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern bool in_macro;
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:add_command");
#endif
/*---------------------------------------------------------------------*/
/* Do not save commands if the commands are issued from a macro. */
/*---------------------------------------------------------------------*/
if (in_macro)
return;
/*---------------------------------------------------------------------*/
/* 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 "=" or "?", return */
/* without adding command to array. */
/*---------------------------------------------------------------------*/
if (!valid_command_to_save(new_cmd))
{
#ifdef TRACE
trace_return();
#endif
return;
}
offset_cmd = 0;
if (strcmp((DEFCHAR *)new_cmd,(DEFCHAR *)cmd_history[current_cmd]) == 0)
{
#ifdef TRACE
trace_return();
#endif
return;
}
if (number_cmds == MAX_SAVED_COMMANDS)
current_cmd = last_cmd = (last_cmd == MAX_SAVED_COMMANDS-1) ? 0 : ++last_cmd;
else
current_cmd = ++last_cmd;
strcpy((DEFCHAR *)cmd_history[current_cmd],(DEFCHAR *)new_cmd);
number_cmds++;
if (number_cmds > MAX_SAVED_COMMANDS)
number_cmds = MAX_SAVED_COMMANDS;
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef HAVE_PROTO
CHARTYPE *get_next_command( short direction, short num)
#else
CHARTYPE *get_next_command(direction,num)
short direction,num;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
CHARTYPE *cmd_to_return=NULL;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:get_next_command");
#endif
if (number_cmds == 0)
{
#ifdef TRACE
trace_return();
#endif
return((CHARTYPE *)NULL);
}
while(num--)
{
switch(direction)
{
case DIRECTION_BACKWARD:
if (current_cmd+1 == number_cmds)
{
current_cmd = 0;
cmd_to_return = cmd_history[current_cmd];
}
else
cmd_to_return = cmd_history[++current_cmd];
break;
case DIRECTION_FORWARD:
if (current_cmd+offset_cmd < 0)
{
current_cmd = number_cmds-1;
cmd_to_return = cmd_history[current_cmd];
}
else
{
current_cmd = current_cmd+offset_cmd;
cmd_to_return = cmd_history[current_cmd];
}
offset_cmd = (-1);
break;
case DIRECTION_NONE:
cmd_to_return = cmd_history[current_cmd];
break;
}
}
#ifdef TRACE
trace_return();
#endif
return(cmd_to_return);
}
/***********************************************************************/
#ifdef HAVE_PROTO
bool valid_command_to_save(CHARTYPE *save_cmd)
#else
bool valid_command_to_save(save_cmd)
CHARTYPE *save_cmd;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:valid_command_to_save");
#endif
/*---------------------------------------------------------------------*/
/* If the command to be added is empty or is "=" or starts with "?", */
/* return FALSE, otherwise return TRUE. */
/*---------------------------------------------------------------------*/
if (save_cmd == NULL
|| strcmp((DEFCHAR *)save_cmd,"") == 0
|| strcmp((DEFCHAR *)save_cmd,"=") == 0
|| save_cmd[0] == '?')
{
#ifdef TRACE
trace_return();
#endif
return(FALSE);
}
#ifdef TRACE
trace_return();
#endif
return(TRUE);
}
/***********************************************************************/
#ifdef HAVE_PROTO
static void save_last_command(CHARTYPE *last_cmd,CHARTYPE *cmnd)
#else
static void save_last_command(last_cmd,cmnd)
CHARTYPE *last_cmd,*cmnd;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern bool in_macro;
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:save_last_command");
#endif
/*---------------------------------------------------------------------*/
/* Do not save commands if the commands are issued from a macro. */
/*---------------------------------------------------------------------*/
if (in_macro)
return;
/*---------------------------------------------------------------------*/
/* 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 "=" or "?", return */
/* without adding command to array. */
/*---------------------------------------------------------------------*/
if (valid_command_to_save(last_cmd))
{
strcpy((DEFCHAR *)last_command_for_reexecute,(DEFCHAR *)last_cmd);
if (!equal((CHARTYPE *)"REPEAT",cmnd,4))
strcpy((DEFCHAR *)last_command_for_repeat,(DEFCHAR *)last_cmd);
}
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef HAVE_PROTO
bool is_tab_col(LENGTHTYPE x)
#else
bool is_tab_col(x)
LENGTHTYPE x;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
/*--------------------------- local data ------------------------------*/
register short i=0;
bool rc=FALSE;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:is_tab_col");
#endif
for (i=0;i<CURRENT_VIEW->numtabs;i++)
{
if (CURRENT_VIEW->tabs[i] == x)
{
rc = TRUE;
break;
}
}
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/***********************************************************************/
#ifdef HAVE_PROTO
LENGTHTYPE find_next_tab_col(LENGTHTYPE x)
#else
LENGTHTYPE find_next_tab_col(x)
LENGTHTYPE x;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
/*--------------------------- local data ------------------------------*/
register short i=0;
LENGTHTYPE next_tab_col=0;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:find_next_tab_col");
#endif
for (i=0;i<CURRENT_VIEW->numtabs;i++)
{
if (CURRENT_VIEW->tabs[i] > x)
{
next_tab_col = CURRENT_VIEW->tabs[i];
break;
}
}
#ifdef TRACE
trace_return();
#endif
return(next_tab_col);
}
/***********************************************************************/
#ifdef HAVE_PROTO
LENGTHTYPE find_prev_tab_col(LENGTHTYPE x)
#else
LENGTHTYPE find_prev_tab_col(x)
LENGTHTYPE x;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
/*--------------------------- local data ------------------------------*/
register short i=0;
LENGTHTYPE next_tab_col=0;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:find_prev_tab_col");
#endif
for (i=CURRENT_VIEW->numtabs-1;i>-1;i--)
{
if (CURRENT_VIEW->tabs[i] < x)
{
next_tab_col = CURRENT_VIEW->tabs[i];
break;
}
}
#ifdef TRACE
trace_return();
#endif
return(next_tab_col);
}
/***********************************************************************/
#ifdef HAVE_PROTO
short tabs_convert(LINE *curr,bool expand_tabs,bool use_tabs,
bool add_to_recovery)
#else
short tabs_convert(curr,expand_tabs,use_tabs,add_to_recovery)
LINE *curr;
bool expand_tabs,use_tabs,add_to_recovery;
#endif
/***********************************************************************/
{
#define STATE_NORMAL 0
#define STATE_TAB 1
/*-------------------------- external data ----------------------------*/
extern CHARTYPE *trec;
extern CHARTYPE TABI_Nx;
/*--------------------------- local data ------------------------------*/
register short i=0,j=0;
bool expanded=FALSE;
bool tabs_exhausted=FALSE;
bool state=FALSE;
LENGTHTYPE tabcol=0;
/*--------------------------- 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')
{
if (use_tabs)
{
if (tabs_exhausted)
{
trec[j++] = ' ';
if (j >= max_line_length)
break;
}
else
{
tabcol = find_next_tab_col(j+1);
if (tabcol == 0)
tabs_exhausted = TRUE;
else
{
tabcol--;
do
{
trec[j++] = ' ';
if (j >= max_line_length)
break;
}
while (j<tabcol);
}
}
}
else
{
do
{
trec[j++] = ' ';
if (j >= max_line_length)
break;
}
while ((j % TABI_Nx) != 0);
}
expanded = TRUE;
}
else
{
trec[j++] = curr->line[i];
if (j >= max_line_length)
break;
}
}
/*---------------------------------------------------------------------*/
/* If we expanded tabs, we need to reallocate memory for the line. */
/*---------------------------------------------------------------------*/
if (expanded)
{
if (add_to_recovery)
add_to_recovery_list(curr->line,curr->length);
curr->line = (CHARTYPE *)(*the_realloc)((void *)curr->line,(j+1)*sizeof(CHARTYPE));
if (curr->line == (CHARTYPE *)NULL)
{
display_error(30,(CHARTYPE *)"",FALSE);
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
/*---------------------------------------------------------------------*/
/* Copy the contents of rec into the line. */
/*---------------------------------------------------------------------*/
memcpy(curr->line,trec,j);
curr->length = j;
*(curr->line+j) = '\0';
}
}
else
{
for (i=(curr->length)-1,j=0;i>(-1);i--)
{
switch(state)
{
case STATE_NORMAL:
trec[j++] = *(curr->line+i);
if (is_tab_col(i+1)
&& i != 0)
{
if (*(curr->line+(i-1)) == ' ')
{
trec[j++] = '\t';
state = STATE_TAB;
expanded = TRUE;
}
}
break;
case STATE_TAB:
#if 0
if (*(curr->line+i) == ' ')
{
if (is_tab_col(i+1)
&& i != 0)
trec[j++] = '\t';
}
else
{
trec[j++] = *(curr->line+i);
state = STATE_NORMAL;
}
#else
if (is_tab_col(i+1)
&& i != 0)
{
if (*(curr->line+i) == ' ')
{
if (*(curr->line+(i-1)) == ' ')
trec[j++] = '\t';
}
else
{
trec[j++] = *(curr->line+i);
state = STATE_NORMAL;
}
}
else
{
if (*(curr->line+i) != ' ')
{
trec[j++] = *(curr->line+i);
state = STATE_NORMAL;
}
}
#endif
break;
}
}
if (expanded)
{
trec[j] = '\0';
curr->length = j;
for (i=0,j--;j>(-1);i++,j--)
*(curr->line+i) = trec[j];
*(curr->line+curr->length) = '\0';
}
}
#ifdef TRACE
trace_return();
#endif
return((expanded)?RC_FILE_CHANGED:RC_OK);
}
/***********************************************************************/
#ifdef HAVE_PROTO
short convert_hex_strings(CHARTYPE *str)
#else
short convert_hex_strings(str)
CHARTYPE *str;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register short i=0;
CHARTYPE *p=NULL;
bool dec_char=FALSE;
CHARTYPE temp_str[MAX_COMMAND_LENGTH];
short num=0;
CHARTYPE ch1=0,ch2=0;
/*--------------------------- 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((DEFCHAR *)str));
}
/*---------------------------------------------------------------------*/
/* Check if the last character is a single quote. If not return (-1) */
/* to indicate an error. */
/*---------------------------------------------------------------------*/
if (*(str+strlen((DEFCHAR *)str)-1) != '\'')
{
#ifdef TRACE
trace_return();
#endif
return((-1));
}
/*---------------------------------------------------------------------*/
/* If we got here we can validate the contents of the string. */
/*---------------------------------------------------------------------*/
*(str+strlen((DEFCHAR *)str)-1) = '\0';
if (*(str) == 'd'
|| *(str) == 'D')
dec_char = TRUE;
else
dec_char = FALSE;
p = (CHARTYPE *)strtok((DEFCHAR *)str+2," ");
while(p != NULL)
{
switch(dec_char)
{
case TRUE: /* parse decimal number */
if (equal((CHARTYPE *)"000000",p,1))
temp_str[i++] = (CHARTYPE)0;
else
{
num = atoi((DEFCHAR *)p);
if (num < 1 || num > 255)
{
#ifdef TRACE
trace_return();
#endif
return((-1));
}
temp_str[i++] = (CHARTYPE)num;
}
break;
case FALSE: /* parse hexidecimal number */
ch1 = *(p);
ch2 = *(p+1);
if (strlen((DEFCHAR *)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++] = (CHARTYPE)num;
break;
}
p = (CHARTYPE *)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 HAVE_PROTO
short marked_block(bool in_current_view)
#else
short marked_block(in_current_view)
bool in_current_view;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern VIEW_DETAILS *vd_mark;
extern bool batch_only;
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:marked_block");
#endif
if (batch_only) /* block commands invalid in batch */
{
display_error(24,(CHARTYPE *)"",FALSE);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_ENVIRON);
}
if (MARK_VIEW == (VIEW_DETAILS *)NULL) /* no marked block */
{
display_error(44,(CHARTYPE *)"",FALSE);
#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,(CHARTYPE *)"",FALSE);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_ENVIRON);
}
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef HAVE_PROTO
short suspend_curses(void)
#else
short suspend_curses()
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:suspend_curses");
#endif
#ifdef UNIX
# if defined(USE_EXTCURSES)
csavetty(FALSE);
reset_shell_mode();
# else
endwin();
# endif
#endif
#if WAS_HAVE_BSD_CURSES
noraw();
nl();
echo();
nocbreak();
#endif
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef HAVE_PROTO
short resume_curses(void)
#else
short resume_curses()
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:resume_curses");
#endif
#ifdef WIN32
reset_prog_mode();
#endif
#ifdef UNIX
# if defined(USE_EXTCURSES)
cresetty(FALSE);
# else
reset_prog_mode();
# ifdef HAVE_BSD_CURSES
raw();
nonl();
noecho();
cbreak();
# endif
# endif
#endif
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef HAVE_PROTO
short restore_THE(void)
#else
short restore_THE()
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern WINDOW *divider;
extern WINDOW *statarea;
extern CHARTYPE display_screens;
extern bool horizontal;
extern bool curses_started;
/*--------------------------- local data ------------------------------*/
unsigned short y=0,x=0;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:restore_THE");
#endif
/*---------------------------------------------------------------------*/
/* If curses hasn't started, no point in doing anything... */
/*---------------------------------------------------------------------*/
if (!curses_started)
{
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
getyx(CURRENT_WINDOW,y,x);
#if 0
wclear(stdscr);
refresh();
#endif
if (display_screens > 1)
{
touch_screen(other_screen);
refresh_screen(other_screen);
if (!horizontal)
{
touchwin(divider);
wnoutrefresh(divider);
}
}
touch_screen(current_screen);
if (statarea != (WINDOW *)NULL)
touchwin(statarea);
wmove(CURRENT_WINDOW,y,x);
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef HAVE_PROTO
short execute_set_sos_command(bool set_command,CHARTYPE *params)
#else
short execute_set_sos_command(set_command,params)
bool set_command;
CHARTYPE *params;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern bool in_readv;
/*--------------------------- local data ------------------------------*/
#define SETSOS_PARAMS 2
CHARTYPE *word[SETSOS_PARAMS+1];
CHARTYPE strip[SETSOS_PARAMS];
unsigned short num_params=0;
short rc=RC_OK,command_index=0;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:execute_set_sos_command");
#endif
strip[0]=STRIP_BOTH;
strip[1]=STRIP_NONE;
num_params = param_split(params,word,SETSOS_PARAMS,WORD_DELIMS,TEMP_PARAM,strip,FALSE);
if (num_params < 1)
{
display_error(1,(CHARTYPE *)"",FALSE);
#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],FALSE);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
/*---------------------------------------------------------------------*/
/* If the SOS command is being executed while in READV CMDLINE, only */
/* execute those commands that are allowed... */
/*---------------------------------------------------------------------*/
if (in_readv)
{
if (command[command_index].valid_readv)
rc = (*command[command_index].function)(word[1]);
}
else
rc = (*command[command_index].function)(word[1]);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/***********************************************************************/
#ifdef HAVE_PROTO
short valid_command_type(bool set_command,CHARTYPE *cmd_line)
#else
short valid_command_type(set_command,cmd_line)
bool set_command;
CHARTYPE *cmd_line;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register short i=0;
/*--------------------------- 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((DEFCHAR *)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 HAVE_PROTO
short allocate_temp_space(unsigned short length,CHARTYPE param_type)
#else
short allocate_temp_space(length,param_type)
unsigned short length;
CHARTYPE param_type;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
CHARTYPE *temp_ptr=NULL;
unsigned short *temp_length=NULL;
/*--------------------------- 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 = (CHARTYPE *)(*the_malloc)(sizeof(CHARTYPE)*(length+1));
else
temp_ptr = (CHARTYPE *)(*the_realloc)(temp_ptr,sizeof(CHARTYPE)*(length+1));
if (temp_ptr == NULL)
{
display_error(30,(CHARTYPE *)"",FALSE);
#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 HAVE_PROTO
void free_temp_space(CHARTYPE param_type)
#else
void free_temp_space(param_type)
CHARTYPE param_type;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
CHARTYPE *temp_ptr=NULL;
unsigned short *temp_length=0;
/*--------------------------- 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_params = NULL;
temp_length = &length_temp_params;
break;
case TEMP_MACRO:
temp_ptr = temp_macros;
temp_macros = NULL;
temp_length = &length_temp_macros;
break;
case TEMP_TMP_CMD:
temp_ptr = tmp_cmd;
tmp_cmd = NULL;
temp_length = &length_tmp_cmd;
break;
case TEMP_TEMP_CMD:
temp_ptr = temp_cmd;
temp_cmd = NULL;
temp_length = &length_temp_cmd;
break;
default:
return;
break;
}
(*the_free)(temp_ptr);
*temp_length = 0;
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef HAVE_PROTO
CHARTYPE calculate_actual_row(CHARTYPE base,short off,CHARTYPE rows,bool force_in_view)
#else
CHARTYPE calculate_actual_row(base,off,rows,force_in_view)
CHARTYPE base,rows;
short off;
bool force_in_view;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
short row=0;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:calculate_actual_row");
#endif
switch(base)
{
case POSITION_TOP:
row = off;
break;
case POSITION_MIDDLE:
row = (rows /2 ) + off;
break;
case POSITION_BOTTOM:
row = rows+off+1;
break;
}
/*---------------------------------------------------------------------*/
/* If the calculated row is outside the screen size, default to middle.*/
/*---------------------------------------------------------------------*/
if ((row < 0 || row > rows)
&& force_in_view)
row = rows / 2;
#ifdef TRACE
trace_return();
#endif
return((CHARTYPE)row-1);
}
/*man***************************************************************************
NAME
get_valid_macro_file_name
SYNOPSIS
short get_valid_macro_file_name(macroname,filename,errnum)
CHARTYPE *macroname;
CHARTYPE *filename;
short *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 HAVE_PROTO
short get_valid_macro_file_name(CHARTYPE *inmacroname,CHARTYPE *filename,short *errnum)
#else
short get_valid_macro_file_name(inmacroname,filename,errnum)
CHARTYPE *inmacroname,*filename;
short *errnum;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern CHARTYPE the_macro_path_buf[MAX_FILE_NAME+1];
extern CHARTYPE *the_macro_dir[MAX_MACRO_DIRS];
extern int max_macro_dirs;
extern CHARTYPE sp_path[MAX_FILE_NAME+1] ;
extern CHARTYPE sp_fname[MAX_FILE_NAME+1] ;
extern CHARTYPE macro_suffix[12];
/*--------------------------- local data ------------------------------*/
register short i=0;
CHARTYPE delims[3];
bool file_found=FALSE;
CHARTYPE macroname[MAX_FILE_NAME+1] ;
unsigned short num_params=0;
int len_macroname=strlen((DEFCHAR*)inmacroname);
int len_macro_suffix=strlen((DEFCHAR*)macro_suffix);
bool append_suffix=TRUE;
/*--------------------------- 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. */
/*---------------------------------------------------------------------*/
strcpy( (DEFCHAR*)macroname, (DEFCHAR*)inmacroname );
(void *)strrmdup(strtrans(macroname,OSLASH,ISLASH),ISLASH);
#ifdef UNIX
strcpy((DEFCHAR *)delims,(DEFCHAR *)ISTR_SLASH);
if (strpbrk((DEFCHAR *)macroname,(DEFCHAR *)delims) == NULL
&& *(macroname) != '~')
#endif
#if defined(DOS) || defined(OS2) || defined(WIN32)
strcpy((DEFCHAR *)delims,ISTR_SLASH);
strcat((DEFCHAR *)delims,":");
if (strpbrk((DEFCHAR *)macroname,(DEFCHAR *)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. */
/*---------------------------------------------------------------------*/
{
if (len_macroname > len_macro_suffix)
{
if (strcmp((DEFCHAR*)macroname+(len_macroname-len_macro_suffix),(DEFCHAR*)macro_suffix) == 0)
append_suffix = FALSE;
else
append_suffix = TRUE;
}
file_found = FALSE;
for (i=0;i<max_macro_dirs;i++)
{
strcpy((DEFCHAR *)filename,(DEFCHAR *)the_macro_dir[i]);
if (strlen((DEFCHAR *)filename) == 0)
continue;
if (*(filename+strlen((DEFCHAR *)filename)-1) != ISLASH)
strcat((DEFCHAR *)filename,(DEFCHAR *)ISTR_SLASH);
strcat((DEFCHAR *)filename,(DEFCHAR *)macroname); /* append the file name */
if (append_suffix)
strcat((DEFCHAR *)filename,(DEFCHAR *)macro_suffix); /* append default suffix */
if (file_exists(filename)) /* check if file exists... */
{
file_found = TRUE;
break;
}
}
if (!file_found)
{
strcpy((DEFCHAR *)filename,(DEFCHAR *)macroname);
if (append_suffix)
strcat((DEFCHAR *)filename,(DEFCHAR *)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((DEFCHAR *)filename,(DEFCHAR *)sp_path);
strcat((DEFCHAR *)filename,(DEFCHAR *)sp_fname);
if (!file_exists(filename)
|| strcmp((DEFCHAR *)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);
}
/***********************************************************************/
#ifdef HAVE_PROTO
bool define_command(CHARTYPE *cmd_line)
#else
bool define_command(cmd_line)
CHARTYPE *cmd_line;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
/*--------------------------- local data ------------------------------*/
register short i=0;
CHARTYPE buf[7];
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:define_command");
#endif
/*---------------------------------------------------------------------*/
/* First check if the command is a synonym, and use the real name to */
/* search the command array. */
/*---------------------------------------------------------------------*/
memset(buf,'\0',7);
memcpy(buf,cmd_line,min(6,strlen((DEFCHAR *)cmd_line)));
for (i=0;i<7;i++)
{
if (buf[i] == ' ')
buf[i] = '\0';
}
if ((i = find_command(buf,FALSE)) == (-1))
{
#ifdef TRACE
trace_return();
#endif
return(FALSE);
}
if (strcmp("define",(DEFCHAR *)command[i].text) == 0)
{
#ifdef TRACE
trace_return();
#endif
return(TRUE);
}
#ifdef TRACE
trace_return();
#endif
return(FALSE);
}
/***********************************************************************/
#ifdef HAVE_PROTO
int find_key_name(CHARTYPE *keyname)
#else
int find_key_name(keyname)
CHARTYPE *keyname;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
/*--------------------------- local data ------------------------------*/
register int i=0;
int key=(-1);
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:find_key_name");
#endif
for (i=0;key_table[i].mnemonic != NULL;i++)
{
if (memcmpi(keyname,key_table[i].mnemonic,strlen((DEFCHAR *)keyname)) == 0)
{
key = key_table[i].key_value;
break;
}
}
#ifdef TRACE
trace_return();
#endif
return(key);
}
/***********************************************************************/
#ifdef HAVE_PROTO
int readv_cmdline(CHARTYPE *initial)
#else
int readv_cmdline(initial)
CHARTYPE *initial;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern CHARTYPE *cmd_rec;
extern unsigned short cmd_rec_len;
extern bool in_readv;
/*--------------------------- local data ------------------------------*/
int key=0;
short rc=RC_OK;
bool cursor_on_cmdline=FALSE;
CHARTYPE buf[3];
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:readv_cmdline");
#endif
if (CURRENT_WINDOW_COMMAND == (WINDOW *)NULL)
{
display_error(86,(CHARTYPE *)"",FALSE);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
buf[1] = '\0';
if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
cursor_on_cmdline = TRUE;
Cmsg(initial);
cursor_cmdline(strlen((DEFCHAR *)initial)+1);
in_readv = TRUE; /* this MUST go here to allow cursor_cmdline() to work */
wrefresh(CURRENT_WINDOW_COMMAND);
while(1)
{
key = my_getch(stdscr);
#if defined(XCURSES)
if (key == KEY_SF || key == KEY_SR)
continue;
#endif
rc = function_key(key,OPTION_READV);
switch(rc)
{
case RC_READV_TERM:
/* cmd_rec[cmd_rec_len] = '\0';*/
set_rexx_variable((CHARTYPE *)"READV",cmd_rec,cmd_rec_len,1);
set_rexx_variable((CHARTYPE *)"READV",(CHARTYPE *)"1",1,0);
wmove(CURRENT_WINDOW_COMMAND,0,0);
my_wclrtoeol(CURRENT_WINDOW_COMMAND);
memset(cmd_rec,' ',max_line_length);
cmd_rec_len = 0;
wmove(CURRENT_WINDOW_COMMAND,0,0);
break;
case RAW_KEY:
if (rc >= RAW_KEY)
{
if (rc > RAW_KEY)
key = rc - (RAW_KEY*2);
if (key < 256 && key >= 0)
{
buf[0] = (CHARTYPE)key;
rc = Text(buf);
}
}
break;
default:
break;
}
show_statarea();
wrefresh(CURRENT_WINDOW_COMMAND);
if (rc == RC_READV_TERM)
break;
}
/*---------------------------------------------------------------------*/
/* If we were NOT on the command line, go back to where we were. */
/*---------------------------------------------------------------------*/
in_readv = FALSE; /* this MUST go here to allow cursor_home() to work */
if (!cursor_on_cmdline)
cursor_home(TRUE);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/***********************************************************************/
#ifdef HAVE_PROTO
short execute_mouse_commands(int key)
#else
short execute_mouse_commands(key)
int key;
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
extern DEFINE *first_mouse_define;
extern CHARTYPE number_of_files;
extern bool readonly;
/*--------------------------- local data ------------------------------*/
register short i=0;
DEFINE *curr=(DEFINE *)NULL;
CHARTYPE *key_cmd=NULL;
short rc=RC_OK;
short macrorc=0;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:execute_mouse_commands");
#endif
curr = first_mouse_define;
while(curr != (DEFINE *)NULL)
{
if (key == curr->def_funkey)
{
/*---------------------------------------------------------------------*/
/* If running in read-only mode and the function selected is not valid */
/* display an error. */
/*---------------------------------------------------------------------*/
if (curr->def_command != (-1)
&& readonly
&& !command[curr->def_command].valid_in_readonly)
{
display_error(56,(CHARTYPE *)"",FALSE);
rc = RC_INVALID_ENVIRON;
curr = NULL;
break;
}
/*---------------------------------------------------------------------*/
/* If there are no more files in the ring, and the command is not a */
/* command to edit a new file, then ignore the command. */
/*---------------------------------------------------------------------*/
if (curr->def_command != (-1)
&& number_of_files == 0
&& !command[curr->def_command].edit_command)
{
rc = RC_OK;
curr = NULL;
break;
}
if ((key_cmd = (CHARTYPE *)my_strdup(curr->def_params)) == NULL)
{
display_error(30,(CHARTYPE *)"",FALSE);
rc = RC_OUT_OF_MEMORY;
curr = NULL;
break;
}
if (curr->def_command == (-1))
rc = execute_macro_instore(key_cmd,¯orc);
else
rc = (*command[curr->def_command].function)((CHARTYPE *)key_cmd);
(*the_free)(key_cmd);
if (rc != RC_OK
&& rc != RC_TOF_EOF_REACHED
&& rc != RC_NO_LINES_CHANGED
&& rc != RC_TARGET_NOT_FOUND)
{
curr = NULL;
break;
}
}
if (curr == NULL)
break;
curr = curr->next;
}
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/***********************************************************************/
#ifdef HAVE_PROTO
short validate_n_m(CHARTYPE *params,short *col1,short *col2)
#else
short validate_n_m(params,col1,col2)
CHARTYPE *params;
short *col1,*col2;
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
/*--------------------------- local data ------------------------------*/
#define NM_PARAMS 2
CHARTYPE *word[NM_PARAMS+1];
CHARTYPE strip[NM_PARAMS];
unsigned short num_params=0;
short rc=RC_OK;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("commutil.c:validate_n_m");
#endif
/*---------------------------------------------------------------------*/
/* Validate the parameters that have been supplied. One only */
/* parameter MUST be supplied. The first parameter MUST be a positive */
/* integer. The second can be a positive integer or '*'. If no second */
/* parameter is supplied, defaults to p1. The second parameter MUST be */
/* >= first parameter. '*' is regarded as the biggest number and is */
/* literally 255. */
/*---------------------------------------------------------------------*/
strip[0]=STRIP_BOTH;
strip[1]=STRIP_BOTH;
num_params = param_split(params,word,NM_PARAMS,WORD_DELIMS,TEMP_PARAM,strip,FALSE);
if (num_params < 1)
{
display_error(3,(CHARTYPE *)"",FALSE);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
if (num_params > 2)
{
display_error(2,(CHARTYPE *)"",FALSE);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
if (!valid_positive_integer(word[0]))
{
display_error(4,word[0],FALSE);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
*col1 = atoi((DEFCHAR *)word[0]);
if (strcmp((DEFCHAR *)word[1],"*") == 0)
*col2 = 255;
else
if (num_params == 1) /* no second parameter, default to first */
*col2 = *col1;
else
if (!valid_positive_integer(word[1]))
{
display_error(4,word[1],FALSE);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
else
*col2 = atoi((DEFCHAR *)word[1]);
if (*col2 > 255)
*col2 = 255;
if (*col1 > *col2)
{
display_error(6,word[0],FALSE);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
#ifdef TRACE
trace_return();
#endif
return(rc);
}