]> git.ipfire.org Git - thirdparty/gnulib.git/commitdiff
stdckdint-h: Don't generate header if it is not needed.
authorCollin Funk <collin.funk1@gmail.com>
Fri, 23 May 2025 02:33:05 +0000 (19:33 -0700)
committerCollin Funk <collin.funk1@gmail.com>
Fri, 23 May 2025 02:33:05 +0000 (19:33 -0700)
Suggested by Paul Eggert in:
<https://lists.gnu.org/archive/html/bug-gnulib/2025-05/msg00216.html>.

* m4/stdckdint_h.m4: New file.
* modules/stdckdint-h (Files): Add m4/stdckdint_h.m4.
(configure.ac): Remove checks and just invoke gl_STDCKDINT_H.
(Makefile.am): Replace variables set by ./configure.
* lib/stdckdint.in.h: Include the compilers header if it exists.  Add
comment mentioning expected future standardization in C++26.
(ckd_add, ckd_sub, ckd_mul): Only define if the compilers definitions do
not work.

ChangeLog
lib/stdckdint.in.h
m4/stdckdint_h.m4 [new file with mode: 0644]
modules/stdckdint-h

index 0145e21fb25d404957817878c7ad0a3b7e5ece83..f2ccb1fb940555573766cef7ebb5b41672012c75 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2025-05-22  Collin Funk  <collin.funk1@gmail.com>
+
+       stdckdint-h: Don't generate header if it is not needed.
+       Suggested by Paul Eggert in:
+       <https://lists.gnu.org/archive/html/bug-gnulib/2025-05/msg00216.html>.
+       * m4/stdckdint_h.m4: New file.
+       * modules/stdckdint-h (Files): Add m4/stdckdint_h.m4.
+       (configure.ac): Remove checks and just invoke gl_STDCKDINT_H.
+       (Makefile.am): Replace variables set by ./configure.
+       * lib/stdckdint.in.h: Include the compilers header if it exists.  Add
+       comment mentioning expected future standardization in C++26.
+       (ckd_add, ckd_sub, ckd_mul): Only define if the compilers definitions do
+       not work.
+
 2025-05-22  Bruno Haible  <bruno@clisp.org>
 
        strchrnul: Update doc.
index 83277b728ee652818209eff13a9066db8d69a194..bb9089b4a131d10a154e11a45b8d925b30b1ef10 100644 (file)
    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
 
-#ifndef _GL_STDCKDINT_H
-#define _GL_STDCKDINT_H
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+@PRAGMA_COLUMNS@
 
-#include "intprops-internal.h"
+#ifndef _@GUARD_PREFIX@_STDCKDINT_H
+
+/* The include_next requires a split double-inclusion guard.  */
+#if defined __cplusplus ? @HAVE_CXX_STDCKDINT_H@ : @HAVE_C_STDCKDINT_H@
+# @INCLUDE_NEXT@ @NEXT_STDCKDINT_H@
+#endif
+
+#ifndef _@GUARD_PREFIX@_STDCKDINT_H
+#define _@GUARD_PREFIX@_STDCKDINT_H
+
+/* Do nothing but include the system header if it works properly.  */
+# if defined __cplusplus ? !@HAVE_WORKING_CXX_STDCKDINT_H@ : !@HAVE_WORKING_C_STDCKDINT_H@
+
+/* Avoid redefining macros.  */
+#  undef ckd_add
+#  undef ckd_sub
+#  undef ckd_mul
+
+#  include "intprops-internal.h"
 
 /* Store into *R the low-order bits of A + B, A - B, A * B, respectively.
    Return 1 if the result overflows, 0 otherwise.
    bit-precise integer type, or an enumeration type.
 
    These are like the standard macros introduced in C23, except that
-   arguments should not have side effects.  */
+   arguments should not have side effects.  The C++26 standard is
+   expected to add this header and it's macros.  */
 
-#define ckd_add(r, a, b) ((bool) _GL_INT_ADD_WRAPV (a, b, r))
-#define ckd_sub(r, a, b) ((bool) _GL_INT_SUBTRACT_WRAPV (a, b, r))
-#define ckd_mul(r, a, b) ((bool) _GL_INT_MULTIPLY_WRAPV (a, b, r))
+#  define ckd_add(r, a, b) ((bool) _GL_INT_ADD_WRAPV (a, b, r))
+#  define ckd_sub(r, a, b) ((bool) _GL_INT_SUBTRACT_WRAPV (a, b, r))
+#  define ckd_mul(r, a, b) ((bool) _GL_INT_MULTIPLY_WRAPV (a, b, r))
 
