/* SPDX-License-Identifier: LGPL-2.1-or-later */ #include #include "alloc-util.h" #include "sort-util.h" /* 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, comparison_userdata_fn_t compar, void *arg) { size_t l, u, idx; const void *p; int comparison; assert(!size_multiply_overflow(nmemb, size)); l = 0; u = nmemb; while (l < u) { idx = (l + u) / 2; p = (const uint8_t*) 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; } void* bsearch_safe(const void *key, const void *base, size_t nmemb, size_t size, comparison_fn_t compar) { /** * Normal bsearch requires base to be nonnull. Here were require * that only if nmemb > 0. */ if (nmemb <= 0) return NULL; assert(base); return bsearch(key, base, nmemb, size, compar); } void qsort_safe(void *base, size_t nmemb, size_t size, comparison_fn_t compar) { /** * Normal qsort requires base to be nonnull. Here were require * that only if nmemb > 0. */ if (nmemb <= 1) return; assert(base); qsort(base, nmemb, size, compar); } void qsort_r_safe(void *base, size_t nmemb, size_t size, comparison_userdata_fn_t compar, void *userdata) { if (nmemb <= 1) return; assert(base); qsort_r(base, nmemb, size, compar, userdata); } int cmp_int(const int *a, const int *b) { return CMP(*a, *b); } int cmp_uint16(const uint16_t *a, const uint16_t *b) { return CMP(*a, *b); }