The new printf writer design focuses on optimizing the fast path. It
inlines any write to a buffer or string, and by handling buffering
itself can more effectively work with both internal and external file
implementations. The overflow hook should allow for expansion to
asprintf with minimal extra code.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
libc/src/stdio/printf_core/char_converter.h | ||
---|---|---|
32 ↗ | (On Diff #535503) | char_converter.h and string_converter.h changes seem to be unrelated to the topic of the patch? |
libc/src/stdio/printf_core/vfprintf_internal.h | ||
26 | This is potentially leaking entrypoints. Is simplicity of flush_and_write and vfprintf_internal the only reason? Can you instead do this: namespace internal { #ifdef LIBC_COPT_PRINTF_USE_SYSTEM_FILE LIBC_INLINE int ferror_unlocked(FILE *f) { return ::ferror_unlocked(f); } ... #else LIBC_INLINE int ferror_unlocked(FILE *f) { return reinterpret_cast<__llvm_libc::File *>(f)->ferror_unlocked(f); } ... #endif } // namespace internal | |
libc/src/stdio/printf_core/writer.h | ||
24 | Looking at the implementation of the hooks above, it seems to me that the expectation is for the hook to adjust the buffer state. I would rather have a single internal place to manage all internal state. So, I suggest the following changes:
Does it cover all use cases? | |
27 | Why isn't the buffer state kept with the writer? In other words, what is the benefit of this separate buffer type WriteBuffer? |
clean up entrypoint leaking and unrelated changes
libc/src/stdio/printf_core/char_converter.h | ||
---|---|---|
32 ↗ | (On Diff #535503) | yes. I'll move them to a separate patch. |
libc/src/stdio/printf_core/writer.h | ||
24 | That covers almost all the use cases. We still need the OverflowHook to be able to modify the buffer to handle the case of asprintf, which dynamically allocates a string for its output. In that case when the buffer fills, the pointer may need to be changed and we don't want to reset the current write position. | |
27 | It allows us to pass just the WriteBuffer to the OverflowHook, since the OverflowHook needs to be able to modify the buffer based not only on the buffer's state but also the length of the new string being written. |
libc/src/stdio/printf_core/writer.h | ||
---|---|---|
24 | asprintf should be implemented with the separation of abstractions intact. So:
|
move to WriteBuffer->stream_writer = nullptr for snprintf
The write buffer is still separate to simplify buffer flushing after the printf_main call
This is potentially leaking entrypoints. Is simplicity of flush_and_write and vfprintf_internal the only reason? Can you instead do this: