diff --git a/lib/bit.h b/lib/bit.h new file mode 100644 index 00000000..9ffe2060 --- /dev/null +++ b/lib/bit.h @@ -0,0 +1,48 @@ +/* + * SPDX-FileCopyrightText: 2022 - 2023, Alejandro Colomar + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + +#ifndef SHADOW_INCLUDE_LIB_BIT_H_ +#define SHADOW_INCLUDE_LIB_BIT_H_ + + +#include + +#include + + +inline unsigned long bit_ceilul(unsigned long x); +inline unsigned long bit_ceil_wrapul(unsigned long x); +inline int leading_zerosul(unsigned long x); + + +/* stdc_bit_ceilul(3) */ +inline unsigned long +bit_ceilul(unsigned long x) +{ + return 1 + (ULONG_MAX >> leading_zerosul(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 bit_ceil_wrapul(x); +} + +/* stdc_leading_zerosul(3) */ +inline int +leading_zerosul(unsigned long x) +{ + return (x == 0) ? ULONG_WIDTH : __builtin_clz(x); +} + + +#endif // include guard diff --git a/libmisc/Makefile.am b/libmisc/Makefile.am index b4ca708d..ab363f54 100644 --- a/libmisc/Makefile.am +++ b/libmisc/Makefile.am @@ -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 index 00000000..1ffc6dc9 --- /dev/null +++ b/libmisc/bit.c @@ -0,0 +1,19 @@ +/* + * SPDX-FileCopyrightText: 2022 - 2023, Alejandro Colomar + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + +#include + +#ident "$Id$" + +#include "bit.h" + +#include + + +extern inline unsigned long bit_ceilul(unsigned long x); +extern inline unsigned long bit_ceil_wrapul(unsigned long x); +extern inline int leading_zerosul(unsigned long x);