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

	FindQR()

	This function "finds" a q-register.  CBfPtr points to the first
character of the q-register name.  If it is a period (q-register is local to
this macro level),  then CBfPtr is incremented to point to the next
character and,  if this is the first use of a local q-register in this macro
level,  then memory for a local q-register table is allocated.

This function sets up the following global variables:

	QBfBeg		pointer to pointer to first character of text
	QBfEnd		pointer to pointer to char after last char of text
	QNumbr		pointer to number

	These variables are all pointers so that the caller can modify the
values which they represent.

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

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

extern	VOID	ErrMsg();	/* display an error message */
extern	DEFAULT	IncCBP();	/* increment CBfPtr */
extern	char	*ZAlloc();	/* allocate memory */

EXTERN	char	*CBfPtr;	/* command buffer pointer */
EXTERN	struct	MStck MStack[];	/* macro stack */
EXTERN	WORD	MStTop;		/* macro stack top */
EXTERN	char	*(*QBfBeg);	/* start of q-register text area */
EXTERN	char	*(*QBfPtr);	/* ptr to end of q-reg text area, plus 1 */
EXTERN	LONG	*QNumbr;	/* pointer to q-register number */
EXTERN	struct	QReg QRgstr[];	/* global q-registers */


DEFAULT FindQR()		/* find q-register index */
{
	static	char	*ErrTxt = "x";
	LOCAL	WORD	i;
	LOCAL	BOOLEAN	LocalQ;
	LOCAL	WORD	QIndex;

#if DEBUGGING
DbgInd+=2;if(DbgLvl>=3){DbgMsg();DbgDBf("FindQR: called.\015\012");DbgROf();}
#endif
	if (LocalQ = (*CBfPtr == '.'))		/* if local q-register name */
		if (IncCBP() == FAILURE)	/* move to next character */
#if DEBUGGING
{if(DbgLvl>=3)
{DbgMsg();DbgDBf("FindQR: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
			return(FAILURE);
#if DEBUGGING
}
#endif

	if (Is_Upper(*CBfPtr))
		QIndex = *CBfPtr - '\67';
	else if (Is_Lower(*CBfPtr))
		QIndex = *CBfPtr - '\127';
	else if (Is_Digit(*CBfPtr))
		QIndex = *CBfPtr - '0';
	else
		{
		*ErrTxt = *CBfPtr;
		ErrMsg(ERR_IQN, ErrTxt);	/* illegal q-register name */
#if DEBUGGING
if(DbgLvl>=3)
{DbgMsg();DbgDBf("FindQR: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
		return(FAILURE);
		}

	if (LocalQ)				/* if local q-register */
		if (MStTop < 0)			/* if not in a macro */
			QIndex += 36;
		else				/* else in a macro */
			{
			if (MStack[MStTop].LQTabl == NULL)
				{
				MStack[MStTop].LQTabl =
			(struct QReg *)ZAlloc(36*sizeof(struct QReg));
				if (MStack[MStTop].LQTabl == NULL)
					{
					ErrMsg(ERR_MEM);
#if DEBUGGING
if(DbgLvl>=3)
{DbgMsg();DbgDBf("FindQR: returning FAILURE.\015\012");DbgROf();}DbgInd-=2;
#endif
					return(FAILURE);
					}
				for (i=0;i<36;i++)
				    {
				    MStack[MStTop].LQTabl[i].Start =
				    MStack[MStTop].LQTabl[i].End_P1 = NULL;
				    MStack[MStTop].LQTabl[i].Number = 0L;
				    }
				}
			QBfBeg = &(MStack[MStTop].LQTabl[QIndex].Start);
			QBfPtr = &(MStack[MStTop].LQTabl[QIndex].End_P1);
			QNumbr = &(MStack[MStTop].LQTabl[QIndex].Number);
#if DEBUGGING
if(DbgLvl>=3)
{DbgMsg();DbgDBf("FindQR: returning SUCCESS.\015\012");DbgROf();}DbgInd-=2;
#endif
			return(SUCCESS);
			}

	QBfBeg = &(QRgstr[QIndex].Start);
	QBfPtr = &(QRgstr[QIndex].End_P1);
	QNumbr = &(QRgstr[QIndex].Number);
#if DEBUGGING
if(DbgLvl>=3)
{DbgMsg();DbgDBf("FindQR: returning SUCCESS.\015\012");DbgROf();}DbgInd-=2;
#endif
	return(SUCCESS);
}
