1*5c90c05cSAndroid Build Coastguard Worker // Formatting library for C++ - optional OS-specific functionality
2*5c90c05cSAndroid Build Coastguard Worker //
3*5c90c05cSAndroid Build Coastguard Worker // Copyright (c) 2012 - present, Victor Zverovich
4*5c90c05cSAndroid Build Coastguard Worker // All rights reserved.
5*5c90c05cSAndroid Build Coastguard Worker //
6*5c90c05cSAndroid Build Coastguard Worker // For the license information refer to format.h.
7*5c90c05cSAndroid Build Coastguard Worker
8*5c90c05cSAndroid Build Coastguard Worker #ifndef FMT_OS_H_
9*5c90c05cSAndroid Build Coastguard Worker #define FMT_OS_H_
10*5c90c05cSAndroid Build Coastguard Worker
11*5c90c05cSAndroid Build Coastguard Worker #include "format.h"
12*5c90c05cSAndroid Build Coastguard Worker
13*5c90c05cSAndroid Build Coastguard Worker #ifndef FMT_MODULE
14*5c90c05cSAndroid Build Coastguard Worker # include <cerrno>
15*5c90c05cSAndroid Build Coastguard Worker # include <cstddef>
16*5c90c05cSAndroid Build Coastguard Worker # include <cstdio>
17*5c90c05cSAndroid Build Coastguard Worker # include <system_error> // std::system_error
18*5c90c05cSAndroid Build Coastguard Worker
19*5c90c05cSAndroid Build Coastguard Worker # if FMT_HAS_INCLUDE(<xlocale.h>)
20*5c90c05cSAndroid Build Coastguard Worker # include <xlocale.h> // LC_NUMERIC_MASK on macOS
21*5c90c05cSAndroid Build Coastguard Worker # endif
22*5c90c05cSAndroid Build Coastguard Worker #endif // FMT_MODULE
23*5c90c05cSAndroid Build Coastguard Worker
24*5c90c05cSAndroid Build Coastguard Worker #ifndef FMT_USE_FCNTL
25*5c90c05cSAndroid Build Coastguard Worker // UWP doesn't provide _pipe.
26*5c90c05cSAndroid Build Coastguard Worker # if FMT_HAS_INCLUDE("winapifamily.h")
27*5c90c05cSAndroid Build Coastguard Worker # include <winapifamily.h>
28*5c90c05cSAndroid Build Coastguard Worker # endif
29*5c90c05cSAndroid Build Coastguard Worker # if (FMT_HAS_INCLUDE(<fcntl.h>) || defined(__APPLE__) || \
30*5c90c05cSAndroid Build Coastguard Worker defined(__linux__)) && \
31*5c90c05cSAndroid Build Coastguard Worker (!defined(WINAPI_FAMILY) || \
32*5c90c05cSAndroid Build Coastguard Worker (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
33*5c90c05cSAndroid Build Coastguard Worker # include <fcntl.h> // for O_RDONLY
34*5c90c05cSAndroid Build Coastguard Worker # define FMT_USE_FCNTL 1
35*5c90c05cSAndroid Build Coastguard Worker # else
36*5c90c05cSAndroid Build Coastguard Worker # define FMT_USE_FCNTL 0
37*5c90c05cSAndroid Build Coastguard Worker # endif
38*5c90c05cSAndroid Build Coastguard Worker #endif
39*5c90c05cSAndroid Build Coastguard Worker
40*5c90c05cSAndroid Build Coastguard Worker #ifndef FMT_POSIX
41*5c90c05cSAndroid Build Coastguard Worker # if defined(_WIN32) && !defined(__MINGW32__)
42*5c90c05cSAndroid Build Coastguard Worker // Fix warnings about deprecated symbols.
43*5c90c05cSAndroid Build Coastguard Worker # define FMT_POSIX(call) _##call
44*5c90c05cSAndroid Build Coastguard Worker # else
45*5c90c05cSAndroid Build Coastguard Worker # define FMT_POSIX(call) call
46*5c90c05cSAndroid Build Coastguard Worker # endif
47*5c90c05cSAndroid Build Coastguard Worker #endif
48*5c90c05cSAndroid Build Coastguard Worker
49*5c90c05cSAndroid Build Coastguard Worker // Calls to system functions are wrapped in FMT_SYSTEM for testability.
50*5c90c05cSAndroid Build Coastguard Worker #ifdef FMT_SYSTEM
51*5c90c05cSAndroid Build Coastguard Worker # define FMT_HAS_SYSTEM
52*5c90c05cSAndroid Build Coastguard Worker # define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
53*5c90c05cSAndroid Build Coastguard Worker #else
54*5c90c05cSAndroid Build Coastguard Worker # define FMT_SYSTEM(call) ::call
55*5c90c05cSAndroid Build Coastguard Worker # ifdef _WIN32
56*5c90c05cSAndroid Build Coastguard Worker // Fix warnings about deprecated symbols.
57*5c90c05cSAndroid Build Coastguard Worker # define FMT_POSIX_CALL(call) ::_##call
58*5c90c05cSAndroid Build Coastguard Worker # else
59*5c90c05cSAndroid Build Coastguard Worker # define FMT_POSIX_CALL(call) ::call
60*5c90c05cSAndroid Build Coastguard Worker # endif
61*5c90c05cSAndroid Build Coastguard Worker #endif
62*5c90c05cSAndroid Build Coastguard Worker
63*5c90c05cSAndroid Build Coastguard Worker // Retries the expression while it evaluates to error_result and errno
64*5c90c05cSAndroid Build Coastguard Worker // equals to EINTR.
65*5c90c05cSAndroid Build Coastguard Worker #ifndef _WIN32
66*5c90c05cSAndroid Build Coastguard Worker # define FMT_RETRY_VAL(result, expression, error_result) \
67*5c90c05cSAndroid Build Coastguard Worker do { \
68*5c90c05cSAndroid Build Coastguard Worker (result) = (expression); \
69*5c90c05cSAndroid Build Coastguard Worker } while ((result) == (error_result) && errno == EINTR)
70*5c90c05cSAndroid Build Coastguard Worker #else
71*5c90c05cSAndroid Build Coastguard Worker # define FMT_RETRY_VAL(result, expression, error_result) result = (expression)
72*5c90c05cSAndroid Build Coastguard Worker #endif
73*5c90c05cSAndroid Build Coastguard Worker
74*5c90c05cSAndroid Build Coastguard Worker #define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
75*5c90c05cSAndroid Build Coastguard Worker
76*5c90c05cSAndroid Build Coastguard Worker FMT_BEGIN_NAMESPACE
77*5c90c05cSAndroid Build Coastguard Worker FMT_BEGIN_EXPORT
78*5c90c05cSAndroid Build Coastguard Worker
79*5c90c05cSAndroid Build Coastguard Worker /**
80*5c90c05cSAndroid Build Coastguard Worker * A reference to a null-terminated string. It can be constructed from a C
81*5c90c05cSAndroid Build Coastguard Worker * string or `std::string`.
82*5c90c05cSAndroid Build Coastguard Worker *
83*5c90c05cSAndroid Build Coastguard Worker * You can use one of the following type aliases for common character types:
84*5c90c05cSAndroid Build Coastguard Worker *
85*5c90c05cSAndroid Build Coastguard Worker * +---------------+-----------------------------+
86*5c90c05cSAndroid Build Coastguard Worker * | Type | Definition |
87*5c90c05cSAndroid Build Coastguard Worker * +===============+=============================+
88*5c90c05cSAndroid Build Coastguard Worker * | cstring_view | basic_cstring_view<char> |
89*5c90c05cSAndroid Build Coastguard Worker * +---------------+-----------------------------+
90*5c90c05cSAndroid Build Coastguard Worker * | wcstring_view | basic_cstring_view<wchar_t> |
91*5c90c05cSAndroid Build Coastguard Worker * +---------------+-----------------------------+
92*5c90c05cSAndroid Build Coastguard Worker *
93*5c90c05cSAndroid Build Coastguard Worker * This class is most useful as a parameter type for functions that wrap C APIs.
94*5c90c05cSAndroid Build Coastguard Worker */
95*5c90c05cSAndroid Build Coastguard Worker template <typename Char> class basic_cstring_view {
96*5c90c05cSAndroid Build Coastguard Worker private:
97*5c90c05cSAndroid Build Coastguard Worker const Char* data_;
98*5c90c05cSAndroid Build Coastguard Worker
99*5c90c05cSAndroid Build Coastguard Worker public:
100*5c90c05cSAndroid Build Coastguard Worker /// Constructs a string reference object from a C string.
basic_cstring_view(const Char * s)101*5c90c05cSAndroid Build Coastguard Worker basic_cstring_view(const Char* s) : data_(s) {}
102*5c90c05cSAndroid Build Coastguard Worker
103*5c90c05cSAndroid Build Coastguard Worker /// Constructs a string reference from an `std::string` object.
basic_cstring_view(const std::basic_string<Char> & s)104*5c90c05cSAndroid Build Coastguard Worker basic_cstring_view(const std::basic_string<Char>& s) : data_(s.c_str()) {}
105*5c90c05cSAndroid Build Coastguard Worker
106*5c90c05cSAndroid Build Coastguard Worker /// Returns the pointer to a C string.
107*5c90c05cSAndroid Build Coastguard Worker auto c_str() const -> const Char* { return data_; }
108*5c90c05cSAndroid Build Coastguard Worker };
109*5c90c05cSAndroid Build Coastguard Worker
110*5c90c05cSAndroid Build Coastguard Worker using cstring_view = basic_cstring_view<char>;
111*5c90c05cSAndroid Build Coastguard Worker using wcstring_view = basic_cstring_view<wchar_t>;
112*5c90c05cSAndroid Build Coastguard Worker
113*5c90c05cSAndroid Build Coastguard Worker #ifdef _WIN32
114*5c90c05cSAndroid Build Coastguard Worker FMT_API const std::error_category& system_category() noexcept;
115*5c90c05cSAndroid Build Coastguard Worker
116*5c90c05cSAndroid Build Coastguard Worker namespace detail {
117*5c90c05cSAndroid Build Coastguard Worker FMT_API void format_windows_error(buffer<char>& out, int error_code,
118*5c90c05cSAndroid Build Coastguard Worker const char* message) noexcept;
119*5c90c05cSAndroid Build Coastguard Worker }
120*5c90c05cSAndroid Build Coastguard Worker
121*5c90c05cSAndroid Build Coastguard Worker FMT_API std::system_error vwindows_error(int error_code, string_view fmt,
122*5c90c05cSAndroid Build Coastguard Worker format_args args);
123*5c90c05cSAndroid Build Coastguard Worker
124*5c90c05cSAndroid Build Coastguard Worker /**
125*5c90c05cSAndroid Build Coastguard Worker * Constructs a `std::system_error` object with the description of the form
126*5c90c05cSAndroid Build Coastguard Worker *
127*5c90c05cSAndroid Build Coastguard Worker * <message>: <system-message>
128*5c90c05cSAndroid Build Coastguard Worker *
129*5c90c05cSAndroid Build Coastguard Worker * where `<message>` is the formatted message and `<system-message>` is the
130*5c90c05cSAndroid Build Coastguard Worker * system message corresponding to the error code.
131*5c90c05cSAndroid Build Coastguard Worker * `error_code` is a Windows error code as given by `GetLastError`.
132*5c90c05cSAndroid Build Coastguard Worker * If `error_code` is not a valid error code such as -1, the system message
133*5c90c05cSAndroid Build Coastguard Worker * will look like "error -1".
134*5c90c05cSAndroid Build Coastguard Worker *
135*5c90c05cSAndroid Build Coastguard Worker * **Example**:
136*5c90c05cSAndroid Build Coastguard Worker *
137*5c90c05cSAndroid Build Coastguard Worker * // This throws a system_error with the description
138*5c90c05cSAndroid Build Coastguard Worker * // cannot open file 'madeup': The system cannot find the file
139*5c90c05cSAndroid Build Coastguard Worker * specified.
140*5c90c05cSAndroid Build Coastguard Worker * // or similar (system message may vary).
141*5c90c05cSAndroid Build Coastguard Worker * const char *filename = "madeup";
142*5c90c05cSAndroid Build Coastguard Worker * LPOFSTRUCT of = LPOFSTRUCT();
143*5c90c05cSAndroid Build Coastguard Worker * HFILE file = OpenFile(filename, &of, OF_READ);
144*5c90c05cSAndroid Build Coastguard Worker * if (file == HFILE_ERROR) {
145*5c90c05cSAndroid Build Coastguard Worker * throw fmt::windows_error(GetLastError(),
146*5c90c05cSAndroid Build Coastguard Worker * "cannot open file '{}'", filename);
147*5c90c05cSAndroid Build Coastguard Worker * }
148*5c90c05cSAndroid Build Coastguard Worker */
149*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
150*5c90c05cSAndroid Build Coastguard Worker auto windows_error(int error_code, string_view message, const T&... args)
151*5c90c05cSAndroid Build Coastguard Worker -> std::system_error {
152*5c90c05cSAndroid Build Coastguard Worker return vwindows_error(error_code, message, vargs<T...>{{args...}});
153*5c90c05cSAndroid Build Coastguard Worker }
154*5c90c05cSAndroid Build Coastguard Worker
155*5c90c05cSAndroid Build Coastguard Worker // Reports a Windows error without throwing an exception.
156*5c90c05cSAndroid Build Coastguard Worker // Can be used to report errors from destructors.
157*5c90c05cSAndroid Build Coastguard Worker FMT_API void report_windows_error(int error_code, const char* message) noexcept;
158*5c90c05cSAndroid Build Coastguard Worker #else
159*5c90c05cSAndroid Build Coastguard Worker inline auto system_category() noexcept -> const std::error_category& {
160*5c90c05cSAndroid Build Coastguard Worker return std::system_category();
161*5c90c05cSAndroid Build Coastguard Worker }
162*5c90c05cSAndroid Build Coastguard Worker #endif // _WIN32
163*5c90c05cSAndroid Build Coastguard Worker
164*5c90c05cSAndroid Build Coastguard Worker // std::system is not available on some platforms such as iOS (#2248).
165*5c90c05cSAndroid Build Coastguard Worker #ifdef __OSX__
166*5c90c05cSAndroid Build Coastguard Worker template <typename S, typename... Args, typename Char = char_t<S>>
say(const S & fmt,Args &&...args)167*5c90c05cSAndroid Build Coastguard Worker void say(const S& fmt, Args&&... args) {
168*5c90c05cSAndroid Build Coastguard Worker std::system(format("say \"{}\"", format(fmt, args...)).c_str());
169*5c90c05cSAndroid Build Coastguard Worker }
170*5c90c05cSAndroid Build Coastguard Worker #endif
171*5c90c05cSAndroid Build Coastguard Worker
172*5c90c05cSAndroid Build Coastguard Worker // A buffered file.
173*5c90c05cSAndroid Build Coastguard Worker class buffered_file {
174*5c90c05cSAndroid Build Coastguard Worker private:
175*5c90c05cSAndroid Build Coastguard Worker FILE* file_;
176*5c90c05cSAndroid Build Coastguard Worker
177*5c90c05cSAndroid Build Coastguard Worker friend class file;
178*5c90c05cSAndroid Build Coastguard Worker
buffered_file(FILE * f)179*5c90c05cSAndroid Build Coastguard Worker inline explicit buffered_file(FILE* f) : file_(f) {}
180*5c90c05cSAndroid Build Coastguard Worker
181*5c90c05cSAndroid Build Coastguard Worker public:
182*5c90c05cSAndroid Build Coastguard Worker buffered_file(const buffered_file&) = delete;
183*5c90c05cSAndroid Build Coastguard Worker void operator=(const buffered_file&) = delete;
184*5c90c05cSAndroid Build Coastguard Worker
185*5c90c05cSAndroid Build Coastguard Worker // Constructs a buffered_file object which doesn't represent any file.
buffered_file()186*5c90c05cSAndroid Build Coastguard Worker inline buffered_file() noexcept : file_(nullptr) {}
187*5c90c05cSAndroid Build Coastguard Worker
188*5c90c05cSAndroid Build Coastguard Worker // Destroys the object closing the file it represents if any.
189*5c90c05cSAndroid Build Coastguard Worker FMT_API ~buffered_file() noexcept;
190*5c90c05cSAndroid Build Coastguard Worker
191*5c90c05cSAndroid Build Coastguard Worker public:
buffered_file(buffered_file && other)192*5c90c05cSAndroid Build Coastguard Worker inline buffered_file(buffered_file&& other) noexcept : file_(other.file_) {
193*5c90c05cSAndroid Build Coastguard Worker other.file_ = nullptr;
194*5c90c05cSAndroid Build Coastguard Worker }
195*5c90c05cSAndroid Build Coastguard Worker
196*5c90c05cSAndroid Build Coastguard Worker inline auto operator=(buffered_file&& other) -> buffered_file& {
197*5c90c05cSAndroid Build Coastguard Worker close();
198*5c90c05cSAndroid Build Coastguard Worker file_ = other.file_;
199*5c90c05cSAndroid Build Coastguard Worker other.file_ = nullptr;
200*5c90c05cSAndroid Build Coastguard Worker return *this;
201*5c90c05cSAndroid Build Coastguard Worker }
202*5c90c05cSAndroid Build Coastguard Worker
203*5c90c05cSAndroid Build Coastguard Worker // Opens a file.
204*5c90c05cSAndroid Build Coastguard Worker FMT_API buffered_file(cstring_view filename, cstring_view mode);
205*5c90c05cSAndroid Build Coastguard Worker
206*5c90c05cSAndroid Build Coastguard Worker // Closes the file.
207*5c90c05cSAndroid Build Coastguard Worker FMT_API void close();
208*5c90c05cSAndroid Build Coastguard Worker
209*5c90c05cSAndroid Build Coastguard Worker // Returns the pointer to a FILE object representing this file.
210*5c90c05cSAndroid Build Coastguard Worker inline auto get() const noexcept -> FILE* { return file_; }
211*5c90c05cSAndroid Build Coastguard Worker
212*5c90c05cSAndroid Build Coastguard Worker FMT_API auto descriptor() const -> int;
213*5c90c05cSAndroid Build Coastguard Worker
214*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
print(string_view fmt,const T &...args)215*5c90c05cSAndroid Build Coastguard Worker inline void print(string_view fmt, const T&... args) {
216*5c90c05cSAndroid Build Coastguard Worker fmt::vargs<T...> vargs = {{args...}};
217*5c90c05cSAndroid Build Coastguard Worker detail::is_locking<T...>() ? fmt::vprint_buffered(file_, fmt, vargs)
218*5c90c05cSAndroid Build Coastguard Worker : fmt::vprint(file_, fmt, vargs);
219*5c90c05cSAndroid Build Coastguard Worker }
220*5c90c05cSAndroid Build Coastguard Worker };
221*5c90c05cSAndroid Build Coastguard Worker
222*5c90c05cSAndroid Build Coastguard Worker #if FMT_USE_FCNTL
223*5c90c05cSAndroid Build Coastguard Worker
224*5c90c05cSAndroid Build Coastguard Worker // A file. Closed file is represented by a file object with descriptor -1.
225*5c90c05cSAndroid Build Coastguard Worker // Methods that are not declared with noexcept may throw
226*5c90c05cSAndroid Build Coastguard Worker // fmt::system_error in case of failure. Note that some errors such as
227*5c90c05cSAndroid Build Coastguard Worker // closing the file multiple times will cause a crash on Windows rather
228*5c90c05cSAndroid Build Coastguard Worker // than an exception. You can get standard behavior by overriding the
229*5c90c05cSAndroid Build Coastguard Worker // invalid parameter handler with _set_invalid_parameter_handler.
230*5c90c05cSAndroid Build Coastguard Worker class FMT_API file {
231*5c90c05cSAndroid Build Coastguard Worker private:
232*5c90c05cSAndroid Build Coastguard Worker int fd_; // File descriptor.
233*5c90c05cSAndroid Build Coastguard Worker
234*5c90c05cSAndroid Build Coastguard Worker // Constructs a file object with a given descriptor.
file(int fd)235*5c90c05cSAndroid Build Coastguard Worker explicit file(int fd) : fd_(fd) {}
236*5c90c05cSAndroid Build Coastguard Worker
237*5c90c05cSAndroid Build Coastguard Worker friend struct pipe;
238*5c90c05cSAndroid Build Coastguard Worker
239*5c90c05cSAndroid Build Coastguard Worker public:
240*5c90c05cSAndroid Build Coastguard Worker // Possible values for the oflag argument to the constructor.
241*5c90c05cSAndroid Build Coastguard Worker enum {
242*5c90c05cSAndroid Build Coastguard Worker RDONLY = FMT_POSIX(O_RDONLY), // Open for reading only.
243*5c90c05cSAndroid Build Coastguard Worker WRONLY = FMT_POSIX(O_WRONLY), // Open for writing only.
244*5c90c05cSAndroid Build Coastguard Worker RDWR = FMT_POSIX(O_RDWR), // Open for reading and writing.
245*5c90c05cSAndroid Build Coastguard Worker CREATE = FMT_POSIX(O_CREAT), // Create if the file doesn't exist.
246*5c90c05cSAndroid Build Coastguard Worker APPEND = FMT_POSIX(O_APPEND), // Open in append mode.
247*5c90c05cSAndroid Build Coastguard Worker TRUNC = FMT_POSIX(O_TRUNC) // Truncate the content of the file.
248*5c90c05cSAndroid Build Coastguard Worker };
249*5c90c05cSAndroid Build Coastguard Worker
250*5c90c05cSAndroid Build Coastguard Worker // Constructs a file object which doesn't represent any file.
file()251*5c90c05cSAndroid Build Coastguard Worker inline file() noexcept : fd_(-1) {}
252*5c90c05cSAndroid Build Coastguard Worker
253*5c90c05cSAndroid Build Coastguard Worker // Opens a file and constructs a file object representing this file.
254*5c90c05cSAndroid Build Coastguard Worker file(cstring_view path, int oflag);
255*5c90c05cSAndroid Build Coastguard Worker
256*5c90c05cSAndroid Build Coastguard Worker public:
257*5c90c05cSAndroid Build Coastguard Worker file(const file&) = delete;
258*5c90c05cSAndroid Build Coastguard Worker void operator=(const file&) = delete;
259*5c90c05cSAndroid Build Coastguard Worker
file(file && other)260*5c90c05cSAndroid Build Coastguard Worker inline file(file&& other) noexcept : fd_(other.fd_) { other.fd_ = -1; }
261*5c90c05cSAndroid Build Coastguard Worker
262*5c90c05cSAndroid Build Coastguard Worker // Move assignment is not noexcept because close may throw.
263*5c90c05cSAndroid Build Coastguard Worker inline auto operator=(file&& other) -> file& {
264*5c90c05cSAndroid Build Coastguard Worker close();
265*5c90c05cSAndroid Build Coastguard Worker fd_ = other.fd_;
266*5c90c05cSAndroid Build Coastguard Worker other.fd_ = -1;
267*5c90c05cSAndroid Build Coastguard Worker return *this;
268*5c90c05cSAndroid Build Coastguard Worker }
269*5c90c05cSAndroid Build Coastguard Worker
270*5c90c05cSAndroid Build Coastguard Worker // Destroys the object closing the file it represents if any.
271*5c90c05cSAndroid Build Coastguard Worker ~file() noexcept;
272*5c90c05cSAndroid Build Coastguard Worker
273*5c90c05cSAndroid Build Coastguard Worker // Returns the file descriptor.
274*5c90c05cSAndroid Build Coastguard Worker inline auto descriptor() const noexcept -> int { return fd_; }
275*5c90c05cSAndroid Build Coastguard Worker
276*5c90c05cSAndroid Build Coastguard Worker // Closes the file.
277*5c90c05cSAndroid Build Coastguard Worker void close();
278*5c90c05cSAndroid Build Coastguard Worker
279*5c90c05cSAndroid Build Coastguard Worker // Returns the file size. The size has signed type for consistency with
280*5c90c05cSAndroid Build Coastguard Worker // stat::st_size.
281*5c90c05cSAndroid Build Coastguard Worker auto size() const -> long long;
282*5c90c05cSAndroid Build Coastguard Worker
283*5c90c05cSAndroid Build Coastguard Worker // Attempts to read count bytes from the file into the specified buffer.
284*5c90c05cSAndroid Build Coastguard Worker auto read(void* buffer, size_t count) -> size_t;
285*5c90c05cSAndroid Build Coastguard Worker
286*5c90c05cSAndroid Build Coastguard Worker // Attempts to write count bytes from the specified buffer to the file.
287*5c90c05cSAndroid Build Coastguard Worker auto write(const void* buffer, size_t count) -> size_t;
288*5c90c05cSAndroid Build Coastguard Worker
289*5c90c05cSAndroid Build Coastguard Worker // Duplicates a file descriptor with the dup function and returns
290*5c90c05cSAndroid Build Coastguard Worker // the duplicate as a file object.
291*5c90c05cSAndroid Build Coastguard Worker static auto dup(int fd) -> file;
292*5c90c05cSAndroid Build Coastguard Worker
293*5c90c05cSAndroid Build Coastguard Worker // Makes fd be the copy of this file descriptor, closing fd first if
294*5c90c05cSAndroid Build Coastguard Worker // necessary.
295*5c90c05cSAndroid Build Coastguard Worker void dup2(int fd);
296*5c90c05cSAndroid Build Coastguard Worker
297*5c90c05cSAndroid Build Coastguard Worker // Makes fd be the copy of this file descriptor, closing fd first if
298*5c90c05cSAndroid Build Coastguard Worker // necessary.
299*5c90c05cSAndroid Build Coastguard Worker void dup2(int fd, std::error_code& ec) noexcept;
300*5c90c05cSAndroid Build Coastguard Worker
301*5c90c05cSAndroid Build Coastguard Worker // Creates a buffered_file object associated with this file and detaches
302*5c90c05cSAndroid Build Coastguard Worker // this file object from the file.
303*5c90c05cSAndroid Build Coastguard Worker auto fdopen(const char* mode) -> buffered_file;
304*5c90c05cSAndroid Build Coastguard Worker
305*5c90c05cSAndroid Build Coastguard Worker # if defined(_WIN32) && !defined(__MINGW32__)
306*5c90c05cSAndroid Build Coastguard Worker // Opens a file and constructs a file object representing this file by
307*5c90c05cSAndroid Build Coastguard Worker // wcstring_view filename. Windows only.
308*5c90c05cSAndroid Build Coastguard Worker static file open_windows_file(wcstring_view path, int oflag);
309*5c90c05cSAndroid Build Coastguard Worker # endif
310*5c90c05cSAndroid Build Coastguard Worker };
311*5c90c05cSAndroid Build Coastguard Worker
312*5c90c05cSAndroid Build Coastguard Worker struct FMT_API pipe {
313*5c90c05cSAndroid Build Coastguard Worker file read_end;
314*5c90c05cSAndroid Build Coastguard Worker file write_end;
315*5c90c05cSAndroid Build Coastguard Worker
316*5c90c05cSAndroid Build Coastguard Worker // Creates a pipe setting up read_end and write_end file objects for reading
317*5c90c05cSAndroid Build Coastguard Worker // and writing respectively.
318*5c90c05cSAndroid Build Coastguard Worker pipe();
319*5c90c05cSAndroid Build Coastguard Worker };
320*5c90c05cSAndroid Build Coastguard Worker
321*5c90c05cSAndroid Build Coastguard Worker // Returns the memory page size.
322*5c90c05cSAndroid Build Coastguard Worker auto getpagesize() -> long;
323*5c90c05cSAndroid Build Coastguard Worker
324*5c90c05cSAndroid Build Coastguard Worker namespace detail {
325*5c90c05cSAndroid Build Coastguard Worker
326*5c90c05cSAndroid Build Coastguard Worker struct buffer_size {
327*5c90c05cSAndroid Build Coastguard Worker constexpr buffer_size() = default;
328*5c90c05cSAndroid Build Coastguard Worker size_t value = 0;
329*5c90c05cSAndroid Build Coastguard Worker FMT_CONSTEXPR auto operator=(size_t val) const -> buffer_size {
330*5c90c05cSAndroid Build Coastguard Worker auto bs = buffer_size();
331*5c90c05cSAndroid Build Coastguard Worker bs.value = val;
332*5c90c05cSAndroid Build Coastguard Worker return bs;
333*5c90c05cSAndroid Build Coastguard Worker }
334*5c90c05cSAndroid Build Coastguard Worker };
335*5c90c05cSAndroid Build Coastguard Worker
336*5c90c05cSAndroid Build Coastguard Worker struct ostream_params {
337*5c90c05cSAndroid Build Coastguard Worker int oflag = file::WRONLY | file::CREATE | file::TRUNC;
338*5c90c05cSAndroid Build Coastguard Worker size_t buffer_size = BUFSIZ > 32768 ? BUFSIZ : 32768;
339*5c90c05cSAndroid Build Coastguard Worker
ostream_paramsostream_params340*5c90c05cSAndroid Build Coastguard Worker constexpr ostream_params() {}
341*5c90c05cSAndroid Build Coastguard Worker
342*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
ostream_paramsostream_params343*5c90c05cSAndroid Build Coastguard Worker ostream_params(T... params, int new_oflag) : ostream_params(params...) {
344*5c90c05cSAndroid Build Coastguard Worker oflag = new_oflag;
345*5c90c05cSAndroid Build Coastguard Worker }
346*5c90c05cSAndroid Build Coastguard Worker
347*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
ostream_paramsostream_params348*5c90c05cSAndroid Build Coastguard Worker ostream_params(T... params, detail::buffer_size bs)
349*5c90c05cSAndroid Build Coastguard Worker : ostream_params(params...) {
350*5c90c05cSAndroid Build Coastguard Worker this->buffer_size = bs.value;
351*5c90c05cSAndroid Build Coastguard Worker }
352*5c90c05cSAndroid Build Coastguard Worker
353*5c90c05cSAndroid Build Coastguard Worker // Intel has a bug that results in failure to deduce a constructor
354*5c90c05cSAndroid Build Coastguard Worker // for empty parameter packs.
355*5c90c05cSAndroid Build Coastguard Worker # if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 2000
ostream_paramsostream_params356*5c90c05cSAndroid Build Coastguard Worker ostream_params(int new_oflag) : oflag(new_oflag) {}
ostream_paramsostream_params357*5c90c05cSAndroid Build Coastguard Worker ostream_params(detail::buffer_size bs) : buffer_size(bs.value) {}
358*5c90c05cSAndroid Build Coastguard Worker # endif
359*5c90c05cSAndroid Build Coastguard Worker };
360*5c90c05cSAndroid Build Coastguard Worker
361*5c90c05cSAndroid Build Coastguard Worker } // namespace detail
362*5c90c05cSAndroid Build Coastguard Worker
363*5c90c05cSAndroid Build Coastguard Worker FMT_INLINE_VARIABLE constexpr auto buffer_size = detail::buffer_size();
364*5c90c05cSAndroid Build Coastguard Worker
365*5c90c05cSAndroid Build Coastguard Worker /// A fast buffered output stream for writing from a single thread. Writing from
366*5c90c05cSAndroid Build Coastguard Worker /// multiple threads without external synchronization may result in a data race.
367*5c90c05cSAndroid Build Coastguard Worker class FMT_API ostream : private detail::buffer<char> {
368*5c90c05cSAndroid Build Coastguard Worker private:
369*5c90c05cSAndroid Build Coastguard Worker file file_;
370*5c90c05cSAndroid Build Coastguard Worker
371*5c90c05cSAndroid Build Coastguard Worker ostream(cstring_view path, const detail::ostream_params& params);
372*5c90c05cSAndroid Build Coastguard Worker
373*5c90c05cSAndroid Build Coastguard Worker static void grow(buffer<char>& buf, size_t);
374*5c90c05cSAndroid Build Coastguard Worker
375*5c90c05cSAndroid Build Coastguard Worker public:
376*5c90c05cSAndroid Build Coastguard Worker ostream(ostream&& other) noexcept;
377*5c90c05cSAndroid Build Coastguard Worker ~ostream();
378*5c90c05cSAndroid Build Coastguard Worker
writer()379*5c90c05cSAndroid Build Coastguard Worker operator writer() {
380*5c90c05cSAndroid Build Coastguard Worker detail::buffer<char>& buf = *this;
381*5c90c05cSAndroid Build Coastguard Worker return buf;
382*5c90c05cSAndroid Build Coastguard Worker }
383*5c90c05cSAndroid Build Coastguard Worker
flush()384*5c90c05cSAndroid Build Coastguard Worker inline void flush() {
385*5c90c05cSAndroid Build Coastguard Worker if (size() == 0) return;
386*5c90c05cSAndroid Build Coastguard Worker file_.write(data(), size() * sizeof(data()[0]));
387*5c90c05cSAndroid Build Coastguard Worker clear();
388*5c90c05cSAndroid Build Coastguard Worker }
389*5c90c05cSAndroid Build Coastguard Worker
390*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
391*5c90c05cSAndroid Build Coastguard Worker friend auto output_file(cstring_view path, T... params) -> ostream;
392*5c90c05cSAndroid Build Coastguard Worker
close()393*5c90c05cSAndroid Build Coastguard Worker inline void close() {
394*5c90c05cSAndroid Build Coastguard Worker flush();
395*5c90c05cSAndroid Build Coastguard Worker file_.close();
396*5c90c05cSAndroid Build Coastguard Worker }
397*5c90c05cSAndroid Build Coastguard Worker
398*5c90c05cSAndroid Build Coastguard Worker /// Formats `args` according to specifications in `fmt` and writes the
399*5c90c05cSAndroid Build Coastguard Worker /// output to the file.
print(format_string<T...> fmt,T &&...args)400*5c90c05cSAndroid Build Coastguard Worker template <typename... T> void print(format_string<T...> fmt, T&&... args) {
401*5c90c05cSAndroid Build Coastguard Worker vformat_to(appender(*this), fmt.str, vargs<T...>{{args...}});
402*5c90c05cSAndroid Build Coastguard Worker }
403*5c90c05cSAndroid Build Coastguard Worker };
404*5c90c05cSAndroid Build Coastguard Worker
405*5c90c05cSAndroid Build Coastguard Worker /**
406*5c90c05cSAndroid Build Coastguard Worker * Opens a file for writing. Supported parameters passed in `params`:
407*5c90c05cSAndroid Build Coastguard Worker *
408*5c90c05cSAndroid Build Coastguard Worker * - `<integer>`: Flags passed to [open](
409*5c90c05cSAndroid Build Coastguard Worker * https://pubs.opengroup.org/onlinepubs/007904875/functions/open.html)
410*5c90c05cSAndroid Build Coastguard Worker * (`file::WRONLY | file::CREATE | file::TRUNC` by default)
411*5c90c05cSAndroid Build Coastguard Worker * - `buffer_size=<integer>`: Output buffer size
412*5c90c05cSAndroid Build Coastguard Worker *
413*5c90c05cSAndroid Build Coastguard Worker * **Example**:
414*5c90c05cSAndroid Build Coastguard Worker *
415*5c90c05cSAndroid Build Coastguard Worker * auto out = fmt::output_file("guide.txt");
416*5c90c05cSAndroid Build Coastguard Worker * out.print("Don't {}", "Panic");
417*5c90c05cSAndroid Build Coastguard Worker */
418*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
419*5c90c05cSAndroid Build Coastguard Worker inline auto output_file(cstring_view path, T... params) -> ostream {
420*5c90c05cSAndroid Build Coastguard Worker return {path, detail::ostream_params(params...)};
421*5c90c05cSAndroid Build Coastguard Worker }
422*5c90c05cSAndroid Build Coastguard Worker #endif // FMT_USE_FCNTL
423*5c90c05cSAndroid Build Coastguard Worker
424*5c90c05cSAndroid Build Coastguard Worker FMT_END_EXPORT
425*5c90c05cSAndroid Build Coastguard Worker FMT_END_NAMESPACE
426*5c90c05cSAndroid Build Coastguard Worker
427*5c90c05cSAndroid Build Coastguard Worker #endif // FMT_OS_H_
428