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

	ExeCtU()

	This function executes a control-U command.

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

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

extern	VOID	ErrMsg();	/* display an error message */
extern	DEFAULT	FindES();	/* find end of string */
extern	DEFAULT	FindQR();	/* find q-register index */
extern	DEFAULT	IncCBP();	/* increment CBfPtr */
extern	VOID	ZFree();	/* free memory */
extern	DEFAULT	GetNmA();	/* get numeric argument */
extern	DEFAULT	MakRom();	/* make room in q-register */
extern	char	ZChrIt();	/* type-convert a long to a char */
extern	VOID	ZCpyBl();	/* copy memory block */

EXTERN	char	*ArgPtr;	/* beginning of text argument */
EXTERN	char	*CBfPtr;	/* pointer into command buffer */
EXTERN	BYTE	CmdMod;		/* command modifier flags for @, ;, etc. */
EXTERN	WORD	EStBot;		/* expression stack bottom */
EXTERN	WORD	EStTop;		/* expression stack top */
EXTERN	LONG	NArgmt;		/* numeric argument */
EXTERN	char	*(*QBfBeg);	/* beginning of q-register text area */
EXTERN	char	*(*QBfPtr);	/* end of q-register text area, plus 1 */


DEFAULT ExeCtU()		/* execute a ^U (control-U) command */
{
	LOCAL	LONG	TmpSiz;

#if DEBUGGING
DbgInd+=2;if(DbgLvl>=1){DbgMsg();DbgDBf("ExeCtU: called.\015\012");DbgROf();}
#endif
	if (IncCBP() == FAILURE)
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeCtU: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
		return(FAILURE);
#if DEBUGGING
}
#endif
	if (FindQR() == FAILURE)
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeCtU: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
		return(FAILURE);
#if DEBUGGING
}
#endif

	if ((CmdMod & COLON) == '\0')		/* if no colon modifier */
		if (*QBfBeg != NULL)		/* if empty */
			{
			ZFree(*QBfBeg);		/* free the memory */
			*QBfBeg = NULL;
			*QBfPtr = NULL;
			}

	if (EStTop > EStBot)			/* if numeric argument */
		{
		if (GetNmA() == FAILURE)	/* get numeric argument */
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeCtU: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
			return(FAILURE);
#if DEBUGGING
}
#endif
		if (CmdMod & ATSIGN)		/* if it's @^T */
			{
			if (IncCBP() == FAILURE)
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeCtU: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
				return(FAILURE);
#if DEBUGGING
}
#endif
			if (IncCBP() == FAILURE)
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeCtU: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
				return(FAILURE);
#if DEBUGGING
}
#endif
			if (*CBfPtr != *(CBfPtr-1))
				{
				ErrMsg(ERR_IIA);
#if DEBUGGING
if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeCtU: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
				return(FAILURE);
				}
			}
		if (MakRom((*QBfPtr-*QBfBeg)+1L) == FAILURE)
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeCtU: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
			return(FAILURE);
#if DEBUGGING
}
#endif
		*(*QBfPtr)++ = ZChrIt(NArgmt);
		}
	else			/* else (no numeric argument) */
		{
		if (FindES(ESCAPE) == FAILURE)
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeCtU: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
			return(FAILURE);
#if DEBUGGING
}
#endif
		TmpSiz = CBfPtr - ArgPtr;
		if (TmpSiz > 0L)
			{
			if (MakRom(TmpSiz) == FAILURE)
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeCtU: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
				return(FAILURE);
#if DEBUGGING
}
#endif
			ZCpyBl(TmpSiz, ArgPtr, *QBfPtr);
			*QBfPtr += TmpSiz;
			}
		}
	CmdMod = '\0';				/* clear modifiers flags */
#if DEBUGGING
if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeCtU: returning SUCCESS.\015\012");DbgROf();}DbgInd-=2;
#endif
	return(SUCCESS);
}
