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

	ExeBSl()

	This function executes a backslash (\) command.  The backslash
command allows the user to convert binary numbers to/from their ASCII
representations.  If a numeric argument preceeds the \ command, then the
ASCII representation for the number is inserted into the edit buffer at the
current point.  If there is no preceeding numeric argument,  then the number
in it's ASCII representation in the edit buffer is converted to binary,
and is returned by the \ command.  In either case, TECO's current radix
controls how the numbers are represented.  If the current radix is
decimal,  then a plus or minus sign can preceed an ASCII number being read,
and a minus sign will be generated if necessary for a number being generated.

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

#include "ZPort.h"		/* define portability identifiers */
#include "DefTeco.h"		/* define general identifiers */
#include "ChrMacs.h"		/* define character processing macros */

extern	DEFAULT	GetNmA();	/* get numeric argument */
extern	DEFAULT	GroEBf();	/* expand edit buffer gap */
extern	BOOLEAN	IsRadx();	/* is the character in the radix set? */
extern	VOID	MakDBf();	/* make digit buffer */
extern	DEFAULT	PushEx();	/* push onto expression stack */
extern	VOID	ZCpyBl();	/* copy block of memory */

EXTERN	BYTE	CmdMod;		/* command modifiers flags for @, :, etc. */
EXTERN	char	*DBfBeg;	/* digit buffer beginning */
EXTERN	char	*DBfPtr;	/* digit buffer pointer */
EXTERN	char	*EBfEnd;	/* end of edit buffer */
EXTERN	char	*GapBeg;	/* edit buffer gap beginning */
EXTERN	char	*GapEnd;	/* edit buffer gap end */
EXTERN	WORD	EStBot;		/* expression stack bottom */
EXTERN	WORD	EStTop;		/* expression stack top */
EXTERN	LONG	NArgmt;		/* numeric argument */
EXTERN	DEFAULT	Radix;		/* TECO's current radix, 2-32 */


DEFAULT ExeBSl()		/* execute a \ (backslash) command */
{
	LOCAL	LONG	StrSiz;
	LOCAL	LONG	TmpLng;

#if DEBUGGING
DbgInd+=2;if(DbgLvl>=1){DbgMsg();DbgDBf("ExeBSl: called.\015\012");DbgROf();}
#endif
	if (EStTop == EStBot)			/* if no numeric argument */
		{
		TmpLng = 0L;
		while ((GapEnd != EBfEnd) && (IsRadx(*(GapEnd+1L))))
			{
			GapEnd++;
			*GapBeg++ = *GapEnd;
			TmpLng *= Radix;
			if (Is_Digit(*GapEnd))
				TmpLng += *GapEnd - '0';
			else if (Is_Upper(*GapEnd))
				TmpLng += *GapEnd - '\67';
			else
				TmpLng += *GapEnd - '\127';
			}
		CmdMod = '\0';
#if DEBUGGING
if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeBSl: returning PushEx().\015\012");DbgROf();}DbgInd-=2;
#endif
		return(PushEx(TmpLng,OPERAND));
		}

/* If we made it to here,  then there is a numeric argument */

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

	MakDBf(NArgmt, Radix);			/* convert it to ASCII */
	StrSiz = DBfPtr - DBfBeg;		/* get digit string size */
	if ((GapEnd-GapBeg) < StrSiz)		/* if no room */
		if (GroEBf(StrSiz) == FAILURE)	/* make room */
#if DEBUGGING
{if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeBSl: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
			return(FAILURE);
#if DEBUGGING
}
#endif
	ZCpyBl(StrSiz, DBfBeg, GapBeg);		/* insert into edit buffer */
	GapBeg += StrSiz;
	CmdMod = '\0';				/* clear modifiers flags */
	EStTop = EStBot;			/* clear expression stack */
#if DEBUGGING
if(DbgLvl>=1)
{DbgMsg();DbgDBf("ExeBSl: returning SUCCESS.\015\012");DbgROf();}DbgInd-=2;
#endif
	return(SUCCESS);
}
