Fix floating point parsing on BE systems (#7256)

* Fix floating point parsing on BE systems

* Load the appropriate endian.h files for macOS and BSD

* Add endian definition for Windows and extra check for ldshape selection

* Fix endian macro definition for macOS

Apparently their macros are defined without a leading __.

* Define new macro for endian checking purposes

This is gross and I really do not like the lack of standardization
around this part, but what can I do?
This commit is contained in:
Koakuma 2020-12-04 03:47:06 +07:00 committed by GitHub
parent 7bbd369fbb
commit 5317f00e04
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -10,6 +10,28 @@
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
// Every OSes seem to define endianness macros in different files.
#if defined(__APPLE__)
#include <machine/endian.h>
#define ZIG_BIG_ENDIAN BIG_ENDIAN
#define ZIG_LITTLE_ENDIAN LITTLE_ENDIAN
#define ZIG_BYTE_ORDER BYTE_ORDER
#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/endian.h>
#define ZIG_BIG_ENDIAN _BIG_ENDIAN
#define ZIG_LITTLE_ENDIAN _LITTLE_ENDIAN
#define ZIG_BYTE_ORDER _BYTE_ORDER
#elif defined(_WIN32) || defined(_WIN64)
// Assume that Windows installations are always little endian.
#define ZIG_LITTLE_ENDIAN 1
#define ZIG_BYTE_ORDER ZIG_LITTLE_ENDIAN
#else // Linux
#include <endian.h>
#define ZIG_BIG_ENDIAN __BIG_ENDIAN
#define ZIG_LITTLE_ENDIAN __LITTLE_ENDIAN
#define ZIG_BYTE_ORDER __BYTE_ORDER
#endif
#define shcnt(f) ((f)->shcnt + ((f)->rpos - (f)->buf)) #define shcnt(f) ((f)->shcnt + ((f)->rpos - (f)->buf))
#define shlim(f, lim) __shlim((f), (lim)) #define shlim(f, lim) __shlim((f), (lim))
#define shgetc(f) (((f)->rpos != (f)->shend) ? *(f)->rpos++ : __shgetc(f)) #define shgetc(f) (((f)->rpos != (f)->shend) ? *(f)->rpos++ : __shgetc(f))
@ -47,8 +69,7 @@
#define DECIMAL_DIG 36 #define DECIMAL_DIG 36
#if defined(ZIG_BYTE_ORDER) && ZIG_BYTE_ORDER == ZIG_LITTLE_ENDIAN
#if __BYTE_ORDER == __LITTLE_ENDIAN
union ldshape { union ldshape {
float128_t f; float128_t f;
struct { struct {
@ -62,7 +83,7 @@ union ldshape {
uint64_t hi; uint64_t hi;
} i2; } i2;
}; };
#elif __BYTE_ORDER == __BIG_ENDIAN #elif defined(ZIG_BYTE_ORDER) && ZIG_BYTE_ORDER == ZIG_BIG_ENDIAN
union ldshape { union ldshape {
float128_t f; float128_t f;
struct { struct {
@ -76,6 +97,7 @@ union ldshape {
uint64_t lo; uint64_t lo;
} i2; } i2;
}; };
#else
#error Unsupported endian #error Unsupported endian
#endif #endif