xref: /dflybsd-src/contrib/lvm2/dist/libdm/datastruct/list.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
1*86d7f5d3SJohn Marino /*	$NetBSD: list.c,v 1.1.1.1 2008/12/22 00:18:36 haad Exp $	*/
2*86d7f5d3SJohn Marino 
3*86d7f5d3SJohn Marino /*
4*86d7f5d3SJohn Marino  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
5*86d7f5d3SJohn Marino  * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
6*86d7f5d3SJohn Marino  *
7*86d7f5d3SJohn Marino  * This file is part of LVM2.
8*86d7f5d3SJohn Marino  *
9*86d7f5d3SJohn Marino  * This copyrighted material is made available to anyone wishing to use,
10*86d7f5d3SJohn Marino  * modify, copy, or redistribute it subject to the terms and conditions
11*86d7f5d3SJohn Marino  * of the GNU Lesser General Public License v.2.1.
12*86d7f5d3SJohn Marino  *
13*86d7f5d3SJohn Marino  * You should have received a copy of the GNU Lesser General Public License
14*86d7f5d3SJohn Marino  * along with this program; if not, write to the Free Software Foundation,
15*86d7f5d3SJohn Marino  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16*86d7f5d3SJohn Marino  */
17*86d7f5d3SJohn Marino 
18*86d7f5d3SJohn Marino #include "lib.h"
19*86d7f5d3SJohn Marino #include <assert.h>
20*86d7f5d3SJohn Marino 
21*86d7f5d3SJohn Marino /*
22*86d7f5d3SJohn Marino  * Initialise a list before use.
23*86d7f5d3SJohn Marino  * The list head's next and previous pointers point back to itself.
24*86d7f5d3SJohn Marino  */
dm_list_init(struct dm_list * head)25*86d7f5d3SJohn Marino void dm_list_init(struct dm_list *head)
26*86d7f5d3SJohn Marino {
27*86d7f5d3SJohn Marino 	head->n = head->p = head;
28*86d7f5d3SJohn Marino }
29*86d7f5d3SJohn Marino 
30*86d7f5d3SJohn Marino /*
31*86d7f5d3SJohn Marino  * Insert an element before 'head'.
32*86d7f5d3SJohn Marino  * If 'head' is the list head, this adds an element to the end of the list.
33*86d7f5d3SJohn Marino  */
dm_list_add(struct dm_list * head,struct dm_list * elem)34*86d7f5d3SJohn Marino void dm_list_add(struct dm_list *head, struct dm_list *elem)
35*86d7f5d3SJohn Marino {
36*86d7f5d3SJohn Marino 	assert(head->n);
37*86d7f5d3SJohn Marino 
38*86d7f5d3SJohn Marino 	elem->n = head;
39*86d7f5d3SJohn Marino 	elem->p = head->p;
40*86d7f5d3SJohn Marino 
41*86d7f5d3SJohn Marino 	head->p->n = elem;
42*86d7f5d3SJohn Marino 	head->p = elem;
43*86d7f5d3SJohn Marino }
44*86d7f5d3SJohn Marino 
45*86d7f5d3SJohn Marino /*
46*86d7f5d3SJohn Marino  * Insert an element after 'head'.
47*86d7f5d3SJohn Marino  * If 'head' is the list head, this adds an element to the front of the list.
48*86d7f5d3SJohn Marino  */
dm_list_add_h(struct dm_list * head,struct dm_list * elem)49*86d7f5d3SJohn Marino void dm_list_add_h(struct dm_list *head, struct dm_list *elem)
50*86d7f5d3SJohn Marino {
51*86d7f5d3SJohn Marino 	assert(head->n);
52*86d7f5d3SJohn Marino 
53*86d7f5d3SJohn Marino 	elem->n = head->n;
54*86d7f5d3SJohn Marino 	elem->p = head;
55*86d7f5d3SJohn Marino 
56*86d7f5d3SJohn Marino 	head->n->p = elem;
57*86d7f5d3SJohn Marino 	head->n = elem;
58*86d7f5d3SJohn Marino }
59*86d7f5d3SJohn Marino 
60*86d7f5d3SJohn Marino /*
61*86d7f5d3SJohn Marino  * Delete an element from its list.
62*86d7f5d3SJohn Marino  * Note that this doesn't change the element itself - it may still be safe
63*86d7f5d3SJohn Marino  * to follow its pointers.
64*86d7f5d3SJohn Marino  */
dm_list_del(struct dm_list * elem)65*86d7f5d3SJohn Marino void dm_list_del(struct dm_list *elem)
66*86d7f5d3SJohn Marino {
67*86d7f5d3SJohn Marino 	elem->n->p = elem->p;
68*86d7f5d3SJohn Marino 	elem->p->n = elem->n;
69*86d7f5d3SJohn Marino }
70*86d7f5d3SJohn Marino 
71*86d7f5d3SJohn Marino /*
72*86d7f5d3SJohn Marino  * Remove an element from existing list and insert before 'head'.
73*86d7f5d3SJohn Marino  */
dm_list_move(struct dm_list * head,struct dm_list * elem)74*86d7f5d3SJohn Marino void dm_list_move(struct dm_list *head, struct dm_list *elem)
75*86d7f5d3SJohn Marino {
76*86d7f5d3SJohn Marino         dm_list_del(elem);
77*86d7f5d3SJohn Marino         dm_list_add(head, elem);
78*86d7f5d3SJohn Marino }
79*86d7f5d3SJohn Marino 
80*86d7f5d3SJohn Marino /*
81*86d7f5d3SJohn Marino  * Is the list empty?
82*86d7f5d3SJohn Marino  */
dm_list_empty(const struct dm_list * head)83*86d7f5d3SJohn Marino int dm_list_empty(const struct dm_list *head)
84*86d7f5d3SJohn Marino {
85*86d7f5d3SJohn Marino 	return head->n == head;
86*86d7f5d3SJohn Marino }
87*86d7f5d3SJohn Marino 
88*86d7f5d3SJohn Marino /*
89*86d7f5d3SJohn Marino  * Is this the first element of the list?
90*86d7f5d3SJohn Marino  */
dm_list_start(const struct dm_list * head,const struct dm_list * elem)91*86d7f5d3SJohn Marino int dm_list_start(const struct dm_list *head, const struct dm_list *elem)
92*86d7f5d3SJohn Marino {
93*86d7f5d3SJohn Marino 	return elem->p == head;
94*86d7f5d3SJohn Marino }
95*86d7f5d3SJohn Marino 
96*86d7f5d3SJohn Marino /*
97*86d7f5d3SJohn Marino  * Is this the last element of the list?
98*86d7f5d3SJohn Marino  */
dm_list_end(const struct dm_list * head,const struct dm_list * elem)99*86d7f5d3SJohn Marino int dm_list_end(const struct dm_list *head, const struct dm_list *elem)
100*86d7f5d3SJohn Marino {
101*86d7f5d3SJohn Marino 	return elem->n == head;
102*86d7f5d3SJohn Marino }
103*86d7f5d3SJohn Marino 
104*86d7f5d3SJohn Marino /*
105*86d7f5d3SJohn Marino  * Return first element of the list or NULL if empty
106*86d7f5d3SJohn Marino  */
dm_list_first(const struct dm_list * head)107*86d7f5d3SJohn Marino struct dm_list *dm_list_first(const struct dm_list *head)
108*86d7f5d3SJohn Marino {
109*86d7f5d3SJohn Marino 	return (dm_list_empty(head) ? NULL : head->n);
110*86d7f5d3SJohn Marino }
111*86d7f5d3SJohn Marino 
112*86d7f5d3SJohn Marino /*
113*86d7f5d3SJohn Marino  * Return last element of the list or NULL if empty
114*86d7f5d3SJohn Marino  */
dm_list_last(const struct dm_list * head)115*86d7f5d3SJohn Marino struct dm_list *dm_list_last(const struct dm_list *head)
116*86d7f5d3SJohn Marino {
117*86d7f5d3SJohn Marino 	return (dm_list_empty(head) ? NULL : head->p);
118*86d7f5d3SJohn Marino }
119*86d7f5d3SJohn Marino 
120*86d7f5d3SJohn Marino /*
121*86d7f5d3SJohn Marino  * Return the previous element of the list, or NULL if we've reached the start.
122*86d7f5d3SJohn Marino  */
dm_list_prev(const struct dm_list * head,const struct dm_list * elem)123*86d7f5d3SJohn Marino struct dm_list *dm_list_prev(const struct dm_list *head, const struct dm_list *elem)
124*86d7f5d3SJohn Marino {
125*86d7f5d3SJohn Marino 	return (dm_list_start(head, elem) ? NULL : elem->p);
126*86d7f5d3SJohn Marino }
127*86d7f5d3SJohn Marino 
128*86d7f5d3SJohn Marino /*
129*86d7f5d3SJohn Marino  * Return the next element of the list, or NULL if we've reached the end.
130*86d7f5d3SJohn Marino  */
dm_list_next(const struct dm_list * head,const struct dm_list * elem)131*86d7f5d3SJohn Marino struct dm_list *dm_list_next(const struct dm_list *head, const struct dm_list *elem)
132*86d7f5d3SJohn Marino {
133*86d7f5d3SJohn Marino 	return (dm_list_end(head, elem) ? NULL : elem->n);
134*86d7f5d3SJohn Marino }
135*86d7f5d3SJohn Marino 
136*86d7f5d3SJohn Marino /*
137*86d7f5d3SJohn Marino  * Return the number of elements in a list by walking it.
138*86d7f5d3SJohn Marino  */
dm_list_size(const struct dm_list * head)139*86d7f5d3SJohn Marino unsigned int dm_list_size(const struct dm_list *head)
140*86d7f5d3SJohn Marino {
141*86d7f5d3SJohn Marino 	unsigned int s = 0;
142*86d7f5d3SJohn Marino 	const struct dm_list *v;
143*86d7f5d3SJohn Marino 
144*86d7f5d3SJohn Marino 	dm_list_iterate(v, head)
145*86d7f5d3SJohn Marino 	    s++;
146*86d7f5d3SJohn Marino 
147*86d7f5d3SJohn Marino 	return s;
148*86d7f5d3SJohn Marino }
149