summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2018-09-18 11:05:20 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2018-09-19 08:06:57 +0900
commitf0f6d791feee4ed4c34624228e6ced8a231b5811 (patch)
tree3e296afceb9e0091701179bcbaa834ec4e0dbf00
parentba0a7bfb983305ac7f86db1e7bbfeb456e11bbd8 (diff)
downloadsystemd-f0f6d791feee4ed4c34624228e6ced8a231b5811.tar.gz
systemd-f0f6d791feee4ed4c34624228e6ced8a231b5811.tar.bz2
systemd-f0f6d791feee4ed4c34624228e6ced8a231b5811.zip
util: introduce typesafe_bsearch() and typesafe_bsearch_r()
-rw-r--r--src/basic/util.c2
-rw-r--r--src/basic/util.h19
2 files changed, 17 insertions, 4 deletions
diff --git a/src/basic/util.c b/src/basic/util.c
index f951d641d7..081c63c898 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -133,7 +133,7 @@ void in_initrd_force(bool value) {
/* 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) {
+ __compar_d_fn_t compar, void *arg) {
size_t l, u, idx;
const void *p;
int comparison;
diff --git a/src/basic/util.h b/src/basic/util.h
index a6e77980a1..5f3f982190 100644
--- a/src/basic/util.h
+++ b/src/basic/util.h
@@ -68,15 +68,21 @@ bool in_initrd(void);
void in_initrd_force(bool value);
void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
- int (*compar) (const void *, const void *, void *),
- void *arg);
+ __compar_d_fn_t compar, void *arg);
+
+#define typesafe_bsearch_r(k, b, n, func, userdata) \
+ ({ \
+ const typeof(b[0]) *_k = k; \
+ int (*_func_)(const typeof(b[0])*, const typeof(b[0])*, typeof(userdata)) = func; \
+ xbsearch_r((const void*) _k, (b), (n), sizeof((b)[0]), (__compar_d_fn_t) _func_, userdata); \
+ })
/**
* Normal bsearch requires base to be nonnull. Here were require
* that only if nmemb > 0.
*/
static inline void* bsearch_safe(const void *key, const void *base,
- size_t nmemb, size_t size, comparison_fn_t compar) {
+ size_t nmemb, size_t size, __compar_fn_t compar) {
if (nmemb <= 0)
return NULL;
@@ -84,6 +90,13 @@ static inline void* bsearch_safe(const void *key, const void *base,
return bsearch(key, base, nmemb, size, compar);
}
+#define typesafe_bsearch(k, b, n, func) \
+ ({ \
+ const typeof(b[0]) *_k = k; \
+ int (*_func_)(const typeof(b[0])*, const typeof(b[0])*) = func; \
+ bsearch_safe((const void*) _k, (b), (n), sizeof((b)[0]), (__compar_fn_t) _func_); \
+ })
+
/**
* Normal qsort requires base to be nonnull. Here were require
* that only if nmemb > 0.