diff options
author | Kay Sievers <kay@vrfy.org> | 2012-10-22 14:31:46 +0200 |
---|---|---|
committer | Kay Sievers <kay@vrfy.org> | 2012-10-22 14:31:46 +0200 |
commit | a9e12476ed32256690eb801099c41526834b6390 (patch) | |
tree | 73d95988cc9bb4078e2b4c8695be3f3bb9a4c578 | |
parent | 1d870ac769c70bae86fed63d9c5a1c42d2af9da3 (diff) |
util: add (x)bsearch_r(), the missing counterpart of qsort_r()
-rw-r--r-- | src/shared/util.c | 24 | ||||
-rw-r--r-- | src/shared/util.h | 4 |
2 files changed, 28 insertions, 0 deletions
diff --git a/src/shared/util.c b/src/shared/util.c index 42a2e27308..2f0aba88ae 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -6069,3 +6069,27 @@ finish: return 0; } + +/* hey glibc, APIs with callbacks without a user pointer are so useless */ +void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size, + int (*compar) (const void *, const void *, void *), + void *arg) { + size_t l, u, idx; + const void *p; + int comparison; + + l = 0; + u = nmemb; + while (l < u) { + idx = (l + u) / 2; + p = (void *)(((const char *) base) + (idx * size)); + comparison = compar(key, p, arg); + if (comparison < 0) + u = idx; + else if (comparison > 0) + l = idx + 1; + else + return (void *)p; + } + return NULL; +} diff --git a/src/shared/util.h b/src/shared/util.h index 77d28751f0..a9c39b867e 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -563,3 +563,7 @@ bool filename_is_safe(const char *p); bool string_is_safe(const char *p); int parse_timestamp(const char *t, usec_t *usec); + +void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size, + int (*compar) (const void *, const void *, void *), + void *arg); |