From d60b2108307dccdc596d1bf3195f6882067e2b2f Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sun, 20 Jan 2013 22:49:58 +1100 Subject: [PATCH] - (djm) [openbsd-compat/sys-tree.h] Sync with OpenBSD. krl.c needs newer version. --- ChangeLog | 2 + krl.c | 4 +- openbsd-compat/sys-tree.h | 109 +++++++++++++++++++++++++++++++------- 3 files changed, 94 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index 43cedb63e..7bc6b451c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -24,6 +24,8 @@ - markus@cvs.openbsd.org 2013/01/19 12:34:55 [krl.c] RB_INSERT does not remove existing elments; ok djm@ + - (djm) [openbsd-compat/sys-tree.h] Sync with OpenBSD. krl.c needs newer + version. 20130118 - (djm) OpenBSD CVS Sync diff --git a/krl.c b/krl.c index b09f2dc11..fe22bde25 100644 --- a/krl.c +++ b/krl.c @@ -20,8 +20,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/openbsd-compat/sys-tree.h b/openbsd-compat/sys-tree.h index d4949b5e7..058fa3b23 100644 --- a/openbsd-compat/sys-tree.h +++ b/openbsd-compat/sys-tree.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tree.h,v 1.10 2007/10/29 23:49:41 djm Exp $ */ +/* $OpenBSD: tree.h,v 1.13 2011/07/09 00:19:45 pirofti Exp $ */ /* * Copyright 2002 Niels Provos * All rights reserved. @@ -331,7 +331,7 @@ struct { \ } while (0) #ifndef RB_AUGMENT -#define RB_AUGMENT(x) +#define RB_AUGMENT(x) do {} while (0) #endif #define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ @@ -375,21 +375,31 @@ struct { \ } while (0) /* Generates prototypes and inline functions */ -#define RB_PROTOTYPE(name, type, field, cmp) \ -void name##_RB_INSERT_COLOR(struct name *, struct type *); \ -void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ -struct type *name##_RB_REMOVE(struct name *, struct type *); \ -struct type *name##_RB_INSERT(struct name *, struct type *); \ -struct type *name##_RB_FIND(struct name *, struct type *); \ -struct type *name##_RB_NEXT(struct type *); \ -struct type *name##_RB_MINMAX(struct name *, int); - +#define RB_PROTOTYPE(name, type, field, cmp) \ + RB_PROTOTYPE_INTERNAL(name, type, field, cmp,) +#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \ + RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static) +#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \ +attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \ +attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ +attr struct type *name##_RB_REMOVE(struct name *, struct type *); \ +attr struct type *name##_RB_INSERT(struct name *, struct type *); \ +attr struct type *name##_RB_FIND(struct name *, struct type *); \ +attr struct type *name##_RB_NFIND(struct name *, struct type *); \ +attr struct type *name##_RB_NEXT(struct type *); \ +attr struct type *name##_RB_PREV(struct type *); \ +attr struct type *name##_RB_MINMAX(struct name *, int); \ + \ /* Main rb operation. * Moves node close to the key of elm to top */ -#define RB_GENERATE(name, type, field, cmp) \ -void \ +#define RB_GENERATE(name, type, field, cmp) \ + RB_GENERATE_INTERNAL(name, type, field, cmp,) +#define RB_GENERATE_STATIC(name, type, field, cmp) \ + RB_GENERATE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static) +#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \ +attr void \ name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ { \ struct type *parent, *gparent, *tmp; \ @@ -433,7 +443,7 @@ name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ RB_COLOR(head->rbh_root, field) = RB_BLACK; \ } \ \ -void \ +attr void \ name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \ { \ struct type *tmp; \ @@ -509,7 +519,7 @@ name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) RB_COLOR(elm, field) = RB_BLACK; \ } \ \ -struct type * \ +attr struct type * \ name##_RB_REMOVE(struct name *head, struct type *elm) \ { \ struct type *child, *parent, *old = elm; \ @@ -577,7 +587,7 @@ color: \ } \ \ /* Inserts a node into the RB tree */ \ -struct type * \ +attr struct type * \ name##_RB_INSERT(struct name *head, struct type *elm) \ { \ struct type *tmp; \ @@ -608,7 +618,7 @@ name##_RB_INSERT(struct name *head, struct type *elm) \ } \ \ /* Finds the node with the same key as elm */ \ -struct type * \ +attr struct type * \ name##_RB_FIND(struct name *head, struct type *elm) \ { \ struct type *tmp = RB_ROOT(head); \ @@ -625,7 +635,29 @@ name##_RB_FIND(struct name *head, struct type *elm) \ return (NULL); \ } \ \ -struct type * \ +/* Finds the first node greater than or equal to the search key */ \ +attr struct type * \ +name##_RB_NFIND(struct name *head, struct type *elm) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + struct type *res = NULL; \ + int comp; \ + while (tmp) { \ + comp = cmp(elm, tmp); \ + if (comp < 0) { \ + res = tmp; \ + tmp = RB_LEFT(tmp, field); \ + } \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + return (res); \ +} \ + \ +/* ARGSUSED */ \ +attr struct type * \ name##_RB_NEXT(struct type *elm) \ { \ if (RB_RIGHT(elm, field)) { \ @@ -646,7 +678,29 @@ name##_RB_NEXT(struct type *elm) \ return (elm); \ } \ \ -struct type * \ +/* ARGSUSED */ \ +attr struct type * \ +name##_RB_PREV(struct type *elm) \ +{ \ + if (RB_LEFT(elm, field)) { \ + elm = RB_LEFT(elm, field); \ + while (RB_RIGHT(elm, field)) \ + elm = RB_RIGHT(elm, field); \ + } else { \ + if (RB_PARENT(elm, field) && \ + (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \ + elm = RB_PARENT(elm, field); \ + else { \ + while (RB_PARENT(elm, field) && \ + (elm == RB_LEFT(RB_PARENT(elm, field), field)))\ + elm = RB_PARENT(elm, field); \ + elm = RB_PARENT(elm, field); \ + } \ + } \ + return (elm); \ +} \ + \ +attr struct type * \ name##_RB_MINMAX(struct name *head, int val) \ { \ struct type *tmp = RB_ROOT(head); \ @@ -667,7 +721,9 @@ name##_RB_MINMAX(struct name *head, int val) \ #define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) #define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) #define RB_FIND(name, x, y) name##_RB_FIND(x, y) +#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y) #define RB_NEXT(name, x, y) name##_RB_NEXT(y) +#define RB_PREV(name, x, y) name##_RB_PREV(y) #define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) #define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) @@ -676,4 +732,19 @@ name##_RB_MINMAX(struct name *head, int val) \ (x) != NULL; \ (x) = name##_RB_NEXT(x)) +#define RB_FOREACH_SAFE(x, name, head, y) \ + for ((x) = RB_MIN(name, head); \ + ((x) != NULL) && ((y) = name##_RB_NEXT(x), 1); \ + (x) = (y)) + +#define RB_FOREACH_REVERSE(x, name, head) \ + for ((x) = RB_MAX(name, head); \ + (x) != NULL; \ + (x) = name##_RB_PREV(x)) + +#define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \ + for ((x) = RB_MAX(name, head); \ + ((x) != NULL) && ((y) = name##_RB_PREV(x), 1); \ + (x) = (y)) + #endif /* _SYS_TREE_H_ */