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

	ExeEQ()

	This function executes an EQ command.  The EQ command reads a file
directly into a q-register.  This command uses the RdPage function to
temporarily append the contents of the file to the end of the edit buffer.
It then copies the text to a q-register.

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

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

extern	DEFAULT	BldStr();	/* build a string */
extern	DEFAULT	FindQR();	/* find q-register index */
extern	DEFAULT	IncCBP();	/* increment CBfPtr */
extern	DEFAULT	MakRom();	/* make room for text in q-register */
extern	VOID	ZCpyBl();	/* copy a block of memory */
extern	VOID	ZIClos();	/* close input file */
extern	DEFAULT	ZOpInp();	/* open input file */
extern	DEFAULT	RdPage();	/* read a page from a file */

EXTERN	BYTE	CmdMod;		/* command modifiers flags for @, :, etc. */
EXTERN	DEFAULT	CurInp;		/* index of current input stream in IFiles */
EXTERN	char	*EBfEnd;	/* edit buffer end */
EXTERN	WORD	EStBot;		/* expression stack bottom */
EXTERN	WORD	EStTop;		/* expression stack top */
EXTERN	char	FBfBeg[];	/* beginning of file specification buffer */
EXTERN	char	*FBfEnd;	/* end of file specification buffer */
EXTERN	char	*FBfPtr;	/* pointer into file specification buffer */
EXTERN	BOOLEAN	IsEofI[];
EXTERN	char	*(*QBfBeg);	/* beginning of q-register text area */
EXTERN	char	*(*QBfPtr);	/* end of q-register text area, plus 1 */


DEFAULT ExeEQ()			/* execute an EQ command */
{
	LONG	FSize;
	DEFAULT	SvCrIn;
	char	*SvEbEn;


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

	if (IncCBP() == FAILURE)		/* move to char after Q */
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeEPr: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
		return(FAILURE);
#if DEBUGGING
}
#endif

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

	if (BldStr(FBfBeg, FBfEnd, &FBfPtr) == FAILURE)
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeEQ: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
		return(FAILURE);
#if DEBUGGING
}
#endif

	if (FBfPtr == FBfBeg)			/* if it's EQq$ */
		{
		ErrMsg(ERR_UTC);		/* unterminated command */
#if DEBUGGING
if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeEQ: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
		return(FAILURE);
		}

	if (ZOpInp(EQFL, NO) == FAILURE)	/* open the file */
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeEQ: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
		return(FAILURE);
#if DEBUGGING
}
#endif

/*
  We borrow RdPage's ability to read files correctly.  RdPage reads file
  CurInp,  so we need to temporarily set CurInp to the EQ file data block.
  The data is appended to the edit buffer,  so we need to save the pointer
  to the current end of the edit buffer.
*/
	SvCrIn = CurInp;			/* save CurInp */
	SvEbEn = EBfEnd;			/* save EBfEnd */
	CurInp = EQFL;
	do
		if (RdPage() == FAILURE)
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeEQ: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
			return(FAILURE);
#if DEBUGGING
}
#endif
	while (!IsEofI[EQFL]);

	FSize = EBfEnd - SvEbEn;		/* get size of text */
	if (MakRom(FSize) == FAILURE)		/* make room in q-register */
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeEQ: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
		return(FAILURE);
#if DEBUGGING
}
#endif
	ZCpyBl(FSize, SvEbEn+1L, *QBfBeg);	/* copy text to q-register */
	*QBfPtr = *QBfBeg + FSize;
	EBfEnd = SvEbEn;			/* restore EBfEnd */
	CurInp = SvCrIn;			/* restore CurInp */

	ZIClos(EQFL);				/* close the file */

	CmdMod = '\0';				/* clear modifiers flags */
	EStTop = EStBot;			/* clear expression stack */

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