diff options
Diffstat (limited to 'rainbow/nss/slist.h')
-rw-r--r-- | rainbow/nss/slist.h | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/rainbow/nss/slist.h b/rainbow/nss/slist.h new file mode 100644 index 0000000..aaccd41 --- /dev/null +++ b/rainbow/nss/slist.h @@ -0,0 +1,50 @@ + +struct slist { struct slist *next; }; + +void slist_init(struct slist* self); +bool slist_null(struct slist* self); +bool slist_non_null(struct slist* self); +size_t slist_length(struct slist* self); +void slist_extend(struct slist* self, struct slist* rhs); + +/* Definition from kernel/include/list.h */ +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) + +/* Definition from kernel/include/list.h */ +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +/* FUN should return false to break iteration. */ +/* NB: Comma-swallowing paste of gnu-style named variadic macro argument. */ +#define slist_search(TYPE, MEMBER, PTR, FOUND_LABEL, NOTFOUND_LABEL, FUN, COOKIE...) ({ \ + struct slist *__slist_iter = ((PTR)->MEMBER).next; \ + struct slist *__slist_next; \ + while(__slist_iter != &((PTR)->MEMBER)) { \ + __slist_next = __slist_iter->next; \ + TYPE* __value_ptr = container_of(__slist_iter, TYPE, MEMBER); \ + if(!(*(FUN))(__value_ptr, ##COOKIE)) goto FOUND_LABEL; \ + __slist_iter = __slist_next; \ + } \ + goto NOTFOUND_LABEL; }) + +#define slist_while(TYPE, MEMBER, PTR, ERR_LABEL, FUN, COOKIE...) ({ \ + struct slist *__slist_iter = ((PTR)->MEMBER).next; \ + struct slist *__slist_next; \ + while(__slist_iter != &((PTR)->MEMBER)) { \ + __slist_next = __slist_iter->next; \ + TYPE* __value_ptr = container_of(__slist_iter, TYPE, MEMBER); \ + if((*(FUN))(__value_ptr, ##COOKIE)) goto ERR_LABEL; \ + __slist_iter = __slist_next; \ + } \ + }) + +#define slist_for(TYPE, MEMBER, PTR, FUN, COOKIE...) ({ \ + struct slist *__slist_iter = ((PTR)->MEMBER).next; \ + struct slist *__slist_next; \ + while(__slist_iter != &((PTR)->MEMBER)) { \ + __slist_next = __slist_iter->next; \ + TYPE* __value_ptr = container_of(__slist_iter, TYPE, MEMBER); \ + (*(FUN))(__value_ptr, ##COOKIE); \ + __slist_iter = __slist_next; \ + } }) |