This is Unofficial EPICS BASE Doxygen Site
ellLib.h File Reference

A doubly-linked list library. More...

#include "libComAPI.h"
+ Include dependency graph for ellLib.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  ELLNODE
 List node type. More...
 
struct  ELLLIST
 List header type. More...
 

Macros

#define ELLNODE_INIT   {NULL, NULL}
 Value of a terminal node. More...
 
#define ELLLIST_INIT   {ELLNODE_INIT, 0}
 Value of an empty list. More...
 
#define ellInit(PLIST)
 Initialize a list type. More...
 
#define ellCount(PLIST)   ((PLIST)->count)
 Report the number of nodes in a list. More...
 
#define ellFirst(PLIST)   ((PLIST)->node.next)
 Find the first node in list. More...
 
#define ellLast(PLIST)   ((PLIST)->node.previous)
 Find the last node in list. More...
 
#define ellNext(PNODE)   ((PNODE)->next)
 Find the next node in list. More...
 
#define ellPrevious(PNODE)   ((PNODE)->previous)
 Find the previous node in list. More...
 
#define ellFree(PLIST)   ellFree2(PLIST, free)
 Free up the list. More...
 

Typedefs

typedef struct ELLNODE ELLNODE
 List node type. More...
 
typedef struct ELLLIST ELLLIST
 List header type. More...
 
typedef void(* FREEFUNC) (void *)
 Pointer to free() for use by ellFree() macro. More...
 
typedef int(* pListCmp) (const ELLNODE *A, const ELLNODE *B)
 

Functions

LIBCOM_API void ellAdd (ELLLIST *pList, ELLNODE *pNode)
 Adds a node to the end of a list. More...
 
LIBCOM_API void ellConcat (ELLLIST *pDstList, ELLLIST *pAddList)
 Concatenates a list to the end of another list. The list to be added is left empty. Either list (or both) can be empty at the beginning of the operation. More...
 
LIBCOM_API void ellDelete (ELLLIST *pList, ELLNODE *pNode)
 Deletes a node from a list. More...
 
LIBCOM_API void ellExtract (ELLLIST *pSrcList, ELLNODE *pStartNode, ELLNODE *pEndNode, ELLLIST *pDstList)
 Extract a sublist from a list. More...
 
LIBCOM_API ELLNODEellGet (ELLLIST *pList)
 Deletes and returns the first node from a list. More...
 
LIBCOM_API ELLNODEellPop (ELLLIST *pList)
 Deletes and returns the last node from a list. More...
 
LIBCOM_API void ellInsert (ELLLIST *plist, ELLNODE *pPrev, ELLNODE *pNode)
 Inserts a node into a list immediately after a specific node. More...
 
LIBCOM_API ELLNODEellNth (ELLLIST *pList, int nodeNum)
 Find the Nth node in a list. More...
 
LIBCOM_API ELLNODEellNStep (ELLNODE *pNode, int nStep)
 Find the list node nStep steps away from a specified node. More...
 
LIBCOM_API int ellFind (ELLLIST *pList, ELLNODE *pNode)
 Find the index of a specific node in a list. More...
 
LIBCOM_API void ellSortStable (ELLLIST *pList, pListCmp pListCmp)
 Stable (MergeSort) of a given list. More...
 
LIBCOM_API void ellFree2 (ELLLIST *pList, FREEFUNC freeFunc)
 Free all the nodes in a list. More...
 
LIBCOM_API void ellVerify (ELLLIST *pList)
 Verifies that the list is consistent. More...
 

Detailed Description

A doubly-linked list library.

Author
John Winans (ANL)
Andrew Johnson (ANL)

This provides similar functionality to the VxWorks lstLib library.

Supports the creation and maintenance of a doubly-linked list. The user supplies a list descriptor (type ELLLIST) that will contain pointers to the first and last nodes in the list, and a count of the number of nodes in the list. The nodes in the list can be any user-defined structure, but they must reserve space for two pointers as their first elements. Both the forward and backward chains are terminated with a NULL pointer.

