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

	ExeI()

	This function executes an I command.

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

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

extern	VOID	ErrMsg();	/* display an error message */
extern	DEFAULT	FindES();	/* find end of string */
extern	DEFAULT	GetNmA();	/* get numeric argument */
extern	DEFAULT	GroEBf();	/* expand edit buffer gap */
extern	DEFAULT	IncCBP();	/* increment CBfPtr */
extern	char	ZChrIt();	/* type convert LONG to char */
extern	VOID	ZCpyBl();	/* copy block of memory */

EXTERN	char	*ArgPtr;	/* beginning of text argument */
EXTERN	BYTE	CmdMod;		/* command modifiers flags for @, :, etc. */
EXTERN	char	*CBfPtr;	/* pointer into 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	char	*GapBeg;	/* edit buffer gap beginning */
EXTERN	char	*GapEnd;	/* edit buffer gap end */
EXTERN	WORD	MStTop;		/* top of macro stack */
EXTERN	LONG	NArgmt;		/* numeric argument */
EXTERN	LONG	RefLen;		/* value of ^S command */


DEFAULT ExeI()			/* execute an I command */
{
#if DEBUGGING
DbgInd+=2;if(DbgLvl>=1){DbgMsg();DbgDBf("ExeI: called.\015\012");DbgROf();}
#endif
	if (EStTop > EStBot)			/* if numeric argument */
		{
		if (GetNmA() == FAILURE)	/* get numeric argument */
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeI: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
			return(FAILURE);
#if DEBUGGING
}
#endif
		if (CmdMod & ATSIGN)		/* if it's n@I// */
			{
			if (IncCBP() == FAILURE)
				return(FAILURE);
			if (IncCBP() == FAILURE)
				return(FAILURE);
			if (*CBfPtr != *(CBfPtr-1))
				{
				ErrMsg(ERR_IIA);     /* illegal insert arg */
#if DEBUGGING
if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeI: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
				return(FAILURE);
				}
			}
		else				/* else must be nI$ */
			{
			if ((CBfPtr+1L) == CStEnd)
				if (MStTop < 0)
					{
					ErrMsg(ERR_UTC);
					return(FAILURE);
					}
				else
					return(SUCCESS);
			if (*(CBfPtr+1L) != ESCAPE)
				{
				ErrMsg(ERR_IIA);     /* illegal insert arg */
#if DEBUGGING
if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeI: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
				return(FAILURE);
				}
			}
		if (GapEnd <= GapBeg)			/* if no room */
			if (GroEBf(EBFEXP) == FAILURE)
				return(FAILURE);
		*GapBeg++ = ZChrIt(NArgmt);
		}
	else				/* else no numeric argument */
		{
		if (FindES(ESCAPE) == FAILURE)
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeI: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
			return(FAILURE);
#if DEBUGGING
}
#endif
		RefLen = ArgPtr - CBfPtr;
		if ((GapEnd-GapBeg) < -RefLen)
			if (GroEBf(-RefLen) == FAILURE)
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeI: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
				return(FAILURE);
#if DEBUGGING
}
#endif
		ZCpyBl(-RefLen, ArgPtr, GapBeg);
		GapBeg -= RefLen;
		}
	CmdMod = '\0';				/* clear modifiers flags */
#if DEBUGGING
if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeI: returning SUCCESS.\015\012");DbgROf();}DbgInd-=2;
#endif
	return(SUCCESS);
}
