]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
Add bit manipulation functions
authorAlejandro Colomar <alx@kernel.org>
Fri, 30 Dec 2022 22:00:14 +0000 (23:00 +0100)
committerSerge Hallyn <serge@hallyn.com>
Sat, 28 Jan 2023 03:48:37 +0000 (21:48 -0600)
These functions implement bit manipulation APIs, which will be added to
C23, so that in the far future, we will be able to replace our functions
by the standard ones, just by adding the stdc_ prefix, and including
<stdbit.h>.

However, we need to avoid UB for an input of 0, so slightly deviate from
C23, and use a different name (with _wrap) for distunguishing our API
from the standard one.

Cc: Joseph Myers <joseph@codesourcery.com>
Cc: Yann Droneaud <ydroneaud@opteya.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
lib/bit.h [new file with mode: 0644]
libmisc/Makefile.am
libmisc/bit.c [new file with mode: 0644]

diff --git a/lib/bit.h b/lib/bit.h
new file mode 100644 (file)
index 0000000..2469255
--- /dev/null
+++ b/lib/bit.h
@@ -0,0 +1,41 @@
+/*
+ * SPDX-FileCopyrightText:  Alejandro Colomar <alx@kernel.org>
+ *
+ * SPDX-License-Identifier:  BSD-3-Clause
+ */
+
+
+#ifndef SHADOW_INCLUDE_LIB_BIT_H_
+#define SHADOW_INCLUDE_LIB_BIT_H_
+
+
+#include <config.h>
+
+#ident "$Id$"
+
+#include <limits.h>
+
+
+inline unsigned long bit_ceil_wrapul(unsigned long x);
+inline int leading_zerosul(unsigned long x);
+
+
+/* stdc_bit_ceilul(3), but wrap instead of having Undefined Behavior */
+inline unsigned long
+bit_ceil_wrapul(unsigned long x)
+{
+       if (x == 0)
+               return 0;
+
+       return 1 + (ULONG_MAX >> leading_zerosul(x));
+}
+
+/* stdc_leading_zerosul(3) */
+inline int
+leading_zerosul(unsigned long x)
+{
+       return (x == 0) ? ULONG_WIDTH : __builtin_clz(x);
+}
+
+
+#endif  // include guard
index b4ca708d7ae05eb50c9aedeebca65b538f6377b6..ab363f549623cfc44519a84c5e0086fe0b2c34c5 100644 (file)
@@ -12,6 +12,7 @@ libmisc_la_SOURCES = \
        agetpass.c \
        audit_help.c \
        basename.c \
+       bit.c \
        chkname.c \
        chkname.h \
        chowndir.c \
diff --git a/libmisc/bit.c b/libmisc/bit.c
new file mode 100644 (file)
index 0000000..39efd56
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * SPDX-FileCopyrightText:  Alejandro Colomar <alx@kernel.org>
+ *
+ * SPDX-License-Identifier:  BSD-3-Clause
+ */
+
+
+#include <config.h>
+
+#ident "$Id$"
+
+#include "bit.h"
+
+#include <limits.h>
+
+
+extern inline unsigned long bit_ceil_wrapul(unsigned long x);
+extern inline int leading_zerosul(unsigned long x);