From 2f4335e0811375370681935c67932f1c2bea094f Mon Sep 17 00:00:00 2001 From: Gabriel Ravier Date: Wed, 29 Mar 2023 09:19:40 +0200 Subject: [PATCH] Fix inttypes.h FAST16 macros to have a correct definition (#791) Cosmopolitan now conforms to the C Standard 7.8.1 specification of the PRI and SCN macros, because this change fixes a bug where the FAST16 ones were incorrectly using the %hd specifier. --- libc/inttypes.h | 28 ++++++------- test/libc/fmt/sscanf_test.c | 82 +++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 14 deletions(-) diff --git a/libc/inttypes.h b/libc/inttypes.h index 7c8e341d8..1b3dcedf6 100644 --- a/libc/inttypes.h +++ b/libc/inttypes.h @@ -86,7 +86,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t; #define PRIdLEAST128 __PRI128 "d" #define PRIdFAST8 __PRI8 "d" -#define PRIdFAST16 __PRI16 "d" +#define PRIdFAST16 __PRI32 "d" #define PRIdFAST32 __PRI32 "d" #define PRIdFAST64 __PRI64 "d" #define PRIdFAST128 __PRI128 "d" @@ -108,7 +108,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t; #define PRIuLEAST128 __PRI128 "u" #define PRIuFAST8 __PRI8 "u" -#define PRIuFAST16 __PRI16 "u" +#define PRIuFAST16 __PRI32 "u" #define PRIuFAST32 __PRI32 "u" #define PRIuFAST64 __PRI64 "u" #define PRIuFAST128 __PRI128 "u" @@ -130,7 +130,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t; #define PRIiLEAST128 __PRI128 "i" #define PRIiFAST8 __PRI8 "i" -#define PRIiFAST16 __PRI16 "i" +#define PRIiFAST16 __PRI32 "i" #define PRIiFAST32 __PRI32 "i" #define PRIiFAST64 __PRI64 "i" #define PRIiFAST128 __PRI128 "i" @@ -152,7 +152,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t; #define PRIoLEAST128 __PRI128 "o" #define PRIoFAST8 __PRI8 "o" -#define PRIoFAST16 __PRI16 "o" +#define PRIoFAST16 __PRI32 "o" #define PRIoFAST32 __PRI32 "o" #define PRIoFAST64 __PRI64 "o" #define PRIoFAST128 __PRI128 "o" @@ -174,7 +174,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t; #define PRIxLEAST128 __PRI128 "x" #define PRIxFAST8 __PRI8 "x" -#define PRIxFAST16 __PRI16 "x" +#define PRIxFAST16 __PRI32 "x" #define PRIxFAST32 __PRI32 "x" #define PRIxFAST64 __PRI64 "x" #define PRIxFAST128 __PRI128 "x" @@ -192,7 +192,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t; #define PRIXLEAST128 __PRI128 "X" #define PRIXFAST8 __PRI8 "X" -#define PRIXFAST16 __PRI16 "X" +#define PRIXFAST16 __PRI32 "X" #define PRIXFAST32 __PRI32 "X" #define PRIXFAST64 __PRI64 "X" #define PRIXFAST128 __PRI128 "X" @@ -214,7 +214,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t; #define PRIbLEAST128 __PRI128 "b" #define PRIbFAST8 __PRI8 "b" -#define PRIbFAST16 __PRI16 "b" +#define PRIbFAST16 __PRI32 "b" #define PRIbFAST32 __PRI32 "b" #define PRIbFAST64 __PRI64 "b" #define PRIbFAST128 __PRI128 "b" @@ -232,7 +232,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t; #define PRIBLEAST128 __PRI128 "B" #define PRIBFAST8 __PRI8 "B" -#define PRIBFAST16 __PRI16 "B" +#define PRIBFAST16 __PRI32 "B" #define PRIBFAST32 __PRI32 "B" #define PRIBFAST64 __PRI64 "B" #define PRIBFAST128 __PRI128 "B" @@ -272,7 +272,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t; #define SCNdLEAST128 __PRI128 "d" #define SCNdFAST8 __PRI8 "d" -#define SCNdFAST16 __PRI16 "d" +#define SCNdFAST16 __PRI32 "d" #define SCNdFAST32 __PRI32 "d" #define SCNdFAST64 __PRI64 "d" #define SCNdFAST128 __PRI128 "d" @@ -294,7 +294,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t; #define SCNiLEAST128 __PRI128 "i" #define SCNiFAST8 __PRI8 "i" -#define SCNiFAST16 __PRI16 "i" +#define SCNiFAST16 __PRI32 "i" #define SCNiFAST32 __PRI32 "i" #define SCNiFAST64 __PRI64 "i" #define SCNiFAST128 __PRI128 "i" @@ -316,7 +316,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t; #define SCNuLEAST128 __PRI128 "u" #define SCNuFAST8 __PRI8 "u" -#define SCNuFAST16 __PRI16 "u" +#define SCNuFAST16 __PRI32 "u" #define SCNuFAST32 __PRI32 "u" #define SCNuFAST64 __PRI64 "u" #define SCNuFAST128 __PRI128 "u" @@ -338,7 +338,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t; #define SCNoLEAST128 __PRI128 "o" #define SCNoFAST8 __PRI8 "o" -#define SCNoFAST16 __PRI16 "o" +#define SCNoFAST16 __PRI32 "o" #define SCNoFAST32 __PRI32 "o" #define SCNoFAST64 __PRI64 "o" #define SCNoFAST128 __PRI128 "o" @@ -360,7 +360,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t; #define SCNxLEAST128 __PRI128 "x" #define SCNxFAST8 __PRI8 "x" -#define SCNxFAST16 __PRI16 "x" +#define SCNxFAST16 __PRI32 "x" #define SCNxFAST32 __PRI32 "x" #define SCNxFAST64 __PRI64 "x" #define SCNxFAST128 __PRI128 "x" @@ -382,7 +382,7 @@ typedef __UINT_FAST64_TYPE__ uint_fast64_t; #define SCNbLEAST128 __PRI128 "b" #define SCNbFAST8 __PRI8 "b" -#define SCNbFAST16 __PRI16 "b" +#define SCNbFAST16 __PRI32 "b" #define SCNbFAST32 __PRI32 "b" #define SCNbFAST64 __PRI64 "b" #define SCNbFAST128 __PRI128 "b" diff --git a/test/libc/fmt/sscanf_test.c b/test/libc/fmt/sscanf_test.c index dfe5b5718..245c6fe86 100644 --- a/test/libc/fmt/sscanf_test.c +++ b/test/libc/fmt/sscanf_test.c @@ -19,6 +19,7 @@ #include "libc/errno.h" #include "libc/fmt/fmt.h" #include "libc/intrin/bits.h" +#include "libc/inttypes.h" #include "libc/limits.h" #include "libc/mem/mem.h" #include "libc/testlib/testlib.h" @@ -149,3 +150,84 @@ TEST(sscanf, testFixedWidthFormat_Integer) { ASSERT_EQ(2, g); ASSERT_EQ(30, b); } + +TEST(sscanf, testInttypes_macros) { + int8_t i8 = (int8_t)0xFFFFFFFFFFFFFFFF; + uint8_t u8 = (uint8_t)0xFFFFFFFFFFFFFFFF; + int16_t i16 = (int16_t)0xFFFFFFFFFFFFFFFF; + uint16_t u16 = (uint16_t)0xFFFFFFFFFFFFFFFF; + int32_t i32 = (int32_t)0xFFFFFFFFFFFFFFFF; + uint32_t u32 = (uint32_t)0xFFFFFFFFFFFFFFFF; + int64_t i64 = (int64_t)0xFFFFFFFFFFFFFFFF; + uint64_t u64 = (uint64_t)0xFFFFFFFFFFFFFFFF; + intmax_t imax = (intmax_t)0xFFFFFFFFFFFFFFFF; + uintmax_t umax = (uintmax_t)0xFFFFFFFFFFFFFFFF; + int_least8_t il8 = (int_least8_t)0xFFFFFFFFFFFFFFFF; + uint_least8_t ul8 = (uint_least8_t)0xFFFFFFFFFFFFFFFF; + int_least16_t il16 = (int_least16_t)0xFFFFFFFFFFFFFFFF; + uint_least16_t ul16 = (uint_least16_t)0xFFFFFFFFFFFFFFFF; + int_least32_t il32 = (int_least32_t)0xFFFFFFFFFFFFFFFF; + uint_least32_t ul32 = (uint_least32_t)0xFFFFFFFFFFFFFFFF; + int_least64_t il64 = (int_least64_t)0xFFFFFFFFFFFFFFFF; + uint_least64_t ul64 = (uint_least64_t)0xFFFFFFFFFFFFFFFF; + int_fast8_t if8 = (int_fast8_t)0xFFFFFFFFFFFFFFFF; + uint_fast8_t uf8 = (uint_fast8_t)0xFFFFFFFFFFFFFFFF; + int_fast16_t if16 = (int_fast16_t)0xFFFFFFFFFFFFFFFF; + uint_fast16_t uf16 = (uint_fast16_t)0xFFFFFFFFFFFFFFFF; + int_fast32_t if32 = (int_fast32_t)0xFFFFFFFFFFFFFFFF; + uint_fast32_t uf32 = (uint_fast32_t)0xFFFFFFFFFFFFFFFF; + int_fast64_t if64 = (int_fast64_t)0xFFFFFFFFFFFFFFFF; + uint_fast64_t uf64 = (uint_fast64_t)0xFFFFFFFFFFFFFFFF; + + ASSERT_EQ(sscanf("1", "%" SCNd8, &i8), 1); + ASSERT_EQ(sscanf("1", "%" SCNu8, &u8), 1); + ASSERT_EQ(sscanf("1", "%" SCNd16, &i16), 1); + ASSERT_EQ(sscanf("1", "%" SCNu16, &u16), 1); + ASSERT_EQ(sscanf("1", "%" SCNd32, &i32), 1); + ASSERT_EQ(sscanf("1", "%" SCNu32, &u32), 1); + ASSERT_EQ(sscanf("1", "%" SCNd64, &i64), 1); + ASSERT_EQ(sscanf("1", "%" SCNu64, &u64), 1); + ASSERT_EQ(sscanf("1", "%" SCNdMAX, &imax), 1); + ASSERT_EQ(sscanf("1", "%" SCNuMAX, &umax), 1); + ASSERT_EQ(sscanf("1", "%" SCNdLEAST8, &il8), 1); + ASSERT_EQ(sscanf("1", "%" SCNuLEAST8, &ul8), 1); + ASSERT_EQ(sscanf("1", "%" SCNdLEAST16, &il16), 1); + ASSERT_EQ(sscanf("1", "%" SCNuLEAST16, &ul16), 1); + ASSERT_EQ(sscanf("1", "%" SCNdLEAST32, &il32), 1); + ASSERT_EQ(sscanf("1", "%" SCNuLEAST32, &ul32), 1); + ASSERT_EQ(sscanf("1", "%" SCNdLEAST64, &il64), 1); + ASSERT_EQ(sscanf("1", "%" SCNuLEAST64, &ul64), 1); + ASSERT_EQ(sscanf("1", "%" SCNdFAST8, &if8), 1); + ASSERT_EQ(sscanf("1", "%" SCNuFAST8, &uf8), 1); + ASSERT_EQ(sscanf("1", "%" SCNdFAST16, &if16), 1); + ASSERT_EQ(sscanf("1", "%" SCNuFAST16, &uf16), 1); + ASSERT_EQ(sscanf("1", "%" SCNdFAST32, &if32), 1); + ASSERT_EQ(sscanf("1", "%" SCNuFAST32, &uf32), 1); + ASSERT_EQ(sscanf("1", "%" SCNdFAST64, &if64), 1); + ASSERT_EQ(sscanf("1", "%" SCNuFAST64, &uf64), 1); + + ASSERT_EQ(i8, 1); + ASSERT_EQ(u8, 1); + ASSERT_EQ(i16, 1); + ASSERT_EQ(u16, 1); + ASSERT_EQ(i32, 1); + ASSERT_EQ(u32, 1); + ASSERT_EQ(i64, 1); + ASSERT_EQ(u64, 1); + ASSERT_EQ(imax, 1); + ASSERT_EQ(umax, 1); + ASSERT_EQ(il8, 1); + ASSERT_EQ(ul8, 1); + ASSERT_EQ(il16, 1); + ASSERT_EQ(ul16, 1); + ASSERT_EQ(il32, 1); + ASSERT_EQ(ul32, 1); + ASSERT_EQ(il64, 1); + ASSERT_EQ(ul64, 1); + ASSERT_EQ(if16, 1); + ASSERT_EQ(uf16, 1); + ASSERT_EQ(if32, 1); + ASSERT_EQ(uf32, 1); + ASSERT_EQ(if64, 1); + ASSERT_EQ(uf64, 1); +}