-#endif /* _GL_STDCKDINT_H */
+# endif /* defined __cplusplus ? @HAVE_WORKING_CXX_STDCKDINT_H@ : @HAVE_WORKING_C_STDCKDINT_H@ */
+#endif /* _@GUARD_PREFIX@_STDCKDINT_H */
+#endif /* _@GUARD_PREFIX@_STDCKDINT_H */
diff --git a/m4/stdckdint_h.m4 b/m4/stdckdint_h.m4
new file mode 100644 (file)
index 0000000..d269faa
--- /dev/null
@@ -0,0 +1,136 @@
+# stdckdint_h.m4
+# serial 1
+dnl Copyright 2025 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl This file is offered as-is, without any warranty.
+
+dnl Written by Collin Funk.
+
+AC_DEFUN_ONCE([gl_STDCKDINT_H],
+[
+  gl_CHECK_NEXT_HEADERS([stdckdint.h])
+  if test $ac_cv_header_stdckdint_h = yes; then
+    HAVE_STDCKDINT_H=1
+  else
+    HAVE_STDCKDINT_H=0
+  fi
+  AC_SUBST([HAVE_STDCKDINT_H])
+
+  if test $HAVE_STDCKDINT_H = 1; then
+    AC_CACHE_CHECK([whether stdckdint.h can be included in C],
+      [gl_cv_header_c_stdckdint_h],
+      [AC_COMPILE_IFELSE(
+         [AC_LANG_PROGRAM(
+            [[#include <stdckdint.h>
+            ]])],
+         [gl_cv_header_c_stdckdint_h=yes],
+         [gl_cv_header_c_stdckdint_h=no])])
+    if test $gl_cv_header_c_stdckdint_h = yes; then
+      HAVE_C_STDCKDINT_H=1
+      AC_CACHE_CHECK([checking for an ISO C23 compliant stdckdint.h in C],
+        [gl_cv_header_c_stdckdint_h_works],
+        [AC_COMPILE_IFELSE(
+           [AC_LANG_PROGRAM(
+              [[#include <stdckdint.h>
+              ]],
+              [[int r;
+                int a = 1;
+                int b = 1;
+                return !!(ckd_add (&r, a, b) || ckd_sub (&r, a, b)
+                          || ckd_mul (&r, a, b));
+              ]])],
+           [gl_cv_header_c_stdckdint_h_works=yes],
+           [gl_cv_header_c_stdckdint_h_works=no])])
+      if test $gl_cv_header_c_stdckdint_h_works = yes; then
+        HAVE_WORKING_C_STDCKDINT_H=1
+      else
+        HAVE_WORKING_C_STDCKDINT_H=0
+      fi
+    else
+      HAVE_C_STDCKDINT_H=0
+      HAVE_WORKING_C_STDCKDINT_H=0
+    fi
+    if test "$CXX" != no; then
+      AC_CACHE_CHECK([whether stdckdint.h can be included in C++],
+        [gl_cv_header_cxx_stdckdint_h],
+        [dnl We can't use AC_LANG_PUSH([C++]) and AC_LANG_POP([C++]) here, due to
+         dnl an autoconf bug <https://savannah.gnu.org/support/?110294>.
+         cat > conftest.cpp <<\EOF
+#include <stdckdint.h>
+EOF
+         gl_command="$CXX $CXXFLAGS $CPPFLAGS -c conftest.cpp"
+         if AC_TRY_EVAL([gl_command]); then
+           gl_cv_header_cxx_stdckdint_h=yes
+         else
+           gl_cv_header_cxx_stdckdint_h=no
+         fi
+         rm -fr conftest*
+        ])
+      if test $gl_cv_header_cxx_stdckdint_h = yes; then
+        HAVE_CXX_STDCKDINT_H=1
+        AC_CACHE_CHECK([checking for an ISO C++26 compliant stdckdint.h in C++],
+          [gl_cv_header_cxx_stdckdint_h_works],
+          [dnl We can't use AC_LANG_PUSH([C++]) and AC_LANG_POP([C++]) here, due to
+           dnl an autoconf bug <https://savannah.gnu.org/support/?110294>.
+           cat > conftest.cpp <<\EOF
+#include <stdckdint.h>
+int
+main (void)
+{
+  int r;
+  int a = 1;
+  int b = 1;
+  return !!(ckd_add (&r, a, b) || ckd_sub (&r, a, b) || ckd_mul (&r, a, b));
+}
+EOF
+           gl_command="$CXX $CXXFLAGS $CPPFLAGS -c conftest.cpp"
+           if AC_TRY_EVAL([gl_command]); then
+             gl_cv_header_cxx_stdckdint_h_works=yes
+           else
+             gl_cv_header_cxx_stdckdint_h_works=no
+           fi
+           rm -fr conftest*
+          ])
+        if test $gl_cv_header_cxx_stdckdint_h_works = yes; then
+          HAVE_WORKING_CXX_STDCKDINT_H=1
+        else
+          HAVE_WORKING_CXX_STDCKDINT_H=0
+        fi
+      else
+        HAVE_CXX_STDCKDINT_H=0
+        HAVE_WORKING_CXX_STDCKDINT_H=0
+      fi
+    fi
+  else
+    HAVE_C_STDCKDINT_H=0
+    HAVE_WORKING_C_STDCKDINT_H=0
+    HAVE_CXX_STDCKDINT_H=0
+    HAVE_WORKING_CXX_STDCKDINT_H=0
+  fi
+  AC_SUBST([HAVE_C_STDCKDINT_H])
+  AC_SUBST([HAVE_WORKING_C_STDCKDINT_H])
+  AC_SUBST([HAVE_CXX_STDCKDINT_H])
+  AC_SUBST([HAVE_WORKING_CXX_STDCKDINT_H])
+
+  if test "$CXX" != no; then
+    dnl We might need the header for C or C++.
+    if test $HAVE_C_STDCKDINT_H = 1 \
+       && test $HAVE_WORKING_C_STDCKDINT_H = 1 \
+       && test $HAVE_CXX_STDCKDINT_H = 1 \
+       && test $HAVE_WORKING_CXX_STDCKDINT_H = 1; then
+      GL_GENERATE_STDCKDINT_H=false
+    else
+      GL_GENERATE_STDCKDINT_H=true
+    fi
+  else
+    dnl We don't care about C++ here.
+    if test $HAVE_C_STDCKDINT_H = 1 \
+       && test $HAVE_WORKING_C_STDCKDINT_H = 1; then
+      GL_GENERATE_STDCKDINT_H=false
+    else
+      GL_GENERATE_STDCKDINT_H=true
+    fi
+  fi
+])
index ff777d8d62b8d91f534cb6ef2dd106cb7e9b1889..7f7c612bce3d82baf67e2cecc246eaf684952dae 100644 (file)
@@ -2,6 +2,7 @@ Description:
 An <stdckdint.h> that is like C23.
 
 Files:
