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

/* System libraries. */

/* Application-specific. */

#include "ring.h"

/* ring_init - initialize ring head */

void    ring_init(ring)
RING   *ring;
{
    ring->pred = ring->succ = ring;
}

/* ring_append - insert entry after ring head */

void    ring_append(ring, entry)
RING   *ring;
RING   *entry;
{
    entry->succ = ring->succ;
    entry->pred = ring;
    ring->succ->pred = entry;
    ring->succ = entry;
}

/* ring_prepend - insert new entry before ring head */

void    ring_prepend(ring, entry)
RING   *ring;
RING   *entry;
{
    entry->pred = ring->pred;
    entry->succ = ring;
    ring->pred->succ = entry;
    ring->pred = entry;
}

/* ring_detach - remove entry from ring */

void    ring_detach(entry)
RING   *entry;
{
    RING   *succ = entry->succ;
    RING   *pred = entry->pred;

    pred->succ = succ;
    succ->pred = pred;

    entry->succ = entry->pred = 0;
}