// Minimal inttypes.h for the W65816 runtime.  Pulls in stdint.h's
// fixed-width types and adds the printf/scanf format-string macros
// for those types.  Standalone (does not include the host clang's
// inttypes.h, which pulls in glibc headers and breaks the build).

#ifndef _INTTYPES_H
#define _INTTYPES_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>

// strtoimax / strtoumax — `intmax_t` is 64-bit on this target.  The
// runtime's strtoll / strtoull cover the 64-bit forms; these wrappers
// just route through.  imaxabs / imaxdiv handle |x| and quot+rem for
// the same width.
extern long long          strtoll (const char *nptr, char **endptr, int base);
extern unsigned long long strtoull(const char *nptr, char **endptr, int base);
static inline intmax_t  strtoimax(const char *n, char **e, int b) { return strtoll (n, e, b); }
static inline uintmax_t strtoumax(const char *n, char **e, int b) { return strtoull(n, e, b); }

extern long long llabs(long long n);
static inline intmax_t imaxabs(intmax_t n) { return llabs(n); }

typedef struct { intmax_t quot; intmax_t rem; } imaxdiv_t;
static inline imaxdiv_t imaxdiv(intmax_t n, intmax_t d) {
    imaxdiv_t r;
    r.quot = n / d;
    r.rem  = n - r.quot * d;
    return r;
}

// **WARNING — limited printf support.**  The runtime's printf /
// snprintf understand the `l` length modifier (long, 32-bit) but
// NOT `ll` (long long, 64-bit).  Using PRId64 / PRIu64 / PRIx64
// will compile but the runtime treats the format as a literal
// "%lld" rather than reading 8 bytes off the va_list — wrong output
// AND a stack misalignment for any subsequent args.  For 32-bit
// values, PRId32 / PRIu32 / PRIx32 work correctly.

#define PRId8  "d"
#define PRIi8  "i"
#define PRIo8  "o"
#define PRIu8  "u"
#define PRIx8  "x"
#define PRIX8  "X"

#define PRId16 "d"
#define PRIi16 "i"
#define PRIo16 "o"
#define PRIu16 "u"
#define PRIx16 "x"
#define PRIX16 "X"

#define PRId32 "ld"
#define PRIi32 "li"
#define PRIo32 "lo"
#define PRIu32 "lu"
#define PRIx32 "lx"
#define PRIX32 "lX"

#define PRId64 "lld"
#define PRIi64 "lli"
#define PRIo64 "llo"
#define PRIu64 "llu"
#define PRIx64 "llx"
#define PRIX64 "llX"

#define PRIdMAX  PRId64
#define PRIuMAX  PRIu64
#define PRIxMAX  PRIx64

#define PRIdPTR  PRId16
#define PRIiPTR  PRIi16
#define PRIuPTR  PRIu16
#define PRIxPTR  PRIx16

#ifdef __cplusplus
}
#endif

#endif
