endian: New module.
authorCollin Funk <collin.funk1@gmail.com>
Sat, 18 May 2024 07:10:33 +0000 (00:10 -0700)
committerCollin Funk <collin.funk1@gmail.com>
Sat, 18 May 2024 07:10:33 +0000 (00:10 -0700)
* doc/glibc-headers/endian.texi, doc/gnulib-tool.texi: Mention it.
* lib/endian.c: New file.
* lib/endian.in.h: New file.
* m4/endian_h.m4: New file.
* modules/endian: New file.

ChangeLog
doc/glibc-headers/endian.texi
doc/gnulib-tool.texi
lib/endian.c [new file with mode: 0644]
lib/endian.in.h [new file with mode: 0644]
m4/endian_h.m4 [new file with mode: 0644]
modules/endian [new file with mode: 0644]

index 8ddc85b1385554eb12424f6e13f9bc377e237b83..4c2d9b516dcc7d3bc8a3f165b3399efaff84aec0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2024-05-18  Collin Funk  <collin.funk1@gmail.com>
+
+       endian: New module.
+       * doc/glibc-headers/endian.texi, doc/gnulib-tool.texi: Mention it.
+       * lib/endian.c: New file.
+       * lib/endian.in.h: New file.
+       * m4/endian_h.m4: New file.
+       * modules/endian: New file.
+
 2024-05-17  Bruno Haible  <bruno@clisp.org>
 
        tests: Fix link errors (regression today).
index c45b87550144a81ee7c58efb7bfd9f0c3f90b706..5c7cb7242909456100341816a925b852c4daeeab 100644 (file)
@@ -5,15 +5,15 @@ Describe's the platform's endianness (byte ordering of words stored in memory).
 Defines the macros @code{BYTE_ORDER}, @code{LITTLE_ENDIAN}, @code{BIG_ENDIAN},
 @code{PDP_ENDIAN}.
 
-Gnulib module: ---
+Gnulib module: endian
 
 Portability problems fixed by Gnulib:
 @itemize
+@item
+This header file is missing on some platforms:
+macOS 11.1, FreeBSD 13.0, NetBSD 7.1, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, Solaris 11.4, mingw, MSVC 14.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
-@item
-This header file is missing on some platforms:
-macOS 11.1, FreeBSD 13.0, NetBSD 7.1, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, Solaris 11.4, mingw, MSVC 14.
 @end itemize
index 5a2fd19cac557b9b5fe2dfb555d81e236fff3139..116734f4d7a3d6b3e38a24d03c954b94c5a184de 100644 (file)
@@ -561,6 +561,7 @@ This is true for the following POSIX or ISO C standardized header files:
 @item @code{assert.h}
 @item @code{ctype.h}
 @item @code{dirent.h}
+@item @code{endian.h}
 @item @code{errno.h}
 @item @code{fcntl.h}
 @item @code{fenv.h}
