From 03d656652776e0e292f1d890ffdff2898df6adc5 Mon Sep 17 00:00:00 2001 From: Walter Doekes Date: Fri, 29 Apr 2016 11:50:14 +0200 Subject: [PATCH] build: Fix compile error on CentOS5 and other old Linuxen lacking le16toh. Reported by: @mscdex (closes #211) --- configure.ac | 12 +++++++++++- include/config.h.in | 10 ++++++++++ include/endianshim.h | 41 ++++++++++++++++++++++++++++++----------- 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index 1ecf0aee..daf51d03 100644 --- a/configure.ac +++ b/configure.ac @@ -207,7 +207,7 @@ AM_CONDITIONAL(HAVE_EPOLL, test "$epoll" = "yes") # ==================== checks for header files ========================== AC_FUNC_ALLOCA -AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h sys/time.h unistd.h]) +AC_CHECK_HEADERS([arpa/inet.h endian.h fcntl.h limits.h netdb.h netinet/in.h stdlib.h string.h sys/endian.h sys/socket.h sys/time.h unistd.h]) # ===== checks for typedefs, structures and compiler characteristics ==== @@ -229,6 +229,16 @@ AC_FUNC_FORK #AC_FUNC_STRTOD AC_CHECK_FUNCS([alarm dup2 floor gethostname gettimeofday inet_ntoa memmove memset pow regcomp socket sqrt strcasecmp strchr strcspn strdup strerror strncasecmp strrchr strstr strtol strtoul strtoull]) +# Check for le16toh in both endian.h and sys/endian.h (for BSD). +AC_CHECK_DECLS([le16toh], [], [], +[#ifdef HAVE_ENDIAN_H +# include +#endif +#ifdef HAVE_SYS_ENDIAN_H +# include +#endif]) + + # ==================== check for clang/gmock workaround ================= # clang++ falls over the use of is_default_constructible, suggesting diff --git a/include/config.h.in b/include/config.h.in index 4ca8d406..7e26471a 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -24,9 +24,16 @@ /* define if the compiler supports basic C++11 syntax */ #undef HAVE_CXX11 +/* Define to 1 if you have the declaration of `le16toh', and to 0 if you + don't. */ +#undef HAVE_DECL_LE16TOH + /* Define to 1 if you have the `dup2' function. */ #undef HAVE_DUP2 +/* Define to 1 if you have the header file. */ +#undef HAVE_ENDIAN_H + /* This platform supports epoll(7). */ #undef HAVE_EPOLL @@ -180,6 +187,9 @@ /* Define to 1 if you have the `strtoull' function. */ #undef HAVE_STRTOULL +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_ENDIAN_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H diff --git a/include/endianshim.h b/include/endianshim.h index 5867a3a6..ad3f51ab 100644 --- a/include/endianshim.h +++ b/include/endianshim.h @@ -1,25 +1,44 @@ #ifndef ENDIANSHIM_H #define ENDIANSHIM_H 1 -#if defined(__CYGWIN) || defined(__LINUX) -#include -#elif defined(__FreeBSD__) -#include -#elif defined(__DARWIN) +/* Fetch HAVE_ENDIAN_H, HAVE_SYS_ENDIAN_H, HAVE_DECL_LE16TOH */ +#include "config.h" + +#ifdef HAVE_ENDIAN_H +/* Linux and friends. */ +# include +#endif +#ifdef HAVE_SYS_ENDIAN_H +/* BSDs */ +# include +#endif +#if defined(__DARWIN) +/* Darwin does something else. */ #include #endif -#ifdef __DARWIN + +#if defined(__DARWIN) #define le16toh(x) OSSwapLittleToHostInt16(x) -#endif -/* HP-UX 11 is missing byteswap.h, so we provide our own bswap_16() */ -#ifdef __HPUX -#define bswap_16(x) ((uint16_t)( \ +#elif defined(__HPUX) +/* HPUX is big endian (apparently..) */ +#define le16toh(x) ((uint16_t)( \ (((uint16_t)(x)) << 8) | \ (((uint16_t)(x)) >> 8))) -#define le16toh(x) bswap_16(x) +#elif !defined(HAVE_DECL_LE16TOH) || HAVE_DECL_LE16TOH == 0 +/* le16toh() is missing in glibc before 2.9 */ +#if BYTE_ORDER == BIG_ENDIAN +# define le16toh(x) ((uint16_t)( \ + (((uint16_t)(x)) << 8) | \ + (((uint16_t)(x)) >> 8))) +#elif BYTE_ORDER == LITTLE_ENDIAN +# define le16toh(x) (x) +#else /* BYTE_ORDER == */ +# error Unknown endianness #endif +#endif /* !HAVE_DECL_LE16TOH */ + #endif /* ENDIANSHIM_H */