]> Savannah Git Hosting - gnulib.git/commitdiff
endian: Make sure system headers can be included.
authorCollin Funk <collin.funk1@gmail.com>
Sat, 18 May 2024 13:36:55 +0000 (06:36 -0700)
committerCollin Funk <collin.funk1@gmail.com>
Sat, 18 May 2024 21:55:23 +0000 (14:55 -0700)
Reported by Bruno Haible in
<https://lists.gnu.org/archive/html/bug-gnulib/2024-05/msg00290.html>.

* lib/endian.in.h (be16toh, be32toh, be64toh, htobe16, htobe32, htobe64)
(le16toh, le32toh, le64toh, htole16, htole32, htole64): Don't define
functions if the system has working versions.
* m4/endian_h.m4 (gl_ENDIAN_H): Separate checks for stdint types and
proper macro/function definitions.
* modules/endian (Depends-on): Add include_next. Update module
dependency conditions.
(Makefile.am): Perform sed replacements on the header substitute.

ChangeLog
lib/endian.in.h
m4/endian_h.m4
modules/endian

index 7de9b90f6d67f40f37abd01efa645ca81a6ed1aa..3ab2dc021aa034f13d34f037a4984847a7957fe5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2024-05-18  Collin Funk  <collin.funk1@gmail.com>
+
+       endian: Make sure system headers can be included.
+       Reported by Bruno Haible in
+       <https://lists.gnu.org/archive/html/bug-gnulib/2024-05/msg00290.html>.
+       * lib/endian.in.h (be16toh, be32toh, be64toh, htobe16, htobe32, htobe64)
+       (le16toh, le32toh, le64toh, htole16, htole32, htole64): Don't define
+       functions if the system has working versions.
+       * m4/endian_h.m4 (gl_ENDIAN_H): Separate checks for stdint types and
+       proper macro/function definitions.
+       * modules/endian (Depends-on): Add include_next. Update module
+       dependency conditions.
+       (Makefile.am): Perform sed replacements on the header substitute.
+
 2024-05-18  Bruno Haible  <bruno@clisp.org>
 
        abort-debug: Integrate with CONTINUE_AFTER_ASSERT.
index 5d755fd7cfe1d7929bbe2291f7b79d18e7df24c2..bd65ae8aaba27eb07b2fac5d5cae86e030e8c717 100644 (file)
 
 /* Written by Collin Funk.  */
 
-#ifndef _GL_ENDIAN_H
-#define _GL_ENDIAN_H 1
+#ifndef _@GUARD_PREFIX@_ENDIAN_H
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+@PRAGMA_COLUMNS@
+
+#if @HAVE_ENDIAN_H@
+
+/* The include_next requires a split double-inclusion guard.  */
+# @INCLUDE_NEXT@ @NEXT_ENDIAN_H@
+
+#endif
+
+
+/* glibc defines all macros and functions but is missing types from
+   stdint.h.  */
+#if @ENDIAN_H_JUST_MISSING_STDINT@
+# include <stdint.h>
+#else
+
+/* Others platforms.  */
+#ifndef _@GUARD_PREFIX@_ENDIAN_H
+#define _@GUARD_PREFIX@_ENDIAN_H 1
 
 /* This file uses _GL_INLINE, WORDS_BIGENDIAN.  */
 #if !_GL_CONFIG_H_INCLUDED
@@ -47,6 +69,22 @@ _GL_INLINE_HEADER_BEGIN
 # define BYTE_ORDER LITTLE_ENDIAN
 #endif
 
+/* Make sure function-like macros get undefined.  */
+#if @HAVE_ENDIAN_H@
+# undef be16toh
+# undef be32toh
+# undef be64toh
+# undef htobe16
+# undef htobe32
+# undef htobe64
+# undef le16toh
+# undef le32toh
+# undef le64toh
+# undef htole16
+# undef htole32
+# undef htole64
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -193,4 +231,6 @@ htole64 (uint64_t x)
 
 _GL_INLINE_HEADER_END
 
-#endif /* _GL_ENDIAN_H */
+#endif /* @ENDIAN_H_JUST_MISSING_STDINT@ */
+#endif /* _@GUARD_PREFIX@_ENDIAN_H */
+#endif /* _@GUARD_PREFIX@_ENDIAN_H */
index ec0d111ae320ad2fd72a31476aa48ea81e8fa34d..29dab603e3f8a74dfe7d9d0cd39ff23b886980e2 100644 (file)
@@ -1,5 +1,5 @@
 # endian_h.m4