Definition in file ellLib.h.

Macro Definition Documentation

#define ellCount (   PLIST)    ((PLIST)->count)

Report the number of nodes in a list.

Parameters
PLISTPointer to list descriptor
Returns
Number of nodes in the list

Definition at line 84 of file ellLib.h.

#define ellFirst (   PLIST)    ((PLIST)->node.next)

Find the first node in list.

Parameters
PLISTPointer to list descriptor
Returns
Pointer to first node in the list

Definition at line 89 of file ellLib.h.

#define ellFree (   PLIST)    ellFree2(PLIST, free)

Free up the list.

Parameters
PLISTList for which to free all nodes

Definition at line 108 of file ellLib.h.

#define ellInit (   PLIST)
Value:
{\
(PLIST)->node.next = (PLIST)->node.previous = NULL;\
(PLIST)->count = 0;\
}
#define NULL
Definition: catime.c:38

Initialize a list type.

Parameters
PLISTPointer to list header to be initialized

Definition at line 76 of file ellLib.h.

#define ellLast (   PLIST)    ((PLIST)->node.previous)

Find the last node in list.

Parameters
PLISTPointer to list descriptor
Returns
Pointer to last node in the list

Definition at line 94 of file ellLib.h.

#define ELLLIST_INIT   {ELLNODE_INIT, 0}

Value of an empty list.

Definition at line 63 of file ellLib.h.

#define ellNext (   PNODE)    ((PNODE)->next)

Find the next node in list.

Parameters
PNODEPointer to node whose successor is to be found
Returns
Pointer to the node following PNODE

Definition at line 99 of file ellLib.h.

#define ELLNODE_INIT   {NULL, NULL}

Value of a terminal node.

Definition at line 52 of file ellLib.h.

#define ellPrevious (   PNODE)    ((PNODE)->previous)

Find the previous node in list.

Parameters
PNODEPointer to node whose predecessor is to be found
Returns
Pointer to the node prior to PNODE

Definition at line 104 of file ellLib.h.

Typedef Documentation

typedef struct ELLLIST ELLLIST

List header type.

typedef struct ELLNODE ELLNODE

List node type.

A list node (an ELLNODE) must be embedded in the structure to be placed on the list, ideally as the first member of that structure.

If the node is elsewhere in the structure, care must be taken to convert between the structure pointer and the node pointer and back every time when calling routines in the ellLib API. The ellFree() and ellFree2() routines cannot be used with such a list.

typedef void(* FREEFUNC) (void *)

Pointer to free() for use by ellFree() macro.

This is required for use on Windows, where each DLL has its own free() function. The ellFree() macro passes the application's version of free() to the ellFree2() function.

Definition at line 71 of file ellLib.h.

typedef int(* pListCmp) (const ELLNODE *A, const ELLNODE *B)

Definition at line 184 of file ellLib.h.

Function Documentation

LIBCOM_API void ellAdd ( ELLLIST pList,
ELLNODE pNode 
)

Adds a node to the end of a list.

Parameters
pListPointer to list descriptor
pNodePointer to node to be added

Definition at line 24 of file ellLib.c.

25 {
26  pNode->next = NULL;
27  pNode->previous = pList->node.previous;
28 
29  if (pList->count)
30  pList->node.previous->next = pNode;
31  else
32  pList->node.next = pNode;
33 
34  pList->node.previous = pNode;
35  pList->count++;
36 
37  return;
38 }
#define NULL
Definition: catime.c:38
struct ELLNODE * previous
Pointer to previous node in list.
Definition: ellLib.h:47
struct ELLNODE * next
Pointer to next node in list.
Definition: ellLib.h:46
int count
Number of nodes on the list.
Definition: ellLib.h:58
ELLNODE node
Pointers to the first and last nodes on list.
Definition: ellLib.h:57
LIBCOM_API void ellConcat ( ELLLIST pDstList,
ELLLIST pAddList 
)

Concatenates a list to the end of another list. The list to be added is left empty. Either list (or both) can be empty at the beginning of the operation.

