File: list.h

package info (click to toggle)
alsa-lib 1.2.15-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 8,592 kB
  • sloc: ansic: 97,922; sh: 4,711; makefile: 653
file content (152 lines) | stat: -rw-r--r-- 4,016 bytes parent folder | download
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/* Doubly linked list macros compatible with Linux kernel's version
 * Copyright (c) 2015 by Takashi Iwai <tiwai@suse.de>
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 */

#ifndef _LIST_H
#define _LIST_H

#include <stddef.h>

struct list_head {
	struct list_head *next;
	struct list_head *prev;
};

/* one-shot definition of a list head */
#define LIST_HEAD(x) \
	struct list_head x = { &x, &x }

/* initialize a list head explicitly */
static inline void INIT_LIST_HEAD(struct list_head *p)
{
	p->next = p->prev = p;
}

#define list_entry_offset(p, type, offset) \
	((type *)((char *)(p) - (offset)))

/* list_entry - retrieve the original struct from list_head
 * @p: list_head pointer
 * @type: struct type
 * @member: struct field member containing the list_head
 */
#define list_entry(p, type, member) \
	list_entry_offset(p, type, offsetof(type, member))

/* list_for_each - iterate over the linked list
 * @p: iterator, a list_head pointer variable
 * @list: list_head pointer containing the list
 */
#define list_for_each(p, list) \
	for (p = (list)->next; p != (list); p = p->next)

/* list_for_each_safe - iterate over the linked list, safe to delete
 * @p: iterator, a list_head pointer variable
 * @s: a temporary variable to keep the next, a list_head pointer, too
 * @list: list_head pointer containing the list
 */
#define list_for_each_safe(p, s, list) \
	for (p = (list)->next; s = p->next, p != (list); p = s)

/* list_add - prepend a list entry at the head
 * @p: the new list entry to add
 * @list: the list head
 */
static inline void list_add(struct list_head *p, struct list_head *list)
{
	struct list_head *first = list->next;

	p->next = first;
	first->prev = p;
	list->next = p;
	p->prev = list;
}

/* list_add_tail - append a list entry at the tail
 * @p: the new list entry to add
 * @list: the list head
 */
static inline void list_add_tail(struct list_head *p, struct list_head *list)
{
	struct list_head *last = list->prev;

	last->next = p;
	p->prev = last;
	p->next = list;
	list->prev = p;
}

/* list_insert - insert a new list entry between two known consecutive entries
 * @p: the new entry to be inserted between prev and next
 * @prev: the left-side entry
 * @next: the right-side entry
 */
static inline void list_insert(struct list_head *p,
			       struct list_head *prev,
			       struct list_head *next)
{
	next->prev = p;
	p->next = next;
	p->prev = prev;
	prev->next = p;
}

/* list_del - delete the given list entry */
static inline void list_del(struct list_head *p)
{
	p->prev->next = p->next;
	p->next->prev = p->prev;
}

/* list_empty - returns 1 if the given list is empty */
static inline int list_empty(const struct list_head *p)
{
	return p->next == p;
}

/* list_splice - join two lists
 * @list: the new list to add
 * @head: the place to add it in the first list
 */
static inline void list_splice(const struct list_head *list,
				struct list_head *head)
{
	if (!list_empty(list)) {
		struct list_head *first = list->next;
		struct list_head *last = list->prev;
		struct list_head *at = head->next;

		first->prev = head;
		head->next = first;

		last->next = at;
		at->prev = last;
	}
}

/* list_splice_init - join two lists and reinitialize the emptied list
 * @list: the new list to add
 * @head: the place to add it in the first list
 *
 * The list at @list is reinitialized
 */
static inline void list_splice_init(struct list_head *list,
				    struct list_head *head)
{
	if (!list_empty(list)) {
		list_splice(list, head);
		INIT_LIST_HEAD(list);
	}
}

#endif /* _LIST_H */