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

	DoCJR()

	This function contains the code that's common to the C, J and R
commands.  It is called by ExeC, ExeJ and ExeR only.

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

#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	PushEx();	/* push onto expression stack */
extern	VOID	ZCpyBl();	/* copy a block of memory */

EXTERN	char	*CBfPtr;	/* pointer into command string */
EXTERN	BYTE	CmdMod;		/* command modifiers flags for @, :, etc. */
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 */

DEFAULT DoCJR(HowFar)		/* do C, J or R stuff */
LONG HowFar;			/* positive or negative displacement */
{
	LOCAL LONG InRange;
	static char *ErrTxt = "x";

#if DEBUGGING
DbgInd+=2;if(DbgLvl>=2){DbgMsg();DbgDBf("DoCJR: called, HowFar = ");
MakDBf(HowFar, 10);ZDspBf(DBfBeg, DBfPtr-DBfBeg);DbgDBf("\015\012");DbgROf();}
#endif

	InRange = -1L;				/* -1 means SUCCESS in TECO */
	if (HowFar > 0L)
		if ((GapEnd+HowFar) > EBfEnd)
			InRange = 0L;		/* 0 means FAILURE in TECO */
		else
			{
			ZCpyBl(HowFar, GapEnd+1L, GapBeg);
			GapBeg += HowFar;
			GapEnd += HowFar;
			}
	else
		if ((GapBeg+HowFar) < EBfBeg)
			InRange = 0L;		/* 0 means FAILURE in TECO */
		else
			{
			GapBeg += HowFar;
			GapEnd += HowFar;
			ZCpyBl(-HowFar, GapBeg, GapEnd+1L);
			}

	if (CmdMod & COLON)			/* if colon modifier */
#if DEBUGGING
{if(DbgLvl>=2){DbgMsg();
DbgDBf("DoCJR: returning.\015\012");DbgROf();}DbgInd-=2;
#endif
		return(PushEx(InRange, OPERAND));
#if DEBUGGING
}
#endif
	else
		if (InRange == 0L)		/* if out-of-bounds */
			{
			*ErrTxt = *CBfPtr;
			ErrMsg(ERR_POP, ErrTxt);
#if DEBUGGING
if(DbgLvl>=2)
{DbgMsg();DbgDBf("DoCJR: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
			return(FAILURE);
			}

	CmdMod = '\0';				/* clear modifiers flags */
	EStTop = EStBot;			/* clear expression stack */
#if DEBUGGING
if(DbgLvl>=2)
{DbgMsg();DbgDBf("DoCJR: returning SUCCESS.\015\012");DbgROf();}DbgInd-=2;
#endif
	return(SUCCESS);
}
