 /* $Header:asscan.h 12.0$ */
 /* $ACIS:asscan.h 12.0$ */
 /* $Source: /ibm/acis/usr/src/bin/as_ca/RCS/asscan.h,v $ */
#ifndef lint
static char rcsidasscan[] = "$Header:asscan.h 12.0$";
#endif
/* $Source: /ibm/acis/usr/src/bin/as_ca/RCS/asscan.h,v $ */
/*
 *	Copyright (c) 1982 Regents of the University of California
 *	@(#)asscan.h 4.9 6/30/83
 */
/*
 *	The character scanner is called to fill up one token buffer
 *
 *	However, once the tokens are filled up by the
 *	character scanner, they are used in both the first and the second
 *	pass.  Holes created by .stab removal are replaced
 *	with 'skip' tokens that direct the second pass to ignore the
 *	following tokens.
 */

#define TOKBUFLG		4096
#define MAXVAX			32		
#define SAFETY			16

#define AVAILTOKS		TOKBUFLG -\
		sizeof(int) -\
		sizeof (struct tokbufdesc *) -\
		MAXVAX - SAFETY

struct tokbufdesc{
	int		tok_count;		/*absolute byte length*/
	struct		tokbufdesc *tok_next;
	char		toks[AVAILTOKS];
	char		bufovf[MAXVAX + SAFETY];
};
/*
 *	Definitions for handling tokens in the intermediate file
 *	buffers.
 *
 *	We want to have the compiler produce the efficient auto increment
 *	instruction for stepping through the buffer of tokens.  We must
 *	fool the type checker into thinking that a pointer can point
 *	to various size things.
 */

typedef int inttoktype;
typedef char bytetoktype;

typedef char *ptrall;			/*all uses will be type cast*/
/* this was u_short in orig. 4.2 code.  u_char is quite sufficient. */
/* Currently is only used to hold length of a string of tokens. */
typedef u_char lgtype;			/*for storing length of strings or skiping*/
#define MAX_SKIPLG	127	/* hack aid for skip across 2 buffers */
/*
 *	definitions for putting various typed values
 *	into the intermediate buffers
 *	ptr will ALWAYS be of type ptrall
 */

#define	pchar(ptr,val)		*ptr++  = val
#define	puchar(ptr,val)		*ptr++  = val
#define	ptoken(ptr,val)		*ptr++  = val

/* Following four macros depend on ibm032 machine characteristics and on
 * knowing sizeof(struct Opcode) == 2.  The performance benefits outweigh
 * the code opacity.
 * 	pint, plong, pptr, popcode may be used only in a statement context.
 */
#define	pint(ptr,val)	{unsigned t = val;\
			if (((int)ptr & 3) == 0) *(unsigned int *)ptr = t;\
			else {\
			    *((char *)ptr+3) = t;\
			    *((char *)ptr+2) = t = t>>8;\
			    *((char *)ptr+1) = t = t>>8;\
			    *ptr = t = t>>8;\
			};\
			ptr += sizeof(int);}
#define	plong(ptr,val)		pint(ptr,val)
#define	pptr(ptr,val)		pint(ptr,val)
#define	popcode(ptr,val)	{*((char *)ptr+1) = *(unsigned short*)&val;\
				 *(char *)ptr = *(unsigned short*)&val>>8;\
				 ptr += 2; }
#define	pnumber(ptr,val)	bcopy(&val,ptr,sizeof(Bignum)),	ptr += sizeof(Bignum)

#define	gchar(val, ptr)		val = *ptr++
#define	guchar(val, ptr)	val = *ptr++
#define	gtoken(val, ptr)	val = *ptr++

/* Following four macros depend on ibm032 machine characteristics and on
 * knowing sizeof(struct Opcode) == 2.  The performance benefits outweigh
 * the code opacity.
 * 	gint, glong, gptr, gopcode may be used only in a statement context
 *	and only with arguments that are identifiers.
 */
#define	gint(val,ptr)	{val = (\
			((unsigned int)ptr & 3) == 0 ?\
			    *(unsigned int *)ptr:\
			    (((( (*((char*)ptr) << 8) | *((char*)ptr+1)) << 8) \
			     | *((char*)ptr+2)) << 8) \
			     | *((char*)ptr+3)\
			 ); ptr += sizeof(int)   ; }
#define	glong(val,ptr)		gint(val,ptr)
#define	gptr(val,ptr)		gint(val,ptr)
#define	gopcode(val,ptr)	{*(short *)&val = (*(unsigned char *)ptr << 8)\
			        | *((unsigned char *)ptr+1);\
					ptr += 2;}

#define	gnumber(val,ptr)	bcopy(ptr,&val,sizeof(Bignum)),	ptr += sizeof(Bignum)

extern	ptrall tokptr;	/*the next token to consume, call by copy*/
extern	ptrall tokub;	/*current upper bound in the current buffer*/