Parameters
pDstListDestination list
pAddListList to be added to pDstList

Definition at line 46 of file ellLib.c.

47 {
48  if (pAddList->count == 0)
49  return; /* Add list is empty, nothing to add. */
50 
51  if (pDstList->count == 0) {
52  /* Destination list is empty... just transfer the add list over. */
53  pDstList->node.next = pAddList->node.next;
54  pDstList->node.previous = pAddList->node.previous;
55  pDstList->count = pAddList->count;
56  } else {
57  /* Destination list not empty... append the add list. */
58  pDstList->node.previous->next = pAddList->node.next;
59  pAddList->node.next->previous = pDstList->node.previous;
60  pDstList->node.previous = pAddList->node.previous;
61  pDstList->count += pAddList->count;
62  }
63 
64  pAddList->count = 0;
65  pAddList->node.next = NULL;
66  pAddList->node.previous = NULL;
67 
68  return;
69 }
#define NULL
Definition: catime.c:38
struct ELLNODE * previous
Pointer to previous node in list.
Definition: ellLib.h:47
struct ELLNODE * next
Pointer to next node in list.
Definition: ellLib.h:46
int count
Number of nodes on the list.
Definition: ellLib.h:58
ELLNODE node
Pointers to the first and last nodes on list.
Definition: ellLib.h:57
LIBCOM_API void ellDelete ( ELLLIST pList,
ELLNODE pNode 
)

Deletes a node from a list.

Parameters
pListPointer to list descriptor
pNodePointer to node to be deleted

Definition at line 75 of file ellLib.c.

76 {
77  if (pList->node.previous == pNode)
78  pList->node.previous = pNode->previous;
79  else
80  pNode->next->previous = pNode->previous;
81 
82  if (pList->node.next == pNode)
83  pList->node.next = pNode->next;
84  else
85  pNode->previous->next = pNode->next;
86 
87  pList->count--;
88 
89  return;
90 }
struct ELLNODE * previous
Pointer to previous node in list.
Definition: ellLib.h:47
struct ELLNODE * next
Pointer to next node in list.
Definition: ellLib.h:46
int count
Number of nodes on the list.
Definition: ellLib.h:58
ELLNODE node
Pointers to the first and last nodes on list.
Definition: ellLib.h:57
LIBCOM_API void ellExtract ( ELLLIST pSrcList,
ELLNODE pStartNode,
ELLNODE pEndNode,
ELLLIST pDstList 
)

Extract a sublist from a list.

Parameters
pSrcListPointer to source list
pStartNodeFirst node in pSrcList to be extracted
pEndNodeLast node in pSrcList to be extracted
pDstListPointer to list where to put extracted list

Definition at line 101 of file ellLib.c.

102 {
103  ELLNODE *pnode;
104  int count;
105 
106  /* Cut the list out of the source list (update count later) */
107  if (pStartNode->previous != NULL)
108  pStartNode->previous->next = pEndNode->next;
109  else
110  pSrcList->node.next = pEndNode->next;
111 
112  if (pEndNode->next != NULL) {
113  pEndNode->next->previous = pStartNode->previous;
114  pEndNode->next = NULL;
115  }
116  else
117  pSrcList->node.previous = pStartNode->previous;
118 
119  /* Place the sublist into the destination list */
120  pStartNode->previous = pDstList->node.previous;
121  if (pDstList->count)
122  pDstList->node.previous->next = pStartNode;
123  else
124  pDstList->node.next = pStartNode;
125 
126  pDstList->node.previous = pEndNode;
127 
128  /* Adjust the counts */
129  pnode = pStartNode;
130  count = 1;
131  while(pnode != pEndNode)
132  {
133  pnode = pnode->next;
134  count++;
135  }
136  pSrcList->count -= count;
137  pDstList->count += count;
138 
139  return;
140 }
#define NULL
Definition: catime.c:38
List node type.
Definition: ellLib.h:45
struct ELLNODE * previous
Pointer to previous node in list.
Definition: ellLib.h:47
struct ELLNODE * next
Pointer to next node in list.
Definition: ellLib.h:46
int count
Number of nodes on the list.
Definition: ellLib.h:58
ELLNODE node
Pointers to the first and last nodes on list.
Definition: ellLib.h:57
LIBCOM_API int ellFind ( ELLLIST pList,
ELLNODE pNode 
)

