334 lines
10 KiB
C
334 lines
10 KiB
C
|
/*****************************************************************************
|
||
|
ExeF()
|
||
|
This function executes a F command.
|
||
|
nF_ Destructive search and replace
|
||
|
F' Flow to end of conditional
|
||
|
F< Flow to start of iteration
|
||
|
F> Flow to end of iteration
|
||
|
F| Flow to ELSE part of conditional
|
||
|
m,nFB Search between locations m and n
|
||
|
nFB Search, bounded by n lines
|
||
|
m,nFC Search and replace between locations m and n
|
||
|
nFC Search and replace over n lines
|
||
|
nFD Search and delete string
|
||
|
nFK Search and delete intervening text
|
||
|
nFN Global string replace
|
||
|
FR Replace last string
|
||
|
nFS Local string replace
|
||
|
*****************************************************************************/
|
||
|
#include "zport.h" /* define portability identifiers */
|
||
|
#include "tecoc.h" /* define general identifiers */
|
||
|
#include "defext.h" /* define external global variables */
|
||
|
#include "chmacs.h" /* define character processing macros */
|
||
|
#include "deferr.h" /* define identifiers for error messages */
|
||
|
#if USE_PROTOTYPES
|
||
|
static DEFAULT ExeFBr(void);
|
||
|
static DEFAULT ExeFC(void);
|
||
|
static DEFAULT ExeFD(void);
|
||
|
static DEFAULT ExeFGt(void);
|
||
|
static DEFAULT ExeFK(void);
|
||
|
static DEFAULT ExeFLs(void);
|
||
|
static DEFAULT ExeFN(void);
|
||
|
static DEFAULT ExeFR(void);
|
||
|
static DEFAULT ExeFS(void);
|
||
|
static DEFAULT ExeFSQ(void);
|
||
|
static DEFAULT ExeFUn(void);
|
||
|
#endif
|
||
|
/*****************************************************************************
|
||
|
ExeFBr()
|
||
|
This function executes a F| (F-bar) command.
|
||
|
*****************************************************************************/
|
||
|
static DEFAULT ExeFBr() /* execute an F| command */
|
||
|
{
|
||
|
DBGFEN(1,"ExeFBr",NULL);
|
||
|
CmdMod = '\0'; /* clear modifiers flags */
|
||
|
EStTop = EStBot; /* clear expression stack */
|
||
|
DBGFEX(1,DbgFNm,"FlowEE()");
|
||
|
return FlowEE();
|
||
|
}
|
||
|
/*****************************************************************************
|
||
|
ExeFC()
|
||
|
This function executes a FC command.
|
||
|
*****************************************************************************/
|
||
|
static DEFAULT ExeFC() /* execute an FC command */
|
||
|
{
|
||
|
DBGFEN(1,"ExeFC",NULL);
|
||
|
if (CmdMod & DCOLON) { /* if it's ::FC */
|
||
|
ErrStr(ERR_ILL, "::FC"); /* illegal command "::FC" */
|
||
|
DBGFEX(1,DbgFNm,"FAILURE");
|
||
|
return FAILURE;
|
||
|
}
|
||
|
SrcTyp = FB_SEARCH;
|
||
|
if (Replac() == FAILURE) {
|
||
|
DBGFEX(1,DbgFNm,"FAILURE");
|
||
|
return FAILURE;
|
||
|
}
|
||
|
CmdMod = '\0'; /* clear modifiers flags */
|
||
|
DBGFEX(1,DbgFNm,"SUCCESS");
|
||
|
return SUCCESS;
|
||
|
}
|
||
|
/*****************************************************************************
|
||
|
ExeFD()
|
||
|
This function executes a FD command.
|
||
|
*****************************************************************************/
|
||
|
static DEFAULT ExeFD() /* execute an FD command */
|
||
|
{
|
||
|
DBGFEN(1,"ExeFD",NULL);
|
||
|
/*
|
||
|
* The command m,nFD is illegal: the user should use m,nFB
|
||
|
*/
|
||
|
if (CmdMod & MARGIS) { /* if it's m,nFD */
|
||
|
ErrStr(ERR_ILL, "m,nFD"); /* illegal command "m,nFD" */
|
||
|
DBGFEX(1,DbgFNm,"FAILURE");
|
||
|
return FAILURE;
|
||
|
}
|
||
|
if (CmdMod & DCOLON) { /* if it's ::FD */
|
||
|
ErrStr(ERR_ILL, "::FD"); /* illegal command "::FD" */
|
||
|
DBGFEX(1,DbgFNm,"FAILURE");
|
||
|
return FAILURE;
|
||
|
}
|
||
|
SrcTyp = S_SEARCH;
|
||
|
if (Search(FALSE) == FAILURE) {
|
||
|
DBGFEX(1,DbgFNm,"FAILURE");
|
||
|
return FAILURE;
|
||
|
}
|
||
|
if (Matchd) { /* if successful search */
|
||
|
GapBeg += RefLen; /* delete found string */
|
||
|
}
|
||
|
CmdMod = '\0'; /* clear modifiers flags */
|
||
|
DBGFEX(1,DbgFNm,"SUCCESS");
|
||
|
return SUCCESS;
|
||
|
}
|
||
|
/*****************************************************************************
|
||
|
ExeFGt()
|
||
|
This function executes a F> command.
|
||
|
*****************************************************************************/
|
||
|
static DEFAULT ExeFGt() /* execute an F> command */
|
||
|
{
|
||
|
DBGFEN(1,"ExeFGt",NULL);
|
||
|
if (LStTop == LStBot) { /* if not in a loop */
|
||
|
DBGFEX(1,DbgFNm,"FAILURE");
|
||
|
return FAILURE;
|
||
|
}
|
||
|
if (FlowEL() == FAILURE) { /* flow to end-of-loop */
|
||
|
DBGFEX(1,DbgFNm,"FAILURE");
|
||
|
return FAILURE;
|
||
|
}
|
||
|
CBfPtr--; /* backup before the ">" */
|
||
|
LStTop++; /* cancel what FlowEL did */
|
||
|
CmdMod = '\0'; /* clear modifiers flags */
|
||
|
EStTop = EStBot; /* clear expression stack */
|
||
|
DBGFEX(1,DbgFNm,"SUCCESS");
|
||
|
return SUCCESS;
|
||
|
}
|
||
|
/*****************************************************************************
|
||
|
ExeFK()
|
||
|
This function executes a FK command.
|
||
|
*****************************************************************************/
|
||
|
static DEFAULT ExeFK() /* execute an FK command */
|
||
|
{
|
||
|
DBGFEN(1,"ExeFK",NULL);
|
||
|
if (CmdMod & MARGIS) { /* if it's m,nFK */
|
||
|
ErrStr(ERR_ILL, "m,nFK"); /* illegal command "m,nFK" */
|
||
|
DBGFEX(1,DbgFNm,"FAILURE");
|
||
|
return FAILURE;
|
||
|
}
|
||
|
if (CmdMod & DCOLON) { /* if it's ::FK */
|
||
|
ErrStr(ERR_ILL, "::FK"); /* illegal command "::FK" */
|
||
|
DBGFEX(1,DbgFNm,"FAILURE");
|
||
|
return FAILURE;
|
||
|
}
|
||
|
SrcTyp = FK_SEARCH;
|
||
|
if (Search(FALSE) == FAILURE) {
|
||
|
DBGFEX(1,DbgFNm,"FAILURE");
|
||
|
return FAILURE;
|
||
|
}
|
||
|
CmdMod = '\0'; /* clear modifiers flags */
|
||
|
DBGFEX(1,DbgFNm,"SUCCESS");
|
||
|
return SUCCESS;
|
||
|
}
|
||
|
/*****************************************************************************
|
||
|
ExeFLs()
|
||
|
This function executes a F< command.
|
||
|
*****************************************************************************/
|
||
|
static DEFAULT ExeFLs() /* execute an F< command */
|
||
|
{
|
||
|
DBGFEN(1,"ExeFLs",NULL);
|
||
|
CmdMod = '\0'; /* clear modifiers flags */
|
||
|
EStTop = EStBot; /* clear expression stack */
|
||
|
CBfPtr = (LStTop == LStBot) ? CStBeg-1 : LStack[LStTop].LAddr;
|
||
|
DBGFEX(1,DbgFNm,"SUCCESS");
|
||
|
return SUCCESS;
|
||
|
}
|
||
|
/*****************************************************************************
|
||
|
ExeFN()
|
||
|
This function executes a FN command.
|
||
|
*****************************************************************************/
|
||
|
static DEFAULT ExeFN() /* execute an FN command */
|
||
|
{
|
||
|
DBGFEN(1,"ExeFN",NULL);
|
||
|
/*
|
||
|
* The command m,nFN is illegal: the user should use m,nFC
|
||
|
*/
|
||
|
if (CmdMod & MARGIS) { /* if it's m,nFN */
|
||
|
ErrStr(ERR_ILL, "m,nFN"); /* illegal command "m,nFN" */
|
||
|
DBGFEX(1,DbgFNm,"FAILURE");
|
||
|
return FAILURE;
|
||
|
}
|
||
|
if (CmdMod & DCOLON) { /* if it's ::FN */
|
||
|
ErrStr(ERR_ILL, "::FN"); /* illegal command "::FN" */
|
||
|
DBGFEX(1,DbgFNm,"FAILURE");
|
||
|
return FAILURE;
|
||
|
}
|
||
|
SrcTyp = N_SEARCH;
|
||
|
if (Replac() == FAILURE) {
|
||
|
DBGFEX(1,DbgFNm,"FAILURE");
|
||
|
return FAILURE;
|
||
|
}
|
||
|
CmdMod = '\0'; /* clear modifiers flags */
|
||
|
DBGFEX(1,DbgFNm,"SUCCESS");
|
||
|
return SUCCESS;
|
||
|
}
|
||
|
/*****************************************************************************
|
||
|
ExeFR()
|
||
|
This function executes a FR command.
|
||
|
*****************************************************************************/
|
||
|
static DEFAULT ExeFR() /* execute an FR command */
|
||
|
{
|
||
|
DBGFEN(1,"ExeFR",NULL);
|
||
|
if ((GapBeg-RefLen) < EBfBeg) { /* if out of range */
|
||
|
ErrMsg(ERR_DTB); /* DTB = "delete too big" */
|
||
|
DBGFEX(1,DbgFNm,"FAILURE");
|
||
|
return FAILURE;
|
||
|
}
|
||
|
GapBeg += RefLen; /* delete */
|
||
|
CmdMod = (CmdMod & COLON); /* retain only colon bit */
|
||
|
EStTop = EStBot; /* clear expression stack */
|
||
|
DBGFEX(1,DbgFNm,"ExeI()");
|
||
|
return ExeI();
|
||
|
}
|
||
|
/*****************************************************************************
|
||
|
ExeFS()
|
||
|
This function executes a FS command.
|
||
|
*****************************************************************************/
|
||
|
static DEFAULT ExeFS() /* execute an FS command */
|
||
|
{
|
||
|
DBGFEN(1,"ExeFS",NULL);
|
||
|
/*
|
||
|
* The command m,nFS is illegal: the user should use m,nFC
|
||
|
*/
|
||
|
if (CmdMod & MARGIS) { /* if it's m,nFS */
|
||
|
ErrStr(ERR_ILL, "m,nFS"); /* illegal command "m,nFS" */
|
||
|
DBGFEX(1,DbgFNm,"FAILURE");
|
||
|
return FAILURE;
|
||
|
}
|
||
|
/*
|
||
|
* If it's ::FStext$, it's a compare, not a search. The text argument is
|
||
|
* compared to the characters immediately following the character pointer.
|
||
|
* It returns -1 if the strings match, else 0. A ::FStext$ command is
|
||
|
* equivalent to a .,.+1:FCtext$ command, so that's the way it's implemented.
|
||
|
*/
|
||
|
if (CmdMod & DCOLON) { /* if it's ::FS */
|
||
|
if (CmdMod & MARGIS) { /* if it's m,n::FS */
|
||
|
ErrStr(ERR_ILL, "m,n::FS");
|
||
|
DBGFEX(1,DbgFNm,"FAILURE");
|
||
|
return FAILURE;
|
||
|
}
|
||
|
if (EStTop > EStBot) { /* if it's n::FS */
|
||
|
ErrStr(ERR_ILL, "n::FS");
|
||
|
DBGFEX(1,DbgFNm,"FAILURE");
|
||
|
return FAILURE;
|
||
|
}
|
||
|
if (GapEnd == EBfEnd) { /* if nothing to search */
|
||
|
CmdMod = '\0'; /* clear modifiers flags */
|
||
|
DBGFEX(1,DbgFNm,"PushEx(0)");
|
||
|
return PushEx(0L,OPERAND);
|
||
|
}
|
||
|
CmdMod &= ~DCOLON; /* clear double-colon bit */
|
||
|
CmdMod |= COLON; /* set colon bit */
|
||
|
CmdMod |= MARGIS; /* set m defined bit */
|
||
|
MArgmt = GapBeg - EBfBeg; /* set m */
|
||
|
if (PushEx((LONG)((GapBeg-EBfBeg)+1),OPERAND) == FAILURE) {
|
||
|
DBGFEX(1,DbgFNm,"FAILURE, PushEx() failed");
|
||
|
return FAILURE;
|
||
|
}
|
||
|
DBGFEX(1,DbgFNm,"ExeFC()");
|
||
|
return ExeFC(); /* execute FC command */
|
||
|
}
|
||
|
SrcTyp = S_SEARCH;
|
||
|
if (Replac() == FAILURE) {
|
||
|
DBGFEX(1,DbgFNm,"FAILURE, Replac() failed");
|
||
|
return FAILURE;
|
||
|
}
|
||
|
CmdMod = '\0'; /* clear modifiers flags */
|
||
|
DBGFEX(1,DbgFNm,"SUCCESS");
|
||
|
return SUCCESS;
|
||
|
}
|
||
|
/*****************************************************************************
|
||
|
ExeFSQ()
|
||
|
This function executes a F' command.
|
||
|
*****************************************************************************/
|
||
|
static DEFAULT ExeFSQ() /* execute an F' command */
|
||
|
{
|
||
|
DBGFEN(1,"ExeFSQ",NULL);
|
||
|
CmdMod = '\0'; /* clear modifiers flags */
|
||
|
EStTop = EStBot; /* clear expression stack */
|
||
|
DBGFEX(1,DbgFNm,"FlowEC()");
|
||
|
return FlowEC();
|
||
|
}
|
||
|
/*****************************************************************************
|
||
|
ExeFUn()
|
||
|
This function executes a F_ command.
|
||
|
*****************************************************************************/
|
||
|
static DEFAULT ExeFUn() /* execute an F_ command */
|
||
|
{
|
||
|
DBGFEN(1,"ExeFUn",NULL);
|
||
|
/*
|
||
|
* The command m,nF_ is illegal: the user should use m,nFC
|
||
|
*/
|
||
|
if (CmdMod & MARGIS) { /* if it's m,nF_ */
|
||
|
ErrStr(ERR_ILL, "m,nF_"); /* illegal command "m,nF_" */
|
||
|
DBGFEX(1,DbgFNm,"FAILURE");
|
||
|
return FAILURE;
|
||
|
}
|
||
|
if (CmdMod & DCOLON) { /* if it's ::F_ */
|
||
|
ErrStr(ERR_ILL, "::F_"); /* illegal command "::F_" */
|
||
|
DBGFEX(1,DbgFNm,"FAILURE");
|
||
|
return FAILURE;
|
||
|
}
|
||
|
SrcTyp = U_SEARCH;
|
||
|
if (Replac() == FAILURE) {
|
||
|
DBGFEX(1,DbgFNm,"FAILURE");
|
||
|
return FAILURE;
|
||
|
}
|
||
|
CmdMod = '\0'; /* clear modifiers flags */
|
||
|
DBGFEX(1,DbgFNm,"SUCCESS");
|
||
|
return SUCCESS;
|
||
|
}
|
||
|
/*****************************************************************************
|
||
|
ExeF()
|
||
|
This function executes an F command.
|
||
|
*****************************************************************************/
|
||
|
DEFAULT ExeF() /* execute one of the F commands */
|
||
|
{
|
||
|
if (IncCBP() == FAILURE) {
|
||
|
return FAILURE;
|
||
|
}
|
||
|
switch (To_Upper(*CBfPtr)) {
|
||
|
case 'S': return ExeFS();
|
||
|
case 'N': return ExeFN();
|
||
|
case 'D': return ExeFD();
|
||
|
case 'R': return ExeFR();
|
||
|
case 'B': return ExeFB();
|
||
|
case 'C': return ExeFC();
|
||
|
case 'K': return ExeFK();
|
||
|
case '_': return ExeFUn();
|
||
|
case '>': return ExeFGt();
|
||
|
case '<': return ExeFLs();
|
||
|
case '\'': return ExeFSQ();
|
||
|
case '|': return ExeFBr();
|
||
|
default: ErrChr(ERR_IFC, *CBfPtr);
|
||
|
return FAILURE;
|
||
|
}
|
||
|
}
|