Warning: This file is not a C or C++ file. It does not have highlighting.
| 1 | //===-- Internal implementation header of vfprintf --------------*- C++ -*-===// |
|---|---|
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #ifndef LLVM_LIBC_SRC_STDIO_PRINTF_CORE_VFPRINTF_INTERNAL_H |
| 10 | #define LLVM_LIBC_SRC_STDIO_PRINTF_CORE_VFPRINTF_INTERNAL_H |
| 11 | |
| 12 | #include "src/__support/File/file.h" |
| 13 | #include "src/__support/arg_list.h" |
| 14 | #include "src/__support/macros/attributes.h" // For LIBC_INLINE |
| 15 | #include "src/__support/macros/config.h" |
| 16 | #include "src/stdio/printf_core/core_structs.h" |
| 17 | #include "src/stdio/printf_core/printf_main.h" |
| 18 | #include "src/stdio/printf_core/writer.h" |
| 19 | |
| 20 | #include "hdr/types/FILE.h" |
| 21 | |
| 22 | namespace LIBC_NAMESPACE_DECL { |
| 23 | |
| 24 | namespace internal { |
| 25 | #ifndef LIBC_COPT_STDIO_USE_SYSTEM_FILE |
| 26 | LIBC_INLINE int ferror_unlocked(FILE *f) { |
| 27 | return reinterpret_cast<LIBC_NAMESPACE::File *>(f)->error_unlocked(); |
| 28 | } |
| 29 | |
| 30 | LIBC_INLINE void flockfile(FILE *f) { |
| 31 | reinterpret_cast<LIBC_NAMESPACE::File *>(f)->lock(); |
| 32 | } |
| 33 | |
| 34 | LIBC_INLINE void funlockfile(FILE *f) { |
| 35 | reinterpret_cast<LIBC_NAMESPACE::File *>(f)->unlock(); |
| 36 | } |
| 37 | |
| 38 | LIBC_INLINE size_t fwrite_unlocked(const void *ptr, size_t size, size_t nmemb, |
| 39 | FILE *f) { |
| 40 | return reinterpret_cast<LIBC_NAMESPACE::File *>(f)->write_unlocked( |
| 41 | ptr, size * nmemb); |
| 42 | } |
| 43 | #else // defined(LIBC_COPT_STDIO_USE_SYSTEM_FILE) |
| 44 | LIBC_INLINE int ferror_unlocked(::FILE *f) { return ::ferror_unlocked(f); } |
| 45 | |
| 46 | LIBC_INLINE void flockfile(::FILE *f) { ::flockfile(f); } |
| 47 | |
| 48 | LIBC_INLINE void funlockfile(::FILE *f) { ::funlockfile(f); } |
| 49 | |
| 50 | LIBC_INLINE size_t fwrite_unlocked(const void *ptr, size_t size, size_t nmemb, |
| 51 | ::FILE *f) { |
| 52 | return ::fwrite_unlocked(ptr, size, nmemb, f); |
| 53 | } |
| 54 | #endif // LIBC_COPT_STDIO_USE_SYSTEM_FILE |
| 55 | } // namespace internal |
| 56 | |
| 57 | namespace printf_core { |
| 58 | |
| 59 | LIBC_INLINE int file_write_hook(cpp::string_view new_str, void *fp) { |
| 60 | ::FILE *target_file = reinterpret_cast<::FILE *>(fp); |
| 61 | // Write new_str to the target file. The logic preventing a zero-length write |
| 62 | // is in the writer, so we don't check here. |
| 63 | size_t written = internal::fwrite_unlocked(new_str.data(), sizeof(char), |
| 64 | new_str.size(), target_file); |
| 65 | if (written != new_str.size() || internal::ferror_unlocked(target_file)) |
| 66 | return FILE_WRITE_ERROR; |
| 67 | return WRITE_OK; |
| 68 | } |
| 69 | |
| 70 | LIBC_INLINE int vfprintf_internal(::FILE *__restrict stream, |
| 71 | const char *__restrict format, |
| 72 | internal::ArgList &args) { |
| 73 | constexpr size_t BUFF_SIZE = 1024; |
| 74 | char buffer[BUFF_SIZE]; |
| 75 | printf_core::WriteBuffer<Mode<WriteMode::FLUSH_TO_STREAM>::value> wb( |
| 76 | buffer, BUFF_SIZE, &file_write_hook, reinterpret_cast<void *>(stream)); |
| 77 | Writer writer(wb); |
| 78 | internal::flockfile(stream); |
| 79 | int retval = printf_main(&writer, format, args); |
| 80 | int flushval = wb.overflow_write(""); |
| 81 | if (flushval != WRITE_OK) |
| 82 | retval = flushval; |
| 83 | internal::funlockfile(stream); |
| 84 | return retval; |
| 85 | } |
| 86 | |
| 87 | } // namespace printf_core |
| 88 | } // namespace LIBC_NAMESPACE_DECL |
| 89 | |
| 90 | #endif // LLVM_LIBC_SRC_STDIO_PRINTF_CORE_VFPRINTF_INTERNAL_H |
| 91 |
Warning: This file is not a C or C++ file. It does not have highlighting.
