mirror of
https://salsa.debian.org/ha-team/libqb
synced 2025-08-26 23:44:41 +00:00

* doxygen2man: Add option to read copyright line from the header file This should help make builds reproducible. I tried various methods of getting the date, using 'git' is no use as it could be run from a tarball, using the file date doesn't work either so this seems a reasonable compromise. * man: Use SOURCE_EPOCH to make manpage dates reproducible Also add build-aux/update-copyright.sh to keep header file copyright lines up-to-date. All code taken from knet
316 lines
8.6 KiB
C
316 lines
8.6 KiB
C
/*
|
|
* Copyright (C) 2010-2020 Red Hat, Inc.
|
|
*
|
|
* Author: Steven Dake <sdake@redhat.com>
|
|
*
|
|
* This file is part of libqb.
|
|
*
|
|
* libqb 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.
|
|
*
|
|
* libqb 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.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#ifndef QB_LIST_H_DEFINED
|
|
#define QB_LIST_H_DEFINED
|
|
|
|
/* *INDENT-OFF* */
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
/* *INDENT-ON* */
|
|
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <qb/qbdefs.h>
|
|
|
|
/**
|
|
* @file qblist.h
|
|
* This is a kernel style list implementation.
|
|
*
|
|
* @author Steven Dake <sdake@redhat.com>
|
|
*/
|
|
|
|
struct qb_list_head {
|
|
struct qb_list_head *next;
|
|
struct qb_list_head *prev;
|
|
};
|
|
|
|
/**
|
|
* @def QB_LIST_DECLARE()
|
|
* Declare and initialize a list head.
|
|
*/
|
|
#define QB_LIST_DECLARE(name) \
|
|
struct qb_list_head name = { &(name), &(name) }
|
|
|
|
#define QB_INIT_LIST_HEAD(ptr) do { \
|
|
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
|
|
} while (0)
|
|
|
|
/**
|
|
* Initialize the list entry.
|
|
*
|
|
* Points next and prev pointers to head.
|
|
* @param head pointer to the list head
|
|
*/
|
|
static inline void qb_list_init(struct qb_list_head *head)
|
|
{
|
|
head->next = head;
|
|
head->prev = head;
|
|
}
|
|
|
|
/**
|
|
* Add this element to the list.
|
|
*
|
|
* @param element the new element to insert.
|
|
* @param head pointer to the list head
|
|
*/
|
|
static inline void qb_list_add(struct qb_list_head *element,
|
|
struct qb_list_head *head)
|
|
{
|
|
head->next->prev = element;
|
|
element->next = head->next;
|
|
element->prev = head;
|
|
head->next = element;
|
|
}
|
|
|
|
/**
|
|
* Add to the list (but at the end of the list).
|
|
*
|
|
* @param element pointer to the element to add
|
|
* @param head pointer to the list head
|
|
* @see qb_list_add()
|
|
*/
|
|
static inline void qb_list_add_tail(struct qb_list_head *element,
|
|
struct qb_list_head *head)
|
|
{
|
|
head->prev->next = element;
|
|
element->next = head;
|
|
element->prev = head->prev;
|
|
head->prev = element;
|
|
}
|
|
|
|
/**
|
|
* Delete an entry from the list.
|
|
*
|
|
* @param _remove the list item to remove
|
|
*/
|
|
static inline void qb_list_del(struct qb_list_head *_remove)
|
|
{
|
|
_remove->next->prev = _remove->prev;
|
|
_remove->prev->next = _remove->next;
|
|
}
|
|
|
|
/**
|
|
* Replace old entry by new one
|
|
* @param old_one: the element to be replaced
|
|
* @param new_one: the new element to insert
|
|
*/
|
|
static inline void qb_list_replace(struct qb_list_head *old_one,
|
|
struct qb_list_head *new_one)
|
|
{
|
|
new_one->next = old_one->next;
|
|
new_one->next->prev = new_one;
|
|
new_one->prev = old_one->prev;
|
|
new_one->prev->next = new_one;
|
|
}
|
|
|
|
/**
|
|
* Tests whether list is the last entry in list head
|
|
* @param list: the entry to test
|
|
* @param head: the head of the list
|
|
* @return boolean true/false
|
|
*/
|
|
static inline int qb_list_is_last(const struct qb_list_head *list,
|
|
const struct qb_list_head *head)
|
|
{
|
|
return list->next == head;
|
|
}
|
|
|
|
/**
|
|
* A quick test to see if the list is empty (pointing to it's self).
|
|
* @param head pointer to the list head
|
|
* @return boolean true/false
|
|
*/
|
|
static inline int32_t qb_list_empty(const struct qb_list_head *head)
|
|
{
|
|
return head->next == head;
|
|
}
|
|
|
|
/**
|
|
* Join two lists.
|
|
* @param list the new list to add.
|
|
* @param head the place to add it in the first list.
|
|
*
|
|
* @note The "list" is reinitialised
|
|
*/
|
|
static inline void qb_list_splice(struct qb_list_head *list,
|
|
struct qb_list_head *head)
|
|
{
|
|
struct qb_list_head *first = list->next;
|
|
struct qb_list_head *last = list->prev;
|
|
struct qb_list_head *at = head->next;
|
|
|
|
if (!qb_list_empty(list)) {
|
|
first->prev = head;
|
|
head->next = first;
|
|
|
|
last->next = at;
|
|
at->prev = last;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Join two lists, each list being a queue
|
|
* @param list: the new list to add.
|
|
* @param head: the place to add it in the first list.
|
|
*/
|
|
static inline void qb_list_splice_tail(struct qb_list_head *list,
|
|
struct qb_list_head *head)
|
|
{
|
|
struct qb_list_head *first = list->next;
|
|
struct qb_list_head *last = list->prev;
|
|
struct qb_list_head *at = head;
|
|
|
|
if (!qb_list_empty(list)) {
|
|
first->prev = head->prev;
|
|
head->prev->next = first;
|
|
|
|
last->next = at;
|
|
at->prev = last;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the struct for this entry
|
|
* @param ptr: the &struct list_head pointer.
|
|
* @param type: the type of the struct this is embedded in.
|
|
* @param member: the name of the list_struct within the struct.
|
|
*/
|
|
#define qb_list_entry(ptr,type,member) ({ \
|
|
((type *)((char*)ptr - offsetof(type, member))); })
|
|
|
|
/**
|
|
* Get the first element from a list
|
|
* @param ptr: the &struct list_head pointer.
|
|
* @param type: the type of the struct this is embedded in.
|
|
* @param member: the name of the list_struct within the struct.
|
|
*/
|
|
#define qb_list_first_entry(ptr, type, member) \
|
|
qb_list_entry((ptr)->next, type, member)
|
|
|
|
/**
|
|
* Iterate over a list
|
|
* @param pos: the &struct list_head to use as a loop counter.
|
|
* @param head: the head for your list.
|
|
*/
|
|
#define qb_list_for_each(pos, head) \
|
|
for (pos = (head)->next; pos != (head); pos = pos->next)
|
|
|
|
/**
|
|
* Iterate over a list backwards
|
|
* @param pos: the &struct list_head to use as a loop counter.
|
|
* @param head: the head for your list.
|
|
*/
|
|
#define qb_list_for_each_reverse(pos, head) \
|
|
for (pos = (head)->prev; pos != (head); pos = pos->prev)
|
|
|
|
/**
|
|
* Iterate over a list safe against removal of list entry
|
|
* @param pos: the &struct list_head to use as a loop counter.
|
|
* @param n: another &struct list_head to use as temporary storage
|
|
* @param head: the head for your list.
|
|
*/
|
|
#define qb_list_for_each_safe(pos, n, head) \
|
|
for (pos = (head)->next, n = pos->next; pos != (head); \
|
|
pos = n, n = pos->next)
|
|
|
|
/**
|
|
* Iterate over list of given type
|
|
* @param pos: the type * to use as a loop counter.
|
|
* @param head: the head for your list.
|
|
* @param member: the name of the list_struct within the struct.
|
|
*/
|
|
#define qb_list_for_each_entry(pos, head, member) \
|
|
for (pos = qb_list_entry((head)->next, typeof(*pos), member); \
|
|
&pos->member != (head); \
|
|
pos = qb_list_entry(pos->member.next, typeof(*pos), member))
|
|
|
|
/**
|
|
* Iterate backwards over list of given type.
|
|
* @param pos: the type to use as a loop counter.
|
|
* @param head: the head for your list.
|
|
* @param member: the name of the list_struct within the struct.
|
|
*/
|
|
#define qb_list_for_each_entry_reverse(pos, head, member) \
|
|
for (pos = qb_list_entry((head)->prev, typeof(*pos), member); \
|
|
&pos->member != (head); \
|
|
pos = qb_list_entry(pos->member.prev, typeof(*pos), member))
|
|
|
|
/**
|
|
* Iterate over list of given type safe against removal of list entry
|
|
* @param pos: the type * to use as a loop cursor.
|
|
* @param n: another type * to use as temporary storage
|
|
* @param head: the head for your list.
|
|
* @param member: the name of the list_struct within the struct.
|
|
*/
|
|
#define qb_list_for_each_entry_safe(pos, n, head, member) \
|
|
for (pos = qb_list_entry((head)->next, typeof(*pos), member), \
|
|
n = qb_list_entry(pos->member.next, typeof(*pos), member); \
|
|
&pos->member != (head); \
|
|
pos = n, n = qb_list_entry(n->member.next, typeof(*n), member))
|
|
|
|
/**
|
|
* Iterate backwards over list safe against removal
|
|
* @param pos: the type * to use as a loop cursor.
|
|
* @param n: another type * to use as temporary storage
|
|
* @param head: the head for your list.
|
|
* @param member: the name of the list_struct within the struct.
|
|
*/
|
|
#define qb_list_for_each_entry_safe_reverse(pos, n, head, member) \
|
|
for (pos = qb_list_entry((head)->prev, typeof(*pos), member), \
|
|
n = qb_list_entry(pos->member.prev, typeof(*pos), member); \
|
|
&pos->member != (head); \
|
|
pos = n, n = qb_list_entry(n->member.prev, typeof(*n), member))
|
|
|
|
/**
|
|
* Iterate over list of given type from the current point
|
|
* @param pos: the type * to use as a loop cursor.
|
|
* @param head: the head for your list.
|
|
* @param member: the name of the list_struct within the struct.
|
|
*/
|
|
#define qb_list_for_each_entry_from(pos, head, member) \
|
|
for (; &pos->member != (head); \
|
|
pos = qb_list_entry(pos->member.next, typeof(*pos), member))
|
|
|
|
/**
|
|
* Count the number of items in the list.
|
|
* @param head: the head for your list.
|
|
* @return length of the list.
|
|
*/
|
|
static inline int32_t qb_list_length(struct qb_list_head *head)
|
|
{
|
|
struct qb_list_head *item;
|
|
int32_t length = 0;
|
|
|
|
qb_list_for_each(item, head)
|
|
length++;
|
|
|
|
return length;
|
|
}
|
|
|
|
/* *INDENT-OFF* */
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif /* __cplusplus */
|
|
/* *INDENT-ON* */
|
|
|
|
#endif /* QB_LIST_H_DEFINED */
|