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

	ExeA()

	This function executes an A command.

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

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

extern	VOID	ErrMsg();	/* display an error message */
extern	DEFAULT	GetNmA();	/* get numeric argument */
extern	DEFAULT	PushEx();	/* push onto expression stack */
extern	DEFAULT	RdPage();	/* read a page */
extern	VOID	UMinus();	/* handle unary minus */
extern	DEFAULT	RdLine();	/* read a line */

EXTERN	BYTE	CmdMod;		/* command modifiers flags for @, :, etc. */
EXTERN	DEFAULT	CurInp;		/* index of current input stream in IFiles */
EXTERN	char	*EBfBeg;	/* beginning of edit buffer */
EXTERN	char	*EBfEnd;	/* end of edit buffer */
EXTERN	WORD	EStBot;		/* expression stack bottom */
EXTERN	WORD	EStTop;		/* expression stack top */
EXTERN	char	*GapBeg;	/* beginning of edit buffer gap */
EXTERN	char	*GapEnd;	/* end of edit buffer gap */
EXTERN	BOOLEAN	IsEofI[];
EXTERN	LONG	NArgmt;		/* numeric argument */


DEFAULT ExeA()			/* execute an A command */
{
	unsigned char TmpChr;

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

	if (EStTop > EStBot)			/* if numeric argument */
		{
		UMinus();			/* if it's -A, make it -1A */
		if (GetNmA() == FAILURE)	/* get numeric argument */
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeA: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
			return(FAILURE);
#if DEBUGGING
}
#endif
		if (CmdMod & COLON)		/* if it's n:A */
			{
			if (NArgmt < 1L)
				{
				ErrMsg(ERR_IPA);
#if DEBUGGING
if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeA: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
				return(FAILURE);
				}
			CmdMod = '\0';		/* clear modifiers flags */
			while (NArgmt-- > 0L)
				{
				if (RdLine() == FAILURE)
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeA: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
					return(FAILURE);
#if DEBUGGING
}
#endif
				if (IsEofI[CurInp])	/* if end-of-file */
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeA: returning PushEx(0L,).\015\012");DbgROf();}DbgInd-=2;
#endif
					return(PushEx(0L, OPERAND));
#if DEBUGGING
}
#endif
				}
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeA: returning PushEx(-1L,).\015\012");DbgROf();}DbgInd-=2;
#endif
			return(PushEx(-1L, OPERAND));
#if DEBUGGING
}
#endif
			}
		if (NArgmt < 0L)
			{
			if ((GapBeg+NArgmt) < EBfBeg)
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeA: returning PushEx(-1L,).\015\012");DbgROf();}DbgInd-=2;
#endif
				return(PushEx(-1L, OPERAND));
#if DEBUGGING
}
#endif
			TmpChr = *(GapBeg+NArgmt);
#if DEBUGGING
if(DbgLvl>=1){DbgMsg();
DbgDBf("ExeA: returning PushEx(something).\015\012");DbgROf();}DbgInd-=2;
#endif
			return(PushEx((LONG)TmpChr, OPERAND));
			}
		else
			{
			if ((GapEnd+NArgmt+1) > EBfEnd)
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeA: returning PushEx(-1L,).\015\012");DbgROf();}DbgInd-=2;
#endif
				return(PushEx(-1L, OPERAND));
#if DEBUGGING
}
#endif
			TmpChr = *(GapEnd+NArgmt+1);
#if DEBUGGING
if(DbgLvl>=1){DbgMsg();
DbgDBf("ExeA: returning PushEx(something).\015\012");DbgROf();}DbgInd-=2;
#endif
			return(PushEx((LONG)TmpChr, OPERAND));
			}
		}

	if (IsEofI[CurInp])			/* if at end-of-file */
		if (CmdMod & COLON)		/* if it's :A */
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeA: returning PushEx(0L,).\015\012");DbgROf();}DbgInd-=2;
#endif
			return(PushEx(0L, OPERAND));
#if DEBUGGING
}
#endif
		else
			{
			CmdMod = '\0';		/* clear modifiers flags */
#if DEBUGGING
if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeA: returning SUCCESS.\015\012");DbgROf();}DbgInd-=2;
#endif
			return(SUCCESS);
			}

	if (RdPage() == FAILURE)		/* read a page */
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeA: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
		return(FAILURE);
#if DEBUGGING
}
#endif
	if (CmdMod & COLON)			/* if it's :A */
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeA: returning PushEx(-1L,).\015\012");DbgROf();}DbgInd-=2;
#endif
		return(PushEx(-1L, OPERAND));
#if DEBUGGING
}
#endif
	CmdMod = '\0';				/* clear modifiers flags */
#if DEBUGGING
if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeA: returning SUCCESS.\015\012");DbgROf();}DbgInd-=2;
#endif
	return(SUCCESS);
}
