| // Copyright 2020 The Fuchsia Authors | |
| // | |
| // Use of this source code is governed by a MIT-style | |
| // license that can be found in the LICENSE file or at | |
| // https://opensource.org/licenses/MIT | |
| #ifndef ZIRCON_KERNEL_LIB_LIBC_INCLUDE_STDIO_H_ | |
| #define ZIRCON_KERNEL_LIB_LIBC_INCLUDE_STDIO_H_ | |
| #include <stdarg.h> | |
| #include <stddef.h> | |
| #include <zircon/compiler.h> | |
| // All anybody really wants from stdio is printf. | |
| #ifdef __cplusplus | |
| #include <ktl/string_view.h> | |
| class FILE { | |
| public: | |
| // This is basically equivalent to having a virtual Write function with | |
| // subclasses providing their own data members in lieu of ptr. But it's | |
| // simpler and avoids a vtable that might need address fixup at load time | |
| // (and the double indirection for a single-entry vtable--at the cost of | |
| // double indirection for the ptr data in a callback that uses it). | |
| using Callback = int(void*, ktl::string_view); | |
| FILE() = default; | |
| constexpr FILE(Callback* write, void* ptr) : write_(write), ptr_(ptr) {} | |
| template <typename T> | |
| explicit FILE(T* writer) | |
| : write_([](void* ptr, ktl::string_view s) { return static_cast<T*>(ptr)->Write(s); }), | |
| ptr_(writer) {} | |
| // This is what fprintf calls to do output. | |
| int Write(ktl::string_view s) { return write_(ptr_, s); } | |
| // This is not defined by libc itself. The kernel defines it to point at | |
| // the default console output mechanism. | |
| static FILE stdout_; | |
| private: | |
| Callback* write_ = nullptr; | |
| void* ptr_ = nullptr; | |
| }; | |
| #define stdout (&FILE::stdout_) | |
| #else // !__cplusplus | |
| // C users just need the function declarations. | |
| typedef struct _FILE_is_opaque FILE; | |
| #endif // __cplusplus | |
| __BEGIN_CDECLS | |
| int printf(const char*, ...) __PRINTFLIKE(1, 2); | |
| int fprintf(FILE*, const char*, ...) __PRINTFLIKE(2, 3); | |
| int snprintf(char* buf, size_t len, const char*, ...) __PRINTFLIKE(3, 4); | |
| int vprintf(const char*, va_list); | |
| int vfprintf(FILE*, const char*, va_list); | |
| int vsnprintf(char* buf, size_t len, const char*, va_list); | |
| __END_CDECLS | |
| #if DISABLE_DEBUG_OUTPUT | |
| // The declarations stand so these can be used without parens to get | |
| // the real functions (e.g. &printf or (printf)(...)). | |
| #define printf(...) | |
| #define vprintf(fmt, args) | |
| #endif | |
| #endif // ZIRCON_KERNEL_LIB_LIBC_INCLUDE_STDIO_H_ |