Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
25c7d79
Change writer to store chars written as size_t
mleleszi Oct 7, 2025
362c00e
Prinf internals: use -errno as return values rather than custrom erro…
mleleszi Oct 7, 2025
f8c7569
Refactor printf family functions to use PrintfResult
mleleszi Oct 7, 2025
f8f3553
Formatting
mleleszi Oct 7, 2025
4761e9a
Fix tests
mleleszi Oct 7, 2025
1dd65af
Add IO error test cases for file variants
mleleszi Oct 7, 2025
ef55545
Add overflow test for fprintf
mleleszi Oct 7, 2025
63c710b
Cleanup
mleleszi Oct 7, 2025
e035a15
Add overflow test for vfprintf
mleleszi Oct 8, 2025
56d6968
Baremetal stuff
mleleszi Oct 8, 2025
995bb08
Add test for nullptr write error
mleleszi Oct 8, 2025
eedbad9
Add overflow handling to strfrom functions
mleleszi Oct 8, 2025
242b75c
Cleanup
mleleszi Oct 10, 2025
a403604
Merge branch 'main' into libc-printf-error-handling
mleleszi Oct 10, 2025
492b9f1
Run clang-format
mleleszi Oct 10, 2025
71554f9
Fix unused param error
mleleszi Oct 10, 2025
b03c545
Refactor File to store error_code instead of error flag
mleleszi Oct 12, 2025
6d05774
Map internall err code to errno
mleleszi Oct 12, 2025
d194975
Return system IO errors return values
mleleszi Oct 17, 2025
69e9362
Use ErroOr for print retval instead of custom struct
mleleszi Oct 17, 2025
f8cb702
Fix tests
mleleszi Oct 17, 2025
0e8b25c
Fix baremetal impl
mleleszi Oct 17, 2025
756cb37
Clean up tests, dependencies
mleleszi Oct 18, 2025
463e929
Add platfrom specific error converter implementations
mleleszi Oct 23, 2025
5f3b0af
Clean up dependencies
mleleszi Oct 23, 2025
428c7e9
Add darwin and generic impl of error converter
mleleszi Oct 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions libc/src/stdio/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ add_entrypoint_object(
DEPENDS
libc.src.stdio.printf_core.printf_main
libc.src.stdio.printf_core.writer
libc.src.stdio.printf_core.core_structs
libc.src.stdio.printf_core.error_converter
libc.src.__support.libc_errno
)

