[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