feat(inttypes): PRI/SCN macros + strtoimax family
This commit is contained in:
@@ -0,0 +1,314 @@
|
||||
#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 */
|
||||
Reference in New Issue
Block a user