+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.
/* 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
# 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
_GL_INLINE_HEADER_END
-#endif /* _GL_ENDIAN_H */
+#endif /* @ENDIAN_H_JUST_MISSING_STDINT@ */
+#endif /* _@GUARD_PREFIX@_ENDIAN_H */
+#endif /* _@GUARD_PREFIX@_ENDIAN_H */
# 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,
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(
# 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
[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])
])
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:
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