home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
thesrc15.zip
/
comm1.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-21
|
50KB
|
1,661 lines
/***********************************************************************/
/* COMM1.C - Commands A-D */
/* This file contains all commands that can be assigned to function */
/* keys or typed on the command line. */
/***********************************************************************/
/*
* THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
* Copyright (C) 1991-1993 Mark Hessling
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
*
* The Free Software Foundation, Inc.
* 675 Mass Ave,
* Cambridge, MA 02139 USA.
*
*
* If you make modifications to this software that you feel increases
* it usefulness for the rest of the community, please email the
* changes, enhancements, bug fixes as well as any and all ideas to me.
* This software is going to be maintained and enhanced as deemed
* necessary by the community.
*
* Mark Hessling email: M.Hessling@gu.edu.au
* 36 David Road Phone: +61 7 849 7731
* Holland Park Fax: +61 7 875 5314
* QLD 4121
* Australia
*/
/*
$Header: C:\THE\RCS\comm1.c 1.4 1993/09/01 16:25:34 MH Interim MH $
*/
#include <stdio.h>
#include "the.h"
#include "proto.h"
/*#define DEBUG 1*/
/*-------------------------- external data ----------------------------*/
extern LINE *next_line,*curr_line;
extern VIEW_DETAILS *vd_current,*vd_first,*vd_mark;
extern char current_screen;
extern SCREEN_DETAILS screen[MAX_SCREENS]; /* screen structures */
extern WINDOW *foot,*error_window,*divider;
extern bool error_on_screen;
extern char *rec;
extern unsigned short rec_len;
extern char *cmd_rec;
extern unsigned short cmd_rec_len;
extern char mode_insert; /* defines insert mode toggle */
extern char in_profile; /* indicates if processing profile */
extern char *temp_cmd;
extern char dir_filename[10];
extern char dir_pathname[MAX_FILE_NAME+1];
extern char sp_path[MAX_FILE_NAME+1] ;
extern char sp_fname[MAX_FILE_NAME+1] ;
extern char dir_path[MAX_FILE_NAME+1] ; /* for dir and ls commands */
/*man-start*********************************************************************
COMMAND
add - add blank line
SYNTAX
ADD [n]
DESCRIPTION
The ADD command inserts the specified number of blank lines after
the current_line (if issued from the command line) or after the
focus_line (if issued in the main of prefix windows).
The cursor is positioned in the column corresponding to the first
column not containing a space in the line above.
COMPATIBILITY
XEDIT: Compatible.
KEDIT: Compatible.
DEFAULT
With no parameters, 1 line is added.
SEE ALSO
SOS ADDLINE
STATUS
Complete
**man-end**********************************************************************/
#ifdef PROTO
int Add(char *params)
#else
int Add(params)
char *params;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
#define ADD_PARAMS 1
char *word[ADD_PARAMS+1];
char parm[ADD_PARAMS];
unsigned short num_params;
long num_lines;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm1.c: Add");
#endif
/*---------------------------------------------------------------------*/
/* Validate the parameters that have been supplied. The one and only */
/* parameter should be a positive integer greater than zero. */
/* If no parameter is supplied, 1 is assumed. */
/*---------------------------------------------------------------------*/
num_params = param_split(params,word,ADD_PARAMS,WORD_DELIMS,TEMP_PARAM);
if (num_params == 0)
{
num_params = 1;
word[0] = (char *)"1";
}
if (num_params != 1)
{
display_error(1,word[1]);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
if (!valid_positive_integer(word[0]))
{
display_error(4,word[0]);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
num_lines = atol(word[0]);
post_process_line(CURRENT_VIEW->focus_line);
insert_new_line((char *)"",0,num_lines,get_true_line(),FALSE,FALSE);
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/*man-start*********************************************************************
COMMAND
all - select and display restricted set of lines
SYNTAX
ALL [string target]
DESCRIPTION
COMPATIBILITY
XEDIT: Compatible.
KEDIT: Compatible.
DEFAULT
SEE ALSO
STATUS
Not Started
**man-end**********************************************************************/
#ifdef PROTO
int All(char *params)
#else
int All(params)
char *params;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm1.c: All");
#endif
display_error(0,(char *)"This function has not yet been implemented");
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/*man-start*********************************************************************
COMMAND
backward - scroll backwards one screen
SYNTAX
BAckward [n|*]
DESCRIPTION
The BACKWARD command scrolls the file contents backwards through
the file [n|*] screens.
COMPATIBILITY
XEDIT: Compatible.
KEDIT: Does not support HALF or Lines options.
DEFAULT
With no parameters, 1 screen is scrolled.
SEE ALSO
forward,top
STATUS
Complete
**man-end**********************************************************************/
#ifdef PROTO
int Backward(char *params)
#else
int Backward(params)
char *params;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
#define BAC_PARAMS 1
char *word[BAC_PARAMS+1];
char parm[BAC_PARAMS];
register int i;
unsigned short num_params;
long num_pages,num_lines;
unsigned short x,y;
int rc;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm1.c: Backward");
#endif
num_params = param_split(params,word,BAC_PARAMS,WORD_DELIMS,TEMP_PARAM);
if (num_params == 0)
{
num_params = 1;
word[0] = (char *)"1";
}
if (num_params != 1)
{
display_error(1,(char *)word[1]);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
if (strcmp(word[0],"*") == 0)
{
CURRENT_VIEW->current_line = 0L;
post_process_line(CURRENT_VIEW->focus_line);
CURRENT_VIEW->focus_line = 0L;
pre_process_line(CURRENT_VIEW->focus_line);
if (!in_profile)
{
if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
getyx(PREVIOUS_WINDOW,y,x);
else
getyx(CURRENT_WINDOW,y,x);
show_page();
y = get_row_for_focus_line(CURRENT_VIEW->current_row,
CURRENT_VIEW->focus_line,
CURRENT_VIEW->current_line);
if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
wmove(PREVIOUS_WINDOW,y,x);
else
wmove(CURRENT_WINDOW,y,x);
}
#ifdef TRACE
trace_return();
#endif
return(RC_TOF_EOF_REACHED);
}
if ((num_pages = atol(word[0])) == 0L)
{
display_error(4,(char *)word[0]);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
num_lines = CURRENT_VIEW->current_line - ((CURRENT_SCREEN.rows-1)*num_pages);
if (num_lines < 0) /* set return code to indicate reaching TOF */
rc = RC_TOF_EOF_REACHED;
else
rc = RC_OK;
CURRENT_VIEW->current_line = max(num_lines,0);
post_process_line(CURRENT_VIEW->focus_line);
CURRENT_VIEW->focus_line = calculate_focus_line(CURRENT_VIEW->current_row,
CURRENT_VIEW->focus_line,
CURRENT_VIEW->current_line);
pre_process_line(CURRENT_VIEW->focus_line);
if (in_profile)
{
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/* getyx(CURRENT_WINDOW_MAIN,y,x);*/
getyx(CURRENT_WINDOW,y,x);
show_page();
if (CURRENT_VIEW->current_window != WINDOW_COMMAND)
{
y = get_row_for_focus_line(CURRENT_VIEW->current_row,
CURRENT_VIEW->focus_line,
CURRENT_VIEW->current_line);
wmove(CURRENT_WINDOW,y,x);
}
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/*man-start*********************************************************************
COMMAND
bottom - move to the bottom of the file
SYNTAX
BOTtom
DESCRIPTION
The BOTTOM command moves to the very end of the current file.
The last line of the file is set to the current_line.
COMPATIBILITY
XEDIT: Compatible.
KEDIT: Compatible.
SEE ALSO
forward,top
STATUS
Complete
**man-end**********************************************************************/
#ifdef PROTO
int Bottom(char *params)
#else
int Bottom(params)
char *params;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
short rc;
char cmd[10];
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm1.c: Bottom");
#endif
sprintf(cmd,":%d",CURRENT_FILE->number_lines);
rc = command_line(cmd,COMMAND_ONLY_FALSE);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/*man-start*********************************************************************
COMMAND
cancel - quickly exit from THE
SYNTAX
CANcel
DESCRIPTION
The CANCEL command exits from THE quickly by QQUITting out of all
files currently in the ring that do not have any outstanding
alterations.
COMPATIBILITY
XEDIT: Compatible.
KEDIT: Compatible.
SEE ALSO
ccancel
STATUS
Complete.
**man-end**********************************************************************/
#ifdef PROTO
int Cancel(char *params)
#else
int Cancel(params)
char *params;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
VIEW_DETAILS *save_current_view=(VIEW_DETAILS *)NULL;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm1.c: Cancel");
#endif
CURRENT_VIEW = vd_first;
while (CURRENT_VIEW != (VIEW_DETAILS *)NULL)
{
if (CURRENT_FILE->save_alt == 0)
Qquit((char *)"");
else
{
save_current_view = CURRENT_VIEW;
CURRENT_VIEW = CURRENT_VIEW->next;
}
}
if (save_current_view != (VIEW_DETAILS *)NULL)
{
CURRENT_VIEW = save_current_view;
pre_process_line(CURRENT_VIEW->focus_line);
show_page();
if (CURRENT_VIEW->prefix)
touchwin(CURRENT_WINDOW_PREFIX);
touchwin(CURRENT_WINDOW_COMMAND);
touchwin(CURRENT_WINDOW_MAIN);
touchwin(CURRENT_WINDOW);
}
#ifdef TRACE
trace_return();
#endif
return(QUIT);
}
/*man-start*********************************************************************
COMMAND
ccancel - quickly exit from THE
SYNTAX
CCancel
DESCRIPTION
The CCANCEL command exits from THE quickly by QQUITting out of all
files currently in the ring. Any changes made to any of the files
will be lost.
COMPATIBILITY
XEDIT: N/A
KEDIT: N/A
SEE ALSO
cancel
STATUS
Complete.
**man-end**********************************************************************/
#ifdef PROTO
int Ccancel(char *params)
#else
int Ccancel(params)
char *params;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm1.c: Ccancel");
#endif
CURRENT_VIEW = vd_first;
while (CURRENT_VIEW != (VIEW_DETAILS *)NULL)
{
Qquit((char *)"");
}
#ifdef TRACE
trace_return();
#endif
return(QUIT);
}
/*man-start*********************************************************************
COMMAND
change - change file text
SYNTAX
Change /string1/string2/ [target] [n] [m]
DESCRIPTION
The CHANGE command changes one string of text to another.
The first parameter to the change command is the old and new
string values, seperated by delimiters.
The allowable delimiters are '/' '\' and '@'.
The second parameter is the target; how many lines are to be
searched for occurrences of the first string to be changed.
The third parameter determines how many occurrences of 'string1'
are to be changed on each line.
The fourth parameter determines at which occurrences of 'string1'
on the line are changes to commence.
COMPATIBILITY
XEDIT: Compatible.
KEDIT: Compatible.
DEFAULT
1 1 1
SEE ALSO
schange
STATUS
Complete.
**man-end**********************************************************************/
#ifdef PROTO
int Change(char *params)
#else
int Change(params)
char *params;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
short rc;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm1.c: Change");
#endif
rc = execute_change_command(params,FALSE);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/*man-start*********************************************************************
COMMAND
cmatch - find matching bracket character
SYNTAX
** effective only if bound to a key **
DESCRIPTION
The CMATCH command searches for the matching bracket character to
the character under the cursor.
It handles nested sets of matching pairs.
The matching character pairs are '[]{}<>()'.
COMPATIBILITY
XEDIT: N/A
KEDIT: Compatible.
STATUS
Complete.
**man-end**********************************************************************/
#ifdef PROTO
int Cmatch(char *params)
#else
int Cmatch(params)
char *params;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
static char *match = (char *)"[]{}<>()";
unsigned short x,y;
char ch,match_ch;
register int i;
int direction_backward;
short matches=1,match_col=(-1),start_col;
long offset=0;
LINE *curr;
WINDOW *w;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm1.c: Cmatch");
#endif
/*---------------------------------------------------------------------*/
/* This command only allowed to be issued from with the MAIN window. */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->current_window != WINDOW_MAIN
|| in_profile)
{
display_error(66,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_ENVIRON);
}
if (CURRENT_VIEW->focus_line == 0
|| CURRENT_VIEW->focus_line == CURRENT_FILE->number_lines+1)
{
display_error(66,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_TOF_EOF_REACHED);
}
getyx(CURRENT_WINDOW,y,x);
/*---------------------------------------------------------------------*/
/* Check if the character under the cursor is a valid match character. */
/*---------------------------------------------------------------------*/
w = CURRENT_WINDOW;
ch = (char)winch(w) & A_CHARTEXT;
match_ch = 0;
for (i=0;i<strlen(match);i++)
if (ch == *(match+i))
{
direction_backward = (i % 2);
match_ch = (direction_backward) ? *(match+i-1) : *(match+i+1);
break;
}
if (match_ch == 0)
{
display_error(67,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
/*---------------------------------------------------------------------*/
/* Calculate the actual position of the character in the LINE. */
/*---------------------------------------------------------------------*/
start_col = CURRENT_VIEW->verify_col + x - 1;
start_col += (direction_backward) ? (-1) : 1;
/*---------------------------------------------------------------------*/
/* Find the focus line linked list entry. */
/*---------------------------------------------------------------------*/
post_process_line(CURRENT_VIEW->focus_line);
#ifdef USE_VOID
curr = (LINE *)ll_find((void *)CURRENT_FILE->first_line,CURRENT_VIEW->focus_line);
#else
curr = lll_find(CURRENT_FILE->first_line,CURRENT_VIEW->focus_line);
#endif
while (curr->next != NULL && curr->prev != NULL)
{
if (direction_backward)
{
for (i=start_col;i>(-1);i--)
{
if (*(curr->line+i) == ch)
matches++;
else
if (*(curr->line+i) == match_ch)
matches--;
if (matches == 0) /* found matching one */
{
match_col = i;
break;
}
}
if (match_col != (-1))
break;
curr = curr->prev;
offset--;
start_col = curr->length;
}
else
{
for (i=start_col;i<curr->length;i++)
{
if (*(curr->line+i) == ch)
matches++;
else
if (*(curr->line+i) == match_ch)
matches--;
if (matches == 0) /* found matching one */
{
match_col = i;
break;
}
}
if (match_col != (-1))
break;
curr = curr->next;
offset++;
start_col = 0;
}
}
if (match_col == (-1)) /* no match found */
{
display_error(68,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_TARGET_NOT_FOUND);
}
/*---------------------------------------------------------------------*/
/* If we get here, we have found the matching character, so we have to */
/* move the cursor to the new column and/or line. */
/*---------------------------------------------------------------------*/
if (offset == 0L)
{
if (match_col >= CURRENT_VIEW->verify_col-1
&& match_col <= (CURRENT_SCREEN.cols+(CURRENT_VIEW->verify_col-1))-1)
/*---------------------------------------------------------------------*/
/* If the new cursor position is in the same panel and on the same line*/
/* just move the cursor there and get out. */
/*---------------------------------------------------------------------*/
{
wmove(CURRENT_WINDOW,y,match_col-(CURRENT_VIEW->verify_col-1));
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
else
{
x = CURRENT_SCREEN.cols / 2;
CURRENT_VIEW->verify_col = max(1,match_col-(short)x);
show_page();
wmove(CURRENT_WINDOW,y,(match_col-(CURRENT_VIEW->verify_col-1)));
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
}
CURRENT_VIEW->focus_line += offset;
pre_process_line(CURRENT_VIEW->focus_line);
if (offset + y <= 0
|| offset + y >= CURRENT_SCREEN.rows)
{
CURRENT_VIEW->current_line = CURRENT_VIEW->focus_line;
y = CURRENT_VIEW->current_row;
}
else
y = get_row_for_focus_line(CURRENT_VIEW->current_row,
CURRENT_VIEW->focus_line,
CURRENT_VIEW->current_line);
if (match_col >= CURRENT_VIEW->verify_col-1
&& match_col <= (CURRENT_SCREEN.cols+(CURRENT_VIEW->verify_col-1))-1)
x = match_col-(CURRENT_VIEW->verify_col-1);
else
{
x = CURRENT_SCREEN.cols / 2;
CURRENT_VIEW->verify_col = max(1,match_col-(short)x);
x = (match_col-(CURRENT_VIEW->verify_col-1));
}
show_page();
wmove(CURRENT_WINDOW,y,x);
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/*man-start*********************************************************************
COMMAND
cmsg - display text on command line
SYNTAX
CMSG [text]
DESCRIPTION
The CMSG command, primarily used in macros, displays text on the
command line.
COMPATIBILITY
XEDIT: Compatible.
KEDIT: Compatible.
SEE ALSO
EMSG, MSG
STATUS
Complete.
**man-end**********************************************************************/
#ifdef PROTO
int Cmsg(char *params)
#else
int Cmsg(params)
char *params;
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
extern bool clear_command;
extern bool extended_display_mode;
register int i;
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm1.c: Cmsg");
#endif
memset(cmd_rec,' ',COLS);
cmd_rec_len = strlen(params);
memcpy(cmd_rec,params,cmd_rec_len);
wmove(CURRENT_WINDOW_COMMAND,0,0);
my_wclrtoeol(CURRENT_WINDOW_COMMAND);
/*---------------------------------------------------------------------*/
/* If the terminal is in ETMODE, display all characters as is, else */
/* display message with translation of non-displaying characters. */
/*---------------------------------------------------------------------*/
if (extended_display_mode)
{
for (i=0;i<cmd_rec_len;i++)
mvwaddch(CURRENT_WINDOW_COMMAND,0,i,cmd_rec[i]);
}
else
put_string(CURRENT_WINDOW_COMMAND,0,0,cmd_rec,cmd_rec_len);
clear_command = FALSE;
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/*man-start*********************************************************************
COMMAND
command - execute a command without synonym translation
SYNTAX
COMMAND command [options]
DESCRIPTION
The COMMAND command executes the specified command without
synonym translation. THE does not attempt to execute the command
as a macro even if IMPMACRO is ON. The command will be passed
to the operating system if IMPOS is ON.
COMPATIBILITY
XEDIT: Compatible.
KEDIT: Compatible.
STATUS
Complete.
**man-end**********************************************************************/
#ifdef PROTO
int Command(char *params)
#else
int Command(params)
char *params;
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
/*--------------------------- local data ------------------------------*/
int rc;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm1.c: Command");
#endif
rc = command_line(params,COMMAND_ONLY_TRUE);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/*man-start*********************************************************************
COMMAND
control_char - allow control characters to be entered
SYNTAX
** effective only if bound to a key **
DESCRIPTION
The CONTROL_CHAR command prompts the user to enter a control character.
COMPATIBILITY
XEDIT: N/A
KEDIT: N/A
STATUS
Complete.
**man-end**********************************************************************/
#ifdef PROTO
int Control_char(char *params)
#else
int Control_char(params)
char *params;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
unsigned short key;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm1.c: Control_char");
#endif
display_error(0,(char *)"Press the character you require.");
touchwin(error_window);
doupdate();
key = my_getch(CURRENT_WINDOW);
if (islower(key))
key = toupper(key);
if (key >= '@'
&& key <= '_')
{
error_on_screen = FALSE;
touchwin(foot);
#ifdef TRACE
trace_return();
#endif
return((RAW_KEY*2)+key-'@');
}
display_error(69,(char *)"- must be between '@' and '_'");
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
/*man-start*********************************************************************
COMMAND
copy - copies text from one position to another
SYNTAX
COPY target1 target2
or
COPY BLOCK [RESET]
DESCRIPTION
With the first form of the COPY command, text is copied from the
first target area to the line specified by target2. Text can
only be copied within the same view of the file.
The second form of the COPY command copies text within the
currently marked block to the current cursor position.
The text can be in the same file or a different file.
COMPATIBILITY
The first form of the COPY command has not yet been implemented.
XEDIT: Not implemented.
KEDIT: Adds extra functionality with [RESET] option.
With the cursor in the marked block this command in KEDIT
acts like DUPLICATE BLOCK.
STATUS
Complete.
**man-end**********************************************************************/
#ifdef PROTO
int Copy(char *params)
#else
int Copy(params)
char *params;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
#define COP_PARAMS 2
char *word[COP_PARAMS+1];
unsigned short num_params;
long num_lines;
LINE *curr_dst,*curr_src;
register int i,j;
unsigned short y,x;
long true_line,off;
char reset_block=0;
bool dst_inside_src;
int rc;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm1.c: Copy");
#endif
num_params = param_split(params,word,COP_PARAMS,WORD_DELIMS,TEMP_PARAM);
if (num_params == 0)
{
display_error(3,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
if (num_params > 2)
{
display_error(2,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
/*---------------------------------------------------------------------*/
/* Test for second form of COPY; block operation. */
/*---------------------------------------------------------------------*/
if (num_params == 1
&& equal((char *)"block",word[0],5))
reset_block = SOURCE_BLOCK;
if (num_params == 2
&& equal((char *)"block",word[0],5)
&& equal((char *)"reset",word[1],5))
reset_block = SOURCE_BLOCK_RESET;
if (reset_block == 0)
{
display_error(0,(char *)"This option has not yet been implemented");
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
/*---------------------------------------------------------------------*/
/* If no marked block in any view, return error. */
/*---------------------------------------------------------------------*/
if (marked_block(FALSE) != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_ENVIRON);
}
/*---------------------------------------------------------------------*/
/* For box blocks, call the appropriate function... */
/*---------------------------------------------------------------------*/
if (MARK_VIEW->mark_type != M_LINE)
{
box_operations(BOX_C,reset_block,FALSE,' ');
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/*---------------------------------------------------------------------*/
/* Determine the target line. If on the command line, target is current*/
/* line, else target line is focus line. */
/*---------------------------------------------------------------------*/
true_line = get_true_line();
/*---------------------------------------------------------------------*/
/* If the true line is the bottom of file line, subtract 1 from it. */
/*---------------------------------------------------------------------*/
if (BOF(true_line))
true_line--;
post_process_line(CURRENT_VIEW->focus_line);
rc = rearrange_line_blocks(COMMAND_COPY,(char)reset_block,MARK_VIEW->mark_start_line,
MARK_VIEW->mark_end_line,true_line,1,MARK_VIEW,CURRENT_VIEW);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/*man-start*********************************************************************
COMMAND
define - assign one or many commands to a key
SYNTAX
DEFine key-name [command [args] [[#command [args]...]]]
DESCRIPTION
The DEFINE command allows the user to assign one or many
commands and optional parameter(s) to a key.
Commands may be abbreviated.
If multiple commands are assigned, then the LINEND setting
must be ON and the LINEND character must match the character
that delimits the commands at the time that the DEFINE command
is executed and at the time the key is pressed.
With no arguments, any existing definition for that key is
removed and the key reverts back to its default assignation (if
it had any).
key-names correspond to the key name shown with the SHOW command.
COMPATIBILITY
XEDIT: N/A
KEDIT: Minimal. No support for in-memory macro commands.
KEDIT does not allow multiple commands except as KEXX
macros.
SEE ALSO
SHOW
STATUS
Complete.
**man-end**********************************************************************/
#ifdef PROTO
int Define(char *params)
#else
int Define(params)
char *params;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
#define DEF_PARAMS 2
char *word[DEF_PARAMS+1];
char parm[DEF_PARAMS];
unsigned short num_params;
short key_value;
int rc=RC_OK;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm1.c: Define");
#endif
num_params = param_split(params,word,DEF_PARAMS,WORD_DELIMS,TEMP_PARAM);
if (num_params ==0)
{
display_error(3,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
/*---------------------------------------------------------------------*/
/* The first parameter is the key name mnemonic , the next is one or */
/* more commands and/or parameters. */
/* First check the mnemonic for decimal string value. ie begins with \ */
/*---------------------------------------------------------------------*/
if (word[0][0] == '\\')
{
if ((key_value = atoi(word[0]+1)) == 0)
{
display_error(13,word[0]);
rc = RC_INVALID_OPERAND;
}
}
else
{
if ((key_value = find_key_value(word[0])) == (-1))
{
display_error(13,word[0]);
rc = RC_INVALID_OPERAND;
}
}
if (rc == RC_OK)
rc = add_define(key_value,word[1]);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/*man-start*********************************************************************
COMMAND
delete - delete lines from a file
SYNTAX
DELete [target|BLOCK]
DESCRIPTION
The DELETE command allows the user remove lines from the current
file. The number of lines removed depends on the target specified.
Lines are removed starting with the current_line.
COMPATIBILITY
XEDIT: BLOCK option not supported in XEDIT.
KEDIT: Compatible.
DEFAULT
1 (the current line)
SEE ALSO
SOS DELETE
STATUS
Complete.
**man-end**********************************************************************/
#ifdef PROTO
int DeleteLine(char *params)
#else
int DeleteLine(params)
char *params;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
#define DEL_PARAMS 1
char *word[DEL_PARAMS+1];
char parm[DEL_PARAMS];
register int i;
unsigned short num_params;
long num_lines,true_line;
unsigned short x,y;
int direction;
LINE *curr;
bool block_delete=FALSE;
int rc;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm1.c: DeleteLine");
#endif
/*---------------------------------------------------------------------*/
/* Validate the parameters that have been supplied. */
/* Valid values are: a target or "block". */
/* If no parameter is supplied, 1 is assumed. */
/*---------------------------------------------------------------------*/
num_params = param_split(params,word,DEL_PARAMS,WORD_DELIMS,TEMP_PARAM);
if (num_params == 0)
{
num_params = 1;
word[0] = (char *)"1";
}
/*---------------------------------------------------------------------*/
/* Set up and validate parameters for "block" deletes. */
/*---------------------------------------------------------------------*/
if (equal((char *)"block",word[0],5))
{
block_delete = TRUE;
if (marked_block(TRUE) != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_ENVIRON);
}
if (MARK_VIEW->mark_type != M_LINE)
{
box_operations(BOX_D,SOURCE_BLOCK_RESET,FALSE,' ');
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
num_lines = CURRENT_VIEW->mark_end_line-CURRENT_VIEW->mark_start_line+1L;
true_line = CURRENT_VIEW->mark_start_line;
direction = DIRECTION_FORWARD;
}
else
/*---------------------------------------------------------------------*/
/* Set up and validate parameters for deletes from command line or */
/* sos delline. */
/*---------------------------------------------------------------------*/
{
if (equal((char *)"all",word[0],3))
true_line = 1L;
else
true_line = get_true_line();
if ((num_lines = valid_target(word[0],true_line)) == TARGET_ERROR)
{
display_error(4,(char *)word[0]);
#ifdef TRACE
trace_return();
#endif
return(RC_TARGET_NOT_FOUND);
}
if (num_lines == TARGET_NOT_FOUND)
{
display_error(17,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_TARGET_NOT_FOUND);
}
/*---------------------------------------------------------------------*/
/* Determine in which direction we are deleting. */
/*---------------------------------------------------------------------*/
if (num_lines < 0)
{
direction = DIRECTION_BACKWARD;
num_lines = num_lines * (-1L);
}
else
direction = DIRECTION_FORWARD;
/*---------------------------------------------------------------------*/
/* Check from which window the command was issued and make adjustments */
/* as required. */
/* Commands issued from the command window relate to the current line, */
/* commands issued from either the prefix or main window relate to the */
/* focus line. */
/*---------------------------------------------------------------------*/
if (equal((char *)"all",word[0],3))
;
else
if (CURRENT_VIEW->current_window == WINDOW_COMMAND
|| in_profile)
{
if (true_line == 0L)
{
true_line++;
if (!valid_integer(word[0]))
num_lines--;
}
if (BOF(true_line))
{
true_line--;
if (!valid_integer(word[0]))
num_lines--;
}
}
else
{
if (BOF(true_line) || TOF(true_line))
{
display_error(38,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_ENVIRON);
}
post_process_line(true_line);
}
}
rc = rearrange_line_blocks(COMMAND_DELETE,TRUE,true_line,
(direction == DIRECTION_FORWARD ? true_line+num_lines-1L : true_line-num_lines+1L),
true_line,1,CURRENT_VIEW,CURRENT_VIEW);
#ifdef TRACE
trace_return();
#endif
if (CURRENT_BOF || CURRENT_TOF)
return(RC_TOF_EOF_REACHED);
else
return(RC_OK);
}
/*man-start*********************************************************************
COMMAND
directory - list the specified directory
SYNTAX
DIRectory [directory]
DESCRIPTION
The DIRECTORY command displays all files in the specified directory.
When no parameter is supplied, the current directory is displayed.
COMPATIBILITY
XEDIT: N/A
KEDIT: Compatible.
STATUS
Complete.
**man-end**********************************************************************/
#ifdef PROTO
int Directory(char *params)
#else
int Directory(params)
char *params;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
#define DIR_PARAMS 1
char *word[DIR_PARAMS+1];
unsigned short num_params;
int rc;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm1.c: Directory");
#endif
/*---------------------------------------------------------------------*/
/* Validate the parameters that have been supplied. The one and only */
/* parameter should be the directory to display. */
/*---------------------------------------------------------------------*/
num_params = param_split(params,word,DIR_PARAMS,WORD_DELIMS,TEMP_PARAM);
if (num_params > 1)
{
display_error(1,(char *)word[1]);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
/*---------------------------------------------------------------------*/
/* Validate that the supplied directory is valid. */
/*---------------------------------------------------------------------*/
if ((rc = splitpath(strtrans(word[0],OSLASH,ISLASH))) != RC_OK)
{
display_error(10,(char *)word[0]);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
if ((rc = read_directory()) != RC_OK)
{
display_error(10,(char *)word[0]);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
strcpy(temp_cmd,dir_pathname);
strcat(temp_cmd,dir_filename);
Xedit(temp_cmd);
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/*man-start*********************************************************************
COMMAND
down_arrow - move the cursor down one line
SYNTAX
** effective only if bound to a key **
DESCRIPTION
The down_arrow command moves the cursor down one line in the main
window. Scrolling of the window occurs if the cursor is on the last
line of the window and CMDARROWS ... SCROLL is set (the default),
otherwise the cursor returns to the command line.
When on the command line, this command moves forward through the
list of previous command line commands if CMDARROWS RETRIEVE ...
is set or tabs to the first line of the main window if
CMDARROWS TAB ... is set.
COMPATIBILITY
XEDIT: N/A
KEDIT: Equivalent of CURSOR DOWN.
SEE ALSO
Up_arrow
STATUS
Complete.
**man-end**********************************************************************/
#ifdef PROTO
int Down_arrow(char *params)
#else
int Down_arrow(params)
char *params;
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
extern char CMDARROWSTABCMDx;
extern char CMDARROWSTABTXTx;
/*--------------------------- local data ------------------------------*/
unsigned short x,y;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm1.c: Down_arrow");
#endif
switch(CURRENT_VIEW->current_window)
{
case WINDOW_PREFIX:
case WINDOW_MAIN:
getyx(CURRENT_WINDOW,y,x);
/*---------------------------------------------------------------------*/
/* If the cursor is on the first line of the window or on the first */
/* line of the file and tabbibg to the command line is set, tab to the */
/* command line. */
/*---------------------------------------------------------------------*/
if (CMDARROWSTABTXTx
&& (FOCUS_BOF || y == CURRENT_SCREEN.rows-1))
{
Tabcmd("");
break;
}
/*---------------------------------------------------------------------*/
/* If the cursor is on the last line of the file... */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->current_line+y-
CURRENT_VIEW->current_row == CURRENT_FILE->number_lines+1)
{
/*---------------------------------------------------------------------*/
/* ... and the last line of the file is on the current row, stay there.*/
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW->current_line ==
CURRENT_FILE->number_lines+1)
break;
/*---------------------------------------------------------------------*/
/* ... and the last line of the file is below the current row, */
/* scroll the window up one line. */
/*---------------------------------------------------------------------*/
CURRENT_VIEW->current_line++;
show_page();
wmove(CURRENT_WINDOW,y-1,x);
break;
}
/*---------------------------------------------------------------------*/
/* If on the bottom of the window, scroll the window up 1 line. */
/*---------------------------------------------------------------------*/
if (y == CURRENT_SCREEN.rows-1) /* on bottom of window */
{
CURRENT_VIEW->current_line++;
post_process_line(CURRENT_VIEW->focus_line);
CURRENT_VIEW->focus_line++;
pre_process_line(CURRENT_VIEW->focus_line);
show_page();
wmove(CURRENT_WINDOW,y,x);
break;
}
/*---------------------------------------------------------------------*/
/* We are in the middle of the window, so just move the cursor down */
/* 1 line. */
/*---------------------------------------------------------------------*/
wmove(CURRENT_WINDOW,y+1,x);
post_process_line(CURRENT_VIEW->focus_line);
CURRENT_VIEW->focus_line++;
pre_process_line(CURRENT_VIEW->focus_line);
break;
case WINDOW_COMMAND:
/*---------------------------------------------------------------------*/
/* Cycle forward through the command list or tab to first line. */
/*---------------------------------------------------------------------*/
if (CMDARROWSTABCMDx)
{
getyx(CURRENT_WINDOW,y,x);
if (CURRENT_VIEW->prefix != PREFIX_LEFT)
x += 6;
if (CURRENT_VIEW->current_line > CURRENT_VIEW->current_row)
{
CURRENT_VIEW->focus_line = CURRENT_VIEW->current_line -
CURRENT_VIEW->current_row ;
y = 0;
}
else
{
CURRENT_VIEW->focus_line = 0;
y = CURRENT_VIEW->current_row -
CURRENT_VIEW->current_line ;
}
pre_process_line(CURRENT_VIEW->focus_line);
CURRENT_VIEW->current_window = WINDOW_MAIN;
wmove(CURRENT_WINDOW,y,x);
}
else
Retrieve("+");
break;
default:
display_error(2,(char *)"");
break;
}
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/*man-start*********************************************************************
COMMAND
duplicate - duplicate lines
SYNTAX
DUPlicate [n [target|BLOCK]]
DESCRIPTION
The DUPLICATE command copies the number of lines extrapolated from
target, n times.
COMPATIBILITY
XEDIT: Equivalent of DUPLICAT command.
KEDIT: Compatible.
STATUS
Complete.
**man-end**********************************************************************/
#ifdef PROTO
int Duplicate(char *params)
#else
int Duplicate(params)
char *params;
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
/*--------------------------- local data ------------------------------*/
unsigned short x,y;
#define DUP_PARAMS 2
char *word[DUP_PARAMS+1];
unsigned short num_params;
int rc,num_occ;
long num_lines,true_line,start_line,end_line,dest_line;
char command_source;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("comm1.c: Duplicate");
#endif
num_params = param_split(params,word,DUP_PARAMS,WORD_DELIMS,TEMP_PARAM);
/*---------------------------------------------------------------------*/
/* If no parameters, default to 1 1 */
/*---------------------------------------------------------------------*/
if (num_params == 0)
{
word[0] = (char *)"1";
word[1] = (char *)"1";
}
/*---------------------------------------------------------------------*/
/* If 1 parameter, default 2nd parameter to 1 */
/*---------------------------------------------------------------------*/
if (num_params == 1)
word[1] = (char *)"1";
/*---------------------------------------------------------------------*/
/* If first parameter is not an integer, error. */
/*---------------------------------------------------------------------*/
if (!valid_integer(word[0]))
{
display_error(4,word[0]);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
num_occ = atoi(word[0]);
/*---------------------------------------------------------------------*/
/* If second parameter is BLOCK, don't check for valid_target... */
/*---------------------------------------------------------------------*/
if (equal((char *)"block",word[1],5))
{
if (marked_block(TRUE) != RC_OK)
{
display_error(44,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_ENVIRON);
}
/*---------------------------------------------------------------------*/
/* This function not valid for box blocks. */
/*---------------------------------------------------------------------*/
if (MARK_VIEW->mark_type == M_BOX)
{
display_error(48,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_ENVIRON);
}
command_source = SOURCE_BLOCK;
start_line = MARK_VIEW->mark_start_line;
end_line = dest_line = MARK_VIEW->mark_end_line;
}
else
{
/*---------------------------------------------------------------------*/
/* If second parameter is not a valid target, error. */
/*---------------------------------------------------------------------*/
true_line = get_true_line();
num_lines = valid_target(word[1],true_line);
if (num_lines == TARGET_ERROR)
{
display_error(4,word[1]);
#ifdef TRACE
trace_return();
#endif
return(RC_INVALID_OPERAND);
}
if (num_lines == TARGET_NOT_FOUND)
{
display_error(17,word[1]);
#ifdef TRACE
trace_return();
#endif
return(RC_TARGET_NOT_FOUND);
}
/*---------------------------------------------------------------------*/
/* If the number of lines to the target is negative, make it positive */
/* and change the true_line to be arget is negative, make it positive */
/*---------------------------------------------------------------------*/
if (num_lines < 0)
{
true_line += num_lines;
num_lines = -num_lines;
}
/*---------------------------------------------------------------------*/
/* If we are on the top of file line, start from the next line... */
/*---------------------------------------------------------------------*/
if (TOF(true_line)
&& num_lines > 0L)
{
true_line++;
num_lines--;
}
/*---------------------------------------------------------------------*/
/* If we are on the bottom of file line, start from the previous line..*/
/*---------------------------------------------------------------------*/
if (BOF(true_line)
&& num_lines < 0L)
{
true_line--;
num_lines++;
}
command_source = SOURCE_COMMAND;
start_line = true_line;
end_line = dest_line = true_line + num_lines -1L;
}
post_process_line(CURRENT_VIEW->focus_line);
rc = rearrange_line_blocks(COMMAND_DUPLICATE,command_source,start_line,end_line,dest_line,num_occ,CURRENT_VIEW,CURRENT_VIEW);
#ifdef TRACE
trace_return();
#endif
return(rc);
}