/*****************************************************************************

	ExeCst()

	This function executes a TECO command string.  The string is pointed
to by CBfPtr.  The last character in the string is pointed to by CStEnd.

*****************************************************************************/

#include "ZPort.h"		/* define portability identifiers */
#include "DefTeco.h"		/* define general identifiers */
#include "DefError.h"		/* define identifiers for error messages */

extern	VOID	EchoIt();	/* echo a character */
extern	VOID	ErrMsg();	/* display an error message */
extern	DEFAULT	ExeA();		/* execute an A command */
extern	DEFAULT	ExeAtS();	/* execute an at-sign (@) command */
extern	DEFAULT	ExeB();		/* execute a B command */
extern	DEFAULT	ExeBar();	/* execute a bar (|) command */
extern	DEFAULT	ExeBSl();	/* execute a backslash (\) command */
extern	DEFAULT	ExeC();		/* execute a C command */
extern	DEFAULT	ExeCCC();	/* execute a control-^ command */
extern	DEFAULT	ExeCln();	/* execute a colon (:) command */
extern	DEFAULT	ExeCom();	/* execute a comma (,) command */
extern	DEFAULT	ExeCrt();	/* execute a caret (^) command */
extern	DEFAULT	ExeCtA();	/* execute a control-A command */
extern	DEFAULT	ExeCtD();	/* execute a control-D command */
extern	DEFAULT	ExeCtE();	/* execute a control-E command */
extern	DEFAULT	ExeCtI();	/* execute a control-I (tab) command */
extern	DEFAULT	ExeCtL();	/* execute a control-L (form feed) command */
extern	DEFAULT	ExeCtN();	/* execute a control-N command */
extern	DEFAULT	ExeCtO();	/* execute a control-O command */
extern	DEFAULT	ExeCtP();	/* execute a control-P command */
extern	DEFAULT	ExeCtR();	/* execute a control-R command */
extern	DEFAULT	ExeCtS();	/* execute a control-S command */
extern	DEFAULT	ExeCtT();	/* execute a control-T command */
extern	DEFAULT	ExeCtU();	/* execute a control-U command */
extern	DEFAULT	ExeCtV();	/* execute a control-V command */
extern	DEFAULT	ExeCtW();	/* execute a control-W command */
extern	DEFAULT	ExeCtX();	/* execute a control-X command */
extern	DEFAULT	ExeCtY();	/* execute a control-Y command */
extern	DEFAULT	ExeCtZ();	/* execute a control-Z command */
extern	DEFAULT	Execut();	/* execute a function */
extern	DEFAULT	ExeD();		/* execute a D command */
extern	DEFAULT	ExeDgt();	/* execute a digit command */
extern	DEFAULT	ExeDot();	/* execute a dot (.) command */
extern	DEFAULT	ExeDQu();	/* execute a double-quote (") command */
extern	DEFAULT	ExeE();		/* execute on of the E commands */
extern	DEFAULT	ExeEqu();	/* execute an equals-sign (=) command */
extern	DEFAULT	ExeEsc();	/* execute an ESCAPE command */
extern	DEFAULT	ExeExc();	/* execute an exclamation-mark (!) command */
extern	DEFAULT	ExeF();		/* execute one of the F commands */
extern	DEFAULT	ExeG();		/* execute a G command */
extern	DEFAULT	ExeGtr();	/* execute a greater-than (>) command */
extern	DEFAULT	ExeH();		/* execute an H command */
extern	DEFAULT	ExeI();		/* execute an I command */
extern	DEFAULT	ExeIll();	/* execute an "illegal" command */
extern	DEFAULT	ExeJ();		/* execute a J command */
extern	DEFAULT	ExeK();		/* execute a K command */
extern	DEFAULT	ExeL();		/* execute an L command */
extern	DEFAULT	ExeLBr();	/* execute a left-bracket ([) command */
extern	DEFAULT	ExeLst();	/* execute a less-than (<) command */
extern	DEFAULT	ExeM();		/* execute an M command */
extern	DEFAULT	ExeN();		/* execute a N command */
extern	DEFAULT	ExeO();		/* execute an O command */
extern	DEFAULT	ExeNul();	/* execute a null command */
extern	DEFAULT	ExeNYI();	/* "not yet implemented" function */
extern	DEFAULT	ExeOpr();	/* execute a operator (+,-,*, etc.) command */
extern	DEFAULT	ExeP();		/* execute a P or PW command */
extern	DEFAULT	ExePrc();	/* execute a percent {%} command */
extern	DEFAULT	ExeQ();		/* execute a Q command */
extern	DEFAULT	ExeQes();	/* execute a question-mark (?) command */
extern	DEFAULT	ExeR();		/* execute an R command */
extern	DEFAULT	ExeRBr();	/* execute a right-bracket (]) command */
extern	DEFAULT	ExeRtP();	/* execute a right-parenthesis command */
extern	DEFAULT	ExeS();		/* execute an S command */
extern	DEFAULT	ExeSCl();	/* execute a semi-colon (;) command */
extern	DEFAULT	ExeT();		/* execute a T command */
extern	DEFAULT	ExeU();		/* execute a U command */
extern	DEFAULT	ExeUnd();	/* execute an underbar (_) command */
extern	DEFAULT	ExeV();		/* execute a V command */
extern	DEFAULT	ExeW();		/* execute a W command */
extern	DEFAULT	ExeX();		/* execute a X command */
extern	DEFAULT	ExeY();		/* execute a Y command */
extern	DEFAULT	ExeZ();		/* execute a Z command */
extern	DEFAULT	ZExCtB();	/* execute a ^B command */
extern	DEFAULT	ZExCtH();	/* execute a ^H command */