-# serial 1
+# serial 2
 dnl Copyright 2024 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -12,8 +12,25 @@ AC_DEFUN_ONCE([gl_ENDIAN_H],
   AC_REQUIRE([gl_BIGENDIAN])
 
   AC_CHECK_HEADERS_ONCE([endian.h])
+  gl_CHECK_NEXT_HEADERS([endian.h])
   if test $ac_cv_header_endian_h = yes; then
-    AC_CACHE_CHECK([if endian.h conforms to POSIX],
+    HAVE_ENDIAN_H=1
+    dnl Check if endian.h defines uint16_t, uint32_t, and uint64_t.
+    AC_CACHE_CHECK([if endian.h defines stdint types],
+      [gl_cv_header_endian_h_stdint_types],
+      [AC_COMPILE_IFELSE(
+         [AC_LANG_PROGRAM(
+            [[#include <endian.h>
+            ]],
+            [[uint16_t t1 = 0;
+              uint32_t t2 = 0;
+              uint64_t t3 = 0;
+              return !(t1 + t2 + t3);
+            ]])],
+      [gl_cv_header_endian_h_stdint_types=yes],
+      [gl_cv_header_endian_h_stdint_types=no])
+    ])
+    AC_CACHE_CHECK([if endian.h defines functions and macros],
       [gl_cv_header_working_endian_h],
       [gl_cv_header_working_endian_h=no
        AC_COMPILE_IFELSE(
@@ -29,29 +46,25 @@ AC_DEFUN_ONCE([gl_ENDIAN_H],
 # error "Byte order not defined."
 #endif
 
-/* Check for uint16_t, uint32_t, uint64_t along with
-   byte order conversion functions that accept floating-point
-   arguments.  */
-
 /* Big endian to host.  */
-uint16_t value16_1 = be16toh (0.0);
-uint32_t value32_1 = be32toh (0.0);
-uint64_t value64_1 = be64toh (0.0);
+int value16_1 = be16toh (0.0);
+int value32_1 = be32toh (0.0);
+int value64_1 = be64toh (0.0);
 
 /* Host to big endian.  */
-uint16_t value16_2 = htobe16 (0.0);
-uint32_t value32_2 = htobe32 (0.0);
-uint64_t value64_2 = htobe64 (0.0);
+int value16_2 = htobe16 (0.0);
+int value32_2 = htobe32 (0.0);
+int value64_2 = htobe64 (0.0);
 
 /* Little endian to host.  */
-uint16_t value16_3 = le16toh (0.0);
-uint32_t value32_3 = le32toh (0.0);
-uint64_t value64_3 = le64toh (0.0);
+int value16_3 = le16toh (0.0);
+int value32_3 = le32toh (0.0);
+int value64_3 = le64toh (0.0);
 
 /* Host to little endian.  */
-uint16_t value16_4 = htole16 (0.0);
-uint32_t value32_4 = htole32 (0.0);
-uint64_t value64_4 = htole64 (0.0);
+int value16_4 = htole16 (0.0);
+int value32_4 = htole32 (0.0);
+int value64_4 = htole64 (0.0);
 
 /* Make sure the variables get used.  */
 return !(value16_1 + value32_1 + value64_1
@@ -62,10 +75,29 @@ return !(value16_1 + value32_1 + value64_1
          [gl_cv_header_working_endian_h=yes],
          [gl_cv_header_working_endian_h=no])
       ])
+  else
+    HAVE_ENDIAN_H=0
   fi
-  if test $gl_cv_header_working_endian_h = yes; then
+
+  dnl Check if endian.h should be generated.
+  if test $gl_cv_header_endian_h_stdint_types = yes \
+     && test $gl_cv_header_working_endian_h = yes; then
     GL_GENERATE_ENDIAN_H=false
   else
     GL_GENERATE_ENDIAN_H=true
   fi
+
+  dnl Check if endian.h works but is missing types from stdint.h.
+  if test $GL_GENERATE_ENDIAN_H; then
+    if test $gl_cv_header_working_endian_h = yes; then
+      ENDIAN_H_JUST_MISSING_STDINT=1
+    else
+      ENDIAN_H_JUST_MISSING_STDINT=0
+    fi
+  else
+    ENDIAN_H_JUST_MISSING_STDINT=0
+  fi
+
+  AC_SUBST([HAVE_ENDIAN_H])
+  AC_SUBST([ENDIAN_H_JUST_MISSING_STDINT])
 ])
index 9da2d2d19c60a599255a809c02bf86b2291ed426..95b9a91e8e3f19ab4ac5f266dace3487a7559ce5 100644 (file)
@@ -8,8 +8,9 @@ m4/endian_h.m4
 
 Depends-on:
 gen-header
-extern-inline           [$GL_GENERATE_ENDIAN_H]
-byteswap                [$GL_GENERATE_ENDIAN_H]
+include_next
+extern-inline           [$GL_GENERATE_ENDIAN_H && test $ENDIAN_H_JUST_MISSING_STDINT = 0]
+byteswap                [$GL_GENERATE_ENDIAN_H && test $ENDIAN_H_JUST_MISSING_STDINT = 0]
 stdint                  [$GL_GENERATE_ENDIAN_H]
 
 configure.ac:
@@ -25,7 +26,15 @@ BUILT_SOURCES += $(ENDIAN_H)
 if GL_GENERATE_ENDIAN_H
 endian.h: endian.in.h $(top_builddir)/config.status
 @NMD@  $(AM_V_GEN)$(MKDIR_P) '%reldir%'
-       $(gl_V_at)$(SED_HEADER_TO_AT_t) $(srcdir)/endian.in.h
+       $(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|@''HAVE_ENDIAN_H''@|$(HAVE_ENDIAN_H)|g' \
+             -e 's|@''NEXT_ENDIAN_H''@|$(NEXT_ENDIAN_H)|g' \
+             -e 's|@''ENDIAN_H_JUST_MISSING_STDINT''@|$(ENDIAN_H_JUST_MISSING_STDINT)|g' \
+       $(srcdir)/endian.in.h > $@-t
        $(AM_V_at)mv $@-t $@
 lib_SOURCES += endian.c
 else