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

	PshMac()

	This function is called when TECO needs to execute a macro.  It saves
several variables which define the "current" command string environment on
the macro stack.  It then defines the environment for the macro command
string,  so that the macro command can be executed when this function exits.
The PopMac function reverses the effects of this function,  redefining the
"current" command string environment.

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

#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	char	*CBfPtr;	/* pointer into command string */
EXTERN	char	*CStBeg;	/* beginning of command string */
EXTERN	char	*CStEnd;	/* pointer to last char of command string */
EXTERN	WORD	EStBot;		/* expression stack bottom */
EXTERN	WORD	EStTop;		/* expression stack top */
EXTERN	WORD	LStBot;		/* loop stack bottom */
EXTERN	WORD	LStTop;		/* loop stack top */
EXTERN	struct	MStck MStack[]; /* macro stack */
EXTERN	WORD	MStTop;		/* top of macro stack */
EXTERN	LONG	NArgmt;		/* numeric argument */


DEFAULT PshMac(Start, End)	/* push environment for a macro call */
char *Start;			/* start of new command string */
char *End;			/* end of new command string, plus one */
{
	LOCAL	BOOLEAN	NumArg;
#if DEBUGGING
DbgInd+=2;if(DbgLvl>=1){DbgMsg();DbgDBf("PshMac: called.\015\012");DbgROf();}
#endif

	if (++MStTop >= MCS_SIZE)		/* if macro stack is full */
		{
		ErrMsg(ERR_PDO);		/* push-down list overflow */
#if DEBUGGING
if(DbgLvl>=1){DbgMsg();
DbgDBf("PshMac: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
		return(FAILURE);
		}

	if (NumArg = (EStTop > EStBot))		/* if numeric argument */
		if (GetNmA() == FAILURE)	/* get the numeric argument */
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("PshMac: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
			return(FAILURE);
#if DEBUGGING
}
#endif

	MStack[MStTop].BegCS = CStBeg;	/* save command string beginning */
	MStack[MStTop].CmdPt = CBfPtr;	/* save command string pointer */
	MStack[MStTop].EndCS = CStEnd;	/* save command string end */
	MStack[MStTop].ESBot = EStBot;	/* save expression stack bottom */
	MStack[MStTop].ESTop = EStTop;	/* save expression stack top */
	MStack[MStTop].LSBot = LStBot;	/* save loop stack bottom */
	MStack[MStTop].LSTop = LStTop;	/* save loop stack top */
	MStack[MStTop].LQTabl = NULL;	/* make new, empty local q-reg tbl */
	CStBeg = CBfPtr = Start;	/* set up the new command string */
	CStEnd = End;			/* set up the new command string */
	CStEnd--;
	EStBot = EStTop;		/* set new expression stack bottom */
	LStBot = LStTop;		/* set new loop stack bottom */

	if (NumArg)			/* if we had a numeric argument */
		if (PushEx(NArgmt, OPERAND) == FAILURE)
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("PshMac: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
			return(FAILURE);
#if DEBUGGING
}
#endif

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