/*static char *SCCSID = "@(#)chain.h	6.1 90/11/18";*/
/*static char *SCCSID = "@(#)chain.h	13.4 90/01/30";*/
/***	Doubly Chained Definitions
 *
 *	HISTORY
 *	    14-Sep-1988 10:56 by Leif Pederson [leifp] resynch w/Gordon
 */

/* XLATON */

/* DCHN - Doubly chained far pointers */

typedef struct DCHN { /* DCHN */
	void far *pFwd;		/* forward pointer */
	void far *pBak;		/* backward pointer */
} DCHN;  /* DCHN */


typedef DCHN far *PDCHN;

#define DOUBLYCHAINEDPTRS  DCHN
#define PDOUBLYCHAINEDPTRS PDCHN


/* NDCHN - Doubly chained near pointers */

typedef struct NDCHN { /* NDCHN */
        void near *pFwd;         /* forward pointer */
        void near *pBak;         /* backward pointer */
} NDCHN;   /* NDCHN */


typedef NDCHN *PNDCHN;

#define DOUBLYCHAINEDNEARPTRS  NDCHN
#define PDOUBLYCHAINEDNEARPTRS PNDCHN

/* XLATOFF */

/*
 *		 Double Chain Manipulation Macros
 *
 *  The following macros manipulate double-linked lists.
 *  All macros take as their first argument the field name of
 *  the pointer pair.
 *
 * Macro names are same as in PIA except that 'far' is appended to them
 * since we allready have macros with these names that handle doubly
 * chained BUFNODEs.
 */


/*	DCADDBfar - Add Item to Back of List
 *	Type	= Structure typedef name.
 *	Field	= Field in structure of links to edit
 *	pHead	= Pointer to list head node
 *	pItem	= Pointer to item to insert
 */

#define DCADDBfar(Type,Field,pHead,pItem) {		\
  ((Type)(pHead)->Field.pBak)->Field.pFwd = (pItem);	\
  (pItem)->Field.pFwd = (pHead);			\
  (pItem)->Field.pBak = (pHead)->Field.pBak;		\
  (pHead)->Field.pBak = (pItem);	  }


/*	DCADDFfar - Add Item to Front of List
 *	Type	= Structure typedef name.
 *	Field	= Field in structure of links to edit
 *	pHead	= Pointer to list head node
 *	pItem	= Pointer to item to insert
 */

#define DCADDFfar(Type,Field,pHead,pItem) {		\
  (pItem)->Field.pFwd = (pHead)->Field.pFwd;		\
  (pItem)->Field.pBak = (pHead);			\
  ((Type)(pHead)->Field.pFwd)->Field.pBak = (pItem);	\
  (pHead)->Field.pFwd = (pItem);	  }


/*	DCREMfar - Remove Item from Double Link Chain
 *	Type	= Structure typedef name.
 *	Field	= Field in structure of links to edit
 *	pItem	= Pointer to item to remove
 */

#define DCREMfar(Type,Field,pItem) {				  \
  ((Type)(pItem)->Field.pFwd)->Field.pBak = (pItem)->Field.pBak;  \
  ((Type)(pItem)->Field.pBak)->Field.pFwd = (pItem)->Field.pFwd; }


/*	DCMOVFfar - Move Item to the Front of the Chain
 *	Type	= Structure typedef name.
 *	Field	= Field in structure of links to edit
 *	pHead	= Pointer to list head node
 *	pItem	= Pointer to item to move
 */

#define DCMOVFfar(Type,Field,pHead,pItem) { \
  DCREMfar(Type,Field,pItem)		    \
  DCADDFfar(Type,Field,pHead,pItem)	  }


/*	DCMOVBfar - Move Item to the Back of the Chain
 *	Type	= Structure typedef name.
 *	Field	= Field in structure of links to edit
 *	pHead	= Pointer to list head node
 *	pItem	= Pointer to item to move
 */

#define DCMOVBfar(Type,Field,pHead,pItem) { \
  DCREMfar(Type,Field,pItem)		    \
  DCADDBfar(Type,Field,pHead,pItem)	  }
