lib/search/, lib/, src/: Add a type parameter to the type-safe macros

This simplifies the implementation, allowing us to use _Generic(3) to
replace _Static_assert(3), is_same_type(), and local variables.

Local variables in macros can cause issues when nesting such macros.

This also makes the code more readable, by having the type explicitly
stated at call site.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
This commit is contained in:
Alejandro Colomar 2025-11-14 01:20:41 +01:00 committed by Serge Hallyn
parent 97380c811a
commit f45082a1e9
6 changed files with 18 additions and 32 deletions

View File

@ -61,7 +61,7 @@ add_groups(const char *list)
continue;
}
LSEARCH(&grp->gr_gid, gids, &n);
LSEARCH(gid_t, &grp->gr_gid, gids, &n);
}
free(dup);

View File

@ -55,7 +55,7 @@ addslN(size_t n, long addend[n])
e = errno;
while (n > 1) {
QSORT(addend, n);
QSORT(long, addend, n);
errno = 0;
addend[0] = addsl2(addend[0], addend[--n]);

View File

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
@ -12,19 +12,13 @@
#include <stddef.h>
#include "search/cmp/cmp.h"
#include "typetraits.h"
#include <assert.h>
#define LFIND(k, a, n) \
#define LFIND(T, k, a, n) \
({ \
__auto_type k_ = k; \
__auto_type a_ = a; \
\
static_assert(is_same_typeof(k_, a_), ""); \
\
(typeof(k_)) lfind_(k_, a_, n, sizeof(*k_), CMP(typeof(k_))); \
_Generic(k, T *: 0, const T *: 0); \
_Generic(a, T *: 0, const T *: 0); \
(T *) lfind_(k, a, n, sizeof(T), CMP(T *)); \
})

View File

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
@ -11,19 +11,13 @@
#include <search.h>
#include "search/cmp/cmp.h"
#include "typetraits.h"
#include <assert.h>
#define LSEARCH(k, a, n) \
#define LSEARCH(T, k, a, n) \
({ \
__auto_type k_ = k; \
__auto_type a_ = a; \
\
static_assert(is_same_typeof(k_, a_), ""); \
\
(typeof(k_)) lsearch(k_, a_, n, sizeof(*k_), CMP(typeof(k_)));\
_Generic(k, T *: 0, const T *: 0); \
_Generic(a, T *: 0); \
(T *) lsearch(k, a, n, sizeof(T), CMP(T *)); \
})

View File

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
@ -11,14 +11,12 @@
#include <stdlib.h>
#include "search/cmp/cmp.h"
#include "typetraits.h"
#define QSORT(a, n) do \
#define QSORT(T, a, n) do \
{ \
__auto_type p_ = a; \
\
qsort(p_, n, sizeof(*p_), CMP(typeof(p_))); \
_Generic(a, T *: 0); \
qsort(a, n, sizeof(T), CMP(T *)); \
} while (0)

View File

@ -619,7 +619,7 @@ int main (int argc, char **argv)
* database. However getgroups() will return the group. So
* if she is listed there already it is ok to grant membership.
*/
is_member = (LFIND(&grp->gr_gid, gids, ngroups) != NULL);
is_member = (LFIND(gid_t, &grp->gr_gid, gids, ngroups) != NULL);
/*
* For split groups (due to limitations of NIS), check all
@ -673,7 +673,7 @@ int main (int argc, char **argv)
*/
gids = XREALLOC(gids, ngroups + 1, gid_t);
LSEARCH(&gid, gids, &ngroups);
LSEARCH(gid_t, &gid, gids, &ngroups);
if (setgroups(ngroups, gids) == -1)
perror("setgroups");