/***********************************
  (C) Copyright 1992-1993; dit/upm
  Distributed under the conditions stated in the
  TOPO General Public License (see file LICENSE)
  ***********************************/

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

  Francisco Monfort Martin

  3 May 1990

  Module to manage dynamic stacks
  of data of any type.

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

/* LINTLIBRARY */


#include "listack.h"


/* Create_Stack
 * Create an empty stack.
 */
StackTyp Create_Stack()
{
  return Create_list();
}

/*----------------------------------------------------------------*/

/* Free_Stack
 * Free the stack.
 * Deallocate the memory used by the elements with FreeF.
 */
void Free_Stack(stack,FreeF)
     StackTyp stack;
     void (*FreeF) ();
{
  Free_list(stack,FreeF);
}

/*----------------------------------------------------------------*/

/* Save_Stack
 * Put the element info onto the stack
 */
StackTyp Save_Stack(info,stack)
     DataStackTyp info;
     StackTyp     stack;
{
  return Insert_list(info,stack);
}

/*----------------------------------------------------------------*/

/* Look_Stack
 * Look at the first element of stack
 */
DataStackTyp Look_Stack(stack)
     StackTyp stack;
{
  return LookInfo_list(stack);
}

/*----------------------------------------------------------------*/

/* Get_Stack
 * Get the first element of the stack pointed by pstack.
 * If the stack is empty, return NULL
 */
DataStackTyp Get_Stack(pstack)
     StackTyp *pstack;
{
  DataStackTyp   i;

  if (*pstack==NULL)
    return NULL;
  i       = GetInfo_list(*pstack);
  *pstack = DeleteNode_list(*pstack,*pstack);
  return i;
}
/*----------------------------------------------------------------*/

/* GetBottom_Stack
 * Get the element at the bottom of the stack pointed by pstack. (FIFO fashion)
 * If the stack is empty, return NULL
 */
DataStackTyp GetBottom_Stack( pstack )
     StackTyp *pstack;
{
  DataStackTyp   i;
  ListTyp lastStackElem;

  if (*pstack==NULL)
    return NULL;
  lastStackElem = Last_list( *pstack );
  i       = GetInfo_list( lastStackElem );
  *pstack = DeleteNode_list( lastStackElem, *pstack );
  return i;
}

/*----------------------------------------------------------------*/

/* Remove_Stack
 * Remove the first element of the stack pointed by pstack.
 * Deallocate the memory used by this element with "func".
 */
StackTyp Remove_Stack(pstack,func)
     StackTyp * pstack;
     void (*func)();
{
  LASSERT(*pstack != NULL);
  if ( func!=NULL )
    func(LookInfo_list((ListTyp)(*pstack)));
  return DeleteNode_list(*pstack,*pstack);
}

/*----------------------------------------------------------------*/

/* Copy_Stack
 * Return a copy of the stack "stack".
 * Elements are copied with func.
 */
StackTyp Copy_Stack(stack,func)
     StackTyp stack;
     int (*func) ();
{
  return Copy_list(stack,(DataStackTyp(*)())func);
}

/*----------------------------------------------------------------*/

/* IsEmpty_Stack
 * Return TRUE if stack is empty and FALSE if it is not.
 */
boolean IsEmpty_Stack(stack)
     StackTyp stack;
{
  return stack == NULL;
}

/*----------------------------------------------------------------*/

/* Print_Stack
 * Prints a stack in the format: infoTop, infoNext, ..., infoLast
 * "f" is a function that returns a string of char with the information
 * of the node.
 * "pstr" is the function used to print the value returned by "f".
 * BE CAREFULL: the strings returned by "f" are not disposed.
 */
void Print_Stack( st, f, pstr )
     StackTyp st;
     char *  (*f)();
     void (*pstr)();
{
  Print_list( st, f, pstr );
}

/*----------------------------------------------------------------*/

/* Count_Stack
 * Number of elements in a stack s.
 */
int Count_Stack(s)
     StackTyp s;
{
  return Length_list(s);
}

/*----------------------------------------------------------------*/


/* Stack_to_list
 * Transform a stack into a list.
 */
ListTyp Stack_to_list( s )
     StackTyp s;
{
  return (ListTyp)s;
}

/*----------------------------------------------------------------*/

/* LookN_Stack
 * Look at the n-th element of stack
 * return NULL if it does not exist.
 */
DataStackTyp LookN_Stack(stack,n)
     StackTyp stack;
     int      n;
{
  LASSERT(n>0);
  for ( ; n>1 && stack!=NULL; n-- ){
    stack = Next_list(stack);
  }
  return stack==NULL ? NULL: LookInfo_list(stack);
}

/*----------------------------------------------------------------*/
