[libc-commits] [libc] [libc] Provide sys/queue.h (PR #78081)

Nick Desaulniers via libc-commits libc-commits at lists.llvm.org
Thu Jan 18 08:48:37 PST 2024


================
@@ -0,0 +1,260 @@
+//===-- Macros defined in sys/queue.h header file -------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __LLVM_LIBC_MACROS_SYS_QUEUE_MACROS_H
+#define __LLVM_LIBC_MACROS_SYS_QUEUE_MACROS_H
+
+#include <llvm-libc-macros/containerof-macro.h>
+#include <llvm-libc-macros/null-macro.h>
+
+#ifdef __cplusplus
+#define QUEUE_TYPEOF(type) type
+#else
+#define QUEUE_TYPEOF(type) struct type
+#endif
+
+// Singly-linked list definitions.
+
+#define SLIST_HEAD(name, type)                                                 \
+  struct name {                                                                \
+    struct type *first;                                                        \
+  }
+
+#define SLIST_CLASS_HEAD(name, type)                                           \
+  struct name {                                                                \
+    class type *first;                                                         \
+  }
+
+#define SLIST_HEAD_INITIALIZER(head)                                           \
+  { NULL }
+
+#define SLIST_ENTRY(type)                                                      \
+  struct {                                                                     \
+    struct type *next;                                                         \
+  }
+
+#define SLIST_CLASS_ENTRY(type)                                                \
+  struct {                                                                     \
+    class type *next;                                                          \
+  }
+
+// Singly-linked list access methods.
+
+#define SLIST_EMPTY(head) ((head)->first == NULL)
+#define SLIST_FIRST(head) ((head)->first)
+#define SLIST_NEXT(elem, field) ((elem)->field.next)
+
+#define SLIST_FOREACH(var, head, field)                                        \
+  for ((var) = SLIST_FIRST(head); (var); (var) = SLIST_NEXT(var, field))
+
+#define SLIST_FOREACH_FROM(var, head, field)                                   \
+  if (!(var))                                                                  \
+    (var) = SLIST_FIRST(head);                                                 \
+  for (; (var); (var) = SLIST_NEXT(var, field))
+
+#define SLIST_FOREACH_SAFE(var, head, field, tvar)                             \
+  for ((var) = SLIST_FIRST(head);                                              \
+       (var) && ((tvar) = SLIST_NEXT(var, field), 1); (var) = (tvar))
+
+#define SLIST_FOREACH_FROM_SAFE(var, head, field, tvar)                        \
+  if (!(var))                                                                  \
+    (var) = SLIST_FIRST(head);                                                 \
+  for (; (var) && ((tvar) = SLIST_NEXT(var, field), 1); (var) = (tvar))
+
+// Singly-linked list functions.
+
+#define SLIST_CONCAT(head1, head2, type, field)                                \
+  do {                                                                         \
+    if (SLIST_EMPTY(head1)) {                                                  \
+      if ((SLIST_FIRST(head1) = SLIST_FIRST(head2)) != NULL)                   \
+        SLIST_INIT(head2);                                                     \
+    } else if (!SLIST_EMPTY(head2)) {                                          \
+      QUEUE_TYPEOF(type) *cur = SLIST_FIRST(head1);                            \
+      while (SLIST_NEXT(cur, field) != NULL)                                   \
+        cur = SLIST_NEXT(cur, field);                                          \
+      SLIST_NEXT(cur, field) = SLIST_FIRST(head2);                             \
+      SLIST_INIT(head2);                                                       \
+    }                                                                          \
+  } while (0)
+
+#define SLIST_INIT(head)                                                       \
+  do {                                                                         \
+    SLIST_FIRST(head) = NULL;                                                  \
+  } while (0)
+
+#define SLIST_INSERT_AFTER(slistelem, elem, field)                             \
+  do {                                                                         \
+    SLIST_NEXT(elem, field) = SLIST_NEXT(slistelem, field);                    \
+    SLIST_NEXT(slistelem, field) = (elem);                                     \
+  } while (0)
+
+#define SLIST_INSERT_HEAD(head, elem, field)                                   \
+  do {                                                                         \
+    SLIST_NEXT(elem, field) = SLIST_FIRST(head);                               \
+    SLIST_FIRST(head) = (elem);                                                \
+  } while (0)
+
+#define SLIST_REMOVE(head, elem, type, field)                                  \
+  do {                                                                         \
+    if (SLIST_FIRST(head) == (elem)) {                                         \
+      SLIST_REMOVE_HEAD(head, field);                                          \
+    } else {                                                                   \
+      QUEUE_TYPEOF(type) *cur = SLIST_FIRST(head);                             \
+      while (SLIST_NEXT(elem, field) != (elem))                                \
----------------
nickdesaulniers wrote:

I think this should also be
```c
while (SLIST_NEXT(cur, field) != (elem)) \
```

https://github.com/llvm/llvm-project/pull/78081


More information about the libc-commits mailing list