diff --git a/libbuild2-autoconf-tests/checks/byte-order/.gitignore b/libbuild2-autoconf-tests/checks/byte-order/.gitignore new file mode 100644 index 0000000..534ba0c --- /dev/null +++ b/libbuild2-autoconf-tests/checks/byte-order/.gitignore @@ -0,0 +1,2 @@ +driver +driver-posix diff --git a/libbuild2-autoconf-tests/checks/byte-order/buildfile b/libbuild2-autoconf-tests/checks/byte-order/buildfile new file mode 100644 index 0000000..1d0346f --- /dev/null +++ b/libbuild2-autoconf-tests/checks/byte-order/buildfile @@ -0,0 +1,23 @@ +# Build two executables: one with no macros defined and one with +# _POSIX_C_SOURCE defined. +# +# _POSIX_C_SOURCE and similar macros can affect whether or not BYTE_ORDER, +# BIG_ENDIAN, and LITTLE_ENDIAN are defined. Only do _POSIX_C_SOURCE here +# because the others are used much less frequently. +# + +./: exe{driver}: c{driver} + +./: h{config}: in{config} + +c.poptions += "-I$out_base" + +if ($c.target.system != 'win32-msvc') +{ + ./: exe{driver-posix}: obje{driver-posix} + + obje{driver-posix}: c{driver} + { + c.poptions += -D_POSIX_C_SOURCE + } +} diff --git a/libbuild2-autoconf-tests/checks/byte-order/config.h.in b/libbuild2-autoconf-tests/checks/byte-order/config.h.in new file mode 100644 index 0000000..d7b4313 --- /dev/null +++ b/libbuild2-autoconf-tests/checks/byte-order/config.h.in @@ -0,0 +1 @@ +#undef BYTE_ORDER diff --git a/libbuild2-autoconf-tests/checks/byte-order/driver.c b/libbuild2-autoconf-tests/checks/byte-order/driver.c new file mode 100644 index 0000000..9eea6d5 --- /dev/null +++ b/libbuild2-autoconf-tests/checks/byte-order/driver.c @@ -0,0 +1,39 @@ +#include // uint32_t + +#include "config.h" + +/* Test that the byte order detected at runtime matches the one detected at + * compile time. + */ + +/* Return: + * + * 0 if the runtime and compile time byte orders match + * + * 1 if the runtime and compile time byte orders do not match + * + * 2 if the BYTE_ORDER macro has a value other than BIG_ENDIAN or + * LITTLE_ENDIAN + * + * 3 if not all of the byte order macros are defined + */ +int +main () +{ +#if !defined(BYTE_ORDER) || !defined(BIG_ENDIAN) || !defined(LITTLE_ENDIAN) + return 3; +#endif + + union { + uint32_t i; + unsigned char a[4]; + } u = {1}; + +#if BYTE_ORDER == LITTLE_ENDIAN + return u.a[0] == 1 ? 0 : 1; +#elif BYTE_ORDER == BIG_ENDIAN + return u.a[3] == 1 ? 0 : 1; +#else + return 2; +#endif +} diff --git a/libbuild2-autoconf/libbuild2/autoconf/checks/BYTE_ORDER.h b/libbuild2-autoconf/libbuild2/autoconf/checks/BYTE_ORDER.h new file mode 100644 index 0000000..475dc32 --- /dev/null +++ b/libbuild2-autoconf/libbuild2/autoconf/checks/BYTE_ORDER.h @@ -0,0 +1,59 @@ +// BYTE_ORDER! + +/* Include the endianness header based on platform. + * + * Each of these headers should define BYTE_ORDER, LITTLE_ENDIAN, BIG_ENDIAN, + * AND PDP_ENDIAN but this can be affected by macros like _ANSI_SOURCE, + * _POSIX_C_SOURCE, _XOPEN_SOURCE and _NETBSD_SOURCE, depending on the + * platform (in which case most of them define underscored versions only). + */ +#if defined(__GLIBC__) || defined(__OpenBSD__) +# include +#elif defined(__FreeBSD__) || defined(__NetBSD__) +# include +#elif defined(__APPLE__) +# include +#elif !defined(_WIN32) +# include +#endif + +/* Try various system- and compiler-specific byte order macro names if the + * endianness headers did not define BYTE_ORDER. + */ +#if !defined(BYTE_ORDER) +# if defined(__linux__) +# if defined(__BYTE_ORDER) +# define BYTE_ORDER __BYTE_ORDER +# define BIG_ENDIAN __BIG_ENDIAN +# define LITTLE_ENDIAN __LITTLE_ENDIAN +# endif +# elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) +# if defined(_BYTE_ORDER) +# define BYTE_ORDER _BYTE_ORDER +# define BIG_ENDIAN _BIG_ENDIAN +# define LITTLE_ENDIAN _LITTLE_ENDIAN +# endif +# elif defined(__APPLE__) +# if defined(__DARWIN_BYTE_ORDER) +# define BYTE_ORDER __DARWIN_BYTE_ORDER +# define BIG_ENDIAN __DARWIN_BIG_ENDIAN +# define LITTLE_ENDIAN __DARWIN_LITTLE_ENDIAN +# endif +# elif defined(_WIN32) +# define BIG_ENDIAN 4321 +# define LITTLE_ENDIAN 1234 +# define BYTE_ORDER LITTLE_ENDIAN +# elif defined(__BYTE_ORDER__) && \ + defined(__ORDER_BIG_ENDIAN__) && \ + defined(__ORDER_LITTLE_ENDIAN__) + /* GCC, Clang (and others, potentially). + */ +# define BYTE_ORDER __BYTE_ORDER__ +# define BIG_ENDIAN __ORDER_BIG_ENDIAN__ +# define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__ +# endif +#endif + +#ifndef BYTE_ORDER +# error no byte order macros defined +#endif diff --git a/libbuild2-autoconf/libbuild2/autoconf/checks/HAVE_BIGENDIAN.h b/libbuild2-autoconf/libbuild2/autoconf/checks/HAVE_BIGENDIAN.h new file mode 100644 index 0000000..87c27b0 --- /dev/null +++ b/libbuild2-autoconf/libbuild2/autoconf/checks/HAVE_BIGENDIAN.h @@ -0,0 +1,7 @@ +// HAVE_BIGENDIAN : BYTE_ORDER + +#undef HAVE_BIGENDIAN + +#if BYTE_ORDER == BIG_ENDIAN +# define HAVE_BIGENDIAN 1 +#endif diff --git a/libbuild2-autoconf/libbuild2/autoconf/checks/WORDS_BIGENDIAN.h b/libbuild2-autoconf/libbuild2/autoconf/checks/WORDS_BIGENDIAN.h new file mode 100644 index 0000000..caa21ae --- /dev/null +++ b/libbuild2-autoconf/libbuild2/autoconf/checks/WORDS_BIGENDIAN.h @@ -0,0 +1,7 @@ +// WORDS_BIGENDIAN : BYTE_ORDER + +#undef WORDS_BIGENDIAN + +#if BYTE_ORDER == BIG_ENDIAN +# define WORDS_BIGENDIAN 1 +#endif