EXTERN	char	*CBfPtr;	/* pointer into command string */
EXTERN	char	*CStEnd;	/* pointer to last char of command string */
EXTERN	BOOLEAN	GotCtC;		/* YES if the user just hit a CTRL_C */
EXTERN	WORD	LStBot;		/* bottom of loop stack */
EXTERN	WORD	LStTop;		/* top of loop stack */
EXTERN	BOOLEAN	TraceM;		/* trace mode flag */


DEFAULT ExeCSt()		/* execute command string */
{
	static DEFAULT (*FArray[])() = {
/*NUL*/ ExeNul,   /* ^A*/ ExeCtA,   /* ^B*/ ZExCtB,   /* ^C*/ ExeIll,
/* ^D*/ ExeCtD,   /* ^E*/ ExeCtE,   /* ^F*/ ExeNYI,   /* ^G*/ ExeIll,
/* ^H*/ ZExCtH,   /* ^I*/ ExeCtI,   /* LF*/ ExeNul,   /* VT*/ ExeIll,
/* ^L*/ ExeCtL,   /* CR*/ ExeNul,   /* ^N*/ ExeCtN,   /* ^O*/ ExeCtO,
/* ^P*/ ExeCtP,   /* ^Q*/ ExeNYI,   /* ^R*/ ExeCtR,   /* ^S*/ ExeCtS,
/* ^T*/ ExeCtT,   /* ^U*/ ExeCtU,   /* ^V*/ ExeCtV,   /* ^W*/ ExeCtW,
/* ^X*/ ExeCtX,   /* ^Y*/ ExeCtY,   /* ^Z*/ ExeCtZ,   /*ESC*/ ExeEsc,
/* ^\*/ ExeIll,   /* ^]*/ ExeIll,   /* ^^*/ ExeCCC,   /* ^_*/ ExeOpr,
/* SP*/ ExeNul,   /* ! */ ExeExc,   /* " */ ExeDQu,   /* # */ ExeOpr,
/* $ */ ExeEsc,   /* % */ ExePrc,   /* & */ ExeOpr,   /* ' */ ExeNul,
/* ( */ ExeOpr,   /* ) */ ExeRtP,   /* * */ ExeOpr,   /* + */ ExeOpr,
/* , */ ExeCom,   /* - */ ExeOpr,   /* . */ ExeDot,   /* / */ ExeOpr,
/* 0 */ ExeDgt,   /* 1 */ ExeDgt,   /* 2 */ ExeDgt,   /* 3 */ ExeDgt,
/* 4 */ ExeDgt,   /* 5 */ ExeDgt,   /* 6 */ ExeDgt,   /* 7 */ ExeDgt,
/* 8 */ ExeDgt,   /* 9 */ ExeDgt,   /* : */ ExeCln,   /* ; */ ExeSCl,
/* < */ ExeLst,   /* = */ ExeEqu,   /* > */ ExeGtr,   /* ? */ ExeQes,
/* @ */ ExeAtS,   /* A */ ExeA,     /* B */ ExeB,     /* C */ ExeC,
/* D */ ExeD,     /* E */ ExeE,     /* F */ ExeF,     /* G */ ExeG,
/* H */ ExeH,     /* I */ ExeI,     /* J */ ExeJ,     /* K */ ExeK,
/* L */ ExeL,     /* M */ ExeM,     /* N */ ExeN,     /* O */ ExeO,
/* P */ ExeP,     /* Q */ ExeQ,     /* R */ ExeR,     /* S */ ExeS,
/* T */ ExeT,     /* U */ ExeU,     /* V */ ExeV,     /* W */ ExeW,
/* X */ ExeX,     /* Y */ ExeY,     /* Z */ ExeZ,     /* [ */ ExeLBr,
/* \ */ ExeBSl,   /* ] */ ExeRBr,   /* ^ */ ExeCrt,   /* _ */ ExeUnd,
/* ` */ ExeIll,   /* a */ ExeA,     /* b */ ExeB,     /* c */ ExeC,
/* d */ ExeD,     /* e */ ExeE,     /* f */ ExeF,     /* g */ ExeG,
/* h */ ExeH,     /* i */ ExeI,     /* j */ ExeJ,     /* k */ ExeK,
/* l */ ExeL,     /* m */ ExeM,     /* n */ ExeN,     /* o */ ExeO,
/* p */ ExeP,     /* q */ ExeQ,     /* r */ ExeR,     /* s */ ExeS,
/* t */ ExeT,     /* u */ ExeU,     /* v */ ExeV,     /* w */ ExeW,
/* x */ ExeX,     /* y */ ExeY,     /* z */ ExeZ,     /* { */ ExeIll,
/* | */ ExeBar,   /* } */ ExeIll,   /* ~ */ ExeIll,   /*DEL*/ ExeIll
	};

#if DEBUGGING
DbgInd+=2;if(DbgLvl>=4){DbgMsg();DbgDBf("ExeCSt: called.\015\012");DbgROf();}
#endif


while (CBfPtr <= CStEnd)			/* while more commands */
	{
	if (TraceM)				/* if trace mode is on */
		EchoIt(*CBfPtr);		/* display the command */
	if (Execut(FArray[*CBfPtr]) == FAILURE)	/* execute the command */
#if DEBUGGING
{if(DbgLvl>=4){
DbgMsg();DbgDBf("ExeCSt: returning FAILURE\015\012");DbgROf();}DbgInd-=2;
#endif
		return(FAILURE);
#if DEBUGGING
}
#endif
	if (GotCtC)				/* if got a control-C */
		{
		GotCtC = NO;
		ErrMsg(ERR_XAB);		/* XAB = execution aborted */
#if DEBUGGING
if(DbgLvl>=4){
DbgMsg();DbgDBf("ExeCSt: returning SUCCESS\015\012");DbgROf();}DbgInd-=2;
#endif
		return(SUCCESS);
		}
	CBfPtr++;				/* move to next command */
	}

	if (LStTop != LStBot)			/* if unclosed loop */
		ErrMsg(ERR_UTC);		/* UTC = unterminated command */

#if DEBUGGING
if(DbgLvl>=4){
DbgMsg();DbgDBf("ExeCSt: returning SUCCESS\015\012");DbgROf();}DbgInd-=2;
#endif
return(SUCCESS);
}
