Skip to content

Commit 519f3e0

Browse files
committed
[libc] Add putc, fputc, and fprintf to stdio/baremetal
Also groups the *_write_hook into a new header file which can be extended to easily support other [v][f]printf functions
1 parent 8063bd1 commit 519f3e0

File tree

11 files changed

+208
-22
lines changed

11 files changed

+208
-22
lines changed

libc/config/baremetal/aarch64/entrypoints.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,11 @@ set(TARGET_LIBC_ENTRYPOINTS
124124

125125
# stdio.h entrypoints
126126
libc.src.stdio.asprintf
127+
libc.src.stdio.fprintf
128+
libc.src.stdio.fputc
127129
libc.src.stdio.getchar
128130
libc.src.stdio.printf
131+
libc.src.stdio.putc
129132
libc.src.stdio.putchar
130133
libc.src.stdio.puts
131134
libc.src.stdio.remove

libc/config/baremetal/arm/entrypoints.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,11 @@ set(TARGET_LIBC_ENTRYPOINTS
124124

125125
# stdio.h entrypoints
126126
libc.src.stdio.asprintf
127+
libc.src.stdio.fprintf
128+
libc.src.stdio.fputc
127129
libc.src.stdio.getchar
128130
libc.src.stdio.printf
131+
libc.src.stdio.putc
129132
libc.src.stdio.putchar
130133
libc.src.stdio.puts
131134
libc.src.stdio.remove

libc/config/baremetal/riscv/entrypoints.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,11 @@ set(TARGET_LIBC_ENTRYPOINTS
124124

125125
# stdio.h entrypoints
126126
libc.src.stdio.asprintf
127+
libc.src.stdio.fprintf
128+
libc.src.stdio.fputc
127129
libc.src.stdio.getchar
128130
libc.src.stdio.printf
131+
libc.src.stdio.putc
129132
libc.src.stdio.putchar
130133
libc.src.stdio.puts
131134
libc.src.stdio.remove

libc/src/stdio/baremetal/CMakeLists.txt

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1+
add_entrypoint_object(
2+
fprintf
3+
SRCS
4+
fprintf.cpp
5+
HDRS
6+
../fprintf.h
7+
write_utils.h
8+
DEPENDS
9+
libc.src.__support.OSUtil.osutil
10+
libc.src.__support.CPP.string_view
11+
libc.src.stdio.printf_core.printf_main
12+
)
13+
14+
add_entrypoint_object(
15+
fputc
16+
SRCS
17+
fputc.cpp
18+
HDRS
19+
../fputc.h
20+
write_utils.h
21+
DEPENDS
22+
libc.src.__support.CPP.string_view
23+
)
24+
125
add_entrypoint_object(
226
getchar
327
SRCS
@@ -20,12 +44,24 @@ add_entrypoint_object(
2044
libc.include.stdio
2145
)
2246

47+
add_entrypoint_object(
48+
putc
49+
SRCS
50+
putc.cpp
51+
HDRS
52+
../putc.h
53+
write_utils.h
54+
DEPENDS
55+
libc.src.__support.CPP.string_view
56+
)
57+
2358
add_entrypoint_object(
2459
printf
2560
SRCS
2661
printf.cpp
2762
HDRS
2863
../printf.h
64+
write_utils.h
2965
DEPENDS
3066
libc.src.stdio.printf_core.printf_main
3167
libc.src.stdio.printf_core.writer
@@ -102,3 +138,16 @@ add_entrypoint_object(
102138
libc.src.__support.arg_list
103139
libc.src.__support.OSUtil.osutil
104140
)
141+
142+
add_header_library(
143+
baremetal_write_utils
144+
HDRS
145+
write_utils.h
146+
DEPENDS
147+
libc.hdr.types.FILE
148+
libc.hdr.stdio_macros
149+
libc.src.__support.OSUtil.osutil
150+
libc.src.__support.CPP.string_view
151+
.stdout
152+
.stderr
153+
)

libc/src/stdio/baremetal/fprintf.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//===-- Implementation of fprintf for baremetal -----------------*- 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/fprintf.h"
10+
11+
#include "hdr/types/FILE.h"
12+
#include "src/__support/arg_list.h"
13+
#include "src/__support/macros/config.h"
14+
#include "src/stdio/baremetal/write_utils.h"
15+
#include "src/stdio/printf_core/printf_main.h"
16+
17+
#include <stdarg.h>
18+
19+
namespace LIBC_NAMESPACE_DECL {
20+
21+
LLVM_LIBC_FUNCTION(int, fprintf,
22+
(::FILE *__restrict stream, const char *__restrict format,
23+
...)) {
24+
va_list vlist;
25+
va_start(vlist, format);
26+
internal::ArgList args(vlist); // This holder class allows for easier copying
27+
// and pointer semantics, as well as handling
28+
// destruction automatically.
29+
va_end(vlist);
30+
static constexpr size_t BUFF_SIZE = 1024;
31+
char buffer[BUFF_SIZE];
32+
33+
printf_core::WriteBuffer<printf_core::WriteMode::FLUSH_TO_STREAM> wb(
34+
buffer, BUFF_SIZE, get_write_hook(stream), nullptr);
35+
printf_core::Writer<printf_core::WriteMode::FLUSH_TO_STREAM> writer(wb);
36+
37+
int retval = printf_core::printf_main(&writer, format, args);
38+
39+
int flushval = wb.overflow_write("");
40+
if (flushval != printf_core::WRITE_OK)
41+
retval = flushval;
42+
43+
return retval;
44+
}
45+
46+
} // namespace LIBC_NAMESPACE_DECL

libc/src/stdio/baremetal/fputc.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//===-- Baremetal Implementation of fputc ---------------------------------===//
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/fputc.h"
10+
11+
#include "src/__support/CPP/string_view.h"
12+
#include "src/__support/macros/config.h"
13+
#include "src/stdio/baremetal/write_utils.h"
14+
15+
namespace LIBC_NAMESPACE_DECL {
16+
17+
LLVM_LIBC_FUNCTION(int, fputc, (int c, ::FILE *stream)) {
18+
char uc = static_cast<char>(c);
19+
20+
write(stream, cpp::string_view(&uc, 1));
21+
22+
return 0;
23+
}
24+
25+
} // namespace LIBC_NAMESPACE_DECL

libc/src/stdio/baremetal/printf.cpp

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,17 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/stdio/printf.h"
10-
#include "src/__support/OSUtil/io.h"
10+
1111
#include "src/__support/arg_list.h"
1212
#include "src/__support/macros/config.h"
13-
#include "src/stdio/printf_core/core_structs.h"
13+
#include "src/stdio/baremetal/write_utils.h"
1414
#include "src/stdio/printf_core/printf_main.h"
15-
#include "src/stdio/printf_core/writer.h"
1615

1716
#include <stdarg.h>
1817
#include <stddef.h>
1918

2019
namespace LIBC_NAMESPACE_DECL {
2120

22-
namespace {
23-
24-
LIBC_INLINE int stdout_write_hook(cpp::string_view new_str, void *) {
25-
write_to_stdout(new_str);
26-
return printf_core::WRITE_OK;
27-
}
28-
29-
} // namespace
30-
3121
LLVM_LIBC_FUNCTION(int, printf, (const char *__restrict format, ...)) {
3222
va_list vlist;
3323
va_start(vlist, format);

libc/src/stdio/baremetal/putc.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//===-- Baremetal Implementation of putc ----------------------------------===//
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/putc.h"
10+
11+
#include "src/__support/CPP/string_view.h"
12+
#include "src/__support/macros/config.h"
13+
#include "src/stdio/baremetal/write_utils.h"
14+
15+
namespace LIBC_NAMESPACE_DECL {
16+
17+
LLVM_LIBC_FUNCTION(int, putc, (int c, ::FILE *stream)) {
18+
char uc = static_cast<char>(c);
19+
20+
write(stream, cpp::string_view(&uc, 1));
21+
22+
return 0;
23+
}
24+
25+
} // namespace LIBC_NAMESPACE_DECL

libc/src/stdio/baremetal/putchar.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/stdio/putchar.h"
10+
1011
#include "src/__support/CPP/string_view.h"
1112
#include "src/__support/OSUtil/io.h"
1213
#include "src/__support/macros/config.h"
1314

1415
namespace LIBC_NAMESPACE_DECL {
1516

1617
LLVM_LIBC_FUNCTION(int, putchar, (int c)) {
17-
char uc = static_cast<char>(c);
18+
char uc = static_cast<unsigned char>(c);
1819

1920
write_to_stdout(cpp::string_view(&uc, 1));
2021

libc/src/stdio/baremetal/vprintf.cpp

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/stdio/vprintf.h"
10+
1011
#include "src/__support/OSUtil/io.h"
1112
#include "src/__support/arg_list.h"
1213
#include "src/__support/macros/config.h"
14+
#include "src/stdio/baremetal/write_utils.h"
1315
#include "src/stdio/printf_core/core_structs.h"
1416
#include "src/stdio/printf_core/printf_main.h"
1517
#include "src/stdio/printf_core/writer.h"
@@ -19,15 +21,6 @@
1921

2022
namespace LIBC_NAMESPACE_DECL {
2123

22-
namespace {
23-
24-
LIBC_INLINE int stdout_write_hook(cpp::string_view new_str, void *) {
25-
write_to_stdout(new_str);
26-
return printf_core::WRITE_OK;
27-
}
28-
29-
} // namespace
30-
3124
LLVM_LIBC_FUNCTION(int, vprintf,
3225
(const char *__restrict format, va_list vlist)) {
3326
internal::ArgList args(vlist); // This holder class allows for easier copying
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//===-- Baremetal helper functions for writing to stdout/stderr -*- 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 "hdr/stdio_macros.h" // For stdout/err
10+
#include "hdr/types/FILE.h"
11+
#include "src/__support/CPP/string_view.h"
12+
#include "src/__support/OSUtil/io.h"
13+
#include "src/__support/macros/config.h"
14+
#include "src/stdio/printf_core/core_structs.h" // For printf_core::WRITE_OK
15+
16+
#include <stddef.h>
17+
18+
namespace LIBC_NAMESPACE_DECL {
19+
namespace {
20+
21+
LIBC_INLINE int stdout_write_hook(cpp::string_view new_str, void *) {
22+
write_to_stdout(new_str);
23+
return printf_core::WRITE_OK;
24+
}
25+
26+
LIBC_INLINE int stderr_write_hook(cpp::string_view new_str, void *) {
27+
write_to_stderr(new_str);
28+
return printf_core::WRITE_OK;
29+
}
30+
31+
LIBC_INLINE void write(::FILE *f, cpp::string_view new_str) {
32+
if (f == stdout) {
33+
write_to_stdout(new_str);
34+
} else {
35+
write_to_stderr(new_str);
36+
}
37+
}
38+
39+
LIBC_INLINE decltype(&stdout_write_hook) get_write_hook(::FILE *f) {
40+
if (f == stdout) {
41+
return &stdout_write_hook;
42+
}
43+
44+
return &stderr_write_hook;
45+
}
46+
47+
} // namespace
48+
} // namespace LIBC_NAMESPACE_DECL

0 commit comments

Comments
 (0)