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

/***********************************
  
  David Larrabeiti Lopez
  
  30-1-1990
  
  Module to manage dynamic lists of
  any type of data.
  
  
  COMPILATION OPTIONS: The behaviour of this module can be modified
  by the following compilation flags:
  
  SDEBUG : activate debugging mode
  DEBUGMEM : activate control of deallocated memory
  
  TYPE DEFINITIONS:
  ListTyp : list type
  DataListTyp : type of list data
  
  FUNCTION DEFINITIONS:
  Create_list : creates a list
  Disp_list : disposes a list of nodes
  Free_list : frees a list and its data
  Insert_list : inserts data at the head of a list
  Add_list : appends data to the tail of a list
  Add_IfNotIn_list : appends data to the tail of a list if not yet done
  Next_list : next node in a list
  LookInfo_list : looks at (returns) the information in the current node
  GetInfo_list : gets (picks up) the information in the current node
  PutInfo_list : puts data in the current node
  In_list : says if an element is in a list
  LookFor_list : looks for the node where some data is stored
  Apply_Proc_list : apply a procedure to all the data in a list
  Apply_Func_list : apply a function to all the data in a list
  Join_list : joins two lists
  Copy_list : copies a list
  Equal_list : says if two lists are equal
  Print_list : prints a list into a file
  SPrint_list : returns a list in a string
  Reverse_list : reverses a list
  Diff_list : lists difference
  SubSet_list : says if a list is a subset of another
  DeleteNode_list : deletes a list node
  ExtractNode_list : picks up a node ( with its data )
  InsertBeforeNode_list : inserts data before current node.
  Length_list : list length
  Stat_list : statistics : allocated and released nodes.
  Last_list : last list node.
  
  ************************************/


#ifndef LIlists_H
#define LIlists_H


#include "listdh.h"


/* 
 * Node list.
 */
typedef void * DataListTyp;

typedef struct listnode{ DataListTyp       info;
			 struct listnode  *next;
		       } *ListTyp,ListNodeTyp;

/* Create_list
 * Creates an empty list.
 */
#define Create_list() (ListTyp)NULL 


/* CreateNode_list
 * Create a single node list.
 */
extern ListTyp CreateNode_list();


/* DispNode_list
 * Deallocates the memory used by the node n.
 */
extern void DispNode_list( /* n */ );
/* ListTyp n;*/


/* Disp_list
 * Frees the memory allocated to the nodes of list l.
 * See Free_list(l) to deallocate the memory used by the information.
 */
extern void Disp_list( /* l */ );
/* ListTyp  l; */


/* Free_list
 * Frees the memory allocated by the list l.
 * Functions f deallocate the information in each node.
 */
extern void Free_list( /*l,f*/ );
/* ListTyp  l;   */
/* void  (*f)(); */


/* Insert_list
 * Inserts the element e in the list l (in the head) and returns the new list. 
 */
extern ListTyp Insert_list( /* e, l */ );
/* DataListTyp e;
   ListTyp l;  */


/* Add_list
 * Appends the data e to the tail of list l.
 * Returns the new list.
 *
 *      DataListTyp  e; 
 *      ListTyp l;
 */
#define Add_list(e,l) (Join_list(l,Insert_list(e,(ListTyp)(NULL))))


/* Add_IfNotIn_list
 * Unlike Add_list the element is not Added if it is already in the list.
 * f==NULL => integer comparison.
 */
extern ListTyp Add_IfNotIn_list(/* e, l, f */);
/*       DataListTyp  e;
         ListTyp l;
         boolean (*f)(); */


/* Next_list
 * Return the next node of the list l.
 * If end of list return NULL.
 *
 *         ListTyp  l;
 */
#define Next_list(l) ( (l==NULL)? NULL:l->next )


/* LookInfo_list
 * Returns the data stored in the actual node (of the list) l.
 * If node is NULL then return NULL.
 *
 * extern DataListTyp LookInfo_list( l );
 *         ListTyp  l; 
 */
#define LookInfo_list(l) ( ((l)==NULL) ? NULL : (l)->info ) 


/* GetInfo_list
 * Picks up the data stored in the actual node (of the list) n.
 * Sets the information stored in n to NULL.
 * If node is NULL then return NULL.
 */
extern DataListTyp GetInfo_list( /* n */ );
/* ListTyp  n; */


/* PutInfo_list
 * Stores the data d into the current node (of the list) n.
 */
#define PutInfo_list(n,d) {LASSERT( n!=NULL ); (n)->info = d;}


/* In_list
 * Explores the list l and returns the boolean "e in l"
 * f is a boolean function to decide when two elements are equal.
 * f == NULL => integer comparison.
 */
