1 #ifndef EXEC_LISTS_H
    2 #define EXEC_LISTS_H
    3 
    4 /*
    5 	exec list definitions (V50)
    6 
    7 	Copyright © 2002 The MorphOS Development Team, All Rights Reserved.
    8 */
    9 
   10 #ifndef EXEC_NODES_H
   11 # include <exec/nodes.h>
   12 #endif
   13 
   14 #pragma pack(2)
   15 
   16 
   17 struct List
   18 {
   19 	struct Node *lh_Head;
   20 	struct Node *lh_Tail;
   21 	struct Node *lh_TailPred;
   22 	UBYTE        lh_Type;
   23 	UBYTE        lh_pad;
   24 };
   25 
   26 struct MinList
   27 {
   28 	struct MinNode *mlh_Head;
   29 	struct MinNode *mlh_Tail;
   30 	struct MinNode *mlh_TailPred;
   31 };
   32 
   33 #ifdef __GNUC__
   34 #define IsListEmpty(x)     ({struct List *__tmpl = x; (APTR)__tmpl->lh_TailPred == (APTR)__tmpl;})
   35 #define IsMsgPortEmpty(x)  ({struct List *__tmpl = &(x)->mp_MsgList; (APTR)__tmpl->lh_TailPred == (APTR)__tmpl;})
   36 #else
   37 #define IsListEmpty(x)     (((x)->lh_TailPred) == (struct Node *)(x))
   38 #define IsMsgPortEmpty(x)  (((x)->mp_MsgList.lh_TailPred) == (struct Node *)(&(x)->mp_MsgList))
   39 #endif
   40 
   41 /*
   42  * Some useful macros
   43  */
   44 #ifndef NO_LIST_MACROS
   45 
   46 #ifndef NEWLIST
   47 #define	NEWLIST(MyList)	\
   48 do { \
   49 	struct MinList *_MyList = (struct MinList *)(MyList); \
   50 	_MyList->mlh_TailPred = (struct MinNode *)_MyList; \
   51 	_MyList->mlh_Tail = (struct MinNode *)NULL; \
   52 	_MyList->mlh_Head = (struct MinNode *)&_MyList->mlh_Tail; \
   53 } while (0)
   54 #endif /* !NEWLIST */
   55 
   56 #ifndef REMHEAD
   57 #define	REMHEAD(MyList) \
   58 ({ \
   59 	struct MinList *_MyList = (struct MinList *)(MyList); \
   60 	struct MinNode *RemovedNode; \
   61 	struct MinNode *Result; \
   62 	if ((RemovedNode = _MyList->mlh_Head)->mln_Succ) \
   63 	{ \
   64 		_MyList->mlh_Head = RemovedNode->mln_Succ; \
   65 		_MyList->mlh_Head->mln_Pred = (struct MinNode *)&_MyList->mlh_Head; \
   66 		Result = RemovedNode; \
   67 	} \
   68 	else \
   69 	{ \
   70 		Result = NULL; \
   71 	} \
   72 	(APTR)Result; \
   73 })
   74 #endif /* !REMHEAD */
   75 
   76 #ifndef REMTAIL
   77 #define	REMTAIL(MyList) \
   78 ({ \
   79 	struct MinList *_MyList = (struct MinList *)(MyList); \
   80 	struct MinNode *RemovedNode; \
   81 	struct MinNode *Result; \
   82 	if ((RemovedNode = _MyList->mlh_TailPred)->mln_Pred) \
   83 	{ \
   84 		_MyList->mlh_TailPred = RemovedNode->mln_Pred; \
   85 		_MyList->mlh_TailPred->mln_Succ = (struct MinNode *)&_MyList->mlh_Tail; \
   86 		Result = RemovedNode; \
   87 	} \
   88 	else \
   89 	{ \
   90 		Result = NULL; \
   91 	} \
   92 	(APTR)Result; \
   93 })
   94 #endif /* !REMTAIL */
   95 
   96 #ifndef ADDHEAD
   97 #define	ADDHEAD(MyList,MyNode) \
   98 do { \
   99 	struct MinList *_MyList = (struct MinList *)(MyList); \
  100 	struct MinNode *_MyNode = (struct MinNode *)(MyNode); \
  101 	struct MinNode *OldHeadNode; \
  102 	OldHeadNode = _MyList->mlh_Head; \
  103 	_MyNode->mln_Succ = OldHeadNode; \
  104 	OldHeadNode->mln_Pred = _MyNode; \
  105 	_MyNode->mln_Pred = (struct MinNode *)_MyList; \
  106 	_MyList->mlh_Head = _MyNode; \
  107 } while (0)
  108 #endif /* !ADDHEAD */
  109 
  110 #ifndef ADDTAIL
  111 #define	ADDTAIL(MyList,MyNode) \
  112 do { \
  113 	struct MinList *_MyList = (struct MinList *)(MyList); \
  114 	struct MinNode *_MyNode = (struct MinNode *)(MyNode); \
  115 	struct MinNode *OldPredNode; \
  116 	OldPredNode = _MyList->mlh_TailPred; \
  117 	_MyNode->mln_Succ = (struct MinNode *)&_MyList->mlh_Tail; \
  118 	_MyNode->mln_Pred = OldPredNode; \
  119 	OldPredNode->mln_Succ = _MyNode; \
  120 	_MyList->mlh_TailPred = _MyNode; \
  121 } while (0)
  122 #endif /* !ADDTAIL */
  123 
  124 #ifndef REMOVE
  125 #define	REMOVE(MyNode) \
  126 ({ \
  127 	struct MinNode *_MyNode = (struct MinNode *)(MyNode); \
  128 	struct MinNode *PredNode; \
  129 	struct MinNode *SuccNode; \
  130 	PredNode = _MyNode->mln_Pred; \
  131 	SuccNode = _MyNode->mln_Succ; \
  132 	PredNode->mln_Succ = SuccNode; \
  133 	SuccNode->mln_Pred = PredNode; \
  134 	_MyNode; \
  135 })
  136 #endif /* !REMOVE */
  137 
  138 #ifndef SWAPNODES
  139 #define	SWAPNODES(MyNode1,MyNode2) \
  140 do { \
  141 	struct MinNode *_MyNode1 = (struct MinNode *)(MyNode1); \
  142 	struct MinNode *_MyNode2 = (struct MinNode *)(MyNode2); \
  143 	if (_MyNode1 != _MyNode2) \
  144 	{ \
  145 		struct MinNode *SuccNode2, *PredNode2; \
  146 		SuccNode2 = _MyNode2->mln_Succ; \
  147 		PredNode2 = _MyNode2->mln_Pred; \
  148 		PredNode2->mln_Succ = _MyNode1; \
  149 		SuccNode2->mln_Pred = _MyNode1; \
  150 		_MyNode2->mln_Succ = _MyNode1->mln_Succ; \
  151 		_MyNode2->mln_Pred = _MyNode1->mln_Pred; \
  152 		_MyNode1->mln_Succ = SuccNode2; \
  153 		_MyNode1->mln_Pred = PredNode2; \
  154 		_MyNode2->mln_Pred->mln_Succ = _MyNode2; \
  155 		_MyNode2->mln_Succ->mln_Pred = _MyNode2; \
  156 	} \
  157 } while (0)
  158 #endif /* !SWAPNODES */
  159 
  160 #ifndef INSERT
  161 #define INSERT(MyList,MyNode,MyListNode) \
  162 do { \
  163 	struct MinList *_MyList = (struct MinList *)(MyList); \
  164 	struct MinNode *_MyNode = (struct MinNode *)(MyNode); \
  165 	struct MinNode *_MyListNode = (struct MinNode *)(MyListNode); \
  166 	if (_MyListNode) \
  167 	{ \
  168 		struct MinNode *MyListNodeSucc; \
  169 		if ((MyListNodeSucc = _MyListNode->mln_Succ)) \
  170 		{ \
  171 			_MyNode->mln_Succ = MyListNodeSucc; \
  172 			_MyNode->mln_Pred = _MyListNode; \
  173 			MyListNodeSucc->mln_Pred = _MyNode; \
  174 			_MyListNode->mln_Succ = _MyNode; \
  175 		} else { \
  176 			struct MinNode *MyListNodePred; \
  177 			_MyNode->mln_Succ = _MyListNode; \
  178 			MyListNodePred = _MyListNode->mln_Pred; \
  179 			_MyNode->mln_Pred = MyListNodePred; \
  180 			_MyListNode->mln_Pred = _MyNode; \
  181 			MyListNodePred->mln_Succ = _MyNode; \
  182 		} \
  183 	} else { \
  184 		struct MinNode *OldHeadNode; \
  185 		OldHeadNode = _MyList->mlh_Head; \
  186 		_MyNode->mln_Succ = OldHeadNode; \
  187 		OldHeadNode->mln_Pred = _MyNode; \
  188 		_MyNode->mln_Pred = (struct MinNode *)_MyList; \
  189 		_MyList->mlh_Head = _MyNode; \
  190 	} \
  191 } while (0)
  192 #endif /* !INSERT */
  193 
  194 #endif /* !NO_LIST_MACROS */
  195 
  196 #ifdef AROS_ALMOST_COMPATIBLE
  197 
  198 #define GetHead(_l)  \
  199 ({ struct List *l = (struct List *)(_l);  \
  200 	l->lh_Head->ln_Succ ? l->lh_Head : (struct Node *)0;  \
  201 })
  202 
  203 #define GetTail(_l)  \
  204 ({ struct List *l = (struct List *)(_l);  \
  205 	l->lh_TailPred->ln_Pred ? l->lh_TailPred : (struct Node *)0;  \
  206 })
  207 
  208 #define GetSucc(_n)  \
  209 ({ struct Node *n = (struct Node *)(_n);  \
  210 	n->ln_Succ->ln_Succ ? n->ln_Succ : (struct Node *)0;  \
  211 })
  212 
  213 #define GetPred(_n)  \
  214 ({ struct Node *n = (struct Node *)(_n);  \
  215 	n->ln_Pred->ln_Pred ? n->ln_Pred : (struct Node *)0;  \
  216 })
  217 
  218 #define ForeachNode(l,n)  \
  219 for (  \
  220 	n = (void *)(((struct List *)(l))->lh_Head);  \
  221 	((struct Node *)(n))->ln_Succ;  \
  222 	n = (void *)(((struct Node *)(n))->ln_Succ)  \
  223 )
  224 
  225 #define ForeachNodeSafe(l,n,n2)  \
  226 for (  \
  227 	n = (void *)(((struct List *)(l))->lh_Head);  \
  228 	(n2 = (void *)((struct Node *)(n))->ln_Succ);  \
  229 	n = (void *)n2  \
  230 )
  231 
  232 #define SetNodeName(node,name)  (((struct Node *)(node))->ln_Name = (char *)(name))
  233 #define GetNodeName(node)       (((struct Node *)(node))->ln_Name)
  234 
  235 #define ListLength(list,count)  \
  236 do {  \
  237 	struct Node *n;  \
  238 	count = 0;  \
  239 	ForeachNode(list,n) count++;  \
  240 } while (0)
  241 
  242 #endif /* AROS_ALMOST_COMPATIBLE */
  243 
  244 
  245 #pragma pack()
  246 
  247 #endif