On 5/18/24 7:45 AM, Bruno Haible wrote:
>> Can you check the attached patch? I think that it should work or
>> at least be in the correct direction...
> 
> In the endian.in.h file: The comments on the 3 last lines are not
> consistent with the '#endif' scopes.

Oops, good catch.

> In the Makefile.am snippet:
> A few lines are indented with spaces, not with a tab. It would
> not cause an error here, since these are only continuation lines,
> I think. But nevertheless better be consistent with how other
> modules do it.

In my Emacs configuration I have a hook that makes makefile-mode use
tabs instead of spaces. For nearly all other modes I use spaces. In
the case of modules/* they are interpreted as text files, so the tab
key inserts spaces.

Perhaps I'll figure out a good way to deal with that if/when it starts
annoying me. Until then I can just insert regular tabs.

> Other than that, it looks correct.

I've applied this patch. Same as before but with those two things
fixed.

Collin
From 83dd4db866cc5dde2fddcf1944f3b5cc3732e48e Mon Sep 17 00:00:00 2001
From: Collin Funk <collin.fu...@gmail.com>
Date: Sat, 18 May 2024 06:36:55 -0700
Subject: [PATCH] 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.
---
 ChangeLog       | 14 ++++++++++
 lib/endian.in.h | 46 +++++++++++++++++++++++++++++---
 m4/endian_h.m4  | 70 +++++++++++++++++++++++++++++++++++--------------
 modules/endian  | 15 ++++++++---
 4 files changed, 120 insertions(+), 25 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 7de9b90f6d..3ab2dc021a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2024-05-18  Collin Funk  <collin.fu...@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  <br...@clisp.org>
 
 	abort-debug: Integrate with CONTINUE_AFTER_ASSERT.
diff --git a/lib/endian.in.h b/lib/endian.in.h
index 5d755fd7cf..bd65ae8aab 100644
--- a/lib/endian.in.h
+++ b/lib/endian.in.h
@@ -17,8 +17,30 @@
 
 /* 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 */
diff --git a/m4/endian_h.m4 b/m4/endian_h.m4
index ec0d111ae3..29dab603e3 100644
--- a/m4/endian_h.m4
+++ b/m4/endian_h.m4
@@ -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 @@ AC_DEFUN_ONCE([gl_ENDIAN_H]
          [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])
 ])
diff --git a/modules/endian b/modules/endian
index 9da2d2d19c..95b9a91e8e 100644
--- a/modules/endian
+++ b/modules/endian
@@ -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
-- 
2.45.1

Reply via email to