Created
January 3, 2019 06:04
-
-
Save nnathan/ce79b21797513fc41b9e71a350a1ae0b to your computer and use it in GitHub Desktop.
Understanding BSD queue.h single linked list implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* See queue(3) or https://www.freebsd.org/cgi/man.cgi?query=queue&sektion=3 for reference. | |
*/ | |
#include <stdio.h> | |
#include <sys/queue.h> | |
struct Pattern { | |
char name[100]; | |
/* Following expands to: | |
* struct { struct Pattern *sle_next; } entries; | |
*/ | |
SLIST_ENTRY(Pattern) entries; | |
}; | |
int main(int argc, char **argv) { | |
/* Following expands to | |
* struct yylisthead { struct Pattern *slh_first; } head = { ((void *)0) }; | |
*/ | |
SLIST_HEAD(yylisthead, Pattern) head = SLIST_HEAD_INITIALIZER(head); | |
/* Following expands to | |
* do { (((&head))->slh_first) = ((void *)0); } while (0); | |
* which can be simplified to: | |
* (&head)->slh_first = NULL; | |
*/ | |
SLIST_INIT(&head); | |
struct Pattern p1 = { .name = "A", .entries = { NULL } }; | |
/* Following expands to | |
* do { (((&p1))->entries.sle_next) = (((&head))->slh_first); (((&head))->slh_first) = (&p1); } while (0); | |
* which can be simplified to: | |
* (&p1)->entries.sle_next = (&head)->slh_first; (&head)->slh_first = (&p1) | |
*/ | |
SLIST_INSERT_HEAD(&head, &p1, entries); | |
struct Pattern *e; | |
/* Following expands to | |
* for ((e) = (((&head))->slh_first); (e); (e) = (((e))->entries.sle_next)) | |
* which can be simplified to: | |
* for (e = (&head)->slh_first; e != NULL; e = e->entries.sle_next) | |
*/ | |
SLIST_FOREACH(e, &head, entries) { | |
printf("1\tname: %s\n", e->name); | |
} | |
puts(""); | |
struct Pattern p3 = { .name = "C", .entries = { NULL } }; | |
SLIST_INSERT_HEAD(&head, &p3, entries); | |
SLIST_FOREACH(e, &head, entries) { | |
printf("2\tname: %s\n", e->name); | |
} | |
puts(""); | |
struct Pattern p2 = { .name = "B", .entries = { NULL } }; | |
SLIST_INSERT_AFTER(&p3, &p2, entries); | |
SLIST_FOREACH(e, &head, entries) { | |
printf("3\tname: %s\n", e->name); | |
} | |
puts(""); | |
struct Pattern *etmp; | |
/* Following expands to | |
* for ((e) = (((&head))->slh_first); (e) && ((etmp) = (((e))->entries.sle_next), 1); (e) = (etmp)) | |
* which can be simplified to: | |
* for (e = (&head)->slh_first; (e != NULL) && (etmp = e->entries.sle_next, 1); e = etmp) | |
*/ | |
SLIST_FOREACH_SAFE(e, &head, entries, etmp) { | |
if (e == &p2) { | |
/* Following expands to | |
* do { | |
* if ((((&head))->slh_first) == (e)) { | |
* do { | |
* ((((&head)))->slh_first) = ((((((&head)))->slh_first))->entries.sle_next); | |
* } while (0); | |
* } else { | |
* struct Pattern *curelm = (((&head))->slh_first); | |
* while (((curelm)->entries.sle_next) != (e)) | |
* curelm = ((curelm)->entries.sle_next); | |
* do { | |
* ((curelm)->entries.sle_next) = ((((curelm)->entries.sle_next))->entries.sle_next); | |
* } while (0); | |
* }; | |
* } while (0) ; | |
* which can be simplified to: | |
* if (&head)->slh_first == e { | |
* (&head)->slh_first = (&head)->slh_first->entries.sle_next; | |
* } else { | |
* struct Pattern *curelm = (&head)->slh_first; | |
* while (curelm->entries.sle_next != e) | |
* curelm = curelm->entries.sle_next; | |
* curelm->entries.sle_next = curelm->entries.sle_next->entries.sle_next; | |
* }; | |
*/ | |
SLIST_REMOVE(&head, &p2, Pattern, entries); | |
continue; | |
} | |
printf("4\tname: %s\n", e->name); | |
} | |
/* Following expands to | |
* while (!((&head)->slh_first == ((void *)0))) | |
* which can be simplified to: | |
* while ((&head)->slh_first != NULL) | |
*/ | |
while (!SLIST_EMPTY(&head)) { | |
/* Following expands to | |
* e = ((&head)->slh_first); | |
* which can be simplified to: | |
* e = (&head)->slh_first; | |
*/ | |
e = SLIST_FIRST(&head); | |
/* Following expands to | |
* do { (((&head))->slh_first) = (((((&head))->slh_first))->entries.sle_next); } while (0); | |
* which can be simplified to: | |
* (&head)->slh_first = (&head)->slh_first->entries.sle_next; | |
*/ | |
SLIST_REMOVE_HEAD(&head, entries); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment