/* * Copyright (c) 2018 naehrwert * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef _LIST_H_ #define _LIST_H_ #include "types.h" /*! Initialize list. */ #define LIST_INIT(name) link_t name = {&name, &name} /*! Initialize static list. */ #define LIST_INIT_STATIC(name) static link_t name = {&name, &name} /*! Iterate over all list links. */ #define LIST_FOREACH(iter, list) \ for(link_t *iter = (list)->next; iter != (list); iter = iter->next) /*! Safely iterate over all list links. */ #define LIST_FOREACH_SAFE(iter, list) \ for(link_t *iter = (list)->next, *safe = iter->next; iter != (list); iter = safe, safe = iter->next) /*! Iterate over all list members. */ #define LIST_FOREACH_ENTRY(etype, iter, list, mn) \ for(etype *iter = CONTAINER_OF((list)->next, etype, mn); &iter->mn != (list); iter = CONTAINER_OF(iter->mn.next, etype, mn)) typedef struct _link_t { struct _link_t *prev; struct _link_t *next; } link_t; static inline void link_init(link_t *l) { l->prev = NULL; l->next = NULL; } static inline int link_used(link_t *l) { if(l->next == NULL) return 1; return 0; } static inline void list_init(link_t *lh) { lh->prev = lh; lh->next = lh; } static inline void list_prepend(link_t *lh, link_t *l) { l->next = lh->next; l->prev = lh; lh->next->prev = l; lh->next = l; } static inline void list_append(link_t *lh, link_t *l) { l->prev = lh->prev; l->next = lh; lh->prev->next = l; lh->prev = l; } static inline void list_remove(link_t *l) { l->next->prev = l->prev; l->prev->next = l->next; link_init(l); } static inline int list_empty(link_t *lh) { if(lh->next == lh) return 1; return 0; } #endif