Skip to content

File tree

6 files changed

+318
-0
lines changed

6 files changed

+318
-0
lines changed

libc/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ add_gen_header(
7373
DEPENDS
7474
.llvm_libc_common_h
7575
.llvm-libc-types.imaxdiv_t
76+
.llvm-libc-macros.inttypes_macros
7677
)
7778

7879
add_gen_header(

libc/include/inttypes.h.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define LLVM_LIBC_INTTYPES_H
1111

1212
#include <__llvm-libc-common.h>
13+
#include <llvm-libc-macros/inttypes-macros.h>
1314
#include <stdint.h>
1415

1516
%%public_api()

libc/include/llvm-libc-macros/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,3 +221,9 @@ add_macro_header(
221221
HDR
222222
wchar-macros.h
223223
)
224+
225+
add_macro_header(
226+
inttypes_macros
227+
HDR
228+
inttypes-macros.h
229+
)
Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
1+
//===-- Definition of macros from inttypes.h ------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
#ifndef __LLVM_LIBC_MACROS_INTTYPES_MACROS_H
9+
#define __LLVM_LIBC_MACROS_INTTYPES_MACROS_H
10+
11+
// fprintf/scanf format macros.
12+
// POSIX.1-2008, Technical Corrigendum 1, XBD/TC1-2008/0050 [211] is applied.
13+
14+
// clang provides these macros, so we don't need to define them.
15+
// TODO: ISO C23 will provide binary notations.
16+
17+
#ifndef __clang__
18+
#if __UINTPTR_MAX__ == __UINT64_MAX__
19+
#define __PRI64 "l"
20+
#define __PRIPTR "l"
21+
#elif __UINTPTR_MAX__ == __UINT32_MAX__
22+
#define __PRI64 "ll"
23+
#define __PRIPTR ""
24+
#else
25+
// CHERI achitecture for example, has 128-bit pointers that use special "P"
26+
// format.
27+
#error "Unsupported pointer format"
28+
#endif
29+
#define __INT8_FMTd__ "hhd"
30+
#define __INT16_FMTd__ "hd"
31+
#define __INT32_FMTd__ "d"
32+
#define __INT64_FMTd__ __PRI64 "d"
33+
#define __INT_LEAST8_FMTd__ "hhd"
34+
#define __INT_LEAST16_FMTd__ "hd"
35+
#define __INT_LEAST32_FMTd__ "d"
36+
#define __INT_LEAST64_FMTd__ __PRI64 "d"
37+
#define __INT_FAST8_FMTd__ "hhd"
38+
#define __INT_FAST16_FMTd__ "hd"
39+
#define __INT_FAST32_FMTd__ "d"
40+
#define __INT_FAST64_FMTd__ __PRI64 "d"
41+
#define __INTMAX_FMTd__ __PRI64 "d"
42+
#define __INTPTR_FMTd__ __PRIPTR "d"
43+
44+
#define __INT8_FMTi__ "hhi"
45+
#define __INT16_FMTi__ "hi"
46+
#define __INT32_FMTi__ "i"
47+
#define __INT64_FMTi__ __PRI64 "i"
48+
#define __INT_LEAST8_FMTi__ "hhi"
49+
#define __INT_LEAST16_FMTi__ "hi"
50+
#define __INT_LEAST32_FMTi__ "i"
51+
#define __INT_LEAST64_FMTi__ __PRI64 "i"
52+
#define __INT_FAST8_FMTi__ "hhi"
53+
#define __INT_FAST16_FMTi__ "hi"
54+
#define __INT_FAST32_FMTi__ "i"
55+
#define __INT_FAST64_FMTi__ __PRI64 "i"
56+
#define __INTMAX_FMTi__ __PRI64 "i"
57+
#define __INTPTR_FMTi__ __PRIPTR "i"
58+
59+
#define __UINT8_FMTo__ "hho"
60+
#define __UINT16_FMTo__ "ho"
61+
#define __UINT32_FMTo__ "o"
62+
#define __UINT64_FMTo__ __PRI64 "o"
63+
#define __UINT_LEAST8_FMTo__ "hho"
64+
#define __UINT_LEAST16_FMTo__ "ho"
65+
#define __UINT_LEAST32_FMTo__ "o"
66+
#define __UINT_LEAST64_FMTo__ __PRI64 "o"
67+
#define __UINT_FAST8_FMTo__ "hho"
68+
#define __UINT_FAST16_FMTo__ "ho"
69+
#define __UINT_FAST32_FMTo__ "o"
70+
#define __UINT_FAST64_FMTo__ __PRI64 "o"
71+
#define __UINTMAX_FMTo__ __PRI64 "o"
72+
#define __UINTPTR_FMTo__ __PRIPTR "o"
73+
74+
#define __UINT8_FMTu__ "hhu"
75+
#define __UINT16_FMTu__ "hu"
76+
#define __UINT32_FMTu__ "u"
77+
#define __UINT64_FMTu__ __PRI64 "u"
78+
#define __UINT_LEAST8_FMTu__ "hhu"
79+
#define __UINT_LEAST16_FMTu__ "hu"
80+
#define __UINT_LEAST32_FMTu__ "u"
81+
#define __UINT_LEAST64_FMTu__ __PRI64 "u"
82+
#define __UINT_FAST8_FMTu__ "hhu"
83+
#define __UINT_FAST16_FMTu__ "hu"
84+
#define __UINT_FAST32_FMTu__ "u"
85+
#define __UINT_FAST64_FMTu__ __PRI64 "u"
86+
#define __UINTMAX_FMTu__ __PRI64 "u"
87+
#define __UINTPTR_FMTu__ __PRIPTR "u"
88+
89+
#define __UINT8_FMTx__ "hhx"
90+
#define __UINT16_FMTx__ "hx"
91+
#define __UINT32_FMTx__ "x"
92+
#define __UINT64_FMTx__ __PRI64 "x"
93+
#define __UINT_LEAST8_FMTx__ "hhx"
94+
#define __UINT_LEAST16_FMTx__ "hx"
95+
#define __UINT_LEAST32_FMTx__ "x"
96+
#define __UINT_LEAST64_FMTx__ __PRI64 "x"
97+
#define __UINT_FAST8_FMTx__ "hhx"
98+
#define __UINT_FAST16_FMTx__ "hx"
99+
#define __UINT_FAST32_FMTx__ "x"
100+
#define __UINT_FAST64_FMTx__ __PRI64 "x"
101+
#define __UINTMAX_FMTx__ __PRI64 "x"
102+
#define __UINTPTR_FMTx__ __PRIPTR "x"
103+
104+
#define __UINT8_FMTX__ "hhX"
105+
#define __UINT16_FMTX__ "hX"
106+
#define __UINT32_FMTX__ "X"
107+
#define __UINT64_FMTX__ __PRI64 "X"
108+
#define __UINT_LEAST8_FMTX__ "hhX"
109+
#define __UINT_LEAST16_FMTX__ "hX"
110+
#define __UINT_LEAST32_FMTX__ "X"
111+
#define __UINT_LEAST64_FMTX__ __PRI64 "X"
112+
#define __UINT_FAST8_FMTX__ "hhX"
113+
#define __UINT_FAST16_FMTX__ "hX"
114+
#define __UINT_FAST32_FMTX__ "X"
115+
#define __UINT_FAST64_FMTX__ __PRI64 "X"
116+
#define __UINTMAX_FMTX__ __PRI64 "X"
117+
#define __UINTPTR_FMTX__ __PRIPTR "X"
118+
#endif
119+
120+
// The fprintf() macros for signed integers.
121+
#define PRId8 __INT8_FMTd__
122+
#define PRId16 __INT16_FMTd__
123+
#define PRId32 __INT32_FMTd__
124+
#define PRId64 __INT64_FMTd__
125+
#define PRIdLEAST8 __INT_LEAST8_FMTd__
126+
#define PRIdLEAST16 __INT_LEAST16_FMTd__
127+
#define PRIdLEAST32 __INT_LEAST32_FMTd__
128+
#define PRIdLEAST64 __INT_LEAST64_FMTd__
129+
#define PRIdFAST8 __INT_FAST8_FMTd__
130+
#define PRIdFAST16 __INT_FAST16_FMTd__
131+
#define PRIdFAST32 __INT_FAST32_FMTd__
132+
#define PRIdFAST64 __INT_FAST64_FMTd__
133+
#define PRIdMAX __INTMAX_FMTd__
134+
#define PRIdPTR __INTPTR_FMTd__
135+
136+
#define PRIi8 __INT8_FMTi__
137+
#define PRIi16 __INT16_FMTi__
138+
#define PRIi32 __INT32_FMTi__
139+
#define PRIi64 __INT64_FMTi__
140+
#define PRIiLEAST8 __INT_LEAST8_FMTi__
141+
#define PRIiLEAST16 __INT_LEAST16_FMTi__
142+
#define PRIiLEAST32 __INT_LEAST32_FMTi__
143+
#define PRIiLEAST64 __INT_LEAST64_FMTi__
144+
#define PRIiFAST8 __INT_FAST8_FMTi__
145+
#define PRIiFAST16 __INT_FAST16_FMTi__
146+
#define PRIiFAST32 __INT_FAST32_FMTi__
147+
#define PRIiFAST64 __INT_FAST64_FMTi__
148+
#define PRIiMAX __INTMAX_FMTi__
149+
#define PRIiPTR __INTPTR_FMTi__
150+
151+
// The fprintf() macros for unsigned integers.
152+
#define PRIo8 __UINT8_FMTo__
153+
#define PRIo16 __UINT16_FMTo__
154+
#define PRIo32 __UINT32_FMTo__
155+
#define PRIo64 __UINT64_FMTo__
156+
#define PRIoLEAST8 __UINT_LEAST8_FMTo__
157+
#define PRIoLEAST16 __UINT_LEAST16_FMTo__
158+
#define PRIoLEAST32 __UINT_LEAST32_FMTo__
159+
#define PRIoLEAST64 __UINT_LEAST64_FMTo__
160+
#define PRIoFAST8 __UINT_FAST8_FMTo__
161+
#define PRIoFAST16 __UINT_FAST16_FMTo__
162+
#define PRIoFAST32 __UINT_FAST32_FMTo__
163+
#define PRIoFAST64 __UINT_FAST64_FMTo__
164+
#define PRIoMAX __UINTMAX_FMTo__
165+
#define PRIoPTR __UINTPTR_FMTo__
166+
167+
#define PRIu8 __UINT8_FMTu__
168+
#define PRIu16 __UINT16_FMTu__
169+
#define PRIu32 __UINT32_FMTu__
170+
#define PRIu64 __UINT64_FMTu__
171+
#define PRIuLEAST8 __UINT_LEAST8_FMTu__
172+
#define PRIuLEAST16 __UINT_LEAST16_FMTu__
173+
#define PRIuLEAST32 __UINT_LEAST32_FMTu__
174+
#define PRIuLEAST64 __UINT_LEAST64_FMTu__
175+
#define PRIuFAST8 __UINT_FAST8_FMTu__
176+
#define PRIuFAST16 __UINT_FAST16_FMTu__
177+
#define PRIuFAST32 __UINT_FAST32_FMTu__
178+
#define PRIuFAST64 __UINT_FAST64_FMTu__
179+
#define PRIuMAX __UINTMAX_FMTu__
180+
#define PRIuPTR __UINTPTR_FMTu__
181+
182+
#define PRIx8 __UINT8_FMTx__
183+
#define PRIx16 __UINT16_FMTx__
184+
#define PRIx32 __UINT32_FMTx__
185+
#define PRIx64 __UINT64_FMTx__
186+
#define PRIxLEAST8 __UINT_LEAST8_FMTx__
187+
#define PRIxLEAST16 __UINT_LEAST16_FMTx__
188+
#define PRIxLEAST32 __UINT_LEAST32_FMTx__
189+
#define PRIxLEAST64 __UINT_LEAST64_FMTx__
190+
#define PRIxFAST8 __UINT_FAST8_FMTx__
191+
#define PRIxFAST16 __UINT_FAST16_FMTx__
192+
#define PRIxFAST32 __UINT_FAST32_FMTx__
193+
#define PRIxFAST64 __UINT_FAST64_FMTx__
194+
#define PRIxMAX __UINTMAX_FMTx__
195+
#define PRIxPTR __UINTPTR_FMTx__
196+
197+
#define PRIX8 __UINT8_FMTX__
198+
#define PRIX16 __UINT16_FMTX__
199+
#define PRIX32 __UINT32_FMTX__
200+
#define PRIX64 __UINT64_FMTX__
201+
#define PRIXLEAST8 __UINT_LEAST8_FMTX__
202+
#define PRIXLEAST16 __UINT_LEAST16_FMTX__
203+
#define PRIXLEAST32 __UINT_LEAST32_FMTX__
204+
#define PRIXLEAST64 __UINT_LEAST64_FMTX__
205+
#define PRIXFAST8 __UINT_FAST8_FMTX__
206+
#define PRIXFAST16 __UINT_FAST16_FMTX__
207+
#define PRIXFAST32 __UINT_FAST32_FMTX__
208+
#define PRIXFAST64 __UINT_FAST64_FMTX__
209+
#define PRIXMAX __UINTMAX_FMTX__
210+
#define PRIXPTR __UINTPTR_FMTX__
211+
212+
// The fscanf() macros for signed integers.
213+
#define SCNd8 __INT8_FMTd__
214+
#define SCNd16 __INT16_FMTd__
215+
#define SCNd32 __INT32_FMTd__
216+
#define SCNd64 __INT64_FMTd__
217+
#define SCNdLEAST8 __INT_LEAST8_FMTd__
218+
#define SCNdLEAST16 __INT_LEAST16_FMTd__
219+
#define SCNdLEAST32 __INT_LEAST32_FMTd__
220+
#define SCNdLEAST64 __INT_LEAST64_FMTd__
221+
#define SCNdFAST8 __INT_FAST8_FMTd__
222+
#define SCNdFAST16 __INT_FAST16_FMTd__
223+
#define SCNdFAST32 __INT_FAST32_FMTd__
224+
#define SCNdFAST64 __INT_FAST64_FMTd__
225+
#define SCNdMAX __INTMAX_FMTd__
226+
#define SCNdPTR __INTPTR_FMTd__
227+
228+
#define SCNi8 __INT8_FMTi__
229+
#define SCNi16 __INT16_FMTi__
230+
#define SCNi32 __INT32_FMTi__
231+
#define SCNi64 __INT64_FMTi__
232+
#define SCNiLEAST8 __INT_LEAST8_FMTi__
233+
#define SCNiLEAST16 __INT_LEAST16_FMTi__
234+
#define SCNiLEAST32 __INT_LEAST32_FMTi__
235+
#define SCNiLEAST64 __INT_LEAST64_FMTi__
236+
#define SCNiFAST8 __INT_FAST8_FMTi__
237+
#define SCNiFAST16 __INT_FAST16_FMTi__
238+
#define SCNiFAST32 __INT_FAST32_FMTi__
239+
#define SCNiFAST64 __INT_FAST64_FMTi__
240+
#define SCNiMAX __INTMAX_FMTi__
241+
#define SCNiPTR __INTPTR_FMTi__
242+
243+
// The fscanf() macros for unsigned integers.
244+
#define SCNo8 __UINT8_FMTo__
245+
#define SCNo16 __UINT16_FMTo__
246+
#define SCNo32 __UINT32_FMTo__
247+
#define SCNo64 __UINT64_FMTo__
248+
#define SCNoLEAST8 __UINT_LEAST8_FMTo__
249+
#define SCNoLEAST16 __UINT_LEAST16_FMTo__
250+
#define SCNoLEAST32 __UINT_LEAST32_FMTo__
251+
#define SCNoLEAST64 __UINT_LEAST64_FMTo__
252+
#define SCNoFAST8 __UINT_FAST8_FMTo__
253+
#define SCNoFAST16 __UINT_FAST16_FMTo__
254+
#define SCNoFAST32 __UINT_FAST32_FMTo__
255+
#define SCNoFAST64 __UINT_FAST64_FMTo__
256+
#define SCNoMAX __UINTMAX_FMTo__
257+
#define SCNoPTR __UINTPTR_FMTo__
258+
259+
#define SCNu8 __UINT8_FMTu__
260+
#define SCNu16 __UINT16_FMTu__
261+
#define SCNu32 __UINT32_FMTu__
262+
#define SCNu64 __UINT64_FMTu__
263+
#define SCNuLEAST8 __UINT_LEAST8_FMTu__
264+
#define SCNuLEAST16 __UINT_LEAST16_FMTu__
265+
#define SCNuLEAST32 __UINT_LEAST32_FMTu__
266+
#define SCNuLEAST64 __UINT_LEAST64_FMTu__
267+
#define SCNuFAST8 __UINT_FAST8_FMTu__
268+
#define SCNuFAST16 __UINT_FAST16_FMTu__
269+
#define SCNuFAST32 __UINT_FAST32_FMTu__
270+
#define SCNuFAST64 __UINT_FAST64_FMTu__
271+
#define SCNuMAX __UINTMAX_FMTu__
272+
#define SCNuPTR __UINTPTR_FMTu__
273+
274+
#define SCNx8 __UINT8_FMTx__
275+
#define SCNx16 __UINT16_FMTx__
276+
#define SCNx32 __UINT32_FMTx__
277+
#define SCNx64 __UINT64_FMTx__
278+
#define SCNxLEAST8 __UINT_LEAST8_FMTx__
279+
#define SCNxLEAST16 __UINT_LEAST16_FMTx__
280+
#define SCNxLEAST32 __UINT_LEAST32_FMTx__
281+
#define SCNxLEAST64 __UINT_LEAST64_FMTx__
282+
#define SCNxFAST8 __UINT_FAST8_FMTx__
283+
#define SCNxFAST16 __UINT_FAST16_FMTx__
284+
#define SCNxFAST32 __UINT_FAST32_FMTx__
285+
#define SCNxFAST64 __UINT_FAST64_FMTx__
286+
#define SCNxMAX __UINTMAX_FMTx__
287+
#define SCNxPTR __UINTPTR_FMTx__
288+
289+
#endif // __LLVM_LIBC_MACROS_INTTYPES_MACROS_H

libc/test/src/stdio/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ add_fp_unittest(
132132
DEPENDS
133133
libc.src.stdio.sprintf
134134
libc.src.__support.FPUtil.fp_bits
135+
libc.include.inttypes
135136
COMPILE_OPTIONS
136137
${sprintf_test_copts}
137138
)

libc/test/src/stdio/sprintf_test.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "src/__support/FPUtil/FPBits.h"
1212
#include "test/UnitTest/RoundingModeUtils.h"
1313
#include "test/UnitTest/Test.h"
14+
#include <inttypes.h>
1415

1516
// TODO: Add a comment here explaining the printf format string.
1617

@@ -33,6 +34,25 @@ using LIBC_NAMESPACE::fputil::testing::RoundingMode;
3334
EXPECT_EQ(actual_written, static_cast<int>(sizeof(expected_str) - 1)); \
3435
EXPECT_STREQ(actual_str, expected_str);
3536

37+
#define macro_test(FMT, X, expected) \
38+
do { \
39+
for (char &c : buff) { \
40+
c = 0; \
41+
} \
42+
LIBC_NAMESPACE::sprintf(buff, "%" FMT, X); \
43+
ASSERT_STREQ(buff, expected); \
44+
} while (0)
45+
46+
TEST(LlvmLibcSPrintfTest, Macros) {
47+
char buff[128];
48+
macro_test(PRIu8, 1, "1");
49+
macro_test(PRIX16, 0xAA, "AA");
50+
macro_test(PRId32, -123, "-123");
51+
macro_test(PRIX32, 0xFFFFFF85, "FFFFFF85");
52+
macro_test(PRIo8, 0xFF, "377");
53+
macro_test(PRIo64, 0123, "123");
54+
}
55+
3656
TEST(LlvmLibcSPrintfTest, SimpleNoConv) {
3757
char buff[64];
3858
int written;

0 commit comments

Comments
 (0)