[PATCH] util: detect byte order

Tomi Ollila tomi.ollila at iki.fi
Tue Nov 26 09:42:16 PST 2013


On Tue, Nov 26 2013, david at tethera.net wrote:

> From: David Bremner <david at tethera.net>
>
> Unfortunately old versions of GCC and clang do not provide byte order
> macros, so we re-invent them.

Brief comments inline :D

>
> If UTIL_BYTE_ORDER is not defined, we fall back to macros supported by
> recent versions of GCC and clang

This is not entirely accurate as -DUTIL_BYTE_ORDER=... is given to
compiler... maybe If UTIL_BYTE_ORDER is not defined, empty or zero (?)

> ---
>
> I pushed the series
> id:1385328583-24602-1-git-send-email-david at tethera.net; unfortunately
> that broke compilation on old versions of GCC, in particular on our
> buildbot. Here is a proposed fix for the fix.
>
>  configure          | 26 ++++++++++++++++++++++++--
>  lib/libsha1.c      | 19 +++++--------------
>  util/endian-util.h | 39 +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 68 insertions(+), 16 deletions(-)
>  create mode 100644 util/endian-util.h
>
> diff --git a/configure b/configure
> index 1a8e939..02d6396 100755
> --- a/configure
> +++ b/configure
> @@ -441,6 +441,21 @@ else
>  EOF
>  fi
>  
> +printf "Checking byte order... "
> +cat> _byteorder.c <<EOF
> +#include <stdio.h>
> +#include <stdint.h>
> +#include <string.h>
> +uint32_t test = 0x31323334;
> +char buf[5];
> +int main() { memcpy(buf, &test, 4); buf[4] = '\0'; printf("%s\n", buf); return 0; }
> +EOF
> +${CC} ${CFLAGS} _byteorder.c -o _byteorder > /dev/null 2>&1
> +util_byte_order=$(./_byteorder)
> +echo $util_byte_order

Austin version with 0x34333231

> +
> +#rm -f _byteorder _byteorder.c
> +
>  if [ $errors -gt 0 ]; then
>      cat <<EOF
>  
> @@ -702,6 +717,9 @@ prefix = ${PREFIX}
>  # LIBDIR_IN_LDCONFIG value below is still set correctly.
>  libdir = ${LIBDIR:=\$(prefix)/lib}
>  
> +# byte order within a 32 bit word. 4321 = little, 1234 = big, 0 = guess
> +UTIL_BYTE_ORDER = ${util_byte_order}
> +
>  # Whether libdir is in a path configured into ldconfig
>  LIBDIR_IN_LDCONFIG = ${libdir_in_ldconfig}
>  
> @@ -807,7 +825,9 @@ CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)      \\
>  		   -DHAVE_STRSEP=\$(HAVE_STRSEP)                         \\
>  		   -DSTD_GETPWUID=\$(STD_GETPWUID)                       \\
>  		   -DSTD_ASCTIME=\$(STD_ASCTIME)                         \\
> -		   -DHAVE_XAPIAN_COMPACT=\$(HAVE_XAPIAN_COMPACT)
> +		   -DHAVE_XAPIAN_COMPACT=\$(HAVE_XAPIAN_COMPACT)	 \\
> +		   -DUTIL_BYTE_ORDER=\$(UTIL_BYTE_ORDER)
> +
>  CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)    \\
>  		     \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\
>  		     \$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS)             \\
> @@ -815,6 +835,8 @@ CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS)    \\
>  		     -DHAVE_STRSEP=\$(HAVE_STRSEP)                       \\
>  		     -DSTD_GETPWUID=\$(STD_GETPWUID)                     \\
>  		     -DSTD_ASCTIME=\$(STD_ASCTIME)                       \\
> -		     -DHAVE_XAPIAN_COMPACT=\$(HAVE_XAPIAN_COMPACT)
> +		     -DHAVE_XAPIAN_COMPACT=\$(HAVE_XAPIAN_COMPACT)       \\
> +		     -DUTIL_BYTE_ORDER=\$(UTIL_BYTE_ORDER)
> +
>  CONFIGURE_LDFLAGS =  \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS)
>  EOF
> diff --git a/lib/libsha1.c b/lib/libsha1.c
> index 87c7c52..3566ed7 100644
> --- a/lib/libsha1.c
> +++ b/lib/libsha1.c
> @@ -34,7 +34,7 @@
>  */
>  
>  #include <string.h>     /* for memcpy() etc.        */
> -
> +#include "endian-util.h"
>  #include "libsha1.h"
>  
>  #if defined(__cplusplus)
> @@ -49,20 +49,11 @@ extern "C"
>  
>  #define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00))
>  
> -/* The macros __BYTE_ORDER__ and __ORDER_*_ENDIAN__ are GNU C
> - * extensions. They are also supported by clang as of v3.2 */
> -
> -#ifdef __BYTE_ORDER__
> -#  if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
> -#    define bsw_32(p,n) \
> -       { int _i = (n); while(_i--) ((uint32_t*)p)[_i] = bswap_32(((uint32_t*)p)[_i]); }
> -#  elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
> -#    define bsw_32(p,n)
> -#  else
> -#    error "unknown byte order"
> -#  endif
> +#if (UTIL_BYTE_ORDER == UTIL_ORDER_LITTLE_ENDIAN)
> +#  define bsw_32(p,n) \
> +     { int _i = (n); while(_i--) ((uint32_t*)p)[_i] = bswap_32(((uint32_t*)p)[_i]); }
>  #else
> -#    error "macro __BYTE_ORDER__ is not defined"
> +#  define bsw_32(p,n)
>  #endif

