#ifndef VLIBC_INTTYPES_H #define VLIBC_INTTYPES_H /* * vlibc — . * * Extended integer type names, the imax* conversions of the widest signed * type, and the PRI and SCN formatted-I/O macros (C23 7.8). Every macro below * expands to a string literal holding the complete conversion specifier * (length modifier included) for the corresponding type on the * x86_64 LP64 target, where the compiler predefined types are: * * int8_t/uint8_t signed char / unsigned char * int16_t/uint16_t short / unsigned short * int32_t/uint32_t int / unsigned int * int64_t/uint64_t long / unsigned long * int_leastN_t identical to the exact-width types * int_fast8_t signed char; int_fast16/32/64_t are long * intmax_t/uintmax_t long / unsigned long * intptr_t/uintptr_t long / unsigned long * * Design rule (per plan): the fprintf macros name the length modifier of * the PROMOTED argument — printf receives an int for every sub-int type, * so PRId8 is "d", not "hhd" — while the fscanf macros name the * exact-width modifier — scanf receives a pointer, so SCNd8 is "hhd". * Both forms convert the corresponding type correctly under C23 7.8.1; * glibc and musl instead use the exact-width modifier in both families, * which is equally conformant and indistinguishable in behavior for * correctly-typed arguments. * * This header is ISO C core and is present in every profile. */ #include #include #ifdef __cplusplus extern "C" { #endif /* Quotient and remainder of the widest integer division (C23 7.8.1). */ typedef struct imaxdiv_t { intmax_t quot; intmax_t rem; } imaxdiv_t; /* * fprintf macros for the signed exact-width types (argument promotes to * int, or stays long for the 64-bit width). */ #define PRId8 "d" #define PRId16 "d" #define PRId32 "d" #define PRId64 "ld" #define PRIi8 "i" #define PRIi16 "i" #define PRIi32 "i" #define PRIi64 "li" /* fprintf macros for the unsigned exact-width types. */ #define PRIo8 "o" #define PRIo16 "o" #define PRIo32 "o" #define PRIo64 "lo" #define PRIu8 "u" #define PRIu16 "u" #define PRIu32 "u" #define PRIu64 "lu" #define PRIx8 "x" #define PRIx16 "x" #define PRIx32 "x" #define PRIx64 "lx" #define PRIX8 "X" #define PRIX16 "X" #define PRIX32 "X" #define PRIX64 "lX" /* fprintf macros for the signed least-width types (same typedefs as the * exact-width types on x86_64). */ #define PRIdLEAST8 "d" #define PRIdLEAST16 "d" #define PRIdLEAST32 "d" #define PRIdLEAST64 "ld" #define PRIiLEAST8 "i" #define PRIiLEAST16 "i" #define PRIiLEAST32 "i" #define PRIiLEAST64 "li" /* fprintf macros for the unsigned least-width types. */ #define PRIoLEAST8 "o" #define PRIoLEAST16 "o" #define PRIoLEAST32 "o" #define PRIoLEAST64 "lo" #define PRIuLEAST8 "u" #define PRIuLEAST16 "u" #define PRIuLEAST32 "u" #define PRIuLEAST64 "lu" #define PRIxLEAST8 "x" #define PRIxLEAST16 "x" #define PRIxLEAST32 "x" #define PRIxLEAST64 "lx" #define PRIXLEAST8 "X" #define PRIXLEAST16 "X" #define PRIXLEAST32 "X" #define PRIXLEAST64 "lX" /* fprintf macros for the signed fastest types (int_fast8_t is signed char, * which promotes to int; int_fast16/32/64_t are long). */ #define PRIdFAST8 "d" #define PRIdFAST16 "ld" #define PRIdFAST32 "ld" #define PRIdFAST64 "ld" #define PRIiFAST8 "i" #define PRIiFAST16 "li" #define PRIiFAST32 "li" #define PRIiFAST64 "li" /* fprintf macros for the unsigned fastest types. */ #define PRIoFAST8 "o" #define PRIoFAST16 "lo" #define PRIoFAST32 "lo" #define PRIoFAST64 "lo" #define PRIuFAST8 "u" #define PRIuFAST16 "lu" #define PRIuFAST32 "lu" #define PRIuFAST64 "lu" #define PRIxFAST8 "x" #define PRIxFAST16 "lx" #define PRIxFAST32 "lx" #define PRIxFAST64 "lx" #define PRIXFAST8 "X" #define PRIXFAST16 "lX" #define PRIXFAST32 "lX" #define PRIXFAST64 "lX" /* fprintf macros for the widest (intmax_t/uintmax_t) and pointer-width * (intptr_t/uintptr_t) types; both families are long/unsigned long. */ #define PRIdMAX "ld" #define PRIiMAX "li" #define PRIoMAX "lo" #define PRIuMAX "lu" #define PRIxMAX "lx" #define PRIXMAX "lX" #define PRIdPTR "ld" #define PRIiPTR "li" #define PRIoPTR "lo" #define PRIuPTR "lu" #define PRIxPTR "lx" #define PRIXPTR "lX" /* * fscanf macros for the signed exact-width types: the pointer targets the * exact type, so the modifier is hh/h/(none)/l by width. */ #define SCNd8 "hhd" #define SCNd16 "hd" #define SCNd32 "d" #define SCNd64 "ld" #define SCNi8 "hhi" #define SCNi16 "hi" #define SCNi32 "i" #define SCNi64 "li" /* fscanf macros for the unsigned exact-width types. */ #define SCNo8 "hho" #define SCNo16 "ho" #define SCNo32 "o" #define SCNo64 "lo" #define SCNu8 "hhu" #define SCNu16 "hu" #define SCNu32 "u" #define SCNu64 "lu" #define SCNx8 "hhx" #define SCNx16 "hx" #define SCNx32 "x" #define SCNx64 "lx" /* fscanf macros for the signed least-width types (same typedefs as the * exact-width types on x86_64). */ #define SCNdLEAST8 "hhd" #define SCNdLEAST16 "hd" #define SCNdLEAST32 "d" #define SCNdLEAST64 "ld" #define SCNiLEAST8 "hhi" #define SCNiLEAST16 "hi" #define SCNiLEAST32 "i" #define SCNiLEAST64 "li" /* fscanf macros for the unsigned least-width types. */ #define SCNoLEAST8 "hho" #define SCNoLEAST16 "ho" #define SCNoLEAST32 "o" #define SCNoLEAST64 "lo" #define SCNuLEAST8 "hhu" #define SCNuLEAST16 "hu" #define SCNuLEAST32 "u" #define SCNuLEAST64 "lu" #define SCNxLEAST8 "hhx" #define SCNxLEAST16 "hx" #define SCNxLEAST32 "x" #define SCNxLEAST64 "lx" /* fscanf macros for the signed fastest types (int_fast8_t is signed char; * int_fast16/32/64_t are long). */ #define SCNdFAST8 "hhd" #define SCNdFAST16 "ld" #define SCNdFAST32 "ld" #define SCNdFAST64 "ld" #define SCNiFAST8 "hhi" #define SCNiFAST16 "li" #define SCNiFAST32 "li" #define SCNiFAST64 "li" /* fscanf macros for the unsigned fastest types. */ #define SCNoFAST8 "hho" #define SCNoFAST16 "lo" #define SCNoFAST32 "lo" #define SCNoFAST64 "lo" #define SCNuFAST8 "hhu" #define SCNuFAST16 "lu" #define SCNuFAST32 "lu" #define SCNuFAST64 "lu" #define SCNxFAST8 "hhx" #define SCNxFAST16 "lx" #define SCNxFAST32 "lx" #define SCNxFAST64 "lx" /* fscanf macros for the widest and pointer-width types. */ #define SCNdMAX "ld" #define SCNiMAX "li" #define SCNoMAX "lo" #define SCNuMAX "lu" #define SCNxMAX "lx" #define SCNdPTR "ld" #define SCNiPTR "li" #define SCNoPTR "lo" #define SCNuPTR "lu" #define SCNxPTR "lx" /* * Return the absolute value of n. abs(INTMAX_MIN) is not representable; * it wraps (implementation-defined, no errno), matching GCC's two's * complement semantics. * const: result depends only on the argument (GCC predeclares imaxabs * with this attribute, so no weaker one may be used). */ __attribute__((const)) intmax_t imaxabs(intmax_t n); /* * Return { quot, rem } of numer / denom, both truncated toward zero with * the remainder taking the sign of numer (C division semantics). * const: result depends only on the arguments. */ __attribute__((const)) imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom); /* * Convert the initial portion of nptr to intmax_t, as strtol with the * widest signed type. intmax_t is long on x86_64 LP64, so this is an * ABI-identical delegation to strtol (same engine, same errno policy: * ERANGE clamps, EINVAL for a base outside {0} union [2, 36]). */ intmax_t strtoimax(const char *restrict nptr, char **restrict endptr, int base); /* As strtoimax, converted to uintmax_t (unsigned long); negative subject * sequences wrap modulo 2^64 and are never a range error (C23 7.8.2.3). */ uintmax_t strtoumax(const char *restrict nptr, char **restrict endptr, int base); /* * Wide-character forms of strtoimax/strtoumax (C23 7.8.2.4-5). The subject * sequence is scanned from nptr under the same rules as strtol: C-locale * whitespace (L' ' and L'\t'..L'\r'), optional sign, base 0/2..36 with the * 0x/0 prefix rules, ASCII digits only. errno and endptr (of type * wchar_t **) behave exactly as the narrow forms. */ intmax_t wcstoimax(const wchar_t *restrict nptr, wchar_t **restrict endptr, int base); uintmax_t wcstoumax(const wchar_t *restrict nptr, wchar_t **restrict endptr, int base); #ifdef __cplusplus } #endif #endif /* VLIBC_INTTYPES_H */