[PATCH v2] util: detect byte order

Tomi Ollila tomi.ollila at iki.fi
Wed Nov 27 00:04:24 PST 2013


On Wed, Nov 27 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.
>
> If UTIL_BYTE_ORDER is not defined or defined to 0, we fall back to
> macros supported by recent versions of GCC and clang
> ---
>
> I think I got all of Tomi's comments, including the most serious one
> about the test in endian-utils.h (LITTLE twice instead of BIG,
> LITTLE).

Agreed. LGTM.

You may want to amend the '#' out of the line

+#rm -f _byteorder _byteorder.c

before pushing ?

Tomi


>
>  configure          | 24 ++++++++++++++++++++++--
>  lib/libsha1.c      | 21 +++++++--------------
>  util/endian-util.h | 38 ++++++++++++++++++++++++++++++++++++++
>  3 files changed, 67 insertions(+), 16 deletions(-)
>  create mode 100644 util/endian-util.h
>
> diff --git a/configure b/configure
> index 1a8e939..a0c6771 100755
> --- a/configure
> +++ b/configure
> @@ -441,6 +441,19 @@ else
>  EOF
>  fi
>  
> +printf "Checking byte order... "
> +cat> _byteorder.c <<EOF
> +#include <stdio.h>
> +#include <stdint.h>
> +uint32_t test = 0x34333231;
> +int main() { printf("%.4s\n", (const char*)&test); return 0; }
> +EOF
> +${CC} ${CFLAGS} _byteorder.c -o _byteorder > /dev/null 2>&1
> +util_byte_order=$(./_byteorder)
> +echo $util_byte_order
> +
> +#rm -f _byteorder _byteorder.c
> +
>  if [ $errors -gt 0 ]; then
>      cat <<EOF
>  
> @@ -702,6 +715,9 @@ prefix = ${PREFIX}
>  # LIBDIR_IN_LDCONFIG value below is still set correctly.
>  libdir = ${LIBDIR:=\$(prefix)/lib}
>  
> +# byte order within a 32 bit word. 1234 = little, 4321 = 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 +823,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 +833,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..aaaa4eb 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,13 @@ 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]); }
> +#elif (UTIL_BYTE_ORDER == UTIL_ORDER_BIG_ENDIAN)
> +#  define bsw_32(p,n)
>  #else
> -#    error "macro __BYTE_ORDER__ is not defined"
> +#  error "Unsupported byte order"
>  #endif
>  
>  #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..bc80c40
> --- /dev/null
> +++ b/util/endian-util.h
> @@ -0,0 +1,38 @@
> +/* 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>
> +uint32_t test = 0x34333231;
> +int main() { printf("%.4s\n", (const char*)&test); return 0; }
> +#endif
> +
> +#define UTIL_ORDER_BIG_ENDIAN	  4321
> +#define UTIL_ORDER_LITTLE_ENDIAN  1234
> +
> +
> +#if !defined(UTIL_BYTE_ORDER) || ((UTIL_BYTE_ORDER != UTIL_ORDER_BIG_ENDIAN) && \
> +				  (UTIL_BYTE_ORDER != UTIL_ORDER_LITTLE_ENDIAN))
> +#undef UTIL_BYTE_ORDER
> +#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
>
> _______________________________________________
> notmuch mailing list
> notmuch at notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch


More information about the notmuch mailing list