+m4/stdckdint_h.m4
 lib/stdckdint.in.h
 lib/intprops-internal.h
 
@@ -10,16 +11,7 @@ gen-header
 bool
 
 configure.ac:
-AC_CHECK_HEADERS_ONCE([stdckdint.h])
-if test $ac_cv_header_stdckdint_h = yes; then
-  if test -n "$CXX" && test "$CXX" != no; then
-    GL_GENERATE_STDCKDINT_H=true
-  else
-    GL_GENERATE_STDCKDINT_H=false
-  fi
-else
-  GL_GENERATE_STDCKDINT_H=true
-fi
+gl_STDCKDINT_H
 gl_CONDITIONAL_HEADER([stdckdint.h])
 AC_PROG_MKDIR_P
 
@@ -32,6 +24,15 @@ if GL_GENERATE_STDCKDINT_H
 stdckdint.h: stdckdint.in.h $(top_builddir)/config.status
 @NMD@  $(AM_V_GEN)$(MKDIR_P) '%reldir%'
        $(gl_V_at)$(SED_HEADER_STDOUT) \
+             -e 's|@''GUARD_PREFIX''@|${gl_include_guard_prefix}|g' \
+             -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+             -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+             -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+             -e 's|@''NEXT_STDCKDINT_H''@|$(NEXT_STDCKDINT_H)|g' \
+             -e 's|@''HAVE_C_STDCKDINT_H''@|$(HAVE_C_STDCKDINT_H)|g' \
+             -e 's|@''HAVE_WORKING_C_STDCKDINT_H''@|$(HAVE_WORKING_C_STDCKDINT_H)|g' \
+             -e 's|@''HAVE_CXX_STDCKDINT_H''@|$(HAVE_CXX_STDCKDINT_H)|g' \
+             -e 's|@''HAVE_WORKING_CXX_STDCKDINT_H''@|$(HAVE_WORKING_CXX_STDCKDINT_H)|g' \
          $(srcdir)/stdckdint.in.h > $@-t
        $(AM_V_at)mv $@-t $@
 else