Files

315 lines
8.1 KiB
C

#ifndef VLIBC_INTTYPES_H
#define VLIBC_INTTYPES_H
/*
* vlibc — <inttypes.h>.
*
* 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 <stdint.h> 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 <stddef.h>
#include <stdint.h>
#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 */