[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