// File: bstrstack.C
//
// Implementation of class BStringStack which was derived from GenStack

#include <iostream.h>
#include <iomanip.h>
#include <stdlib.h>
#include "bstrstack.h"

// "Local" functions
//
static void CrashOnNULL(void *ptr, char *mesg) ;

static void CrashOnNULL(void *ptr, char *mesg) {
   if (ptr == NULL) {
      cerr << "CrashOnNULL: " << mesg << endl ;
      exit(1) ;
   }
}


// Default constructor
//
BStringStack::BStringStack()
: GenStack(cmp, prt)        // member initializer
{
#ifndef NDEBUG
   cerr << "BStringStack constructor, this = " << this << endl ;
#endif
   // Do nothing
}


// Destructor
//
BStringStack::~BStringStack() {
#ifndef NDEBUG
   cerr << "BStringStack destructor, this = " << this << endl ;
#endif

   // Do nothing, GenStack destructor automatically called
}


// Add a string to the end top of the stack
//
void BStringStack::push(const BString& bs) {

   BString *newstr = new BString(bs) ;
   CrashOnNULL(newstr, "Out of memory in BStringStack::push()") ;

   GenStack::push(newstr) ;
}


// Return and delete from top of the stack
//
BString BStringStack::pop() {
   BString bs, *bsptr ;

   bsptr = (BString *) GenStack::pop() ;

   bs = *bsptr ;    // inefficient, but avoids memory leaks
   delete bsptr ;
   return bs ;
}


// Return string at the top of the stack
//
BString BStringStack::top() {
   BString bs, *bsptr ;

   bsptr = (BString *) GenStack::top() ;
   return *bsptr ;
}


// Compare two strings
//
int BStringStack::cmp(void *vptr1, void *vptr2) {
   BString *ptr1, *ptr2 ;

   ptr1 = (BString *) vptr1 ;
   ptr2 = (BString *) vptr2 ;

   if (ptr1 == NULL && ptr2 == NULL) return 0 ;
   if (ptr1 == NULL) return -1 ;
   if (ptr2 == NULL) return  1 ;

   if (*ptr1 < *ptr2) return -1 ; // uses overloaded BString comps.
   if (*ptr1 == *ptr2) return 0 ;
   return 1 ;
}


// print out a string
//
void BStringStack::prt(void *vptr) {
   BString *ptr ;

   if (vptr == NULL) return ;

   ptr = (BString *) vptr ;
   cout << *ptr << " " ;
}
