Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/rainbow/nss/slist.h
diff options
context:
space:
mode:
Diffstat (limited to 'rainbow/nss/slist.h')
-rw-r--r--rainbow/nss/slist.h50
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; \
+ } })