master ohmu/fastfetch-openbsd / src / common / endian.h
ohmu  ·  2026-10-15
 1#pragma once
 2
 3#include <stdint.h>
 4
 5// `__BIG_ENDIAN__` alone is not enough: GCC does not define it, it documents only `__BYTE_ORDER__`
 6// and the `__ORDER_*_ENDIAN__` values. Testing the former silently selected the little-endian
 7// branch on s390x, where `FF_READ_BE` then byte-swapped values that were already big-endian.
 8// `defined(__BIG_ENDIAN__)` alone would not do either: a macro that is defined as 0 is not a
 9// big-endian platform.
10#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || (defined(__BIG_ENDIAN__) && __BIG_ENDIAN__)
11    #define FF_READ_LE(x) _Generic((x), \
12        uint16_t: __builtin_bswap16(x), \
13        uint32_t: __builtin_bswap32(x), \
14        uint64_t: __builtin_bswap64(x))
15    #define FF_READ_BE(x) (x)
16#else
17    #define FF_READ_LE(x) (x)
18    #define FF_READ_BE(x) _Generic((x), \
19        uint16_t: __builtin_bswap16(x), \
20        uint32_t: __builtin_bswap32(x), \
21        uint64_t: __builtin_bswap64(x))
22#endif