#ifndef __CONSOLE_SLIST_H__
#define __CONSOLE_SLIST_H__

#include <stdbool.h>

struct stc_slist {
    struct stc_slist *next;
};
typedef struct stc_slist stc_slist_t;

static inline bool slist_empty(const stc_slist_t *head)
{
    return (NULL == head->next);
}

static inline void slist_del(stc_slist_t *head, stc_slist_t *node)
{
    while ((head->next != NULL) && (head->next != node)) {
        head = head->next;
    }

    if (head->next == node) {
        head->next = head->next->next;
    }
}

static inline void slist_add_head(stc_slist_t *head, stc_slist_t *node)
{
    node->next = head->next;
    head->next = node;
}

static inline void slist_add_tail(stc_slist_t *head, stc_slist_t *node)
{
    while (NULL != head->next) {
        head = head->next;
    }

    head->next = node;
    node->next = NULL;
}

#define INIT_SLIST_HEAD(ptr) ((ptr)->next = NULL)

#define container_of(ptr, type, member) \
    ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))

#define slist_entry(ptr, type, member) container_of(ptr,type,member)

#define slist_for_each(pos, head) \
    for (pos = (head)->next; (pos != NULL); pos = pos->next)

#define slist_for_each_safe(pos, prev, next, head) \
    for (pos = (head)->next, prev = (head); \
         (pos != NULL) && ({ next = pos->next; 1; }); \
         ({ prev = (prev->next != next) ? prev->next : prev; }), pos = next)

#endif /* __CONSOLE_SLIST_H__ */
