1 /*++
2 /* NAME
3 /*	ring 3
4 /* SUMMARY
5 /*	circular list management
6 /* SYNOPSIS
7 /*	#include <ring.h>
8 /*
9 /*	void	ring_init(list)
10 /*	RING	*list;
11 /*
12 /*	void	ring_prepend(list, element)
13 /*	RING	*list;
14 /*	RING	*element;
15 /*
16 /*	void	ring_append(list, element)
17 /*	RING	*list;
18 /*	RING	*element;
19 /*
20 /*	RING	*ring_pred(element)
21 /*	RING	*element;
22 /*
23 /*	RING	*ring_succ(element)
24 /*	RING	*element;
25 /*
26 /*	void	ring_detach(element)
27 /*	RING	*element;
28 /*
29 /*	RING_FOREACH(RING *element, RING *head)
30 /* DESCRIPTION
31 /*	This module manages circular, doubly-linked, lists. It provides
32 /*	operations to initialize a list, to add or remove an element,
33 /*	and to iterate over a list. Although the documentation appears
34 /*	to emphasize the special role of the list head, each operation
35 /*	can be applied to each list member.
36 /*
37 /*	Examples of applications: any sequence of objects such as queue,
38 /*	unordered list, or stack. Typically, an application embeds a RING
39 /*	structure into its own data structure, and uses the RING primitives
40 /*	to maintain the linkage between application-specific data objects.
41 /*
42 /*	ring_init() initializes its argument to a list of just one element.
43 /*
44 /*	ring_append() appends the named element to the named list head.
45 /*
46 /*	ring_prepend() prepends the named element to the named list head.
47 /*
48 /*	ring_succ() returns the list element that follows its argument.
49 /*
50 /*	ring_pred() returns the list element that precedes its argument.
51 /*
52 /*	ring_detach() disconnects a list element from its neighbors
53 /*	and closes the hole. This routine performs no implicit ring_init()
54 /*	on the removed element.
55 /*
56 /*	RING_FOREACH() is a macro that expands to a for (... ; ... ; ...)
57 /*	statement that iterates over each list element in forward order.
58 /*	Upon completion, the \fIelement\fR variable is set equal to
59 /*	\fIhead\fR. The list head itself is not treated as a list member.
60 /* LICENSE
61 /* .ad
62 /* .fi
63 /*	The Secure Mailer license must be distributed with this software.
64 /* AUTHOR(S)
65 /*	Wietse Venema
66 /*	IBM T.J. Watson Research
67 /*	P.O. Box 704
68 /*	Yorktown Heights, NY 10598, USA
69 /*--*/
70 
71 /* System libraries. */
72 
73 /* Application-specific. */
74 
75 #include "ring.h"
76 
77 /* ring_init - initialize ring head */
78 
ring_init(ring)79 void    ring_init(ring)
80 RING   *ring;
81 {
82     ring->pred = ring->succ = ring;
83 }
84 
85 /* ring_append - insert entry after ring head */
86 
ring_append(ring,entry)87 void    ring_append(ring, entry)
88 RING   *ring;
89 RING   *entry;
90 {
91     entry->succ = ring->succ;
92     entry->pred = ring;
93     ring->succ->pred = entry;
94     ring->succ = entry;
95 }
96 
97 /* ring_prepend - insert new entry before ring head */
98 
ring_prepend(ring,entry)99 void    ring_prepend(ring, entry)
100 RING   *ring;
101 RING   *entry;
102 {
103     entry->pred = ring->pred;
104     entry->succ = ring;
105     ring->pred->succ = entry;
106     ring->pred = entry;
107 }
108 
109 /* ring_detach - remove entry from ring */
110 
ring_detach(entry)111 void    ring_detach(entry)
112 RING   *entry;
113 {
114     RING   *succ = entry->succ;
115     RING   *pred = entry->pred;
116 
117     pred->succ = succ;
118     succ->pred = pred;
119 
120     entry->succ = entry->pred = 0;
121 }
122