static char SList_id[] = "$Header: /usr/tiburon/xPlatform/utils/RCS/SList.cc,v 1.3 1996/07/22 10:20:44 oreilly Exp pean $";

/*
$Log: SList.cc,v $
Revision 1.3  1996/07/22 10:20:44  oreilly
Added RCS stuff

*/

#include <stdio.h>
#include <stdlib.h>
#include "SList.h"

int SListBase::remove(SLink *a)
{
  if (last == 0)
    // Empty list
    return -1;

  // Walk the list, searching for specified link  
  SLink *lnk = last->next;
  SLink *prev = last;
  do 
  {
    if (lnk == a)
    {
      // Found target link; delete it
      if (last == last->next)
        // There was only 1 link on list
        last = 0;
      else
      {       
	if (lnk == last)
	  // Reset last pointer to previous link
	    last = prev;
	else if (lnk == last->next)
	  last->next = lnk->next;
	
	prev->next = lnk->next;
      }
      return 0;
    } 
    prev = lnk;
    lnk = lnk->next;
    
  } while (lnk != last->next);
  

  // Never found target
  return -1;
}


// Prepend to list
void SListBase::insert(SLink *a)
{
  if (last)
    a->next = last->next;
  else
    last = a;
  
  last->next = a;
}


// Append to list
void SListBase::append(SLink *a)
{
  if (last) 
  {
    a->next = last->next;
    // last = last->next = a;
    last->next = a;
    last = a;
  }
  else
    last = a->next = a;
}


// Return head and delete from list
SLink *SListBase::get()
{
  if (last == 0) 
  {
    fprintf(stderr, "SListBase::get() - get from empty SList\n");
    exit(1);
  }
  
  SLink *f = last->next;
  if (f == last)
    last = 0;
  else
    last->next = f->next;
  
  return f;
}


int SListBase::length()
{
  SListBaseIter iter(*this);
  SLink *link;
  int len = 0;
  while (link = iter())
  {
    len++;
  }
  return len;
}


SListBaseIter::SListBaseIter(SListBase &s)
{
  atEnd = FALSE;
  cs = &s;
  ce = cs->last;
}


// return 0 to indicate end of iteration 
SLink *SListBaseIter::operator() ()    
{
  if (atEnd)
    return 0;

  ce = ce->next;
  SLink *ret = ce;

  if (ret == cs->last) 
  {
    atEnd = TRUE;
  }
  
  return ret;
}


int SListBaseIter::remove() 
{
  if (ce == 0)
    return -1;
  
  if (cs->remove(ce) == 0)
    return 0;
  
  else
    return -1;
}



  



