* This file is part of the openHiTLS project.
*
* openHiTLS is licensed under the Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#ifndef BSL_MODULE_LIST_H
#define BSL_MODULE_LIST_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
* This structure is used to store the forward and backward pointers of nodes in the bidirectional linked list.
* This linked list does not contain substantial data areas and is generally used to organize (concatenate) data nodes.
*/
typedef struct ListHeadSt {
struct ListHeadSt *next, *prev;
} ListHead;
* @brief initialize the linked list when the linked list is reused
*
* @param head [IN] The address of the head node of the list
*/
#define BSL_LIST_INIT(head) (head)->next = (head)->prev = (head)
* @brief Insert the 'item' node after the 'where' node.
Before the change: where->A->B. After the change: where->item->A->B
*
* @param where [IN] The address where the item will be inserted after
* @param item [IN] Address of the node(item) to be inserted
*/
#define LIST_ADD_AFTER(where, item) do { \
(item)->next = (where)->next; \
(item)->prev = (where); \
(where)->next = (item); \
(item)->next->prev = (item); \
} while (0)
* @brief Insert the 'item' node before the 'where' node.
* Before change: A->where->B. After change: A->item->where->B
*
* @param where [IN] The address where the item will be inserted before
* @param item [IN] Address of the node to be inserted
*/
#define LIST_ADD_BEFORE(where, item) LIST_ADD_AFTER((where)->prev, (item))
* @brief Delete the node item.
*
* @param item [IN] The address of the item to be removed
*/
#define BSL_LIST_REMOVE(item) do { \
(item)->prev->next = (item)->next; \
(item)->next->prev = (item)->prev; \
} while (0)
* @brief Check whether a list is empty
*
* @param head [IN] The address of the list to be checked.
*/
#define LIST_IS_EMPTY(head) ((head)->next == (head))
* @brief Travel through a list safety
*
* @param head [IN] Linked list to be traversed (The head of a list)
* @param temp [IN] Point to the current node to safely delete the current node
* @param item [IN] A temporary list node item for travelling the list
*/
#define LIST_FOR_EACH_ITEM_SAFE(item, temp, head) \
for ((item) = (head)->next, (temp) = (item)->next; (item) != (head); (item) = (temp), (temp) = (item)->next)
* @brief Find the start address of the struct(large node) where the node is located
* through a node (small node) in the linked list.
*
* @param item [IN] The address of a list item
* @param type [IN] Type of the large node that contains the linked list node.
* @param member [IN] Name of the list node in the structure
*
* Note:
* Each struct variable forms a large node (including data and list nodes).
* The large node is connected through the list(small node).
* --------- --------- --------- -- ----
* | pre |<---| pre |<---| pre | |==>small node |
* | next |--->| next |--->| next | | |
* --------- --------- --------- -- | ===> Large node
* | data1 | | data1 | | data1 | |
* | data2 | | data2 | | data2 | |
* --------- --------- --------- ----
* The reason why the list is not directly used as the big node is that
* the list (ListHead type) has only the head and tail pointers and does not contain the data area.
* In this way, the list can be used for mounting any data and is universal.
*/
#define BSL_LIST_ENTRY(item, type, member) \
((type *)((uintptr_t)(char *)(item) - (uintptr_t)(&((type *)0)->member)))
#ifdef __cplusplus
}
#endif
#endif