Add checks for endianness

This commit is contained in:
Francois Kritzinger 2022-01-14 15:27:20 +02:00
parent d72596f486
commit 17aa02d771
7 changed files with 138 additions and 0 deletions

View File

@ -0,0 +1,2 @@
driver
driver-posix

View File

@ -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
}
}

View File

@ -0,0 +1 @@
#undef BYTE_ORDER

View File

@ -0,0 +1,39 @@
#include <stdint.h> // 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
}

View File

@ -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 <endian.h>
#elif defined(__FreeBSD__) || defined(__NetBSD__)
# include <sys/endian.h>
#elif defined(__APPLE__)
# include <machine/endian.h>
#elif !defined(_WIN32)
# include <sys/param.h>
#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

View File

@ -0,0 +1,7 @@
// HAVE_BIGENDIAN : BYTE_ORDER
#undef HAVE_BIGENDIAN
#if BYTE_ORDER == BIG_ENDIAN
# define HAVE_BIGENDIAN 1
#endif

View File

@ -0,0 +1,7 @@
// WORDS_BIGENDIAN : BYTE_ORDER
#undef WORDS_BIGENDIAN
#if BYTE_ORDER == BIG_ENDIAN
# define WORDS_BIGENDIAN 1
#endif