/*char RcsId[] = "$Header: /scisoft/users/mirone/SOURCESCVS/specfile/src/sflists.c,v 1.2 2003/02/12 09:00:03 mirone Exp $"; */
/************************************************************************
 *
 *   File:          sflists.c
 *
 *   Project:       SpecFile library
 *
 *   Description:   Functions to handle lists
 * 
 *   Author:        V.Rey
 *
 *   Date:          $Date: 2003/02/12 09:00:03 $
 *
 ************************************************************************/
/*
 *   Log: $Log: sflists.c,v $
 *   Log: Revision 1.2  2003/02/12 09:00:03  mirone
 *   Log: just log comments
 *   Log:
 *   Log: Revision 3.0  2000/12/20 14:17:19  rey
 *   Log: Python version available
 *   Log:
 * Revision 2.1  2000/07/31  19:03:25  19:03:25  rey (Vicente Rey-Bakaikoa)
 * SfUpdate and bug corrected in ReadIndex
 * 
 * Revision 2.0  2000/04/13  13:28:54  13:28:54  rey (Vicente Rey-Bakaikoa)
 * New version of the library. Complete rewrite
 * Adds support for MCA
 */
#include <stdio.h>
#include <string.h>
#include <Lists.h>

/*
 * Function declaration
 */
ObjectList * findInList     ( ListHeader *list, int (*proc)(void *,void *), void *value );
long         addToList      ( ListHeader *list, void *object, long size );
void         unlinkFromList ( ListHeader *list, ObjectList *element );

static long  linkToList     ( ListHeader *list, void *object );


/*********************************************************************
 *   Function:		ObjectList *findInList( list, proc, value )
 *
 *   Description:	Looks for an list element.
 *
 *   Parameters:
 *		Input :	(1) ListHeader pointer   
 *			(2) Comp. procedure
 *			(3) value 
 *   Returns:
 *		Pointer to the found element ,
 *		NULL if not found .
 *
 *********************************************************************/
ObjectList *
findInList( ListHeader *list, int (*proc)(void * , void *), void *value )
{
     register ObjectList	*ptr;
     
     for ( ptr=list->first ; ptr ; ptr=ptr->next ) {
          if ( (*proc)(ptr->contents, value) ) {
	       return( ptr );
	  }
     }
     return (ObjectList *)NULL;
}


/*********************************************************************
 *   Function:		int addToList( list, object, size )
 *
 *   Description:	Adds an element to the list.
 *
 *   Parameters:
 *		Input :	(1) List pointer   
 *			(2) Pointer to the new element
 *			(3) Size of the new element
 *   Returns:		
 *		(  0 ) => OK
 *	        ( -1 ) => error
 *	
 *********************************************************************/
long
addToList( ListHeader *list, void *object, long size )
{
     void    *newobj;

     if ( (newobj = (void *)malloc(size)) == (void *)NULL ) return( -1 );
     memcpy(newobj, object, size);
     
     return( linkToList( list, newobj ) );
       
}


/*********************************************************************
 *   Function:		int linkToList( list, object )
 *
 *   Description:	Adds an element to the list.
 *
 *   Parameters:
 *		Input:	(1) ListHeader pointer   
 *			(2) pointer to the new element
 *   Returns:		
 *		(  0 ) => OK
 *	        ( -1 ) => error
 *
 *********************************************************************/
static long
linkToList( ListHeader *list, void *object )
{
     ObjectList	*newobj;


     if ((newobj = (ObjectList *) malloc(sizeof(ObjectList))) == 
	    (ObjectList *) NULL)  return( -1 );
      
     newobj->contents	= object;
     newobj->prev	= list->last;
     newobj->next	= NULL;

     if (list->first == (ObjectList *)NULL) {
         list->first  = newobj;
     } else {
         (list->last)->next = newobj;
     }

     list->last = newobj;
     return( 0 );
}


/*********************************************************************
 *   Function:		int unlinkFromList( list, element )
 *
 *   Description:	Removes an element from the list.
 *
 *   Parameters:
 *		Input :	(1) List pointer   
 *			(2) Pointer to the element
 *
 *********************************************************************/
void
unlinkFromList( ListHeader *list, ObjectList *element )
{

     if ( element != (ObjectList *)NULL ) {
	  if ( element->next != (ObjectList *)NULL ) {
	       element->next->prev = element->prev;
	  }
	  else {
	       list->last = element->prev ;
	  }
	  if ( element->prev != (ObjectList *)NULL ) {
	       element->prev->next = element->next;
	  } 
	  else {
	       list->first = element->next;
	  }
	  free( element->contents );
	  free( element );
     }
}

