Coverage Report

Created: 2025-06-22 06:56

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