I'd keep the BIG_ENDIAN check too, as we don't know what would happen w/
PDP_ENDIAN...

>  
>  #define SHA1_MASK   (SHA1_BLOCK_SIZE - 1)
> diff --git a/util/endian-util.h b/util/endian-util.h
> new file mode 100644
> index 0000000..cbecf66
> --- /dev/null
> +++ b/util/endian-util.h
> @@ -0,0 +1,39 @@
> +/* this file mimics the macros present in recent GCC and CLANG */
> +
> +#ifndef _ENDIAN_UTIL_H
> +#define _ENDIAN_UTIL_H
> +
> +/* This are prefixed with UTIL to avoid collisions
> + *
> + * You can use something like the following to define UTIL_BYTE_ORDER
> + * in a configure script.
> + */
> +#if 0
> +#include <stdio.h>
> +#include <stdint.h>
> +#include <string.h>
> +uint32_t test = 0x31323334;
> +char buf[5];
> +int main() { memcpy(buf, &test, 4); buf[4] = '\0'; printf("%s\n", buf); return 0; }
> +#endif

The "fixed simpler version" version, or just reference configure.

> +
> +#define UTIL_ORDER_LITTLE_ENDIAN 4321
> +#define UTIL_ORDER_BIG_ENDIAN    1234

swap :D

> +
> +
> +#if !defined(UTIL_BYTE_ORDER) || ((UTIL_BYTE_ORDER != UTIL_ORDER_LITTLE_ENDIAN) && \
> +				   (UTIL_BYTE_ORDER != UTIL_ORDER_LITTLE_ENDIAN))

for "guess" this needs to be #if !UTIL_BYTE_ORDER || ((UTIL_BYTE...
... as UTIL_BYTE_ORDER could be defined as 0 (or empty?) in configure.

$ gcc -dM -DUTIL_BYTE_ORDER= -E - </dev/null | grep -i util
#define UTIL_BYTE_ORDER 


Tomi

> +#ifdef __BYTE_ORDER__
> +#  if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
> +#    define UTIL_BYTE_ORDER UTIL_ORDER_LITTLE_ENDIAN
> +#  elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
> +#    define UTIL_BYTE_ORDER UTIL_ORDER_BIG_ENDIAN
> +#  else
> +#    error "Unsupported __BYTE_ORDER__"
> +#  endif
> +#else
> +#  error "UTIL_BYTE_ORDER not correctly defined and __BYTE_ORDER__ not defined."
> +#endif
> +#endif
> +
> +#endif
> -- 
> 1.8.4.2


More information about the notmuch mailing list