77 lines
2.3 KiB
C
77 lines
2.3 KiB
C
/* Focused compile smoke test for compat/msvc600/stdint.h.
|
|
*
|
|
* The VC6 compatibility header forwards to the existing
|
|
* compat/msvc600/inttypes.h typedefs. This fixture exercises exactly the
|
|
* subset that cpython/Modules/_blake2/impl/blake2-impl.h needs: uint8_t,
|
|
* uint32_t, and uint64_t, in the same load/store/rotate shapes that file
|
|
* uses, plus a compile-time width check for each. It also includes
|
|
* <inttypes.h> alongside <stdint.h> in the same translation unit, the way
|
|
* a Python.h + blake2.h translation unit would, to guard against the
|
|
* duplicate-typedef failure mode the stdint.h header is designed to avoid.
|
|
*/
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <inttypes.h>
|
|
#include <string.h>
|
|
|
|
typedef char vc6_stdint_check_uint8_is_1_byte[(sizeof(uint8_t) == 1) ? 1 : -1];
|
|
typedef char vc6_stdint_check_uint32_is_4_bytes[(sizeof(uint32_t) == 4) ? 1 : -1];
|
|
typedef char vc6_stdint_check_uint64_is_8_bytes[(sizeof(uint64_t) == 8) ? 1 : -1];
|
|
|
|
static uint32_t
|
|
vc6_stdint_load32(const void *src)
|
|
{
|
|
const uint8_t *p = (const uint8_t *)src;
|
|
uint32_t w = *p++;
|
|
w |= ((uint32_t)(*p++)) << 8;
|
|
w |= ((uint32_t)(*p++)) << 16;
|
|
w |= ((uint32_t)(*p++)) << 24;
|
|
return w;
|
|
}
|
|
|
|
static uint64_t
|
|
vc6_stdint_load64(const void *src)
|
|
{
|
|
const uint8_t *p = (const uint8_t *)src;
|
|
uint64_t w = *p++;
|
|
w |= ((uint64_t)(*p++)) << 8;
|
|
w |= ((uint64_t)(*p++)) << 16;
|
|
w |= ((uint64_t)(*p++)) << 24;
|
|
w |= ((uint64_t)(*p++)) << 32;
|
|
w |= ((uint64_t)(*p++)) << 40;
|
|
w |= ((uint64_t)(*p++)) << 48;
|
|
w |= ((uint64_t)(*p++)) << 56;
|
|
return w;
|
|
}
|
|
|
|
static uint32_t
|
|
vc6_stdint_rotl32(const uint32_t w, const unsigned c)
|
|
{
|
|
return (w << c) | (w >> (32 - c));
|
|
}
|
|
|
|
static uint64_t
|
|
vc6_stdint_rotl64(const uint64_t w, const unsigned c)
|
|
{
|
|
return (w << c) | (w >> (64 - c));
|
|
}
|
|
|
|
int
|
|
vc6_stdint_smoke(void)
|
|
{
|
|
static const uint8_t bytes32[4] = { 0x01, 0x02, 0x03, 0x04 };
|
|
static const uint8_t bytes64[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
|
|
uint32_t w32;
|
|
uint64_t w64;
|
|
int ok;
|
|
|
|
w32 = vc6_stdint_load32(bytes32);
|
|
w64 = vc6_stdint_load64(bytes64);
|
|
|
|
ok = 1;
|
|
ok = ok && (w32 == 0x04030201UL);
|
|
ok = ok && (vc6_stdint_rotl32(w32, 8) == ((w32 << 8) | (w32 >> 24)));
|
|
ok = ok && (vc6_stdint_rotl64(w64, 8) == ((w64 << 8) | (w64 >> 56)));
|
|
return ok ? 0 : 1;
|
|
}
|