/* @(#)star.h	1.3	2/10/93 */
/*******************************************************************************

This code was written and designed by 
Andrew Gene HALL of I.N. Services Pty. Ltd., Scarborough WA, Australia,
for the 
University of Western Australia, Crawley WA, Australia.

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

#ifndef STAR_H
#define STAR_H
/* forward declaration of functions */
extern Data_Seq	*Data_Seq_froma_Data_Name_Seq( Data_Name_Seq*, Data_Name_Seq* );
extern void	Add_Data_Item( Data_Item * );
extern void	Stop_Loop( Domain );

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

/*
** Various Stacks for retaining state information between calls
*/

/* length of each block in the stack */
#define BLOCK_SIZE 32

/* Operations on a stack of 
** Restart Positions In List_Value_Sequence
*/
extern int	*RPIV;	/* stack of restart positions within the L_V_Ss */
extern int	current_RPIV;	/* the current top of the stack */
extern int	Sizeof_RPIV;	/* the current size of the stack */
extern int	N_blocks_RPIV;	/* the number of blocks in the stack */

/* Push a value onto the top of the stack,
** increase the size of the stack if necessary
*/
#define Push_Restart_Data_Posn( a ) \
   if( ++current_RPIV == Sizeof_RPIV ) \
      /* we've just overgrown the stack */ \
      /* add another block on the stack */ \
      if( RPIV = (int *)realloc( RPIV, ++N_blocks_RPIV * BLOCK_SIZE * sizeof( int )) ) \
         { RPIV[ current_RPIV ] = a; Sizeof_RPIV += BLOCK_SIZE; } \
      else \
         ERROR_MSG("Push_RPIV: Out of memory"); \
   else \
      /* add the position to the top of the stack */ \
      RPIV[ current_RPIV ] = a
      
/* Drop the top of the stack
*/
#define Decrement_Restart_Data_Posn \
   --current_RPIV

/* return and remove the top of value on the stack,
*/
#define Pop_Restart_Data_Posn \
   RPIV[ current_RPIV-- ]

/* return the top of value on the stack,
** leaving the stack pointer where it is
*/
#define Top_Restart_Data_Posn \
   RPIV[ current_RPIV ]

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

/* Operations on a stack of 
** The Next Tail Position In List_Value_Sequence
*/
extern int	*NPIV;	/* stack of offsets into the stack of tail positions
                	** within the L_V_Ss */
extern int	current_NPIV;	/* the current top of the stack */
extern int	Sizeof_NPIV;	/* the current size of the stack */
extern int	N_blocks_NPIV;	/* the number of blocks in the stack */

/* Push a value onto the top of the stack,
** increase the size of the stack if necessary
*/
#define Push_Next_Data_Posn( a ) \
   if( ++current_NPIV == Sizeof_NPIV ) \
      /* we've just overgrown the stack */ \
      /* add another block on the stack */ \
      if( NPIV = (int *)realloc( NPIV, ++N_blocks_NPIV * BLOCK_SIZE * sizeof( int )) )\
         { NPIV[ current_NPIV ] = a; Sizeof_NPIV += BLOCK_SIZE; }\
      else \
         ERROR_MSG("Push_NPIV: Out of memory"); \
   else \
      /* add the position to the top of the stack */ \
      NPIV[ current_NPIV ] = a
      
/* Drop the top of the stack
*/
#define Decrement_Next_Data_Posn \
   --current_NPIV

/* return and remove the top of value on the stack,
*/
#define Pop_Next_Data_Posn \
   NPIV[ current_NPIV-- ]

/* return the top of value on the stack,
** leaving the stack pointer where it is
*/
#define Top_Next_Data_Posn \
   NPIV[ current_NPIV ]

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

/* Operations on a stack of
** Pointers into List_Value_Sequence
*/
typedef List_Value_Seq	**ptrptrLVS;	/* base type in stack */
extern ptrptrLVS	*tail_positions;	/* stack of pointers to pointers */
extern int	current_tp;		/* the current top of the stack */
extern int	Sizeof_tp;		/* the current size of the stack */
extern int	N_blocks_tp;		/* the number of blocks in the stack */

/* Push a value onto the top of the stack,
** increase the size of the stack if necessary
*/
#define Push_Tail_Posn( a ) \
   if( ++current_tp == Sizeof_tp ) \
      /* we've just overgrown the stack */ \
      /* add another block on the stack */ \
      if( tail_positions = (ptrptrLVS *)realloc( tail_positions, ++N_blocks_tp * BLOCK_SIZE * sizeof( ptrptrLVS )) ) \
         { tail_positions[ current_tp ] = a; Sizeof_tp += BLOCK_SIZE; }\
      else \
         ERROR_MSG("Push_Tail_Posn: Out of memory"); \
   else \
      /* add the position to the top of the stack */ \
      tail_positions[ current_tp ] = a
      
/* Drop the top of the stack
*/
#define Decrement_Tail_Posn \
   --current_tp

/* return and remove the top of value on the stack,
*/
#define Pop_Tail_Posn \
   tail_positions[ current_tp-- ]