Find the index of a specific node in a list.

Parameters
pListPointer to list to search
pNodePointer to node to search for
Returns
The node's index, or -1 if it cannot be found on the list.
Note
The first node has index 1.

Definition at line 258 of file ellLib.c.

259 {
260  ELLNODE *got = pList->node.next;
261  int count = 1;
262 
263  while ((got != pNode) && (got != NULL)) {
264  got = got->next;
265  count++;
266  }
267  if (got == NULL)
268  return -1;
269 
270  return count;
271 }
#define NULL
Definition: catime.c:38
List node type.
Definition: ellLib.h:45
struct ELLNODE * next
Pointer to next node in list.
Definition: ellLib.h:46
ELLNODE node
Pointers to the first and last nodes on list.
Definition: ellLib.h:57
LIBCOM_API void ellFree2 ( ELLLIST pList,
FREEFUNC  freeFunc 
)

Free all the nodes in a list.

This routine empties a list, calling freeFunc() for every node on it.

Parameters
pListList from which to free all nodes
freeFuncThe free() routine to be called
Note
The nodes in the list are free()'d on the assumption that the node structures were malloc()'d one-at-a-time and that the ELLNODE structure is the first member of the parent structure.

Definition at line 282 of file ellLib.c.

283 {
284  ELLNODE *nnode = pList->node.next;
285  ELLNODE *pnode;
286 
287  while (nnode != NULL)
288  {
289  pnode = nnode;
290  nnode = nnode->next;
291  freeFunc(pnode);
292  }
293  pList->node.next = NULL;
294  pList->node.previous = NULL;
295  pList->count = 0;
296 }
#define NULL
Definition: catime.c:38
List node type.
Definition: ellLib.h:45
struct ELLNODE * previous
Pointer to previous node in list.
Definition: ellLib.h:47
struct ELLNODE * next
Pointer to next node in list.
Definition: ellLib.h:46
int count
Number of nodes on the list.
Definition: ellLib.h:58
ELLNODE node
Pointers to the first and last nodes on list.
Definition: ellLib.h:57
LIBCOM_API ELLNODE* ellGet ( ELLLIST pList)

Deletes and returns the first node from a list.

Parameters
pListPointer to list from which to get node
Returns
Pointer to the first node from the list, or NULL if the list is empty

Definition at line 147 of file ellLib.c.

148 {
149  ELLNODE *pnode = pList->node.next;
150 
151  if (pnode != NULL)
152  ellDelete(pList, pnode);
153 
154  return pnode;
155 }
#define NULL
Definition: catime.c:38
List node type.
Definition: ellLib.h:45
struct ELLNODE * next
Pointer to next node in list.
Definition: ellLib.h:46
void ellDelete(ELLLIST *pList, ELLNODE *pNode)
Deletes a node from a list.
Definition: ellLib.c:75
ELLNODE node
Pointers to the first and last nodes on list.
Definition: ellLib.h:57
LIBCOM_API void ellInsert ( ELLLIST plist,
ELLNODE pPrev,
ELLNODE pNode 
)

Inserts a node into a list immediately after a specific node.

Parameters
plistPointer to list into which to insert node
pPrevPointer to the node after which to insert
pNodePointer to the node to be inserted
Note
If pPrev is NULL pNode will be inserted at the head of the list

Definition at line 178 of file ellLib.c.

