Skip to content

Commit afae7c9

Browse files
authored
[libc] Support for scanf on baremetal (llvm#131043)
This uses the templatized scanf Reader interface introduced in llvm#131037.
1 parent 88a51d2 commit afae7c9

File tree

15 files changed

+215
-70
lines changed

15 files changed

+215
-70
lines changed

libc/config/baremetal/aarch64/entrypoints.txt

+6-2
Original file line numberDiff line numberDiff line change
@@ -123,18 +123,22 @@ set(TARGET_LIBC_ENTRYPOINTS
123123
libc.src.inttypes.strtoumax
124124

125125
# stdio.h entrypoints
126+
libc.src.stdio.asprintf
126127
libc.src.stdio.getchar
127128
libc.src.stdio.printf
128129
libc.src.stdio.putchar
129130
libc.src.stdio.puts
130131
libc.src.stdio.remove
132+
libc.src.stdio.scanf
131133
libc.src.stdio.snprintf
132134
libc.src.stdio.sprintf
133-
libc.src.stdio.asprintf
135+
libc.src.stdio.sscanf
136+
libc.src.stdio.vasprintf
134137
libc.src.stdio.vprintf
138+
libc.src.stdio.vscanf
135139
libc.src.stdio.vsnprintf
136140
libc.src.stdio.vsprintf
137-
libc.src.stdio.vasprintf
141+
libc.src.stdio.vsscanf
138142

139143
# stdbit.h entrypoints
140144
libc.src.stdbit.stdc_bit_ceil_uc

libc/config/baremetal/arm/entrypoints.txt

+6-2
Original file line numberDiff line numberDiff line change
@@ -123,18 +123,22 @@ set(TARGET_LIBC_ENTRYPOINTS
123123
libc.src.inttypes.strtoumax
124124

125125
# stdio.h entrypoints
126+
libc.src.stdio.asprintf
126127
libc.src.stdio.getchar
127128
libc.src.stdio.printf
128129
libc.src.stdio.putchar
129130
libc.src.stdio.puts
130131
libc.src.stdio.remove
132+
libc.src.stdio.scanf
131133
libc.src.stdio.snprintf
132134
libc.src.stdio.sprintf
133-
libc.src.stdio.asprintf
135+
libc.src.stdio.sscanf
136+
libc.src.stdio.vasprintf
134137
libc.src.stdio.vprintf
138+
libc.src.stdio.vscanf
135139
libc.src.stdio.vsnprintf
136140
libc.src.stdio.vsprintf
137-
libc.src.stdio.vasprintf
141+
libc.src.stdio.vsscanf
138142

139143
# stdbit.h entrypoints
140144
libc.src.stdbit.stdc_bit_ceil_uc

libc/config/baremetal/riscv/entrypoints.txt

+6-2
Original file line numberDiff line numberDiff line change
@@ -119,18 +119,22 @@ set(TARGET_LIBC_ENTRYPOINTS
119119
libc.src.inttypes.strtoumax
120120

121121
# stdio.h entrypoints
122+
libc.src.stdio.asprintf
122123
libc.src.stdio.getchar
123124
libc.src.stdio.printf
124125
libc.src.stdio.putchar
125126
libc.src.stdio.puts
126127
libc.src.stdio.remove
128+
libc.src.stdio.scanf
127129
libc.src.stdio.snprintf
128130
libc.src.stdio.sprintf
129-
libc.src.stdio.asprintf
131+
libc.src.stdio.sscanf
132+
libc.src.stdio.vasprintf
130133
libc.src.stdio.vprintf
134+
libc.src.stdio.vscanf
131135
libc.src.stdio.vsnprintf
132136
libc.src.stdio.vsprintf
133-
libc.src.stdio.vasprintf
137+
libc.src.stdio.vsscanf
134138

135139
# stdbit.h entrypoints
136140
libc.src.stdbit.stdc_bit_ceil_uc

libc/src/stdio/CMakeLists.txt

+4-54
Original file line numberDiff line numberDiff line change
@@ -95,20 +95,6 @@ add_entrypoint_object(
9595
libc.src.__support.File.platform_file
9696
)
9797

98-
list(APPEND scanf_deps
99-
libc.src.__support.arg_list
100-
libc.src.stdio.scanf_core.vfscanf_internal
101-
libc.hdr.types.FILE
102-
)
103-
104-
if(LLVM_LIBC_FULL_BUILD AND NOT LIBC_TARGET_OS_IS_GPU)
105-
list(APPEND scanf_deps
106-
libc.src.__support.File.file
107-
libc.src.__support.File.platform_file
108-
libc.src.__support.File.platform_stdin
109-
)
110-
endif()
111-
11298
add_entrypoint_object(
11399
sscanf
114100
SRCS
@@ -133,46 +119,6 @@ add_entrypoint_object(
133119
libc.src.stdio.scanf_core.string_reader
134120
)
135121

136-
add_entrypoint_object(
137-
fscanf
138-
SRCS
139-
fscanf.cpp
140-
HDRS
141-
fscanf.h
142-
DEPENDS
143-
${scanf_deps}
144-
)
145-
146-
add_entrypoint_object(
147-
vfscanf
148-
SRCS
149-
vfscanf.cpp
150-
HDRS
151-
vfscanf.h
152-
DEPENDS
153-
${scanf_deps}
154-
)
155-
156-
add_entrypoint_object(
157-
scanf
158-
SRCS
159-
scanf.cpp
160-
HDRS
161-
scanf.h
162-
DEPENDS
163-
${scanf_deps}
164-
)
165-
166-
add_entrypoint_object(
167-
vscanf
168-
SRCS
169-
vscanf.cpp
170-
HDRS
171-
vscanf.h
172-
DEPENDS
173-
${scanf_deps}
174-
)
175-
176122
add_entrypoint_object(
177123
sprintf
178124
SRCS
@@ -295,8 +241,12 @@ add_stdio_entrypoint_object(getchar)
295241
add_stdio_entrypoint_object(getchar_unlocked)
296242
add_stdio_entrypoint_object(fgets)
297243
add_stdio_entrypoint_object(ungetc)
244+
add_stdio_entrypoint_object(scanf)
245+
add_stdio_entrypoint_object(fscanf)
298246
add_stdio_entrypoint_object(stdin)
299247
add_stdio_entrypoint_object(stdout)
300248
add_stdio_entrypoint_object(stderr)
301249
add_stdio_entrypoint_object(vprintf)
302250
add_stdio_entrypoint_object(vfprintf)
251+
add_stdio_entrypoint_object(vscanf)
252+
add_stdio_entrypoint_object(vfscanf)

libc/src/stdio/baremetal/CMakeLists.txt

+35
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,28 @@ add_entrypoint_object(
5555
libc.src.__support.CPP.string_view
5656
)
5757

58+
add_header_library(
59+
scanf_internal
60+
HDRS
61+
scanf_internal.h
62+
DEPENDS
63+
libc.src.stdio.scanf_core.reader
64+
libc.src.__support.OSUtil.osutil
65+
)
66+
67+
add_entrypoint_object(
68+
scanf
69+
SRCS
70+
scanf.cpp
71+
HDRS
72+
../scanf.h
73+
DEPENDS
74+
.scanf_internal
75+
libc.src.stdio.scanf_core.scanf_main
76+
libc.src.__support.arg_list
77+
libc.src.__support.OSUtil.osutil
78+
)
79+
5880
add_entrypoint_object(
5981
vprintf
6082
SRCS
@@ -67,3 +89,16 @@ add_entrypoint_object(
6789
libc.src.__support.arg_list
6890
libc.src.__support.OSUtil.osutil
6991
)
92+
93+
add_entrypoint_object(
94+
vscanf
95+
SRCS
96+
vscanf.cpp
97+
HDRS
98+
../vscanf.h
99+
DEPENDS
100+
.scanf_internal
101+
libc.src.stdio.scanf_core.scanf_main
102+
libc.src.__support.arg_list
103+
libc.src.__support.OSUtil.osutil
104+
)

libc/src/stdio/baremetal/getchar.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace LIBC_NAMESPACE_DECL {
1717
LLVM_LIBC_FUNCTION(int, getchar, ()) {
1818
char buf[1];
1919
auto result = read_from_stdin(buf, sizeof(buf));
20-
if (result < 0)
20+
if (result <= 0)
2121
return EOF;
2222
return buf[0];
2323
}

libc/src/stdio/baremetal/scanf.cpp

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//===-- Implementation of scanf ---------------------------------*- C++ -*-===//
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+
9+
#include "src/stdio/scanf.h"
10+
11+
#include "hdr/stdio_macros.h"
12+
#include "src/__support/OSUtil/io.h"
13+
#include "src/__support/arg_list.h"
14+
#include "src/__support/macros/config.h"
15+
#include "src/stdio/baremetal/scanf_internal.h"
16+
#include "src/stdio/scanf_core/scanf_main.h"
17+
18+
#include <stdarg.h>
19+
20+
namespace LIBC_NAMESPACE_DECL {
21+
22+
LLVM_LIBC_FUNCTION(int, scanf, (const char *__restrict format, ...)) {
23+
va_list vlist;
24+
va_start(vlist, format);
25+
internal::ArgList args(vlist); // This holder class allows for easier copying
26+
// and pointer semantics, as well as handling
27+
// destruction automatically.
28+
va_end(vlist);
29+
30+
scanf_core::StdinReader reader;
31+
int retval = scanf_core::scanf_main(&reader, format, args);
32+
// This is done to avoid including stdio.h in the internals. On most systems
33+
// EOF is -1, so this will be transformed into just "return retval".
34+
return (retval == -1) ? EOF : retval;
35+
}
36+
37+
} // namespace LIBC_NAMESPACE_DECL
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//===-- Internal implementation header of scanf -----------------*- C++ -*-===//
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+
9+
#include "src/__support/OSUtil/io.h"
10+
#include "src/__support/macros/config.h"
11+
#include "src/stdio/scanf_core/reader.h"
12+
13+
namespace LIBC_NAMESPACE_DECL {
14+
15+
namespace scanf_core {
16+
17+
struct StdinReader : public Reader<StdinReader> {
18+
LIBC_INLINE char getc() {
19+
char buf[1];
20+
auto result = read_from_stdin(buf, sizeof(buf));
21+
if (result <= 0)
22+
return EOF;
23+
return buf[0];
24+
}
25+
LIBC_INLINE void ungetc(int) {}
26+
};
27+
28+
} // namespace scanf_core
29+
30+
} // namespace LIBC_NAMESPACE_DECL

libc/src/stdio/baremetal/vscanf.cpp

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//===-- Implementation of vscanf --------------------------------*- C++ -*-===//
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+
9+
#include "src/stdio/vscanf.h"
10+
11+
#include "hdr/stdio_macros.h"
12+
#include "src/__support/OSUtil/io.h"
13+
#include "src/__support/arg_list.h"
14+
#include "src/__support/macros/config.h"
15+
#include "src/stdio/baremetal/scanf_internal.h"
16+
#include "src/stdio/scanf_core/scanf_main.h"
17+
18+
#include <stdarg.h>
19+
20+
namespace LIBC_NAMESPACE_DECL {
21+
22+
LLVM_LIBC_FUNCTION(int, vscanf,
23+
(const char *__restrict format, va_list vlist)) {
24+
internal::ArgList args(vlist); // This holder class allows for easier copying
25+
// and pointer semantics, as well as handling
26+
// destruction automatically.
27+
va_end(vlist);
28+
29+
scanf_core::StdinReader reader;
30+
int retval = scanf_core::scanf_main(&reader, format, args);
31+
// This is done to avoid including stdio.h in the internals. On most systems
32+
// EOF is -1, so this will be transformed into just "return retval".
33+
return (retval == -1) ? EOF : retval;
34+
}
35+
36+
} // namespace LIBC_NAMESPACE_DECL

libc/src/stdio/generic/CMakeLists.txt

+54
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,60 @@ add_entrypoint_object(
425425
${fprintf_deps}
426426
)
427427

428+
list(APPEND scanf_deps
429+
libc.src.__support.arg_list
430+
libc.src.stdio.scanf_core.vfscanf_internal
431+
libc.hdr.types.FILE
432+
)
433+
434+
if(LLVM_LIBC_FULL_BUILD AND NOT LIBC_TARGET_OS_IS_GPU)
435+
list(APPEND scanf_deps
436+
libc.src.__support.File.file
437+
libc.src.__support.File.platform_file
438+
libc.src.__support.File.platform_stdin
439+
)
440+
endif()
441+
442+
add_entrypoint_object(
443+
fscanf
444+
SRCS
445+
fscanf.cpp
446+
HDRS
447+
../fscanf.h
448+
DEPENDS
449+
${scanf_deps}
450+
)
451+
452+
add_entrypoint_object(
453+
vfscanf
454+
SRCS
455+
vfscanf.cpp
456+
HDRS
457+
../vfscanf.h
458+
DEPENDS
459+
${scanf_deps}
460+
)
461+
462+
add_entrypoint_object(
463+
scanf
464+
SRCS
465+
scanf.cpp
466+
HDRS
467+
../scanf.h
468+
DEPENDS
469+
${scanf_deps}
470+
)
471+
472+
add_entrypoint_object(
473+
vscanf
474+
SRCS
475+
vscanf.cpp
476+
HDRS
477+
../vscanf.h
478+
DEPENDS
479+
${scanf_deps}
480+
)
481+
428482
add_entrypoint_object(
429483
fgets
430484
SRCS
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)