/* return the top of value on the stack,
** leaving the stack pointer where it is
*/
#define Top_Tail_Posn \
   tail_positions[ current_tp ]

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

/* Operations on a stack of
** Pointers into a Data_Name_Sequence,
** indicating the restart position for a packet
*/
typedef Data_Name_Seq *ptrDNS;	/* base type in stack */
extern ptrDNS	*restart_positions;	/* stack of pointers */
extern int	current_rp;		/* the current top of the stack */
extern int	Sizeof_rp;		/* the current size of the stack */
extern int	N_blocks_rp;		/* the number of blocks in the stack */

/* Push a value onto the top of the stack,
** increase the size of the stack if necessary
*/
#define Push_Restart_Name_Posn( a ) \
do {\
   if( ++current_rp == Sizeof_rp ) \
      /* we've just overgrown the stack */ \
      /* add another block on the stack */ \
      if( restart_positions = (ptrDNS *)realloc( restart_positions, ++N_blocks_rp * BLOCK_SIZE * sizeof( ptrDNS )) ) \
         {\
/* DEBUG_MSG("Pushing,");fprintf(error_fp,"(d)   %p\n",a);DEBUG_MSG("onto restart_positions at,");fprintf(error_fp,"(d)   %d\n",current_rp); */\
           restart_positions[ current_rp ] = a; Sizeof_rp += BLOCK_SIZE; }\
      else \
         ERROR_MSG("Push_Tail_Posn: Out of memory"); \
   else \
      /* add the position to the top of the stack */ \
      {\
/* DEBUG_MSG("Pushing,");fprintf(error_fp,"(d)   %p\n",a);DEBUG_MSG("onto restart_positions at,");fprintf(error_fp,"(d)   %d\n",current_rp); */\
      restart_positions[ current_rp ] = a;\
      }\
} while(0)
      
/* Drop the top of the stack
*/
#define Decrement_Restart_Name_Posn \
   --current_rp

/* return and remove the top of value on the stack,
*/
#define Pop_Restart_Name_Posn \
   restart_positions[ current_rp-- ]

/* return the top of value on the stack,
** leaving the stack pointer where it is
*/
#define Top_Restart_Name_Posn \
   restart_positions[ current_rp ]

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

/* Operations on a stack of
** Pointers into a Data_Name_Sequence,
** indicating the next position in the packet
*/
extern ptrDNS	*next_positions;	/* stack of pointers */
extern int current_np;			/* the current top of the stack */
extern int Sizeof_np;			/* the current size of the stack */
extern int N_blocks_np;			/* the number of blocks in the stack */


/* Push a value onto the top of the stack,
** increase the size of the stack if necessary
*/
#define Push_Next_Name_Posn( a ) \
   if( ++current_np == Sizeof_np ) \
      /* we've just overgrown the stack */ \
      /* add another block on the stack */ \
      if( next_positions = (ptrDNS *)realloc( next_positions, ++N_blocks_np * BLOCK_SIZE * sizeof( ptrDNS )) ) \
         { next_positions[ current_np ] = a; Sizeof_np += BLOCK_SIZE; }\
      else \
         ERROR_MSG("Push_Next_Name_Posn: Out of memory."); \
   else \
      /* add the position to the top of the stack */ \
      next_positions[ current_np ] = a
      
/* Drop the top of the stack
*/
#define Decrement_Next_Name_Posn \
   --current_np

/* return and remove the top of value on the stack,
*/
#define Pop_Next_Name_Posn \
   next_positions[ current_np-- ]

/* return the top of value on the stack,
** decrementing the stack pointer where it is
*/
#define Top_Next_Name_Posn \
   next_positions[ current_np ]

/* D E B U G  M A C R O S */
#define DUMP_restart_positions \
do {\
int q;\
\
fprintf(error_fp,"restart_positions stack\n");\
for( q = 0; q <= current_rp; q++ )\
	fprintf(error_fp,"(d)   %d:\t%p\n",q,restart_positions[q]);\
} while ( 0 )

#define DUMP_next_positions \
do {\
int q;\
\
fprintf(error_fp,"next_positions stack\n");\
for( q = 0; q <= current_np; q++ )\
	fprintf(error_fp,"(d)   %d:\t%p\n",q,next_positions[q]);\
} while ( 0 )

#define DUMP_tail_positions \
do {\
int q;\
\
fprintf(error_fp,"tail_positions stack\n");\
for( q = 0; q <= current_tp; q++ )\
	fprintf(error_fp,"(d)   %d:\t%p\n",q,tail_positions[q]);\
} while ( 0 )

#define DUMP_NPIV \
do {\
int q;\
\
fprintf(error_fp,"NPIV stack\n");\
for( q = 0; q <= current_NPIV; q++ )\
	fprintf(error_fp,"(d)   %d:\t%d\n",q,NPIV[q]);\
} while ( 0 )

#define DUMP_RPIV \
do {\
int q;\
\
fprintf(error_fp,"RPIV stack\n");\
for( q = 0; q <= current_RPIV; q++ )\
	fprintf(error_fp,"(d)   %d:\t%d\n",q,RPIV[q]);\
} while ( 0 )
#endif