extern boolean In_list( /* e, l, f */ );
/* DataListTyp  e;
   ListTyp l;
   boolean (*f)();  */


/* LookFor_list
 * Explores the list l and returns the first node where element e is found.
 * If e is not in l, then returns NULL.
 * Function f is a boolean function to decide when two elements are equal.
 * f == NULL => integer comparison.
 */
extern ListTyp LookFor_list( /* e, l, f */ );
/* DataListTyp  e;
   ListTyp l;
   boolean (*f)();  */


/* Apply_Proc_list
 * Applies procedure p to all the data stored in the list l.
 */
extern void Apply_Proc_list( /* l, p */ );
/* ListTyp l;
   void    (*p)();  */


/* Apply_Func_list
 * Applies function f to all the data stored in the list l.
 * The datas stored in the list will be updated with the value returned by f.
 */
extern void Apply_Func_list( /* l, f */ );
/* ListTyp l;
   DataListTyp    (*f)();  */


/* Join_list
 * Returns the concatenation l1.l2.
 */
extern ListTyp Join_list( /* l1, l2 */ );
/* ListTyp  l1, l2; */



/* Copy_list
 * Returns a copy of list l.
 * f is used to copy the data stored in the nodes.
 * f == NULL => integer echoing.
 */
extern ListTyp Copy_list( /* l, f */);
/*  ListTyp l;
    DataListTyp (*f)();*/


/* Equal_list
 * Returns the boolean: "list l1 == list l2".
 * The order of the elements must be the same.
 * eq is a function that returns the equallity of two elements of the list
 * boolean eq( e1, e2 )
 * eq == NULL => integer comparison.
 */
extern boolean Equal_list(/* l1, l2, eq */);
/* ListTyp l1,l2;
   boolean (*eq)();*/


/* Print_list
 * Prints a list in the format: info1, info2, ..., infoN
 * "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.
 */
extern void Print_list( /* l, f, pstr */ );
/*         ListTyp l;
           char * (*f)();
           void (*pstr)(); */


/* SPrint_list
 * return a char string with list l with the format:
 *   f(info1), f(info2), ..., infoN
 * f is a function that makes a string of char with the information
 * of the node. The strings generated by f are disposed.
 */
extern char * SPrint_list(/* l, f */);
/*       ListTyp l;
         char * (*f)(); */


/* Reverse_list
 * Reverses a list l.
 */
extern ListTyp Reverse_list(/*l*/);
/*  ListTyp l; */


/* Diff_list
 * returns the difference l1-l2.
 * Equal decides whether two elements are equal. ( NULL=> integer comparison )
 * FreeInfo is used to release the info of the rest in l1.
 * ( l1 is modified ; l2 remains unchanged. )
 */
extern ListTyp Diff_list(/* l1, l2, Equal, FreeInfo */);
/*     ListTyp l1,l2;
       boolean (*Equal)();
       void (*FreeInfo)(); */


/* SubSet_list
 * Determine if all the elements of list l1 are included in list l2.
 * Example: SubSet_list( a-b-c-a-b, a-b-c-d-e-f-g, EqInt ) -> TRUE 
 */
extern boolean SubSet_list(/* l1, l2, Eq */);
/*     ListTyp l1,l2;
       boolean (*Eq)(); */



/* DeleteNode_list
 * Deletes the current node n of list l.
 * Returns the new list.
 * Conditions: 
 *   n must belong to l.
 *   n !=NULL. l !=NULL.
 */
extern ListTyp DeleteNode_list( /* n, l */ );
/* ListTyp n,l;*/


/* ExtractNode_list
 * Takes out the current node n of list l.
 * Returns the new list. It works like DeleteNode_list, but n is not deleted.
 * Conditions: 
 *   n must belong to l.
 *   n !=NULL. l !=NULL.
 */
extern ListTyp ExtractNode_list( /* n, l */ );
/* ListTyp n,l; */


/* InsertBeforeNode_list
 * Insert element e before node n in list l
 */
extern ListTyp InsertBeforeNode_list(/* e, l, n */);
/*     DataListTyp e;
       ListTyp     l,n;  */


/* Length_list
 * list length
 */
extern int Length_list(/*l*/);
/*       ListTyp l;*/


/* Stat_list
 * statistics about list nodes:
 *   *pin = total list nodes allocation queries.
 *   *pid = list node releases
 *   *pim = max list nodes used during execution
 */
extern void Stat_list(/* pin, pid, pim */);
/*     int *pin, *pid, *pim; */


/* Last_list
 * returns the last list node
 */
extern ListTyp Last_list(/* l */);
/* ListTyp l; */


/* Init_list
 * Initialize the module
 */
extern void Init_list();


#endif




