diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt index bf59ba6b0a3ea..0e314c60870c6 100644 --- a/libc/config/gpu/entrypoints.txt +++ b/libc/config/gpu/entrypoints.txt @@ -88,6 +88,10 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.stdio.fclose libc.src.stdio.fread libc.src.stdio.fputs + libc.src.stdio.fwrite + libc.src.stdio.fputc + libc.src.stdio.putc + libc.src.stdio.putchar libc.src.stdio.stdin libc.src.stdio.stdout libc.src.stdio.stderr diff --git a/libc/docs/gpu/support.rst b/libc/docs/gpu/support.rst index 3e8de03050332..fabdfb968a741 100644 --- a/libc/docs/gpu/support.rst +++ b/libc/docs/gpu/support.rst @@ -118,20 +118,24 @@ strtoumax |check| ============= ========= ============ stdio.h --------- +------- ============= ========= ============ Function Name Available RPC Required ============= ========= ============ puts |check| |check| fputs |check| |check| +fputc |check| |check| +fwrite |check| |check| +putc |check| |check| +putchar |check| |check| fclose |check| |check| fopen |check| |check| fread |check| |check| ============= ========= ============ time.h --------- +------ ============= ========= ============ Function Name Available RPC Required diff --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt index 79863f83c1e5e..740ec106da2e4 100644 --- a/libc/src/stdio/CMakeLists.txt +++ b/libc/src/stdio/CMakeLists.txt @@ -229,71 +229,6 @@ add_entrypoint_object( libc.src.__support.File.platform_file ) -add_entrypoint_object( - fwrite_unlocked - SRCS - fwrite_unlocked.cpp - HDRS - fwrite_unlocked.h - DEPENDS - libc.src.errno.errno - libc.include.stdio - libc.src.__support.File.file - libc.src.__support.File.platform_file -) - -add_entrypoint_object( - fwrite - SRCS - fwrite.cpp - HDRS - fwrite.h - DEPENDS - libc.src.errno.errno - libc.include.stdio - libc.src.__support.File.file - libc.src.__support.File.platform_file -) - -add_entrypoint_object( - fputc - SRCS - fputc.cpp - HDRS - fputc.h - DEPENDS - libc.src.errno.errno - libc.include.stdio - libc.src.__support.File.file - libc.src.__support.File.platform_file -) - -add_entrypoint_object( - putc - SRCS - putc.cpp - HDRS - putc.h - DEPENDS - libc.src.errno.errno - libc.include.stdio - libc.src.__support.File.file - libc.src.__support.File.platform_file -) - -add_entrypoint_object( - putchar - SRCS - putchar.cpp - HDRS - putchar.h - DEPENDS - libc.src.errno.errno - libc.include.stdio - libc.src.__support.File.file - libc.src.__support.File.platform_file -) - add_entrypoint_object( fseek SRCS @@ -538,6 +473,11 @@ add_stdio_entrypoint_object(fread_unlocked) add_stdio_entrypoint_object(fread) add_stdio_entrypoint_object(puts) add_stdio_entrypoint_object(fputs) +add_stdio_entrypoint_object(fwrite_unlocked) +add_stdio_entrypoint_object(fwrite) +add_stdio_entrypoint_object(fputc) +add_stdio_entrypoint_object(putc) +add_stdio_entrypoint_object(putchar) add_stdio_entrypoint_object(stdin) add_stdio_entrypoint_object(stdout) add_stdio_entrypoint_object(stderr) diff --git a/libc/src/stdio/generic/CMakeLists.txt b/libc/src/stdio/generic/CMakeLists.txt index 8d14d9fbf6f24..e40e2cc9e04d3 100644 --- a/libc/src/stdio/generic/CMakeLists.txt +++ b/libc/src/stdio/generic/CMakeLists.txt @@ -75,6 +75,71 @@ add_entrypoint_object( libc.src.__support.File.platform_stdout ) +add_entrypoint_object( + fwrite_unlocked + SRCS + fwrite_unlocked.cpp + HDRS + ../fwrite_unlocked.h + DEPENDS + libc.src.errno.errno + libc.include.stdio + libc.src.__support.File.file + libc.src.__support.File.platform_file +) + +add_entrypoint_object( + fwrite + SRCS + fwrite.cpp + HDRS + ../fwrite.h + DEPENDS + libc.src.errno.errno + libc.include.stdio + libc.src.__support.File.file + libc.src.__support.File.platform_file +) + +add_entrypoint_object( + fputc + SRCS + fputc.cpp + HDRS + ../fputc.h + DEPENDS + libc.src.errno.errno + libc.include.stdio + libc.src.__support.File.file + libc.src.__support.File.platform_file +) + +add_entrypoint_object( + putc + SRCS + putc.cpp + HDRS + ../putc.h + DEPENDS + libc.src.errno.errno + libc.include.stdio + libc.src.__support.File.file + libc.src.__support.File.platform_file +) + +add_entrypoint_object( + putchar + SRCS + putchar.cpp + HDRS + ../putchar.h + DEPENDS + libc.src.errno.errno + libc.include.stdio + libc.src.__support.File.file + libc.src.__support.File.platform_file +) + add_entrypoint_object( stdin SRCS diff --git a/libc/src/stdio/fputc.cpp b/libc/src/stdio/generic/fputc.cpp similarity index 100% rename from libc/src/stdio/fputc.cpp rename to libc/src/stdio/generic/fputc.cpp diff --git a/libc/src/stdio/fwrite.cpp b/libc/src/stdio/generic/fwrite.cpp similarity index 100% rename from libc/src/stdio/fwrite.cpp rename to libc/src/stdio/generic/fwrite.cpp diff --git a/libc/src/stdio/fwrite_unlocked.cpp b/libc/src/stdio/generic/fwrite_unlocked.cpp similarity index 100% rename from libc/src/stdio/fwrite_unlocked.cpp rename to libc/src/stdio/generic/fwrite_unlocked.cpp diff --git a/libc/src/stdio/putc.cpp b/libc/src/stdio/generic/putc.cpp similarity index 100% rename from libc/src/stdio/putc.cpp rename to libc/src/stdio/generic/putc.cpp diff --git a/libc/src/stdio/putchar.cpp b/libc/src/stdio/generic/putchar.cpp similarity index 100% rename from libc/src/stdio/putchar.cpp rename to libc/src/stdio/generic/putchar.cpp diff --git a/libc/src/stdio/gpu/CMakeLists.txt b/libc/src/stdio/gpu/CMakeLists.txt index 458dd86175021..d35b1925c6a47 100644 --- a/libc/src/stdio/gpu/CMakeLists.txt +++ b/libc/src/stdio/gpu/CMakeLists.txt @@ -61,6 +61,50 @@ add_entrypoint_object( .gpu_file ) +add_entrypoint_object( + fwrite + SRCS + fwrite.cpp + HDRS + ../fwrite.h + DEPENDS + libc.include.stdio + .gpu_file +) + +add_entrypoint_object( + fputc + SRCS + fputc.cpp + HDRS + ../fputc.h + DEPENDS + libc.include.stdio + .gpu_file +) + +add_entrypoint_object( + putc + SRCS + putc.cpp + HDRS + ../putc.h + DEPENDS + libc.include.stdio + .gpu_file +) + +add_entrypoint_object( + putchar + SRCS + putchar.cpp + HDRS + ../putchar.h + DEPENDS + libc.include.stdio + .gpu_file +) + add_entrypoint_object( stdin SRCS diff --git a/libc/src/stdio/gpu/fputc.cpp b/libc/src/stdio/gpu/fputc.cpp new file mode 100644 index 0000000000000..90d238972972e --- /dev/null +++ b/libc/src/stdio/gpu/fputc.cpp @@ -0,0 +1,26 @@ +//===-- GPU implementation of fputc ---------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "file.h" +#include "src/stdio/fputc.h" + +#include + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, fputc, (int c, ::FILE *stream)) { + unsigned char uc = static_cast(c); + + size_t written = file::write(stream, &uc, 1); + if (1 != written) + return EOF; + + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/src/stdio/gpu/fwrite.cpp b/libc/src/stdio/gpu/fwrite.cpp new file mode 100644 index 0000000000000..fccaabd0673ec --- /dev/null +++ b/libc/src/stdio/gpu/fwrite.cpp @@ -0,0 +1,26 @@ +//===-- GPU implementation of fwrite --------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/stdio/fwrite.h" +#include "file.h" + +#include + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(size_t, fwrite, + (const void *__restrict buffer, size_t size, size_t nmemb, + ::FILE *stream)) { + if (size == 0 || nmemb == 0) + return 0; + + auto result = file::write(stream, buffer, size * nmemb); + return result / size; +} + +} // namespace __llvm_libc diff --git a/libc/src/stdio/gpu/putc.cpp b/libc/src/stdio/gpu/putc.cpp new file mode 100644 index 0000000000000..d450edb6596df --- /dev/null +++ b/libc/src/stdio/gpu/putc.cpp @@ -0,0 +1,26 @@ +//===-- GPU implementation of putc ----------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/stdio/putc.h" +#include "file.h" + +#include + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, putc, (int c, ::FILE *stream)) { + unsigned char uc = static_cast(c); + + size_t written = file::write(stream, &uc, 1); + if (1 != written) + return EOF; + + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/src/stdio/gpu/putchar.cpp b/libc/src/stdio/gpu/putchar.cpp new file mode 100644 index 0000000000000..df577544b8ba4 --- /dev/null +++ b/libc/src/stdio/gpu/putchar.cpp @@ -0,0 +1,26 @@ +//===-- GPU implementation of putchar -------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "file.h" +#include "src/stdio/putchar.h" + +#include + +namespace __llvm_libc { + +LLVM_LIBC_FUNCTION(int, putchar, (int c)) { + unsigned char uc = static_cast(c); + + size_t written = file::write(stdout, &uc, 1); + if (1 != written) + return EOF; + + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/test/src/stdio/CMakeLists.txt b/libc/test/src/stdio/CMakeLists.txt index 01590f9acb854..6090dc1f46c87 100644 --- a/libc/test/src/stdio/CMakeLists.txt +++ b/libc/test/src/stdio/CMakeLists.txt @@ -271,6 +271,20 @@ add_libc_test( libc.src.stdio.stderr ) +add_libc_test( + fputc_test + HERMETIC_TEST_ONLY # writes to libc's stdout and stderr + SUITE + libc_stdio_unittests + SRCS + fputc_test.cpp + DEPENDS + libc.src.stdio.fputc + libc.src.stdio.putchar + libc.src.stdio.stdout + libc.src.stdio.stderr +) + add_libc_test( fopen_test SUITE @@ -279,7 +293,7 @@ add_libc_test( fopen_test.cpp DEPENDS libc.src.stdio.fread - libc.src.stdio.fputs + libc.src.stdio.fwrite libc.src.stdio.fclose libc.src.stdio.fopen ) diff --git a/libc/test/src/stdio/fopen_test.cpp b/libc/test/src/stdio/fopen_test.cpp index 8e8a1c9638f5b..f0de8caf673cc 100644 --- a/libc/test/src/stdio/fopen_test.cpp +++ b/libc/test/src/stdio/fopen_test.cpp @@ -9,7 +9,7 @@ #include "src/__support/File/file.h" #include "src/stdio/fclose.h" #include "src/stdio/fopen.h" -#include "src/stdio/fputs.h" +#include "src/stdio/fwrite.h" #include "src/stdio/fread.h" #include "test/UnitTest/Test.h" @@ -21,7 +21,7 @@ TEST(LlvmLibcFOpenTest, PrintToFile) { ASSERT_FALSE(file == nullptr); static constexpr char STRING[] = "A simple string written to a file\n"; - result = __llvm_libc::fputs(STRING, file); + result = __llvm_libc::fwrite(STRING, 1, sizeof(STRING) - 1, file); EXPECT_GE(result, 0); ASSERT_EQ(0, __llvm_libc::fclose(file)); diff --git a/libc/test/src/stdio/fputc_test.cpp b/libc/test/src/stdio/fputc_test.cpp new file mode 100644 index 0000000000000..e5aa7c713463b --- /dev/null +++ b/libc/test/src/stdio/fputc_test.cpp @@ -0,0 +1,30 @@ +//===-- Unittests for fputc / putchar -------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/__support/File/file.h" +#include "src/stdio/fputc.h" +#include "src/stdio/putchar.h" + +#include "test/UnitTest/Test.h" + +TEST(LlvmLibcPutcTest, PrintOut) { + int result; + + constexpr char simple[] = "A simple string written to stdout\n"; + for (const char &c : simple) { + result = __llvm_libc::putchar(c); + EXPECT_GE(result, 0); + } + + constexpr char more[] = "A simple string written to stderr\n"; + for (const char &c : simple) { + result = + __llvm_libc::fputc(c, reinterpret_cast(__llvm_libc::stderr)); + } + EXPECT_GE(result, 0); +}