diff --git a/lib/endian.c b/lib/endian.c
new file mode 100644 (file)
index 0000000..3e7e56f
--- /dev/null
@@ -0,0 +1,23 @@
+/* Inline functions for <endian.h>.
+
+   Copyright 2024 Free Software Foundation, Inc.
+
+   This file is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   This file is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Lesser General Public License for more details.
+
+   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/>.  */
+
+/* Written by Collin Funk.  */
+
+#include <config.h>
+
+#define _GL_ENDIAN_INLINE _GL_EXTERN_INLINE
+#include <endian.h>
diff --git a/lib/endian.in.h b/lib/endian.in.h
new file mode 100644 (file)
index 0000000..5d755fd
--- /dev/null
@@ -0,0 +1,196 @@
+/* endian.h - Byte order macros
+
+   Copyright 2024 Free Software Foundation, Inc.
+
+   This file is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   This file is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Lesser General Public License for more details.
+
+   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/>.  */
+
+/* Written by Collin Funk.  */
+
+#ifndef _GL_ENDIAN_H
+#define _GL_ENDIAN_H 1
+
+/* This file uses _GL_INLINE, WORDS_BIGENDIAN.  */
+#if !_GL_CONFIG_H_INCLUDED
+ #error "Please include config.h first."
+#endif
+
+/* Define uint16_t and uint32_t.
+   Define uint64_t if it is available.  */
+#include <stdint.h>
+
+/* Byteswap functions.  */
+#include <byteswap.h>
+
+_GL_INLINE_HEADER_BEGIN
+#ifndef _GL_ENDIAN_INLINE
+# define _GL_ENDIAN_INLINE _GL_INLINE
+#endif
+
+#define LITTLE_ENDIAN 1234
+#define BIG_ENDIAN 4321
+#define PDP_ENDIAN 3412
+
+#ifdef WORDS_BIGENDIAN
+# define BYTE_ORDER BIG_ENDIAN
+#else
+# define BYTE_ORDER LITTLE_ENDIAN
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Big endian to host.  */
+
+_GL_ENDIAN_INLINE uint16_t
+be16toh (uint16_t x)
+{
+#if BYTE_ORDER == BIG_ENDIAN
+  return x;
+#else
+  return bswap_16 (x);
+#endif
+}
+
+_GL_ENDIAN_INLINE uint32_t
+be32toh (uint32_t x)
+{
+#if BYTE_ORDER == BIG_ENDIAN
+  return x;
+#else
+  return bswap_32 (x);
+#endif
+}
+
+#ifdef UINT64_MAX
+_GL_ENDIAN_INLINE uint64_t
+be64toh (uint64_t x)
+{
+# if BYTE_ORDER == BIG_ENDIAN
+  return x;
+# else
+  return bswap_64 (x);
+# endif
+}
+#endif
+
+/* Host to big endian.  */
+
+_GL_ENDIAN_INLINE uint16_t
+htobe16 (uint16_t x)
+{
+#if BYTE_ORDER == BIG_ENDIAN
+  return x;
+#else
+  return bswap_16 (x);
+#endif
+}
+
+_GL_ENDIAN_INLINE uint32_t
+htobe32 (uint32_t x)
+{
+#if BYTE_ORDER == BIG_ENDIAN
+  return x;
+#else
+  return bswap_32 (x);
+#endif
+}
+
+#ifdef UINT64_MAX
+_GL_ENDIAN_INLINE uint64_t
+htobe64 (uint64_t x)
+{
+# if BYTE_ORDER == BIG_ENDIAN
+  return x;
+# else
+  return bswap_64 (x);
+# endif
+}
+#endif
+
+/* Little endian to host.  */
+
+_GL_ENDIAN_INLINE uint16_t
+le16toh (uint16_t x)
+{
+#if BYTE_ORDER == BIG_ENDIAN
+  return bswap_16 (x);
+#else
+  return x;
+#endif
+}
+
+_GL_ENDIAN_INLINE uint32_t
+le32toh (uint32_t x)
+{
+#if BYTE_ORDER == BIG_ENDIAN
+  return bswap_32 (x);
+#else
+  return x;
+#endif
+}
+
+#ifdef UINT64_MAX
+_GL_ENDIAN_INLINE uint64_t
+le64toh (uint64_t x)
+{
+# if BYTE_ORDER == BIG_ENDIAN
+  return bswap_64 (x);
+# else
+  return x;
+# endif
+}
+#endif
+
+/* Host to little endian.  */
+
+_GL_ENDIAN_INLINE uint16_t
+htole16 (uint16_t x)
+{
+#if BYTE_ORDER == BIG_ENDIAN
+  return bswap_16 (x);
+#else
+  return x;
+#endif
+}
+
+_GL_ENDIAN_INLINE uint32_t
+htole32 (uint32_t x)
+{
+#if BYTE_ORDER == BIG_ENDIAN
+  return bswap_32 (x);
+#else
+  return x;
+#endif
+}
+
+#ifdef UINT64_MAX
+_GL_ENDIAN_INLINE uint64_t
+htole64 (uint64_t x)
+{
+# if BYTE_ORDER == BIG_ENDIAN
+  return bswap_64 (x);
+# else
+  return x;
+# endif
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+_GL_INLINE_HEADER_END
+
+#endif /* _GL_ENDIAN_H */
diff --git a/m4/endian_h.m4 b/m4/endian_h.m4
new file mode 100644 (file)
index 0000000..ec0d111
--- /dev/null
@@ -0,0 +1,71 @@
+# endian_h.m4
+# serial 1
+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,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl A placeholder for <endian.h>, for platforms that have issues.
+
+AC_DEFUN_ONCE([gl_ENDIAN_H],
+[
+  AC_REQUIRE([gl_BIGENDIAN])
+
+  AC_CHECK_HEADERS_ONCE([endian.h])
+  if test $ac_cv_header_endian_h = yes; then
+    AC_CACHE_CHECK([if endian.h conforms to POSIX],
+      [gl_cv_header_working_endian_h],
+      [gl_cv_header_working_endian_h=no
+       AC_COMPILE_IFELSE(
+         [AC_LANG_PROGRAM(
+[[
+#include <endian.h>
+]],
+[[
+#if LITTLE_ENDIAN == BIG_ENDIAN
+# error "Endian macros not unique."
+#endif
+#if BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN
+# 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);
+
+/* 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);
+
+/* 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);
+
+/* 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);
+
+/* Make sure the variables get used.  */
+return !(value16_1 + value32_1 + value64_1
+         + value16_2 + value32_2 + value64_2
+         + value16_3 + value32_3 + value64_3
+         + value16_4 + value32_4 + value64_4);
+]])],
+         [gl_cv_header_working_endian_h=yes],
+         [gl_cv_header_working_endian_h=no])
+      ])
+  fi
+  if test $gl_cv_header_working_endian_h = yes; then
+    GL_GENERATE_ENDIAN_H=false
+  else
+    GL_GENERATE_ENDIAN_H=true
+  fi
+])
diff --git a/modules/endian b/modules/endian
new file mode 100644 (file)
index 0000000..9da2d2d
--- /dev/null
@@ -0,0 +1,44 @@
+Description:
+A POSIX-like <endian.h>.
+
+Files:
+lib/endian.in.h
+lib/endian.c
+m4/endian_h.m4
+
+Depends-on:
+gen-header
+extern-inline           [$GL_GENERATE_ENDIAN_H]
+byteswap                [$GL_GENERATE_ENDIAN_H]
+stdint                  [$GL_GENERATE_ENDIAN_H]
+
+configure.ac:
+gl_ENDIAN_H
+gl_CONDITIONAL_HEADER([endian.h])
+AC_PROG_MKDIR_P
+
+Makefile.am:
+BUILT_SOURCES += $(ENDIAN_H)
+
+# We need the following in order to create <endian.h> when the system
+# doesn't have one.
+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
+       $(AM_V_at)mv $@-t $@
+lib_SOURCES += endian.c
+else
+endian.h: $(top_builddir)/config.status
+       rm -f $@
+endif
+MOSTLYCLEANFILES += endian.h endian.h-t
+
+Include:
+<endian.h>
+
+License:
+LGPLv2+
+
+Maintainer:
+all