/* ======================================================================= */
/* SourceCode:       Stack ADT routines                                    */
/* Programmer:       Paul Overaa                                           */
/* OriginalDate:     17th Jan 91                                           */
/* Modifications:                                                          */
/* ----------------------------------------------------------------------- */
/* Notes: These routines allow a program to use a true dynamic stack data 
          structure without the knowing anything about how it's done.      */
/* ----------------------------------------------------------------------- */
#include <stdio.h>
#include <stdlib.h>
#include <exec/types.h>
#include "stack_adt.h"

struct StackItem {
        
        struct StackItem *NextItem;
        
        UBYTE  Data[1]; /* actually user defined amount of data */

};

struct StackDescriptor {

        struct StackItem *FirstItem;

        UBYTE  ItemSize;

};

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

STACK *CreateStk(ULONG unit_size)

{
        
struct StackDescriptor *stack_descriptor_p;
        
if (stack_descriptor_p=(struct StackDescriptor *)

                       calloc(1,sizeof(struct StackDescriptor)))
        
        {
                
         stack_descriptor_p->ItemSize=unit_size;
                
        }

return((STACK *)stack_descriptor_p);

}

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

void KillStk(STACK *descriptor_p)

{

UBYTE *dead_block_p; struct StackDescriptor *stack_descriptor_p;

stack_descriptor_p=(struct StackDescriptor *)descriptor_p;

while (stack_descriptor_p->FirstItem)
        
        {
      
        dead_block_p=(UBYTE *)stack_descriptor_p->FirstItem;

        stack_descriptor_p->FirstItem=stack_descriptor_p->FirstItem->NextItem;

        free(dead_block_p);
        
        }

free(stack_descriptor_p);

}

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

BOOL PushStk(STACK *descriptor_p, UBYTE *data_item)

{

BOOL error_flag=TRUE; COUNT i; struct StackItem *new_item_p;

struct StackDescriptor *stack_descriptor_p;

stack_descriptor_p=(struct StackDescriptor *)descriptor_p;

if (new_item_p=(struct StackItem *)

        calloc(1, sizeof(struct StackItem)-1+stack_descriptor_p->ItemSize))

        {
        
        new_item_p->NextItem=stack_descriptor_p->FirstItem;
        
        stack_descriptor_p->FirstItem=new_item_p;
        
        for (i=0;i<stack_descriptor_p->ItemSize;i++)
        
                {
                
                new_item_p->Data[i]=*data_item++;
                
                }
        
        error_flag=FALSE;
        
        }      

return(error_flag);

}

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

BOOL PopStk(STACK *descriptor_p, UBYTE *data_item)

{
        
BOOL error_flag=TRUE; COUNT i; UBYTE *dead_block_p;

struct StackDescriptor *stack_descriptor_p;

stack_descriptor_p=(struct StackDescriptor *)descriptor_p;

if (stack_descriptor_p->FirstItem)

    {

    for (i=0; i<stack_descriptor_p->ItemSize; i++)

        {
        
        *data_item++=stack_descriptor_p->FirstItem->Data[i];
        
        }

    dead_block_p=(UBYTE *)stack_descriptor_p->FirstItem;

    stack_descriptor_p->FirstItem=stack_descriptor_p->FirstItem->NextItem;

    free(dead_block_p); error_flag=FALSE;

    }

return(error_flag);

}

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

BOOL StkEmpty(STACK *descriptor_p)

{
        
BOOL empty_flag=TRUE; struct StackDescriptor *stack_descriptor_p;

stack_descriptor_p=(struct StackDescriptor *)descriptor_p;

if (stack_descriptor_p->FirstItem) {empty_flag=FALSE;}

return(empty_flag);

}

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







