/***********************************************
 (C) Copyright 1992-1993; dit/upm
   Distributed under the conditions stated in the
   EPS General Public License (see file LICENSE)
 ***********************************************
 $Log: stack.c,v $
 * Revision 2.5  1993/06/15  10:58:17  eps
 * is a LINTLIBRARY
 *
 * Revision 2.4  1993/01/12  16:35:05  eps
 * portability issues
 *
 * Revision 2.3  1992/11/17  11:48:18  eps
 * fix definition of *alloc for PC portability
 *
 * Revision 2.2  1992/01/14  15:43:30  eps
 * distribution issues
 *
 **********************************************/

#ifndef lint
static char rcsid[]= "$Id: stack.c,v 2.5 1993/06/15 10:58:17 eps Exp $";
#endif

/* LINTLIBRARY */

# define stack_IMP      1
# include "cast.hh"
# include <stdio.h>
# include <assert.h>

TNODE**	st_store= NULL;
int	st_size= 0;
int	st_pos= -1;

# define st_top		(*(st_store+st_pos))
# define st_pick(n)	(*(st_store+st_pos-n))
# define st_isfull	(st_pos+1 >= st_size ? TRUE : FALSE)
# define st_isempty	(st_pos <= -1 ? TRUE : FALSE)
# define st_desc(n)	(st_pos -= n)

/* ------ Public Functions ------------------------------------ */

PUBLIC	void
stinit	(size)
	int	size;
{
   if (size != 0){
      st_store= (TNODE**) calloc(size, sizeof(TNODE*));
      st_size= size;
   }
   st_pos= -1;
}

PUBLIC	void
stpush	(nd)
	TNODE* nd;
{
    assert (st_isfull == FALSE);
    st_pos++;
    st_top= nd;
}

PUBLIC void
stpop ()
{
    assert(st_isempty == FALSE);
    st_pos--;
}

PUBLIC	void
stkpop ()
{
    assert(st_isempty == FALSE);
    st_pos--;
    free_node (*(st_store + st_pos + 1));
}

PUBLIC	int
stdepth	()
{
   return st_pos+1;
}

PUBLIC	int
stisempty ()
{
   return st_isempty;
}

PUBLIC	int
stisfull ()
{
   return st_isfull;
}

PUBLIC TNODE*
sttop ()
{
   assert (st_isempty == FALSE);
   return st_top;
}

PUBLIC	TNODE*
stpick	(n)
	int	n;
{
   assert (st_pos >= n);
   return st_pick(n);
}

PUBLIC	void
stpft	(ft)
	TNODE*	ft;
{
   assert (st_isempty == FALSE);
   st_top->father= ft;
}

PUBLIC	void
stpfs	(fs)
	TNODE*	fs;
{
   assert (st_isempty == FALSE);
   st_top->sons= fs;
}

PUBLIC	void
stprb	(rb)
	TNODE*	rb;
{
   assert (st_isempty == FALSE);
   st_top->brothers= rb;
}

PUBLIC	void
stswap	()
{
	TNODE* auxt;

  assert(st_pos >= 1);
  auxt= st_top;
  st_top = st_pick (1);
  st_pick(1)= auxt;
}

PUBLIC	void
stput	(type)
	int	type;
{
    assert (st_isfull == FALSE);
    st_pos++;
    st_top= new_node (type);
}

PUBLIC	void
stincr	(n)
	int	n;
{
    st_pos += n;
    assert(st_isfull == FALSE);
}

PUBLIC	void
stdecr	(n)
	int	n;
{
    st_pos -= n;
    assert(st_isempty == FALSE);
}

PUBLIC	void
stlrlink ()
{
	TNODE*	auxt;

   assert(st_pos >= 1);
   auxt= st_pick(1);
   if (auxt == NULL){
       st_pick(1)= st_top;
       st_pos--;
   }
   else{
       while (auxt->brothers != NULL)
	    auxt= auxt->brothers;
       auxt->brothers= st_top;
       st_pos--;
   }
}

PUBLIC	void
staddrb	()
{
	TNODE*	auxt;

   assert(st_pos >= 1);
   auxt= st_top;
   stlrlink ();
   for ( ; auxt != NULL; auxt= auxt->brothers)
	auxt->father= st_top->father;
}

PUBLIC	void
stsflink ()
{
    assert(st_pos >= 1);
    st_top->sons= NULL;
    (void)lnsons(st_top, st_pick(1));
    st_pick(1)= st_top;
    st_pos--;
}

PUBLIC  void
staclr  (clr, value)
	int clr;
	CLR_TYPE value;
{
    assert (st_isempty == FALSE);
    assert (st_top != NULL);
    assert (find_attr (clr, st_top) == NULL);
    set_attr (clr, st_top, value);
}

PUBLIC  CLR_TYPE
stfclr  (clr)
	int clr;
{
    assert (st_isempty == FALSE);
    assert (st_top != NULL);
    assert (find_attr (clr, st_top) != NULL);
    return find_attr (clr, st_top)->value;
}

PUBLIC  int
stchclr (clr)
	int clr;
{
    assert (st_isempty == FALSE);
    assert (st_top != NULL);
    return (find_attr (clr, st_top) != NULL ? TRUE : FALSE);
}

PUBLIC  void
stsclr  (clr, value)
	int clr;
	CLR_TYPE value;
{
	TATTR*	att;

    assert (st_isempty == FALSE);
    assert (st_top != NULL);
    if (find_attr (clr, st_top) != NULL){
	 att= find_attr (clr, st_top);
	 att->value= value;
    }
    else {
     fprintf(stderr, "stsclr %d\n", value);
     set_attr (clr, st_top, value);
   }

}

PUBLIC	void
stdraw	(depth)
	int	depth;
{
  /*KJT 22/01/23: added "int" type */
  register int i;

  for (i = st_pos; i >= 0; i--)
  {
    if (*(st_store+i) == NULL){
	 (void) fprintf (stderr, "%4d\n",i);
    }
    else if (depth == 0){
	 (void) fprintf (stderr, "%4d  ",i);
	 dr_node (*(st_store+i));
    }
    else{
	 (void) fprintf (stderr, "%4d  ",i);
	 dr_tree (*(st_store+i));
    }
  }
}