add_entrypoint_object(
Expand All @@ -136,6 +139,9 @@ add_entrypoint_object(
DEPENDS
libc.src.stdio.printf_core.printf_main
libc.src.stdio.printf_core.writer
libc.src.stdio.printf_core.core_structs
libc.src.stdio.printf_core.error_converter
libc.src.__support.libc_errno
)

add_entrypoint_object(
Expand All @@ -146,6 +152,9 @@ add_entrypoint_object(
asprintf.h
DEPENDS
libc.src.stdio.printf_core.vasprintf_internal
libc.src.stdio.printf_core.core_structs
libc.src.stdio.printf_core.error_converter
libc.src.__support.libc_errno
)

add_entrypoint_object(
Expand All @@ -157,6 +166,8 @@ add_entrypoint_object(
DEPENDS
libc.src.stdio.printf_core.printf_main
libc.src.stdio.printf_core.writer
libc.src.stdio.printf_core.core_structs
libc.src.stdio.printf_core.error_converter
)

add_entrypoint_object(
Expand All @@ -168,6 +179,9 @@ add_entrypoint_object(
DEPENDS
libc.src.stdio.printf_core.printf_main
libc.src.stdio.printf_core.writer
libc.src.stdio.printf_core.core_structs
libc.src.stdio.printf_core.error_converter
libc.src.__support.libc_errno
)

add_entrypoint_object(
Expand All @@ -178,6 +192,9 @@ add_entrypoint_object(
vasprintf.h
DEPENDS
libc.src.stdio.printf_core.vasprintf_internal
libc.src.stdio.printf_core.core_structs
libc.src.stdio.printf_core.error_converter
libc.src.__support.libc_errno
)

add_subdirectory(printf_core)
Expand Down
17 changes: 15 additions & 2 deletions libc/src/stdio/asprintf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@

#include "src/stdio/asprintf.h"
#include "src/__support/arg_list.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
#include "src/stdio/printf_core/core_structs.h"
#include "src/stdio/printf_core/error_converter.h"
#include "src/stdio/printf_core/vasprintf_internal.h"

namespace LIBC_NAMESPACE_DECL {
Expand All @@ -22,8 +25,18 @@ LLVM_LIBC_FUNCTION(int, asprintf,
// and pointer semantics, as well as handling
// destruction automatically.
va_end(vlist);
int ret = printf_core::vasprintf_internal(buffer, format, args);
return ret;
auto ret_val = printf_core::vasprintf_internal(buffer, format, args);
if (!ret_val.has_value()) {
libc_errno = printf_core::internal_error_to_errno(ret_val.error());
return -1;
}
if (ret_val.value() > cpp::numeric_limits<int>::max()) {
libc_errno =
printf_core::internal_error_to_errno(-printf_core::OVERFLOW_ERROR);
return -1;
}

return static_cast<int>(ret_val.value());
}

} // namespace LIBC_NAMESPACE_DECL
6 changes: 6 additions & 0 deletions libc/src/stdio/baremetal/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ add_entrypoint_object(
DEPENDS
libc.src.stdio.printf_core.printf_main
libc.src.stdio.printf_core.writer
libc.src.stdio.printf_core.error_converter
libc.src.stdio.printf_core.core_structs
libc.src.__support.arg_list
libc.src.__support.OSUtil.osutil
libc.src.__support.libc_errno
)

add_entrypoint_object(
Expand Down Expand Up @@ -87,8 +90,11 @@ add_entrypoint_object(
DEPENDS
libc.src.stdio.printf_core.printf_main
libc.src.stdio.printf_core.writer
libc.src.stdio.printf_core.error_converter
libc.src.stdio.printf_core.core_structs
libc.src.__support.arg_list
libc.src.__support.OSUtil.osutil
libc.src.__support.libc_errno
)

add_entrypoint_object(
Expand Down
22 changes: 18 additions & 4 deletions libc/src/stdio/baremetal/printf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
#include "src/stdio/printf.h"
#include "src/__support/OSUtil/io.h"
#include "src/__support/arg_list.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
#include "src/stdio/printf_core/core_structs.h"
#include "src/stdio/printf_core/error_converter.h"
#include "src/stdio/printf_core/printf_main.h"
#include "src/stdio/printf_core/writer.h"

Expand Down Expand Up @@ -42,13 +44,25 @@ LLVM_LIBC_FUNCTION(int, printf, (const char *__restrict format, ...)) {
buffer, BUFF_SIZE, &stdout_write_hook, nullptr);
printf_core::Writer<printf_core::WriteMode::FLUSH_TO_STREAM> writer(wb);

int retval = printf_core::printf_main(&writer, format, args);
auto retval = printf_core::printf_main(&writer, format, args);
if (!retval.has_value()) {
libc_errno = printf_core::internal_error_to_errno(retval.error());
return -1;
}

int flushval = wb.overflow_write("");
if (flushval != printf_core::WRITE_OK)
retval = flushval;
if (flushval != printf_core::WRITE_OK) {
libc_errno = printf_core::internal_error_to_errno(-flushval);
return -1;
}

return retval;
if (retval.value() > cpp::numeric_limits<int>::max()) {
libc_errno =
printf_core::internal_error_to_errno(-printf_core::OVERFLOW_ERROR);
return -1;
}

return static_cast<int>(retval.value());
}

} // namespace LIBC_NAMESPACE_DECL
22 changes: 18 additions & 4 deletions libc/src/stdio/baremetal/vprintf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
#include "src/stdio/vprintf.h"
#include "src/__support/OSUtil/io.h"
#include "src/__support/arg_list.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
#include "src/stdio/printf_core/core_structs.h"
#include "src/stdio/printf_core/error_converter.h"
#include "src/stdio/printf_core/printf_main.h"
#include "src/stdio/printf_core/writer.h"

Expand Down Expand Up @@ -40,13 +42,25 @@ LLVM_LIBC_FUNCTION(int, vprintf,
buffer, BUFF_SIZE, &stdout_write_hook, nullptr);
printf_core::Writer<printf_core::WriteMode::FLUSH_TO_STREAM> writer(wb);

int retval = printf_core::printf_main(&writer, format, args);
auto retval = printf_core::printf_main(&writer, format, args);
if (!retval.has_value()) {
libc_errno = printf_core::internal_error_to_errno(retval.error());
return -1;
}

int flushval = wb.overflow_write("");
if (flushval != printf_core::WRITE_OK)
retval = flushval;
if (flushval != printf_core::WRITE_OK) {
libc_errno = printf_core::internal_error_to_errno(-flushval);
return -1;
}

return retval;
if (retval.value() > cpp::numeric_limits<int>::max()) {
libc_errno =
printf_core::internal_error_to_errno(-printf_core::OVERFLOW_ERROR);
return -1;
}

return static_cast<int>(retval.value());
}

} // namespace LIBC_NAMESPACE_DECL
2 changes: 2 additions & 0 deletions libc/src/stdio/generic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,8 @@ list(APPEND fprintf_deps
libc.hdr.types.FILE
libc.src.__support.arg_list
libc.src.stdio.printf_core.vfprintf_internal
libc.src.stdio.printf_core.core_structs
libc.src.stdio.printf_core.error_converter
)

if(LLVM_LIBC_FULL_BUILD)
Expand Down
16 changes: 14 additions & 2 deletions libc/src/stdio/generic/fprintf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "src/__support/File/file.h"
#include "src/__support/arg_list.h"
#include "src/__support/macros/config.h"
#include "src/stdio/printf_core/core_structs.h"
#include "src/stdio/printf_core/error_converter.h"
#include "src/stdio/printf_core/vfprintf_internal.h"

#include "hdr/types/FILE.h"
Expand All @@ -27,8 +29,18 @@ LLVM_LIBC_FUNCTION(int, fprintf,
// and pointer semantics, as well as handling
// destruction automatically.
va_end(vlist);
int ret_val = printf_core::vfprintf_internal(stream, format, args);
return ret_val;
auto ret_val = printf_core::vfprintf_internal(stream, format, args);
if (!ret_val.has_value()) {
libc_errno = printf_core::internal_error_to_errno(ret_val.error());
return -1;
}
if (ret_val.value() > cpp::numeric_limits<int>::max()) {
libc_errno =
printf_core::internal_error_to_errno(-printf_core::OVERFLOW_ERROR);
return -1;
}

return static_cast<int>(ret_val.value());
}

} // namespace LIBC_NAMESPACE_DECL
16 changes: 14 additions & 2 deletions libc/src/stdio/generic/printf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "src/__support/File/file.h"
#include "src/__support/arg_list.h"
#include "src/__support/macros/config.h"
#include "src/stdio/printf_core/core_structs.h"
#include "src/stdio/printf_core/error_converter.h"
#include "src/stdio/printf_core/vfprintf_internal.h"

#include "hdr/types/FILE.h"
Expand All @@ -31,9 +33,19 @@ LLVM_LIBC_FUNCTION(int, printf, (const char *__restrict format, ...)) {
// and pointer semantics, as well as handling
// destruction automatically.
va_end(vlist);
int ret_val = printf_core::vfprintf_internal(
auto ret_val = printf_core::vfprintf_internal(
reinterpret_cast<::FILE *>(PRINTF_STDOUT), format, args);
return ret_val;
if (!ret_val.has_value()) {
libc_errno = printf_core::internal_error_to_errno(ret_val.error());
return -1;
}
if (ret_val.value() > cpp::numeric_limits<int>::max()) {
libc_errno =
printf_core::internal_error_to_errno(-printf_core::OVERFLOW_ERROR);
return -1;
}

return static_cast<int>(ret_val.value());
}

} // namespace LIBC_NAMESPACE_DECL
16 changes: 14 additions & 2 deletions libc/src/stdio/generic/vfprintf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "src/__support/File/file.h"
#include "src/__support/arg_list.h"
#include "src/__support/macros/config.h"
#include "src/stdio/printf_core/core_structs.h"
#include "src/stdio/printf_core/error_converter.h"
#include "src/stdio/printf_core/vfprintf_internal.h"

#include "hdr/types/FILE.h"
Expand All @@ -24,8 +26,18 @@ LLVM_LIBC_FUNCTION(int, vfprintf,
internal::ArgList args(vlist); // This holder class allows for easier copying
// and pointer semantics, as well as handling
// destruction automatically.
int ret_val = printf_core::vfprintf_internal(stream, format, args);
return ret_val;
auto ret_val = printf_core::vfprintf_internal(stream, format, args);
if (!ret_val.has_value()) {
libc_errno = printf_core::internal_error_to_errno(ret_val.error());
return -1;
}
if (ret_val.value() > cpp::numeric_limits<int>::max()) {
libc_errno =
printf_core::internal_error_to_errno(-printf_core::OVERFLOW_ERROR);
return -1;
}

return static_cast<int>(ret_val.value());
}

} // namespace LIBC_NAMESPACE_DECL
16 changes: 14 additions & 2 deletions libc/src/stdio/generic/vprintf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "src/__support/File/file.h"
#include "src/__support/arg_list.h"
#include "src/__support/macros/config.h"
#include "src/stdio/printf_core/core_structs.h"
#include "src/stdio/printf_core/error_converter.h"
#include "src/stdio/printf_core/vfprintf_internal.h"

#include "hdr/types/FILE.h"
Expand All @@ -29,9 +31,19 @@ LLVM_LIBC_FUNCTION(int, vprintf,
internal::ArgList args(vlist); // This holder class allows for easier copying
// and pointer semantics, as well as handling
// destruction automatically.
int ret_val = printf_core::vfprintf_internal(
auto ret_val = printf_core::vfprintf_internal(
reinterpret_cast<::FILE *>(PRINTF_STDOUT), format, args);
return ret_val;
if (!ret_val.has_value()) {
libc_errno = printf_core::internal_error_to_errno(ret_val.error());
return -1;
}
if (ret_val.value() > cpp::numeric_limits<int>::max()) {
libc_errno =
printf_core::internal_error_to_errno(-printf_core::OVERFLOW_ERROR);
return -1;
}

return static_cast<int>(ret_val.value());
}

} // namespace LIBC_NAMESPACE_DECL
25 changes: 25 additions & 0 deletions libc/src/stdio/printf_core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,17 @@ if(printf_config_copts)
list(PREPEND printf_config_copts "COMPILE_OPTIONS")
endif()

if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
add_subdirectory(${LIBC_TARGET_OS})
else()
add_subdirectory(generic)
endif()

set(target_error_converter libc.src.stdio.printf_core.${LIBC_TARGET_OS}.${LIBC_TARGET_OS}_error_converter)
if(NOT TARGET ${target_error_converter})
set(target_error_converter libc.src.stdio.printf_core.generic.generic_error_converter)
endif()

add_header_library(
printf_config
HDRS
Expand All @@ -47,6 +58,7 @@ add_header_library(
libc.include.inttypes
libc.src.__support.CPP.string_view
libc.src.__support.FPUtil.fp_bits
libc.hdr.errno_macros
)

add_header_library(
Expand Down Expand Up @@ -125,6 +137,7 @@ add_header_library(
.writer
.core_structs
libc.src.__support.arg_list
libc.src.__support.error_or
)

add_header_library(
Expand All @@ -136,10 +149,20 @@ add_header_library(
libc.hdr.func.free
libc.hdr.func.realloc
libc.src.__support.arg_list
libc.src.__support.error_or
libc.src.stdio.printf_core.printf_main
libc.src.stdio.printf_core.writer
)

add_header_library(
error_converter
HDRS
error_converter.h
DEPENDS
${target_error_converter}
libc.src.__support.macros.properties.architectures
)

if(NOT (TARGET libc.src.__support.File.file) AND LLVM_LIBC_FULL_BUILD)
# Not all platforms have a file implementation. If file is unvailable, and a
# full build is requested, then we must skip all file based printf sections.
Expand All @@ -152,8 +175,10 @@ add_header_library(
vfprintf_internal.h
DEPENDS
libc.src.__support.File.file
libc.src.__support.error_or
libc.src.__support.arg_list
libc.src.stdio.printf_core.printf_main
libc.src.stdio.printf_core.writer
${use_system_file}
)

Loading
Loading