From 95f7085c87236bea297f9251ecb58e0bd821552c Mon Sep 17 00:00:00 2001 From: Collin Funk Date: Sat, 18 May 2024 00:10:33 -0700 Subject: [PATCH] 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. --- ChangeLog | 9 ++ doc/glibc-headers/endian.texi | 8 +- doc/gnulib-tool.texi | 1 + lib/endian.c | 23 ++++ lib/endian.in.h | 196 ++++++++++++++++++++++++++++++++++ m4/endian_h.m4 | 71 ++++++++++++ modules/endian | 44 ++++++++ 7 files changed, 348 insertions(+), 4 deletions(-) create mode 100644 lib/endian.c create mode 100644 lib/endian.in.h create mode 100644 m4/endian_h.m4 create mode 100644 modules/endian diff --git a/ChangeLog b/ChangeLog index 8ddc85b138..4c2d9b516d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2024-05-18 Collin Funk + + 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 tests: Fix link errors (regression today). diff --git a/doc/glibc-headers/endian.texi b/doc/glibc-headers/endian.texi index c45b875501..5c7cb72429 100644 --- a/doc/glibc-headers/endian.texi +++ b/doc/glibc-headers/endian.texi @@ -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 diff --git a/doc/gnulib-tool.texi b/doc/gnulib-tool.texi index 5a2fd19cac..116734f4d7 100644 --- a/doc/gnulib-tool.texi +++ b/doc/gnulib-tool.texi @@ -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 index 0000000000..3e7e56f523 --- /dev/null +++ b/lib/endian.c @@ -0,0 +1,23 @@ +/* Inline functions for . + + 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 . */ + +/* Written by Collin Funk. */ + +#include + +#define _GL_ENDIAN_INLINE _GL_EXTERN_INLINE +#include diff --git a/lib/endian.in.h b/lib/endian.in.h new file mode 100644 index 0000000000..5d755fd7cf --- /dev/null +++ b/lib/endian.in.h @@ -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 . */ + +/* 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 + +/* Byteswap functions. */ +#include + +_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 index 0000000000..ec0d111ae3 --- /dev/null +++ b/m4/endian_h.m4 @@ -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 , 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 +]], +[[ +#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 index 0000000000..9da2d2d19c --- /dev/null +++ b/modules/endian @@ -0,0 +1,44 @@ +Description: +A POSIX-like . + +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 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: + + +License: +LGPLv2+ + +Maintainer: +all -- 2.39.5