TEACL is a fork of TECOC created for the purpose of describing diffs in a document being collaboratively edited
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

1443 lines
36 KiB

/*****************************************************************************
ExeE()
This function executes a E command.
EA Select secondary output stream
EBfilespec$ Open file for input and output
:EBfilespec$ EB, return status
EC Close out (copy in to out and close)
ED Edit mode flag
EE Escape surrogate character
EF Close output file
EG Close out and exit, run last COMPIL class command
:EGcmd args$ Performs operating system function
:EGtext$ Close out and exit, run "text"
EH Help level flag
EI Close current indirect command file
EIfilespec$ Open indirect command file
m,nEJ Set environment characteristics
nEJ Return environment characteristics
EK Kill output file
ELfilespec$ Open log file
mEM Position mag tape
EN Wildcard lookup
:EN EN, return status
ENfilespec$ Preset wildcard lookup
EO Version of TECO
nEO Set TECO to function as version n
EP Select secondary input stream
EQqfilespec$ Read file into Q-register q
ER Select primary input stream
ERfilespec$ Open input file
:ERfilespec$ ER, return status
ES Search verification flag
ET Type out control flag
EU Case flagging flag
EV Edit verify flag
EWfilespec$ Open output file
EW Select primary output stream
EX Close out and exit
EY Read without yank protection
EZ System-dependent mode control flags
E%qfilespec$ Write Q-register q into a file
nE_ Search without yank protection
*****************************************************************************/
#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 "dchars.h" /* define identifiers for characters */
#include "deferr.h" /* define identifiers for error messages */
#if USE_PROTOTYPES
static DEFAULT DoEI(DEFAULT IfIndx);
static DEFAULT ExeEA(void);
static DEFAULT ExeEB(void);
static DEFAULT ExeEC(void);
static DEFAULT ExeED(void);
static DEFAULT ExeEF(void);
static DEFAULT ExeEG(void);
static DEFAULT ExeEH(void);
static DEFAULT ExeEI(void);
static DEFAULT ExeEK(void);
static DEFAULT ExeEN(void);
static DEFAULT ExeEO(void);
static DEFAULT ExeEP(void);
static DEFAULT ExeEPr(void);
static DEFAULT ExeEQ(void);
static DEFAULT ExeER(void);
static DEFAULT ExeES(void);
static DEFAULT ExeET(void);
static DEFAULT ExeEU(void);
static DEFAULT ExeEUn(void);
static DEFAULT ExeEV(void);
static DEFAULT ExeEW(void);
static DEFAULT ExeEX(void);
static DEFAULT ExeEZ(void);
static DEFAULT GetWha(charptr TxtPtr, ptrdiff_t TxtLen);
static DEFAULT OpnEI(DEFAULT EInd);
static DEFAULT OpnInp(DEFAULT IfIndx, BOOLEAN EIFile, BOOLEAN RepFNF);
static DEFAULT OpnOut(DEFAULT OfIndx, BOOLEAN RepErr, BOOLEAN Backup);
static DEFAULT ReadEI(DEFAULT IfIndx, charptr *ZBfPtr, charptr *EscPtr);
#endif
charptr ZBfBeg;
charptr ZBfEnd;
charptr ZBfRdP; /* pointer where to start reading into ZBf */
/*****************************************************************************
OpnInp()
This function opens an input file. The name of the file is pointed
to by FBfBeg. FBfPtr points to the character following the last character of
the file name.
*****************************************************************************/
static DEFAULT OpnInp(IfIndx, EIFile, RepFNF)
DEFAULT IfIndx; /* output file indicator */
BOOLEAN EIFile; /* is it a macro file? */
BOOLEAN RepFNF; /* report "file not found" error? */
{
DEFAULT status;
DBGFEN(2,"OpnInp",NULL);
ZIClos(IfIndx); /* close input file, if any */
status = ZOpInp(IfIndx, EIFile, RepFNF);
if (status != SUCCESS) {
if (!RepFNF && (status == FILENF)) {
DBGFEX(2,DbgFNm,"FILENF");
return FILENF;
}
ErrPSt(ERR_UFI, FBfBeg, FBfPtr);
DBGFEX(2,DbgFNm,"status");
return status;
}
IsOpnI[IfIndx] = TRUE; /* mark the file as open */
IsEofI[IfIndx] = FALSE; /* end-of-file indicator */
DBGFEX(2,DbgFNm,"SUCCESS");
return SUCCESS;
}
/*****************************************************************************
OpnOut()
This function creates and opens an output file. The name of the file
to be created is pointed to by FBfBeg. FBfPtr points to the character
following the last character of the file name.
*****************************************************************************/
static DEFAULT OpnOut(OfIndx, RepErr, Backup)
DEFAULT OfIndx; /* output file indicator */
BOOLEAN RepErr; /* report errors? */
BOOLEAN Backup; /* create backup? TAA Added */
{
DBGFEN(2,"OpnOut",NULL);
if (IsOpnO[OfIndx]) { /* if output file is open */
ErrMsg(ERR_OFO); /* OFO = output file already open */
DBGFEX(2,DbgFNm,"FAILURE");
return FAILURE;
}
if (ZOpOut(OfIndx, RepErr, Backup) == FAILURE) {
if (RepErr) {
ErrPSt(ERR_UFO, FBfBeg, FBfPtr);
}
DBGFEX(2,DbgFNm,"FAILURE");
return FAILURE;
}
IsOpnO[OfIndx] = TRUE;
DBGFEX(2,DbgFNm,"SUCCESS");
return SUCCESS;
}
/*****************************************************************************
ExeEA()
This function executes an EA command.
EA Select secondary output stream
*****************************************************************************/
static DEFAULT ExeEA() /* execute an EA command */
{
DBGFEN(1,"ExeEA",NULL);
CurOut = SOUTFL;
CmdMod = '\0'; /* clear modifiers flags */
EStTop = EStBot; /* clear expression stack */
DBGFEX(1,DbgFNm,"SUCCESS");
return SUCCESS;
}
/*****************************************************************************
ExeEB()
This function executes an EB command.
EBfilespec$ Open file for input and output
:EBfilespec$ EB, return status
*****************************************************************************/
static DEFAULT ExeEB() /* execute an EB command */
{
BOOLEAN RepFNF; /* report "file not found" ? */
DEFAULT status; /* OpnInp() status */
DBGFEN(1,"ExeEB",NULL);
if (BldStr(FBfBeg, FBfEnd, &FBfPtr) == FAILURE) {
DBGFEX(1,DbgFNm,"FAILURE, BldStr() failed");
return FAILURE;
}
RepFNF = !(CmdMod & COLON); /* report file not found? */
CmdMod = '\0'; /* clear modifiers flags */
status = OpnInp(CurInp, FALSE, RepFNF); /* open input file */
if (status != SUCCESS) {
if (status == FILENF) {
if (!RepFNF) { /* if it's :EB */
DBGFEX(1,DbgFNm,"PushEx(0)");
return PushEx(0L,OPERAND);
}
}
DBGFEX(1,DbgFNm,"FAILURE, OpnInp() failed");
return FAILURE;
}
ZMKOFN(); /* kludge for VMS filenames */
if (OpnOut(CurOut, RepFNF, TRUE) == FAILURE) {/* open output file */
#if DEBUGGING
sprintf(DbgSBf,"%s, OpnOut() failed",
(RepFNF) ? "FAILURE" : "PushEx(0)");
DbgFEx(1,DbgFNm,DbgSBf);
#endif
return (RepFNF) ? FAILURE : PushEx(0L,OPERAND);
}
if (!RepFNF) { /* if it's :EB */
DBGFEX(1,DbgFNm,"PushEx(-1)");
return PushEx(-1L,OPERAND);
}
EStTop = EStBot; /* clear expression stack */
DBGFEX(1,DbgFNm,"SUCCESS");
return SUCCESS;
}
/*****************************************************************************
ExeEC()
This function executes an EC command.
EC Close out (copy in to out and close)
*****************************************************************************/
static DEFAULT ExeEC() /* execute an EC command */
{
DBGFEN(1,"ExeEC",NULL);
if (EStTop > EStBot) { /* if numeric argument */
if (GetNmA() == FAILURE) { /* get numeric argument */
DBGFEX(1,DbgFNm,"FAILURE, GetNmA() failed");
return FAILURE;
}
/* ??? */ ZDspBf("memory expand as per page 84\r\n", 29);
CmdMod = '\0'; /* clear modifiers flags */
DBGFEX(1,DbgFNm,"SUCCESS");
return SUCCESS;
}
if (IsOpnO[CurOut]) {
/*
* if there's text in the edit buffer, or if the form feed flag indicates
* that the current page needs to be output, call WrPage to write the page,
* then clear the edit buffer.
*/
if ((GapBeg > EBfBeg) || (GapEnd < EBfEnd) || FFPage) {
if (WrPage(CurOut, EBfBeg, EBfEnd, FFPage) == FAILURE) {
DBGFEX(1,DbgFNm,"FAILURE, WrPage() failed");
return FAILURE;
}
GapBeg = EBfBeg; /* clear the... */
GapEnd = EBfEnd; /* ...edit buffer */
}
/*
* Move the remainder of the current input file, if any, to the currenti
* output file.
*/
if (IsOpnI[CurInp]) { /* if input file is open */
while (!IsEofI[CurInp]) { /* while not end-of-file */
if (RdPage() == FAILURE) { /* read a page */
DBGFEX(1,DbgFNm,"FAILURE, RdPage() failed");
return FAILURE;
}
if (WrPage(CurOut, EBfBeg, EBfEnd, FFPage) == FAILURE) {
DBGFEX(1,DbgFNm,"FAILURE, WrPage() failed");
return FAILURE;
}
GapBeg = EBfBeg; /* clear the... */
GapEnd = EBfEnd; /* ...edit buffer */
}
}
}
ZIClos(PINPFL); /* close primary input file */
ZIClos(SINPFL); /* close secondary input file */
ZOClos(POUTFL); /* close primary output file */
ZOClos(SOUTFL); /* close secondary output file */
CmdMod = '\0'; /* clear modifiers flag */
DBGFEX(1,DbgFNm,"SUCCESS");
return SUCCESS;
}
/*****************************************************************************
ExeED()
This function executes an ED command.
ED Edit mode flag
*****************************************************************************/
static DEFAULT ExeED() /* execute an ED command */
{
DBGFEN(1,"ExeED",NULL);
DBGFEX(1,DbgFNm,"DoFlag(&EdFlag)");
return DoFlag(&EdFlag);
}
/*****************************************************************************
ExeEF()
This function executes an EF command.
EF Close output file
*****************************************************************************/
static DEFAULT ExeEF() /* execute an EF command */
{
DBGFEN(1,"ExeEF",NULL);
ZOClos(CurOut); /* close output file */
CmdMod = '\0'; /* clear modifiers flags */
EStTop = EStBot; /* clear expression stack */
DBGFEX(1,DbgFNm,"SUCCESS");
return SUCCESS;
}
/*****************************************************************************
ExeEG()
This function implements the EG command. If the EG command is not
colon modified, it terminates TECO and passes a command line to the command
line interpreter.
EG Close out and exit
EGtext$ Close out and exit, execute "text" command
If the EG command is colon modified, then it implements one of the "special
functions" as follows:
:EGINI$ gets, sets or clears the initialization file name
:EGLIB$ gets, sets or clears the macro library directory
:EGMEM$ gets, sets or clears the file name memory
:EGVTE$ gets, sets or clears the video macro file name
other, system-dependent functions may be defined. See the ZClnEG function.
*****************************************************************************/
static DEFAULT GetWha(TxtPtr, TxtLen) /* get "what to operate on" */
charptr TxtPtr; /* string to parse */
ptrdiff_t TxtLen; /* length of string */
{
if (TxtLen >= 3) { /* it's long enough */
switch(To_Upper(*TxtPtr)) {
case 'I': /* INI (init macro) */
TxtPtr++;
if (To_Upper(*TxtPtr) == 'N') {
++TxtPtr;
if (To_Upper(*TxtPtr) == 'I') {
return EG_INI;
}
}
break;
case 'L': /* LIB (macro directory) */
TxtPtr++;
if (To_Upper(*TxtPtr) == 'I') {
TxtPtr++;
if (To_Upper(*TxtPtr) == 'B') {
return EG_LIB;
}
}
break;
case 'M': /* MEM (filename memory) */
TxtPtr++;
if (To_Upper(*TxtPtr) == 'E') {
TxtPtr++;
if (To_Upper(*TxtPtr) == 'M') {
return EG_MEM;
}
}
break;
case 'V': /* VTE (vtedit macro) */
TxtPtr++;
if (To_Upper(*TxtPtr) == 'T') {
TxtPtr++;
if (To_Upper(*TxtPtr) == 'E') {
return EG_VTE;
}
}
break;
default:
break;
}
}
return EG_OTHER;
}
#define GBFSIZE 256
static DEFAULT ExeEG() /* perform operating system function */
{
DEFAULT EGWhat; /* what to operate on: INI, VTE, etc. */
unsigned char GBfBeg[GBFSIZE];
charptr GBfPtr;
ptrdiff_t GBfLen;
DBGFEN(1,"ExeEG",NULL);
if (BldStr(GBfBeg, GBfBeg+GBFSIZE-2, &GBfPtr) == FAILURE) {
DBGFEX(1,DbgFNm,"FAILURE, BldStr() failed");
return FAILURE;
}
GBfLen = GBfPtr - GBfBeg;
if (CmdMod & COLON) { /* if it's :EG */
DEFAULT EGOper = GET_VAL; /* get, set or clear */
charptr TmpPtr;
CmdMod &= ~COLON; /* clear colon flag */
EGWhat = GetWha(GBfBeg,GBfLen);
TmpPtr = (charptr)GBfBeg;
if (EGWhat != EG_OTHER) {
if (GBfLen == 4) { /* if it's "clear" */
if (*(TmpPtr+3) != ' ') {
DBGFEX(1,DbgFNm,"PushEx(0)");
return PushEx(0L,OPERAND);
}
EGOper = CLEAR_VAL;
} else if (GBfLen != 3) { /* it it's not "get" */
EGOper = SET_VAL;
TmpPtr += 4;
}
}
*GBfPtr = '\0';
DBGFEX(1,DbgFNm,"PushEx(ZClnEG())");
return PushEx(ZClnEG(EGWhat,EGOper,TmpPtr),OPERAND);
}
if (ExeEC() == FAILURE) { /* do an EC command */
DBGFEX(1,DbgFNm,"FAILURE, ExeEC() failed");
return FAILURE;
}
if (GBfLen == 0) { /* if it was EC$ */
TAbort(EXIT_SUCCESS); /* just exit TECO-C */
}
ZDoCmd(GBfBeg, GBfPtr); /* exit with a command */
DBGFEX(1,DbgFNm,"SUCCESS"); /* we should never reach this */
return SUCCESS;
}
/*****************************************************************************
ExeEH()
This function executes an EH command.
EH Help level flag
*****************************************************************************/
static DEFAULT ExeEH() /* execute an EH command */
{
DBGFEN(1,"ExeEH",NULL);
DBGFEX(1,DbgFNm,"DoFlag()");
return DoFlag(&EhFlag);
}
/*****************************************************************************
ReadEI()
This function reads an EI file. It is passed an index for the file
data block of the open EI file, and a buffer. It reads the contents of the
file into the buffer, stopping when a double ESCAPE or end-of-file is
encountered.
*****************************************************************************/
static DEFAULT ReadEI(IfIndx, ZBfPtr, EscPtr)
DEFAULT IfIndx; /* index into IFiles array */
charptr *ZBfPtr; /* returned ptr to end of EI string (+1) */
charptr *EscPtr; /* returned ptr to $$ in EI string (+1) */
{
DEFAULT line_len;
charptr NewBuf;
SIZE_T NewSiz;
BOOLEAN previous_char_was_escape;
charptr TmpPtr;
#if DEBUGGING
static char *DbgFNm = "ReadEI";
sprintf(DbgSBf,"ZBfBeg = %ld, ZBfEnd = %ld",
Zcp2ul(ZBfBeg), Zcp2ul(ZBfEnd));
DbgFEn(1,DbgFNm,DbgSBf);
#endif
FOREVER {
/*
* potentially reallocate ZBf
*/
if ((ZBfEnd - ZBfRdP) < ZBFMIN) {
NewSiz = (ZBfEnd - ZBfBeg) + ZBFEXP;
NewBuf = (charptr)ZRaloc(ZBfBeg, NewSiz);
if (NewBuf == NULL) {
ErrMsg(ERR_MEM); /* MEM = memory overflow */
DBGFEX(1,DbgFNm,"FAILURE, ZRaloc() failed");
return (FAILURE);
}
ZBfRdP = NewBuf + (ZBfRdP - ZBfBeg);
ZBfEnd = NewBuf + NewSiz;
ZBfBeg = NewBuf;
}
/*
* append a line from the EI file to ZBf
*/
if (ZRdLin(ZBfRdP,ZBfEnd-ZBfRdP,IfIndx,&line_len) == FAILURE) {
DBGFEX(1,DbgFNm,"FAILURE, ZRdLin() failed");
return (FAILURE);
}
/*
* break out of FOREVER loop if we tried reading past end of file.
*/
if (IsEofI[IfIndx]) {
DBGFMS(1,DbgFNm,"ran into EOF");
break;
}
#if DEBUGGING
sprintf(DbgSBf,"read %d bytes: \"%.*s\"",
(int)line_len, (int)line_len, ZBfRdP);
DbgFMs(1,DbgFNm,DbgSBf);
#endif
/*
* go through the line we've read, looking for $$.
*/
TmpPtr = ZBfRdP;
ZBfRdP += line_len;
previous_char_was_escape = FALSE;
for (; TmpPtr < ZBfRdP; ++TmpPtr) {
if (*TmpPtr == ESCAPE) {
if (previous_char_was_escape) {
*ZBfPtr = ZBfRdP;
*EscPtr = ++TmpPtr;
DBGFEX(1,DbgFNm,
"SUCCESS, ran into $$");
return (SUCCESS);
}
previous_char_was_escape = TRUE;
} else {
previous_char_was_escape = FALSE;
}
}
}
*ZBfPtr = ZBfRdP;
*EscPtr = NULL;
DBGFEX(1,DbgFNm,"SUCCESS");
return SUCCESS;
}
/*****************************************************************************
OpnEI()
This function opens an EI file. The file name given by the user may
find the file one of the following ways:
1. as given (current directory)
2. as given, but with a ".TEC" type (current directory)
3. as given, in the default directory, with a ".TEC" type
3. as given, in the default directory
As soon as one of these forms is found and opened, this function returns.
*****************************************************************************/
static DEFAULT OpnEI(EInd) /* open an EI file */
DEFAULT EInd;
{
#ifdef OPNEI_FINISHED
if (OpnInp(EInd, FALSE, TRUE) == SUCCESS)
return(SUCCESS);
if (OpnInp(EInd, TRUE, TRUE) == SUCCESS)
return(SUCCESS);
save contents of FBf
use :EGDEF command to fill FBf with default directory (how?)
append saved FBf to actual FBf
if (OpnInp(EInd, FALSE, TRUE) == SUCCESS)
return(SUCCESS);
if (OpnInp(EInd, TRUE, TRUE) == SUCCESS)
return(SUCCESS);
#else
return OpnInp(EInd, TRUE, TRUE);
#endif
}
/*****************************************************************************
DoEI()
This function performs the execution part of an EI command. It is
called by the ExeEI function. It is passed an index to a file data block in
the IFiles array that has been opened. It is also passed a memory buffer.
This function reads text from the file into the buffer and calls ExeCSt to
execute the text.
*****************************************************************************/
static DEFAULT DoEI(IfIndx) /* do an EI command */
DEFAULT IfIndx; /* index into IFiles array */
{
charptr ZBfPtr; /* pointer to end of command string in ZBf */
charptr EscPtr; /* ptr into ZBf past second $ of $$ pair */
DEFAULT status; /* return status of ExeCSt() */
DBGFEN(1,"DoEI",NULL);
status = SUCCESS; /* in case we try doing an empty EI file */
ZBfRdP = ZBfBeg; /* start reading into beginning of ZBf */
do {
/*
* Read EI file into ZBf until $$ or EOF, whichever comes first
*/
if (ReadEI(IfIndx, &ZBfPtr, &EscPtr) == FAILURE) {
ErrMsg(ERR_URE); /* Unable to Read EI file */
DBGFEX(1,DbgFNm,"FAILURE, ReadEI() failed");
return FAILURE;
}
/*
* save the current execution state and make ZBf the current command string
* to execute
*/
if (PshMac(ZBfBeg, (EscPtr) ? EscPtr : ZBfPtr) == FAILURE) {
DBGFEX(1,DbgFNm,"FAILURE, PshMac() failed");
return FAILURE;
}
/*
* execute macro in ZBf
*/
status = ExeCSt();
#if DEBUGGING
if (status == FAILURE) {
DbgFMs(1,DbgFNm,"ExeCSt() failed");
}
#endif
/*
* restore old execution state
*/
if (PopMac() == FAILURE) {
DBGFEX(1,DbgFNm,"FAILURE, PopMac() failed");
return FAILURE;
}
/*
* if we ran into an $$ that was in the middle of a line, then we want to
* move it to the beginning of ZBf and append the rest of the EI file to
* it; otherwise, we'll just start reading into the beginning of ZBf.
*/
if (EscPtr) {
ptrdiff_t LeftOver;
LeftOver = ZBfPtr - EscPtr;
MEMMOVE(ZBfBeg, EscPtr, LeftOver);
ZBfRdP = ZBfBeg + LeftOver;
} else {
ZBfRdP = ZBfBeg;
}
} while (!IsEofI[IfIndx] && !GotCtC && status != FAILURE);
DBGFEX(1,DbgFNm,(status == FAILURE) ? "FAILURE" : "SUCCESS");
return status; /* return ExeCSt() status */
}
/*****************************************************************************
ExeEI()
This function executes an EI command. This function does only part of
the work; the DoEI function does the rest. This function opens/closes the
file and allocates/deallocates an input buffer. The code executes such that
no matter what happens, an open file will always be closed and allocated
memory will always be freed.
EI Close current indirect command file
EIfilespec$ Open indirect command file
*****************************************************************************/
/*
* EIIndx is an index into the IFiles array. It is incremented each time an
* EI command is executed and decremented each time an EI command completes.
* It is the index of the file data block of the currently open EI input file.
* When EIIndx equals EIFL-1, no EI files are open.
*/
static DEFAULT EIIndx = EIFL-1;
static DEFAULT ExeEI() /* execute an EI command */
{
int status;
DBGFEN(1,"ExeEI",NULL);
if (BldStr(FBfBeg, FBfEnd, &FBfPtr) == FAILURE) {
DBGFEX(1,DbgFNm,"FAILURE, BldStr() failed");
return FAILURE;
}
if (FBfPtr == FBfBeg) { /* if it's EI$ */
if (EIIndx >= EIFL) { /* if EI file is open */
CmdMod = '\0'; /* clear modifiers flags */
}
EStTop = EStBot; /* clear expression stack */
DBGFEX(1,DbgFNm,"SUCCESS");
return SUCCESS;
}
if (++EIIndx > NIFDBS) { /* If EI nesting too deep */
EIIndx--;
ErrMsg(ERR_MEM); /* ERR_MEM=memory overflow */
DBGFEX(1,DbgFNm,"FAILURE, EI nested too deep");
return FAILURE;
}
if (OpnEI(EIIndx) != SUCCESS) { /* open EI file */
status = FAILURE;
} else {
ZBfBeg = (charptr)ZAlloc(ZBFINIT); /* allocate input buffer */
if (ZBfBeg == NULL) { /* if allocation failed */
ErrMsg(ERR_MEM); /* MEM = memory overflow */
status = FAILURE;
} else { /* else allocation ok */
ZBfEnd = ZBfBeg + ZBFINIT;
status = DoEI(EIIndx);
ZFree((voidptr)ZBfBeg); /* free allocated memory */
}
ZIClos(EIIndx);
}
EIIndx--; /* decrement nesting count */
CmdMod = '\0'; /* clear modifiers flags */
EStTop = EStBot; /* clear expression stack */
DBGFEX(1,DbgFNm,"SUCCESS");
return status;
}
/*****************************************************************************
ExeEK()
This function executes an EK command.
EK Kill output file
*****************************************************************************/
static DEFAULT ExeEK() /* execute an EK command */
{
DBGFEN(1,"ExeEK",NULL);
ZOClDe(CurOut); /* close and delete output file */
CmdMod = '\0'; /* clear modifiers flags */
EStTop = EStBot; /* clear expression stack */
DBGFEX(1,DbgFNm,"SUCCESS");
return SUCCESS;
}
/*****************************************************************************
ExeEN()
This function executes an EN command.
EN Wildcard lookup
:EN EN, return status
ENfilespec$ Preset wildcard lookup
*****************************************************************************/
static DEFAULT ExeEN() /* execute an EN command */
{
DBGFEN(1,"ExeEN",NULL);
if (BldStr(FBfBeg, FBfEnd, &FBfPtr) == FAILURE) {
DBGFEX(1,DbgFNm,"FAILURE, BldStr() failed");
return FAILURE;
}
if (FBfPtr == FBfBeg) { /* if it's EN$ or :EN$ */
switch (ZSWild()) {
case FAILURE:
DBGFEX(1,DbgFNm,"FAILURE, ZSWild() failed");
return FAILURE;
case FILENF:
if (CmdMod & COLON) { /* if it's :EN */
CmdMod = '\0'; /* clear modifiers flags */
EStTop = EStBot;/* clear expression stack */
DBGFEX(1,DbgFNm,"PushEx(0)");
return PushEx(0L,OPERAND);
}
ErrStr(ERR_FNF, ""); /* file not found */
DBGFEX(1,DbgFNm,"FAILURE");
return FAILURE;
case SUCCESS:
if (CmdMod & COLON) { /* if it's :EN */
CmdMod = '\0'; /* clear modifiers flags */
DBGFEX(1,DbgFNm,"PushEx(-1)");
return PushEx(-1L,OPERAND);
}
EStTop = EStBot;/* clear expression stack */
CmdMod = '\0'; /* clear modifiers flags */
DBGFEX(1,DbgFNm,"SUCCESS");
return SUCCESS;
}
}
if (ZPWild() == FAILURE) { /* preset wildcard filepsec */
DBGFEX(1,DbgFNm,"FAILURE, ZPWild() failed");
return FAILURE;
}
EStTop = EStBot; /* clear expression stack */
CmdMod = '\0'; /* clear modifiers flags */
DBGFEX(1,DbgFNm,"SUCCESS");
return SUCCESS;
}
/*****************************************************************************
ExeEO()
This function executes an EO command. TECO-C's version numbers
started at 100 and went up. Other implementations of TECO have version
numbers less than 100.
EO Version of TECO
nEO Set TECO to function as version n
*****************************************************************************/
static DEFAULT ExeEO() /* execute an EO command */
{
return ((EStTop > EStBot) /* is it nEO ? */
? ExeNYI() /* ...yes, not supported */
: PushEx((LONG)TVERSION,OPERAND)); /* ...no, return version */
}
/*****************************************************************************
ExeEP()
This function executes an EP command.
EP Select secondary input stream
*****************************************************************************/
static DEFAULT ExeEP() /* execute an EP command */
{
DBGFEN(1,"ExeEP",NULL);
CurInp = SINPFL; /* select secondary input stream */
CmdMod = '\0'; /* clear modifiers flags */
EStTop = EStBot; /* clear expression stack */
DBGFEX(1,DbgFNm,"SUCCESS");
return SUCCESS;
}
/*****************************************************************************
ExeEPr()
This function executes an E% command.
E%qfilespec$ Write Q-register q into a file
*****************************************************************************/
static DEFAULT ExeEPr() /* execute an E% command */
{
BOOLEAN RepErr; /* report errors? */
DBGFEN(1,"ExeEPr",NULL);
if (IncCBP() == FAILURE) { /* move to char after % */
DBGFEX(1,DbgFNm,"FAILURE, IncCBP() failed");
return FAILURE;
}
if (FindQR() == FAILURE) { /* find q-register */
DBGFEX(1,DbgFNm,"FAILURE, FindQR() failed");
return FAILURE;
}
if (BldStr(FBfBeg, FBfEnd, &FBfPtr) == FAILURE) {
DBGFEX(1,DbgFNm,"FAILURE, BldStr() failed");
return FAILURE;
}
if (FBfPtr == FBfBeg) { /* if it's E%q$ */
ErrUTC(); /* unterminated command */
DBGFEX(1,DbgFNm,"FAILURE, unterminated command");
return FAILURE;
}
RepErr = !(CmdMod & COLON);
CmdMod = '\0';
if (OpnOut(EPRCFL, RepErr, FALSE) == FAILURE) {
#if DEBUGGING
sprintf(DbgSBf,"%s, OpnOut() failed",
(RepErr) ? "FAILURE" : "PushEx(0)");
DbgFEx(1,DbgFNm,DbgSBf);
#endif
return ((RepErr) ? FAILURE : PushEx(0L,OPERAND));
}
if (QR->Start != NULL) { /* if it's not empty */
if (ZWrBfr(EPRCFL, QR->Start, QR->End_P1-1) == FAILURE) {
#if DEBUGGING
sprintf(DbgSBf,"%s, ZWrBfr() failed",
(RepErr) ? "FAILURE" : "PushEx(0)");
DbgFEx(1,DbgFNm,DbgSBf);
#endif
return ((RepErr) ? FAILURE : PushEx(0L,OPERAND));
}
}
ZOClos(EPRCFL); /* close the file */
if (!RepErr) {
DBGFEX(1,DbgFNm,"PushEx(-1)");
return PushEx(-1L,OPERAND);
}
EStTop = EStBot; /* clear expression stack */
DBGFEX(1,DbgFNm,"SUCCESS");
return SUCCESS;
}
/*****************************************************************************
ExeEQ()
This function executes an EQ command. The EQ command reads a file
directly into a q-register. This command uses the RdPage function to
temporarily append the contents of the file to the end of the edit buffer.
It then copies the text to a q-register.
EQqfilespec$ Read file into Q-register q
*****************************************************************************/
static DEFAULT ExeEQ() /* execute an EQ command */
{
ptrdiff_t FSize; /* file size */
LONG SvFFPg; /* saved FFPage value */
DEFAULT SvCrIn; /* saved CurInp value */
ptrdiff_t SvEbSz; /* saved edit buffer size */
DEFAULT Status;
DBGFEN(1,"ExeEQ",NULL);
if (IncCBP() == FAILURE) { /* move to char after Q */
DBGFEX(1,DbgFNm,"FAILURE, IncCBP() failed");
return FAILURE;
}
if (FindQR() == FAILURE) {
DBGFEX(1,DbgFNm,"FAILURE, FindQR() failed");
return FAILURE;
}
if (BldStr(FBfBeg, FBfEnd, &FBfPtr) == FAILURE) {
DBGFEX(1,DbgFNm,"FAILURE, BldStr() failed");
return FAILURE;
}
if (FBfPtr == FBfBeg) { /* if it's EQq$ */
ErrUTC(); /* unterminated command */
DBGFEX(1,DbgFNm,"FAILURE, unterminated command");
return FAILURE;
}
if (OpnInp(EQFL, FALSE, TRUE) != SUCCESS) { /* open the file */
DBGFEX(1,DbgFNm,"FAILURE, OpnInp() failed");
return FAILURE;
}
/*
* We borrow RdPage's ability to read files correctly. RdPage reads file
* CurInp, so we need to temporarily set CurInp to the EQ file data block.
* The data is appended to the edit buffer, so we need to save the pointer
* to the current end of the edit buffer.
*/
SvCrIn = CurInp; /* save CurInp */
SvEbSz = (EBfEnd - EBfBeg) - (GapEnd - GapBeg); /* save EBfEnd */
SvFFPg = FFPage; /* save FFPage */
CurInp = EQFL;
do {
if (RdPage() == FAILURE) {
Status = FAILURE;
goto exeeqdone;
}
} while (!IsEofI[EQFL]);
/*
* Make room in the q-register.
*/
FSize = EBfEnd - (EBfBeg + SvEbSz + (GapEnd - GapBeg));
if (MakRom((SIZE_T)FSize) == FAILURE) {
Status = FAILURE;
goto exeeqdone;
}
/*
* Copy the text that we just read from the file into the q-register.
*/
MEMMOVE(QR->Start,
EBfBeg + SvEbSz + 1 + (GapEnd - GapBeg),
(SIZE_T)FSize);
QR->End_P1 = QR->Start + FSize;
Status = SUCCESS;
exeeqdone:
FFPage = SvFFPg; /* restore FFpage */
EBfEnd = EBfBeg + SvEbSz +
(GapEnd - GapBeg); /* restore EBfEnd */
CurInp = SvCrIn; /* restore CurInp */
ZIClos(EQFL); /* close the file */
CmdMod = '\0'; /* clear modifiers flags */
EStTop = EStBot; /* clear expression stack */
DBGFEX(1,DbgFNm,(Status == SUCCESS) ? "SUCCESS" : "FAILURE");
return Status;
}
/*****************************************************************************
ExeER()
This function executes an ER command.
ER Select primary input stream
ERfilespec$ Open input file
:ERfilespec$ ER, return status
*****************************************************************************/
static DEFAULT ExeER() /* execute an ER command */
{
BOOLEAN RepFNF; /* report "file not found" errors? */
DEFAULT status;
DBGFEN(1,"ExeER",NULL);
if (BldStr(FBfBeg, FBfEnd, &FBfPtr) == FAILURE) {
DBGFEX(1,DbgFNm,"FAILURE, BldStr() failed");
return FAILURE;
}
if (FBfPtr == FBfBeg) { /* if it's ER$ */
CurInp = PINPFL; /* primary input stream */
CmdMod = '\0'; /* clear modifiers flags */
EStTop = EStBot; /* clear expression stack */
DBGFEX(1,DbgFNm,"SUCCESS");
return SUCCESS;
}
RepFNF = !(CmdMod & COLON); /* report file not found? */
CmdMod = '\0'; /* clear modifiers flags */
status = OpnInp(CurInp, FALSE, RepFNF); /* open input file */
if (status != SUCCESS) {
if (status == FILENF) {
if (!RepFNF) { /* if it's :ER */
DBGFEX(1,DbgFNm,"PushEx(0)");
return PushEx(0L,OPERAND);
}
}
DBGFEX(1,DbgFNm,"FAILURE, OpnInp() failed");
return FAILURE;
}
if (!RepFNF) { /* if it's :ER */
DBGFEX(1,DbgFNm,"PushEx(-1)");
return PushEx(-1L,OPERAND);
}
EStTop = EStBot; /* clear expression stack */
DBGFEX(1,DbgFNm,"SUCCESS");
return SUCCESS;
}
/*****************************************************************************
ExeES()
This function executes an ES command.
ES Search verification flag
*****************************************************************************/
static DEFAULT ExeES() /* execute an ES command */
{
DBGFEN(1,"ExeES",NULL);
DBGFEX(1,DbgFNm,"DoFlag(&EsFlag)");
return DoFlag(&EsFlag);
}
/*****************************************************************************
ExeET()
This function executes an ET command.
ET Type out control flag
*****************************************************************************/
static DEFAULT ExeET() /* execute an ET command */
{
DEFAULT status;
WORD TmpET;
DBGFEN(1,"ExeET",NULL);
TmpET = EtFlag;
status = DoFlag(&EtFlag);
/*
* If DoFlag set or cleared the 8-bit flag, we have to tell the operating
* system.
*/
if (status != FAILURE) {
if ((TmpET & ET_EIGHTBIT) && /* eightbit flag cleared? */
!(EtFlag & ET_EIGHTBIT)) {
status = ZSetTT(TT8BIT, 0);
} else if (!(TmpET & ET_EIGHTBIT) && /* eightbit flag set? */
(EtFlag & ET_EIGHTBIT)) {
status = ZSetTT(TT8BIT, 1);
}
}
/*
* If one of the read-only flags was changed, set it back.
*/
if ((TmpET & ET_WAT_SCOPE) != (EtFlag & ET_WAT_SCOPE)) {
if (TmpET & ET_WAT_SCOPE) /* if it was cleared */
EtFlag |= ET_WAT_SCOPE; /* set it */
else
EtFlag &= ~ET_WAT_SCOPE; /* clear it */
}
if ((TmpET & ET_WAT_REFRESH) != (EtFlag & ET_WAT_REFRESH)) {
if (TmpET & ET_WAT_REFRESH) /* if it was cleared */
EtFlag |= ET_WAT_REFRESH; /* set it */
else
EtFlag &= ~ET_WAT_REFRESH; /* clear it */
}
DBGFEX(1,DbgFNm,(status==FAILURE) ? "FAILURE" : "SUCCESS");
return status;
}
/*****************************************************************************
ExeEU()
This function executes an EU command.
EU Case flagging flag
*****************************************************************************/
static DEFAULT ExeEU() /* execute an EU command */
{
DBGFEN(1,"ExeEU",NULL);
DBGFEX(1,DbgFNm,"DoFlag(&EuFlag)");
return DoFlag(&EuFlag);
}
/*****************************************************************************
ExeEUn()
This function executes an E_ command.
nE_ Search without yank protection
*****************************************************************************/
static DEFAULT ExeEUn() /* execute an E_ command */
{
DBGFEN(1,"ExeEUn",NULL);
/*
* The command m,nE_ is illegal: the user should use m,nFB
*/
if (CmdMod & MARGIS) { /* if it's m,nE_ */
ErrStr(ERR_ILL, "m,nE_"); /* illegal command "m,nE_" */
DBGFEX(1,DbgFNm,"FAILURE, m,nE is illegal");
return FAILURE;
}
if (CmdMod & DCOLON) { /* if it's ::E_ */
ErrStr(ERR_ILL, "::E_"); /* illegal command "::E_" */
DBGFEX(1,DbgFNm,"FAILURE, ::E_ is illegal");
return FAILURE;
}
SrcTyp = E_SEARCH;
if (Search(FALSE) == FAILURE) {
DBGFEX(1,DbgFNm,"FAILURE, Search() failed");
return FAILURE;
}
CmdMod = '\0'; /* clear modifiers flags */
DBGFEX(1,DbgFNm,"SUCCESS");
return SUCCESS;
}
/*****************************************************************************
ExeEV()
This function executes an EV command.
EV Edit verify flag
*****************************************************************************/
static DEFAULT ExeEV() /* execute an EV command */
{
DBGFEN(1,"ExeEV",NULL);
DBGFEX(1,DbgFNm,"DoFlag()");
return DoFlag(&EvFlag);
}
/*****************************************************************************
ExeEW()
This function executes an EW command.
EWfilespec$ Open output file
EW Select primary output stream
*****************************************************************************/
static DEFAULT ExeEW() /* execute an EW command */
{
BOOLEAN RepErr; /* report errors? */
DBGFEN(1,"ExeEW",NULL);
if (BldStr(FBfBeg, FBfEnd, &FBfPtr) == FAILURE) {
DBGFEX(1,DbgFNm,"FAILURE, BldStr() failed");
return FAILURE;
}
if (FBfPtr == FBfBeg) { /* if it's EW$ */
CmdMod = '\0'; /* clear modifiers flags */
CurOut = POUTFL; /* primary output stream */
EStTop = EStBot; /* clear expression stack */
DBGFEX(1,DbgFNm,"SUCCESS");
return SUCCESS;
}
RepErr = !(CmdMod & COLON);
CmdMod = '\0'; /* clear modifiers flags */
if (OpnOut(CurOut, RepErr, FALSE) == FAILURE) {
#if DEBUGGING
sprintf(DbgSBf,"%s, OpnOut() failed",
(RepErr) ? "FAILURE" : "PushEx(0)");
DbgFEx(1,DbgFNm,DbgSBf);
#endif
return ((RepErr) ? FAILURE : PushEx(0L,OPERAND));
}
if (!RepErr) {
DBGFEX(1,DbgFNm,"PushEx(-1)");
return PushEx(-1L,OPERAND);
}
EStTop = EStBot; /* clear expression stack */
DBGFEX(1,DbgFNm,"SUCCESS");
return SUCCESS;
}
/*****************************************************************************
ExeEX()
This function executes an EX command.
EX Close out and exit
*****************************************************************************/
static DEFAULT ExeEX() /* execute an EX command */
{
DBGFEN(1,"ExeEX",NULL);
if (ExeEC() != FAILURE) { /* execute an EC command */
DBGFEX(1,DbgFNm,"exiting successfully!");
TAbort(EXIT_SUCCESS); /* exit TECO-C */
}
DBGFEX(1,DbgFNm,"FAILURE, ExeEX() failed");
return FAILURE;
}
/*****************************************************************************
ExeEZ()
This function executes an EZ command. EZ is a mode control flag
that contains bits specific to the operating system we're using.
*****************************************************************************/
static DEFAULT ExeEZ() /* execute an EZ command */
{
DBGFEN(1,"ExeEZ",NULL);
DBGFEX(1,DbgFNm,"DoFlag(&EZFlag)");
return DoFlag(&EzFlag);
}
/*****************************************************************************
ExeE()
This function executes two-letter commands that start with "E".
It uses the character following the "E" to index into a table of functions.
*****************************************************************************/
DEFAULT ExeE() /* execute an E command */
{
unsigned char TmpChr;
static DEFAULT (*FEAray[])(VVOID) = {
/* A */ ExeEA, /* B */ ExeEB,
/* C */ ExeEC, /* D */ ExeED,
/* E */ ExeIll, /* F */ ExeEF,
/* G */ ExeEG, /* H */ ExeEH,
/* I */ ExeEI, /* J */ ZExeEJ,
/* K */ ExeEK, /* L */ ExeNYI,
/* M */ ExeNYI, /* N */ ExeEN,
/* O */ ExeEO, /* P */ ExeEP,
/* Q */ ExeEQ, /* R */ ExeER,
/* S */ ExeES, /* T */ ExeET,
/* U */ ExeEU, /* V */ ExeEV,
/* W */ ExeEW, /* X */ ExeEX,
/* Y */ ExeEY, /* Z */ ExeEZ
};
if (IncCBP() == FAILURE) {
return FAILURE;
}
TmpChr = To_Upper (*CBfPtr);
if (TmpChr == '%') { /* we have E%q */
return ExeEPr();
}
if (TmpChr == '_') { /* we have nE_ */
return ExeEUn();
}
if (!Is_Upper(TmpChr) || (TmpChr == 'E')) {
ErrChr(ERR_IEC, TmpChr);
return FAILURE;
}
return (*FEAray[TmpChr-'A'])();
}