123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- /*
- * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the Apache License 2.0 (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
- #ifndef OSSL_INTERNAL_LIST_H
- # define OSSL_INTERNAL_LIST_H
- # pragma once
- # include <string.h>
- # include <assert.h>
- # ifdef NDEBUG
- # define OSSL_LIST_DBG(x)
- # else
- # define OSSL_LIST_DBG(x) x;
- # endif
- /* Define a list structure */
- # define OSSL_LIST(name) OSSL_LIST_ ## name
- /* Define fields to include an element of a list */
- # define OSSL_LIST_MEMBER(name, type) \
- struct { \
- type *next, *prev; \
- OSSL_LIST_DBG(struct ossl_list_st_ ## name *list) \
- } ossl_list_ ## name
- # define DEFINE_LIST_OF(name, type) \
- typedef struct ossl_list_st_ ## name OSSL_LIST(name); \
- struct ossl_list_st_ ## name { \
- type *alpha, *omega; \
- size_t num_elems; \
- }; \
- static ossl_unused ossl_inline void \
- ossl_list_##name##_init(OSSL_LIST(name) *list) \
- { \
- memset(list, 0, sizeof(*list)); \
- } \
- static ossl_unused ossl_inline void \
- ossl_list_##name##_init_elem(type *elem) \
- { \
- memset(&elem->ossl_list_ ## name, 0, \
- sizeof(elem->ossl_list_ ## name)); \
- } \
- static ossl_unused ossl_inline int \
- ossl_list_##name##_is_empty(const OSSL_LIST(name) *list) \
- { \
- return list->num_elems == 0; \
- } \
- static ossl_unused ossl_inline size_t \
- ossl_list_##name##_num(const OSSL_LIST(name) *list) \
- { \
- return list->num_elems; \
- } \
- static ossl_unused ossl_inline type * \
- ossl_list_##name##_head(const OSSL_LIST(name) *list) \
- { \
- assert(list->alpha == NULL \
- || list->alpha->ossl_list_ ## name.list == list); \
- return list->alpha; \
- } \
- static ossl_unused ossl_inline type * \
- ossl_list_##name##_tail(const OSSL_LIST(name) *list) \
- { \
- assert(list->omega == NULL \
- || list->omega->ossl_list_ ## name.list == list); \
- return list->omega; \
- } \
- static ossl_unused ossl_inline type * \
- ossl_list_##name##_next(const type *elem) \
- { \
- assert(elem->ossl_list_ ## name.next == NULL \
- || elem->ossl_list_ ## name.next \
- ->ossl_list_ ## name.prev == elem); \
- return elem->ossl_list_ ## name.next; \
- } \
- static ossl_unused ossl_inline type * \
- ossl_list_##name##_prev(const type *elem) \
- { \
- assert(elem->ossl_list_ ## name.prev == NULL \
- || elem->ossl_list_ ## name.prev \
- ->ossl_list_ ## name.next == elem); \
- return elem->ossl_list_ ## name.prev; \
- } \
- static ossl_unused ossl_inline void \
- ossl_list_##name##_remove(OSSL_LIST(name) *list, type *elem) \
- { \
- assert(elem->ossl_list_ ## name.list == list); \
- OSSL_LIST_DBG(elem->ossl_list_ ## name.list = NULL) \
- if (list->alpha == elem) \
- list->alpha = elem->ossl_list_ ## name.next; \
- if (list->omega == elem) \
- list->omega = elem->ossl_list_ ## name.prev; \
- if (elem->ossl_list_ ## name.prev != NULL) \
- elem->ossl_list_ ## name.prev->ossl_list_ ## name.next = \
- elem->ossl_list_ ## name.next; \
- if (elem->ossl_list_ ## name.next != NULL) \
- elem->ossl_list_ ## name.next->ossl_list_ ## name.prev = \
- elem->ossl_list_ ## name.prev; \
- list->num_elems--; \
- memset(&elem->ossl_list_ ## name, 0, \
- sizeof(elem->ossl_list_ ## name)); \
- } \
- static ossl_unused ossl_inline void \
- ossl_list_##name##_insert_head(OSSL_LIST(name) *list, type *elem) \
- { \
- assert(elem->ossl_list_ ## name.list == NULL); \
- OSSL_LIST_DBG(elem->ossl_list_ ## name.list = list) \
- if (list->alpha != NULL) \
- list->alpha->ossl_list_ ## name.prev = elem; \
- elem->ossl_list_ ## name.next = list->alpha; \
- elem->ossl_list_ ## name.prev = NULL; \
- list->alpha = elem; \
- if (list->omega == NULL) \
- list->omega = elem; \
- list->num_elems++; \
- } \
- static ossl_unused ossl_inline void \
- ossl_list_##name##_insert_tail(OSSL_LIST(name) *list, type *elem) \
- { \
- assert(elem->ossl_list_ ## name.list == NULL); \
- OSSL_LIST_DBG(elem->ossl_list_ ## name.list = list) \
- if (list->omega != NULL) \
- list->omega->ossl_list_ ## name.next = elem; \
- elem->ossl_list_ ## name.prev = list->omega; \
- elem->ossl_list_ ## name.next = NULL; \
- list->omega = elem; \
- if (list->alpha == NULL) \
- list->alpha = elem; \
- list->num_elems++; \
- } \
- static ossl_unused ossl_inline void \
- ossl_list_##name##_insert_before(OSSL_LIST(name) *list, type *e, \
- type *elem) \
- { \
- assert(elem->ossl_list_ ## name.list == NULL); \
- OSSL_LIST_DBG(elem->ossl_list_ ## name.list = list) \
- elem->ossl_list_ ## name.next = e; \
- elem->ossl_list_ ## name.prev = e->ossl_list_ ## name.prev; \
- if (e->ossl_list_ ## name.prev != NULL) \
- e->ossl_list_ ## name.prev->ossl_list_ ## name.next = elem; \
- e->ossl_list_ ## name.prev = elem; \
- if (list->alpha == e) \
- list->alpha = elem; \
- list->num_elems++; \
- } \
- static ossl_unused ossl_inline void \
- ossl_list_##name##_insert_after(OSSL_LIST(name) *list, type *e, \
- type *elem) \
- { \
- assert(elem->ossl_list_ ## name.list == NULL); \
- OSSL_LIST_DBG(elem->ossl_list_ ## name.list = list) \
- elem->ossl_list_ ## name.prev = e; \
- elem->ossl_list_ ## name.next = e->ossl_list_ ## name.next; \
- if (e->ossl_list_ ## name.next != NULL) \
- e->ossl_list_ ## name.next->ossl_list_ ## name.prev = elem; \
- e->ossl_list_ ## name.next = elem; \
- if (list->omega == e) \
- list->omega = elem; \
- list->num_elems++; \
- } \
- struct ossl_list_st_ ## name
- #endif
|