/*
 * (C) Copyright Cogent Real-Time Systems Inc., 1997-2000.
 *     All rights reserved.
 *
 * This file constitutes a part of the Cascade (TM) C-Language
 * application programming interface.  It is not to be modified.  This
 * file is licensed for the purpose of creating programs that will
 * communicate with Cogent's products, and for no other purpose.
 * Cogent claims no rights in any program created by a party other than
 * Cogent by compiling this file, and accepts no responsibility or
 * liability in such a program.
 *
 * It is illegal for any party other than Cogent to sell the contents of
 * this file, or any part thereof, or to attempt to gain in any way from
 * the transmission of this file.  It is illegal to remove this notice
 * from this file.
 */

#ifndef LINKLIST_H
#define		LINKLIST_H	

typedef	struct	LL_stLINK
{
	struct LL_stLINK	*pnext;
	struct LL_stLINK	*pprev;
	void				*pdata;
} LL_stLINK;

typedef LL_stLINK		*LL_pLINK;

typedef struct LL_stLISTHEAD
{
	LL_pLINK			phead;
	LL_pLINK			ptail;
	int					count;
} LL_stLISTHEAD;

typedef LL_stLISTHEAD	*LL_LIST;

typedef struct LL_stITERATOR
{
	LL_LIST				list;
	LL_pLINK			pcurr;
} LL_stITERATOR;

typedef LL_stITERATOR	*LL_pITERATOR;

#define	LL_HEAD(l)		((l)->phead)
#define	LL_TAIL(l)		((l)->ptail)
#define LL_COUNT(l)		((l)->count)

#define LL_DATA(e)		((e)->pdata)
#define LL_NEXT(e)		((e)->pnext)
#define LL_PREV(e)		((e)->pprev)

#define	LL_SHEAD(l)		((LL_pLINK)((l) ? (l)->phead : NULL))
#define	LL_STAIL(l)		((LL_pLINK)((l) ? (l)->ptail : NULL))
#define LL_SCOUNT(l)	((l) ? (l)->count : 0)

#define LL_SDATA(e)		((e) ? (e)->pdata : NULL)
#define LL_SNEXT(e)		((e) ? (e)->pnext : NULL)
#define LL_SPREV(e)		((e) ? (e)->pprev : NULL)

#define LL_ICURRENT(i)	((i).pcurr)
#define LL_ILIST(i)		((i).list)
#define LL_ISTART(i,l)	((i).list = (l), (i).pcurr = LL_SHEAD(l), \
						 LL_SDATA((i).pcurr))
#define LL_IFINISH(i,l)	((i).list = (l), (i).pcurr = LL_STAIL(l), \
						 LL_SDATA((i).pcurr))
#define LL_IFORWARD(i)	((i).pcurr = LL_SNEXT((i).pcurr), LL_SDATA((i).pcurr))
#define LL_IBACKWARD(i)	((i).pcurr = LL_SPREV((i).pcurr), LL_SDATA((i).pcurr))
#define LL_IDONE(i)		((i).pcurr == NULL)

#define LL_TRAVERSE(l,t,v,i)	for (v=(t)LL_ISTART(i,l);!LL_IDONE(i); \
									 v=(t)LL_IFORWARD(i))
#define LL_REVERSE(l,t,v,i)		for (v=(t)LL_IFINISH(i,l);!LL_IDONE(i); \
									 v=(t)LL_IBACKWARD(i))


typedef ST_STATUS	(*LL_pfDESTROY)(void*);
typedef int			(*LL_pfCOMPARE)(const void*, const void*);
typedef int			(*LL_pfSORT)(const void*, const void*);
typedef void*		(*LL_pfAPPLY)(void*);
typedef void*		(*LL_pfAPPLY1)(void*, void*);
typedef void*		(*LL_pfAPPLY2)(void*, void*, void*);

DllSym ST_STATUS	LL_AddHead		(LL_LIST l, void* p);
DllSym ST_STATUS	LL_AddTail		(LL_LIST l, void* p);
DllSym ST_STATUS	LL_AddSorted	(LL_LIST l, void* p, LL_pfCOMPARE pfcmp);
DllSym ST_STATUS	LL_Apply		(LL_LIST l, LL_pfAPPLY pfapply);
DllSym ST_STATUS	LL_Apply1		(LL_LIST l, LL_pfAPPLY1 pfapply,
									 void* param);
DllSym ST_STATUS	LL_Apply2		(LL_LIST l, LL_pfAPPLY2 pfapply,
									 void* param1, void *param2);
DllSym LL_LIST		LL_Collect		(LL_LIST l, LL_pfAPPLY pfapply);
DllSym LL_LIST		LL_Collect1		(LL_LIST l, LL_pfAPPLY1 pfapply,
									 void* param);
DllSym LL_LIST		LL_Collect2		(LL_LIST l, LL_pfAPPLY2 pfapply,
									 void* param1, void *param2);
DllSym LL_LIST		LL_Copy			(LL_LIST l, LL_pfAPPLY pfcopy);
DllSym int			LL_Count		(LL_LIST l);
DllSym ST_STATUS	LL_Clear		(LL_LIST l);
DllSym LL_LIST		LL_Create		(void* p);
DllSym ST_STATUS	LL_Destroy		(LL_LIST l, LL_pfDESTROY pfdest);
DllSym ST_STATUS	LL_Free			(LL_LIST l);
DllSym void*		LL_Head			(LL_LIST l);
DllSym ST_BOOLEAN	LL_IsEmpty		(LL_LIST l);
DllSym LL_LIST		LL_New			(void);
DllSym void*		LL_Nth			(LL_LIST l, int n);
DllSym void*		LL_PopHead		(LL_LIST l);
DllSym void*		LL_PopTail		(LL_LIST l);
DllSym int			LL_Position		(LL_LIST l, void* p);
DllSym ST_STATUS	LL_Qsort		(LL_LIST list, LL_pfSORT pfsort);
DllSym ST_STATUS	LL_RApply		(LL_LIST l, LL_pfAPPLY pfapply);
DllSym ST_STATUS	LL_RApply1		(LL_LIST l, LL_pfAPPLY1 pfapply,
									 void* param);
DllSym ST_STATUS	LL_RApply2		(LL_LIST l, LL_pfAPPLY2 pfapply,
									 void* param1, void *param2);
DllSym void*		LL_Remove		(LL_LIST l, void* p);
DllSym void*		LL_RemoveAll	(LL_LIST l, void* p);
DllSym void*		LL_RemoveN		(LL_LIST l, void* p, int count);
DllSym LL_LIST		LL_Search		(LL_LIST l, void* p, LL_pfCOMPARE pfcomp);
DllSym void*		LL_SearchTo		(LL_LIST l, void* p, LL_pfCOMPARE pfcomp);
DllSym void*		LL_Tail			(LL_LIST l);

#endif /* LINKLIST_H */