179 {
180  if (pPrev != NULL) {
181  pNode->previous = pPrev;
182  pNode->next = pPrev->next;
183  pPrev->next = pNode;
184  } else {
185  pNode->previous = NULL;
186  pNode->next = plist->node.next;
187  plist->node.next = pNode;
188  }
189 
190  if (pNode->next == NULL)
191  plist->node.previous = pNode;
192  else
193  pNode->next->previous = pNode;
194 
195  plist->count++;
196 
197  return;
198 }
#define NULL
Definition: catime.c:38
struct ELLNODE * previous
Pointer to previous node in list.
Definition: ellLib.h:47
struct ELLNODE * next
Pointer to next node in list.
Definition: ellLib.h:46
int count
Number of nodes on the list.
Definition: ellLib.h:58
ELLNODE node
Pointers to the first and last nodes on list.
Definition: ellLib.h:57
LIBCOM_API ELLNODE* ellNStep ( ELLNODE pNode,
int  nStep 
)

Find the list node nStep steps away from a specified node.

Parameters
pNodeThe known node
nStepHow many steps to take, may be negative to step backwards
Returns
Pointer to the node nStep nodes from pNode, or NULL if there is no such node in the list.

Definition at line 237 of file ellLib.c.

238 {
239  if (nStep > 0) {
240  while ((pNode != NULL) && nStep) {
241  pNode = pNode->next;
242  nStep--;
243  }
244  } else {
245  while ((pNode != NULL) && nStep) {
246  pNode = pNode->previous;
247  nStep++;
248  }
249  }
250  return pNode;
251 }
#define NULL
Definition: catime.c:38
struct ELLNODE * previous
Pointer to previous node in list.
Definition: ellLib.h:47
struct ELLNODE * next
Pointer to next node in list.
Definition: ellLib.h:46
LIBCOM_API ELLNODE* ellNth ( ELLLIST pList,
int  nodeNum 
)

Find the Nth node in a list.

Parameters
pListPointer to list from which to find node
nodeNumIndex of the node to be found
Returns
Pointer to the element at index nodeNum in pList, or NULL if there is no such node in the list.
Note
The first node has index 1.

Definition at line 205 of file ellLib.c.

206 {
207  ELLNODE *pnode;
208 
209  if ((nodeNum < 1) || (pList->count == 0))
210  return NULL;
211 
212  if (nodeNum > pList->count/2) {
213  if (nodeNum > pList->count)
214  return NULL;
215 
216  pnode = pList->node.previous;
217  nodeNum = pList->count - nodeNum;
218  while(nodeNum) {
219  pnode = pnode->previous;
220  nodeNum--;
221  }
222  return pnode;
223  }
224 
225  pnode = pList->node.next;
226  while (--nodeNum > 0)
227  pnode = pnode->next;
228 
229  return pnode;
230 }
#define NULL
Definition: catime.c:38
List node type.
Definition: ellLib.h:45
struct ELLNODE * previous
Pointer to previous node in list.
Definition: ellLib.h:47
struct ELLNODE * next
Pointer to next node in list.
Definition: ellLib.h:46
int count
Number of nodes on the list.
Definition: ellLib.h:58
ELLNODE node
Pointers to the first and last nodes on list.
Definition: ellLib.h:57
LIBCOM_API ELLNODE* ellPop ( ELLLIST pList)

Deletes and returns the last node from a list.

Parameters
pListPointer to list from which to get node
Returns
Pointer to the last node from the list, or NULL if the list is empty

Definition at line 162 of file ellLib.c.

163 {
164  ELLNODE *pnode = pList->node.previous;
165 
166  if (pnode != NULL)
167  ellDelete(pList, pnode);
168 
169  return pnode;
170 }
#define NULL
Definition: catime.c:38
List node type.
Definition: ellLib.h:45
struct ELLNODE * previous
Pointer to previous node in list.
Definition: ellLib.h:47
void ellDelete(ELLLIST *pList, ELLNODE *pNode)
Deletes a node from a list.
Definition: ellLib.c:75
ELLNODE node
Pointers to the first and last nodes on list.
Definition: ellLib.h:57
LIBCOM_API void ellSortStable ( ELLLIST pList,
pListCmp  pListCmp 
)

Stable (MergeSort) of a given list.

