On Fri, Mar 20, 2020 at 01:47:46PM +0100, Tomas Mraz wrote:
On Wed, 2020-03-18 at 11:41 +0300, Dmitry V. Levin wrote:
> Introduce a new internal header file for definitions of handly inline
> functions and macros providing some convenient functionality to
> libpam
> and its modules.
>
> * libpam/include/pam_cc_compat.h (PAM_SAME_TYPE): New macro.
> * libpam/include/pam_inline.h: New file.
> * libpam/Makefile.am (noinst_HEADERS): Add include/pam_inline.h.
> ---
> libpam/Makefile.am | 3 ++-
> libpam/include/pam_cc_compat.h | 6 ++++++
> libpam/include/pam_inline.h | 30 ++++++++++++++++++++++++++++++
> 3 files changed, 38 insertions(+), 1 deletion(-)
> create mode 100644 libpam/include/pam_inline.h
>
> diff --git a/libpam/Makefile.am b/libpam/Makefile.am
> index bd3dc5d3..3845517f 100644
> --- a/libpam/Makefile.am
> +++ b/libpam/Makefile.am
> @@ -23,7 +23,8 @@ include_HEADERS = include/security/_pam_compat.h \
> include/security/pam_ext.h include/security/pam_modutil.h
>
> noinst_HEADERS = pam_prelude.h pam_private.h pam_tokens.h \
> - pam_modutil_private.h include/pam_cc_compat.h
> + pam_modutil_private.h include/pam_cc_compat.h \
> + include/pam_inline.h
>
> libpam_la_LDFLAGS = -no-undefined -version-info 85:1:85
> libpam_la_LIBADD = @LIBAUDIT@ $(LIBPRELUDE_LIBS) $(ECONF_LIBS)
> @LIBDL@
> diff --git a/libpam/include/pam_cc_compat.h
> b/libpam/include/pam_cc_compat.h
> index a4b84c62..9fb2dfe0 100644
> --- a/libpam/include/pam_cc_compat.h
> +++ b/libpam/include/pam_cc_compat.h
> @@ -32,4 +32,10 @@
> # define DIAG_POP_IGNORE_CAST_QUAL /* empty */
> #endif
>
> +#if PAM_GNUC_PREREQ(3, 0)
> +# define PAM_SAME_TYPE(x_, y_) __builtin_types_compatible_p(ty
> peof(x_), typeof(y_))
> +#else
> +# define PAM_SAME_TYPE(x_, y_) 0
> +#endif
Although this works it took me quite long time to find out why this
must be 0 when not supported. I'd propose to move the PAM_MUST_BE_ARRAY
to this header or use something like PAM_IS_ARRAY here if you want to
keep PAM_FAIL_BUILD_ON_ZERO in the pam_inline.h and not use it here.
pam_cc_compat.h was intended to be a thin compatibility layer for hiding
differences between various versions of gcc and clang, with more fancy
stuff going elsewhere.
I renamed PAM_SAME_TYPE to PAM_IS_SAME_TYPE, introduced PAM_IS_ARRAY,
and added more comments hopefully explaining things.
Here is the second edition of this patch; does it address your comments?
From 878e6aa471fc69b2695c00c88dcf97332933a951 Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv(a)altlinux.org>
Date: Mon, 16 Mar 2020 21:02:18 +0000
Subject: [PATCH v2 01/33] Introduce pam_inline.h
Introduce a new internal header file for definitions of handly inline
functions and macros providing some convenient functionality to libpam
and its modules.
* libpam/include/pam_cc_compat.h (PAM_SAME_TYPE): New macro.
* libpam/include/pam_inline.h: New file.
* libpam/Makefile.am (noinst_HEADERS): Add include/pam_inline.h.
---
libpam/Makefile.am | 3 ++-
libpam/include/pam_cc_compat.h | 12 +++++++++++
libpam/include/pam_inline.h | 37 ++++++++++++++++++++++++++++++++++
3 files changed, 51 insertions(+), 1 deletion(-)
create mode 100644 libpam/include/pam_inline.h
diff --git a/libpam/Makefile.am b/libpam/Makefile.am
index bd3dc5d3..3845517f 100644
--- a/libpam/Makefile.am
+++ b/libpam/Makefile.am
@@ -23,7 +23,8 @@ include_HEADERS = include/security/_pam_compat.h \
include/security/pam_ext.h include/security/pam_modutil.h
noinst_HEADERS = pam_prelude.h pam_private.h pam_tokens.h \
- pam_modutil_private.h include/pam_cc_compat.h
+ pam_modutil_private.h include/pam_cc_compat.h \
+ include/pam_inline.h
libpam_la_LDFLAGS = -no-undefined -version-info 85:1:85
libpam_la_LIBADD = @LIBAUDIT@ $(LIBPRELUDE_LIBS) $(ECONF_LIBS) @LIBDL@
diff --git a/libpam/include/pam_cc_compat.h b/libpam/include/pam_cc_compat.h
index c43989f7..326d2eba 100644
--- a/libpam/include/pam_cc_compat.h
+++ b/libpam/include/pam_cc_compat.h
@@ -50,4 +50,16 @@
# define DIAG_POP_IGNORE_CAST_ALIGN /* empty */
#endif
+/*
+ * Evaluates to
+ * 1, if the given two types are known to be the same
+ * 0, otherwise.
+ */
+#if PAM_GNUC_PREREQ(3, 0)
+# define PAM_IS_SAME_TYPE(x_, y_) __builtin_types_compatible_p(typeof(x_), typeof(y_))
+#else
+/* Cannot tell whether these types are the same. */
+# define PAM_IS_SAME_TYPE(x_, y_) 0
+#endif
+
#endif /* PAM_CC_COMPAT_H */
diff --git a/libpam/include/pam_inline.h b/libpam/include/pam_inline.h
new file mode 100644
index 00000000..0e93b1fe
--- /dev/null
+++ b/libpam/include/pam_inline.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2020 Dmitry V. Levin <ldv(a)altlinux.org>
+ *
+ * Handy inline functions and macros providing some convenient functionality
+ * to libpam and its modules.
+ */
+
+#ifndef PAM_INLINE_H
+#define PAM_INLINE_H
+
+#include "pam_cc_compat.h"
+
+/*
+ * Evaluates to
+ * - a syntax error if the argument is 0,
+ * 0, otherwise.
+ */
+#define PAM_FAIL_BUILD_ON_ZERO(e_) (sizeof(int[-1 + 2 * !!(e_)]) * 0)
+
+/*
+ * Evaluates to
+ * 0, if the given type is known to be a non-array type
+ * 1, otherwise.
+ */
+#define PAM_IS_ARRAY(a_) (!PAM_IS_SAME_TYPE((a_), &(a_)[0]))
+
+/*
+ * Evaluates to
+ * - a syntax error if the argument is not an array,
+ * 0, otherwise.
+ */
+#define PAM_MUST_BE_ARRAY(a_) PAM_FAIL_BUILD_ON_ZERO(PAM_IS_ARRAY(a_))
+
+/* Evaluates to the number of elements in the specified array. */
+#define PAM_ARRAY_SIZE(a_) (sizeof(a_) / sizeof((a_)[0]) + PAM_MUST_BE_ARRAY(a_))
+
+#endif /* PAM_INLINE_H */
--
ldv