blob: 92e9c6cb177c9b6b89df58cd9fd1af44c7a414bc [file] [log] [blame]
// 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;
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_