|  | /* | 
|  | * Copyright (c) 2016 Intel Corporation | 
|  | * | 
|  | * SPDX-License-Identifier: Apache-2.0 | 
|  | */ | 
|  |  | 
|  | #ifndef ZEPHYR_INCLUDE_SYS_LIST_GEN_H_ | 
|  | #define ZEPHYR_INCLUDE_SYS_LIST_GEN_H_ | 
|  |  | 
|  | #include <stddef.h> | 
|  | #include <stdbool.h> | 
|  | #include <sys/util.h> | 
|  |  | 
|  | #define Z_GENLIST_FOR_EACH_NODE(__lname, __l, __sn)			\ | 
|  | for (__sn = sys_ ## __lname ## _peek_head(__l); __sn != NULL;	\ | 
|  | __sn = sys_ ## __lname ## _peek_next(__sn)) | 
|  |  | 
|  |  | 
|  | #define Z_GENLIST_ITERATE_FROM_NODE(__lname, __l, __sn)			\ | 
|  | for (__sn = __sn ? sys_ ## __lname ## _peek_next_no_check(__sn)	\ | 
|  | : sys_ ## __lname ## _peek_head(__l);		\ | 
|  | __sn != NULL;						\ | 
|  | __sn = sys_ ## __lname ## _peek_next(__sn)) | 
|  |  | 
|  | #define Z_GENLIST_FOR_EACH_NODE_SAFE(__lname, __l, __sn, __sns)		\ | 
|  | for (__sn = sys_ ## __lname ## _peek_head(__l),			\ | 
|  | __sns = sys_ ## __lname ## _peek_next(__sn);	\ | 
|  | __sn != NULL ; __sn = __sns,				\ | 
|  | __sns = sys_ ## __lname ## _peek_next(__sn)) | 
|  |  | 
|  | #define Z_GENLIST_CONTAINER(__ln, __cn, __n)				\ | 
|  | ((__ln) ? CONTAINER_OF((__ln), __typeof__(*(__cn)), __n) : NULL) | 
|  |  | 
|  | #define Z_GENLIST_PEEK_HEAD_CONTAINER(__lname, __l, __cn, __n)		\ | 
|  | Z_GENLIST_CONTAINER(sys_ ## __lname ## _peek_head(__l), __cn, __n) | 
|  |  | 
|  | #define Z_GENLIST_PEEK_TAIL_CONTAINER(__lname, __l, __cn, __n)		\ | 
|  | Z_GENLIST_CONTAINER(sys_ ## __lname ## _peek_tail(__l), __cn, __n) | 
|  |  | 
|  | #define Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n)		\ | 
|  | ((__cn) ? Z_GENLIST_CONTAINER(					\ | 
|  | sys_ ## __lname ## _peek_next(&((__cn)->__n)),	\ | 
|  | __cn, __n) : NULL) | 
|  |  | 
|  | #define Z_GENLIST_FOR_EACH_CONTAINER(__lname, __l, __cn, __n)		\ | 
|  | for (__cn = Z_GENLIST_PEEK_HEAD_CONTAINER(__lname, __l, __cn,	\ | 
|  | __n);			\ | 
|  | __cn != NULL;						\ | 
|  | __cn = Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n)) | 
|  |  | 
|  | #define Z_GENLIST_FOR_EACH_CONTAINER_SAFE(__lname, __l, __cn, __cns, __n)     \ | 
|  | for (__cn = Z_GENLIST_PEEK_HEAD_CONTAINER(__lname, __l, __cn, __n),   \ | 
|  | __cns = Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n); \ | 
|  | __cn != NULL; __cn = __cns,				\ | 
|  | __cns = Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n)) | 
|  |  | 
|  | #define Z_GENLIST_IS_EMPTY(__lname)					\ | 
|  | static inline bool						\ | 
|  | sys_ ## __lname ## _is_empty(sys_ ## __lname ## _t *list)	\ | 
|  | {								\ | 
|  | return (sys_ ## __lname ## _peek_head(list) == NULL);	\ | 
|  | } | 
|  |  | 
|  | #define Z_GENLIST_PEEK_NEXT_NO_CHECK(__lname, __nname)			    \ | 
|  | static inline sys_ ## __nname ## _t *				    \ | 
|  | sys_ ## __lname ## _peek_next_no_check(sys_ ## __nname ## _t *node) \ | 
|  | {								    \ | 
|  | return z_ ## __nname ## _next_peek(node);		    \ | 
|  | } | 
|  |  | 
|  | #define Z_GENLIST_PEEK_NEXT(__lname, __nname)				     \ | 
|  | static inline sys_ ## __nname ## _t *				     \ | 
|  | sys_ ## __lname ## _peek_next(sys_ ## __nname ## _t *node)	     \ | 
|  | {								     \ | 
|  | return node != NULL ?                                        \ | 
|  | sys_ ## __lname ## _peek_next_no_check(node) :       \ | 
|  | NULL;					     \ | 
|  | } | 
|  |  | 
|  | #define Z_GENLIST_PREPEND(__lname, __nname)				      \ | 
|  | static inline void						      \ | 
|  | sys_ ## __lname ## _prepend(sys_ ## __lname ## _t *list,	      \ | 
|  | sys_ ## __nname ## _t *node)	      \ | 
|  | {								      \ | 
|  | z_ ## __nname ## _next_set(node,			      \ | 
|  | sys_ ## __lname ## _peek_head(list)); \ | 
|  | z_ ## __lname ## _head_set(list, node);			      \ | 
|  | \ | 
|  | if (sys_ ## __lname ## _peek_tail(list) == NULL) {	      \ | 
|  | z_ ## __lname ## _tail_set(list,		      \ | 
|  | sys_ ## __lname ## _peek_head(list)); \ | 
|  | }							      \ | 
|  | } | 
|  |  | 
|  | #define Z_GENLIST_APPEND(__lname, __nname)				\ | 
|  | static inline void						\ | 
|  | sys_ ## __lname ## _append(sys_ ## __lname ## _t *list,		\ | 
|  | sys_ ## __nname ## _t *node)		\ | 
|  | {								\ | 
|  | z_ ## __nname ## _next_set(node, NULL);			\ | 
|  | \ | 
|  | if (sys_ ## __lname ## _peek_tail(list) == NULL) {	\ | 
|  | z_ ## __lname ## _tail_set(list, node);		\ | 
|  | z_ ## __lname ## _head_set(list, node);		\ | 
|  | } else {						\ | 
|  | z_ ## __nname ## _next_set(			\ | 
|  | sys_ ## __lname ## _peek_tail(list),	\ | 
|  | node);					\ | 
|  | z_ ## __lname ## _tail_set(list, node);		\ | 
|  | }							\ | 
|  | } | 
|  |  | 
|  | #define Z_GENLIST_APPEND_LIST(__lname, __nname)				\ | 
|  | static inline void						\ | 
|  | sys_ ## __lname ## _append_list(sys_ ## __lname ## _t *list,	\ | 
|  | void *head, void *tail)		\ | 
|  | {									\ | 
|  | if (sys_ ## __lname ## _peek_tail(list) == NULL) {		\ | 
|  | z_ ## __lname ## _head_set(list,			\ | 
|  | (sys_ ## __nname ## _t *)head); \ | 
|  | } else {							\ | 
|  | z_ ## __nname ## _next_set(				\ | 
|  | sys_ ## __lname ## _peek_tail(list),		\ | 
|  | (sys_ ## __nname ## _t *)head);			\ | 
|  | }								\ | 
|  | z_ ## __lname ## _tail_set(list,				\ | 
|  | (sys_ ## __nname ## _t *)tail);	\ | 
|  | } | 
|  |  | 
|  | #define Z_GENLIST_MERGE_LIST(__lname, __nname)				\ | 
|  | static inline void						\ | 
|  | sys_ ## __lname ## _merge_ ## __lname (				\ | 
|  | sys_ ## __lname ## _t *list,		\ | 
|  | sys_ ## __lname ## _t *list_to_append)	\ | 
|  | {								\ | 
|  | sys_ ## __nname ## _t *head, *tail;			\ | 
|  | head = sys_ ## __lname ## _peek_head(list_to_append);	\ | 
|  | tail = sys_ ## __lname ## _peek_tail(list_to_append);	\ | 
|  | sys_ ## __lname ## _append_list(list, head, tail);	\ | 
|  | sys_ ## __lname ## _init(list_to_append);		\ | 
|  | } | 
|  |  | 
|  | #define Z_GENLIST_INSERT(__lname, __nname)				\ | 
|  | static inline void						\ | 
|  | sys_ ## __lname ## _insert(sys_ ## __lname ## _t *list,		\ | 
|  | sys_ ## __nname ## _t *prev,		\ | 
|  | sys_ ## __nname ## _t *node)		\ | 
|  | {								\ | 
|  | if (prev == NULL) {					\ | 
|  | sys_ ## __lname ## _prepend(list, node);	\ | 
|  | } else if (z_ ## __nname ## _next_peek(prev) == NULL) {	\ | 
|  | sys_ ## __lname ## _append(list, node);		\ | 
|  | } else {						\ | 
|  | z_ ## __nname ## _next_set(node,		\ | 
|  | z_ ## __nname ## _next_peek(prev));	\ | 
|  | z_ ## __nname ## _next_set(prev, node);		\ | 
|  | }							\ | 
|  | } | 
|  |  | 
|  | #define Z_GENLIST_GET_NOT_EMPTY(__lname, __nname)			\ | 
|  | static inline sys_ ## __nname ## _t *				\ | 
|  | sys_ ## __lname ## _get_not_empty(sys_ ## __lname ## _t *list)	\ | 
|  | {								\ | 
|  | sys_ ## __nname ## _t *node =				\ | 
|  | sys_ ## __lname ## _peek_head(list);	\ | 
|  | \ | 
|  | z_ ## __lname ## _head_set(list,			\ | 
|  | z_ ## __nname ## _next_peek(node));	\ | 
|  | if (sys_ ## __lname ## _peek_tail(list) == node) {	\ | 
|  | z_ ## __lname ## _tail_set(list,		\ | 
|  | sys_ ## __lname ## _peek_head(list));	\ | 
|  | }							\ | 
|  | \ | 
|  | return node;						\ | 
|  | } | 
|  |  | 
|  | #define Z_GENLIST_GET(__lname, __nname)					\ | 
|  | static inline sys_ ## __nname ## _t *				\ | 
|  | sys_ ## __lname ## _get(sys_ ## __lname ## _t *list)		\ | 
|  | {								\ | 
|  | return sys_ ## __lname ## _is_empty(list) ? NULL :	\ | 
|  | sys_ ## __lname ## _get_not_empty(list);	\ | 
|  | } | 
|  |  | 
|  | #define Z_GENLIST_REMOVE(__lname, __nname)				      \ | 
|  | static inline void						      \ | 
|  | sys_ ## __lname ## _remove(sys_ ## __lname ## _t *list,		      \ | 
|  | sys_ ## __nname ## _t *prev_node,	      \ | 
|  | sys_ ## __nname ## _t *node)		      \ | 
|  | {								      \ | 
|  | if (prev_node == NULL) {				      \ | 
|  | z_ ## __lname ## _head_set(list,		      \ | 
|  | z_ ## __nname ## _next_peek(node));	      \ | 
|  | \ | 
|  | /* Was node also the tail? */			      \ | 
|  | if (sys_ ## __lname ## _peek_tail(list) == node) {    \ | 
|  | z_ ## __lname ## _tail_set(list,	      \ | 
|  | sys_ ## __lname ## _peek_head(list)); \ | 
|  | }						      \ | 
|  | } else {						      \ | 
|  | z_ ## __nname ## _next_set(prev_node,		      \ | 
|  | z_ ## __nname ## _next_peek(node));	      \ | 
|  | \ | 
|  | /* Was node the tail? */			      \ | 
|  | if (sys_ ## __lname ## _peek_tail(list) == node) {    \ | 
|  | z_ ## __lname ## _tail_set(list,	      \ | 
|  | prev_node);      \ | 
|  | }						      \ | 
|  | }							      \ | 
|  | \ | 
|  | z_ ## __nname ## _next_set(node, NULL);			      \ | 
|  | } | 
|  |  | 
|  | #define Z_GENLIST_FIND_AND_REMOVE(__lname, __nname)			 \ | 
|  | static inline bool						 \ | 
|  | sys_ ## __lname ## _find_and_remove(sys_ ## __lname ## _t *list, \ | 
|  | sys_ ## __nname ## _t *node) \ | 
|  | {								 \ | 
|  | sys_ ## __nname ## _t *prev = NULL;			 \ | 
|  | sys_ ## __nname ## _t *test;				 \ | 
|  | \ | 
|  | Z_GENLIST_FOR_EACH_NODE(__lname, list, test) {		 \ | 
|  | if (test == node) {				 \ | 
|  | sys_ ## __lname ## _remove(list, prev,	 \ | 
|  | node);	 \ | 
|  | return true;				 \ | 
|  | }						 \ | 
|  | \ | 
|  | prev = test;					 \ | 
|  | }							 \ | 
|  | \ | 
|  | return false;						 \ | 
|  | } | 
|  |  | 
|  | #endif /* ZEPHYR_INCLUDE_SYS_LIST_GEN_H_ */ |