Parameters
pListPointer to list to be sorted
pListCmpCompare function to be used
Note
The comparison function cmp(A,B) is expected to return -1 for A<B, 0 for A==B, and 1 for A>B.
Use of mergesort algorithm based on analysis by http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html

Definition at line 30 of file ellSort.c.

31 {
32  ELLLIST INP, P, Q;
33  size_t insize = 1; /* initial sub-list size */
34  if(ellCount(pList)<=1)
35  return;
36 
37  ellInit(&INP);
38  ellInit(&P);
39  ellInit(&Q);
40 
41  /* Process is to iteratively sort
42  * a sequence of sub-lists of size 'insize'
43  */
44 
45  while(insize < ellCount(pList)) {
46 
47  assert(ellCount(&INP)==0);
48 
49  /* shift previous results to inputs */
50  ellConcat(&INP, pList);
51 
52  while(ellCount(&INP))
53  {
54  ELLNODE *p, *q;
55 
56  /* Pull out the next pair of sub-lists */
57  ellMoveN(&Q, &INP, insize);
58  ellMoveN(&P, &INP, insize);
59 
60  /* merge these sub-lists */
61  while((p=ellFirst(&P)) && (q=ellFirst(&Q)))
62  {
63  if((*cmp)(p,q) < 0) {
64  ellAdd(pList, ellGet(&P));
65  } else {
66  ellAdd(pList, ellGet(&Q));
67  }
68  }
69 
70  /* concatenate any remaining to result */
71  if(ellFirst(&P))
72  ellConcat(pList, &P);
73  else if(ellFirst(&Q))
74  ellConcat(pList, &Q);
75 
76  assert(!ellFirst(&P) && !ellFirst(&Q));
77  }
78 
79  insize *= 2;
80  }
81 
82 }
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
#define ellCount(PLIST)
Report the number of nodes in a list.
Definition: ellLib.h:84
ELLNODE * ellGet(ELLLIST *pList)
Deletes and returns the first node from a list.
Definition: ellLib.c:147
void ellAdd(ELLLIST *pList, ELLNODE *pNode)
Adds a node to the end of a list.
Definition: ellLib.c:24
List node type.
Definition: ellLib.h:45
#define ellInit(PLIST)
Initialize a list type.
Definition: ellLib.h:76
void ellConcat(ELLLIST *pDstList, ELLLIST *pAddList)
Concatenates a list to the end of another list. The list to be added is left empty. Either list (or both) can be empty at the beginning of the operation.
Definition: ellLib.c:46
List header type.
Definition: ellLib.h:56
#define ellFirst(PLIST)
Find the first node in list.
Definition: ellLib.h:89
LIBCOM_API void ellVerify ( ELLLIST pList)

Verifies that the list is consistent.

Parameters
pListList to be verified

Definition at line 304 of file ellLib.c.

305 {
306  ELLNODE *pNode;
307  ELLNODE *pNext;
308  int count = 0;
309 
310  assert (pList);
311 
312  pNode = ellFirst(pList);
313  if (pNode) {
314  assert (ellPrevious(pNode) == NULL);
315  while (1) {
316  count++;
317  pNext = ellNext(pNode);
318  if (pNext) {
319  assert (ellPrevious(pNext) == pNode);
320  } else {
321  break;
322  }
323  pNode = pNext;
324  }
325  assert (ellNext(pNode) == NULL);
326  }
327 
328  assert (pNode == ellLast(pList));
329  assert (count == ellCount(pList));
330 }
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
#define ellCount(PLIST)
Report the number of nodes in a list.
Definition: ellLib.h:84
#define NULL
Definition: catime.c:38
#define ellPrevious(PNODE)
Find the previous node in list.
Definition: ellLib.h:104
#define ellNext(PNODE)
Find the next node in list.
Definition: ellLib.h:99
#define ellLast(PLIST)
Find the last node in list.
Definition: ellLib.h:94
List node type.
Definition: ellLib.h:45
#define ellFirst(PLIST)
Find the first node in list.
Definition: ellLib.h:89