Photon 1.0.0
Loading...
Searching...
No Matches
os.h
Go to the documentation of this file.
1// Formatting library for C++ - optional OS-specific functionality
2//
3// Copyright (c) 2012 - present, Victor Zverovich
4// All rights reserved.
5//
6// For the license information refer to format.h.
7
8#ifndef FMT_OS_H_
9#define FMT_OS_H_
10
11#include <cerrno>
12#include <cstddef>
13#include <cstdio>
14#include <system_error> // std::system_error
15
16#if defined __APPLE__ || defined(__FreeBSD__)
17#include <xlocale.h> // for LC_NUMERIC_MASK on OS X
18#endif
19
20#include "format.h"
21
22#ifndef FMT_USE_FCNTL
23// UWP doesn't provide _pipe.
24#if FMT_HAS_INCLUDE("winapifamily.h")
25#include <winapifamily.h>
26#endif
27#if (FMT_HAS_INCLUDE(<fcntl.h>) || defined(__APPLE__) || \
28 defined(__linux__)) && \
29 (!defined(WINAPI_FAMILY) || \
30 (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
31#include <fcntl.h> // for O_RDONLY
32#define FMT_USE_FCNTL 1
33#else
34#define FMT_USE_FCNTL 0
35#endif
36#endif
37
38#ifndef FMT_POSIX
39#if defined(_WIN32) && !defined(__MINGW32__)
40// Fix warnings about deprecated symbols.
41#define FMT_POSIX(call) _##call
42#else
43#define FMT_POSIX(call) call
44#endif
45#endif
46
47// Calls to system functions are wrapped in FMT_SYSTEM for testability.
48#ifdef FMT_SYSTEM
49#define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
50#else
51#define FMT_SYSTEM(call) ::call
52#ifdef _WIN32
53// Fix warnings about deprecated symbols.
54#define FMT_POSIX_CALL(call) ::_##call
55#else
56#define FMT_POSIX_CALL(call) ::call
57#endif
58#endif
59
60// Retries the expression while it evaluates to error_result and errno
61// equals to EINTR.
62#ifndef _WIN32
63#define FMT_RETRY_VAL(result, expression, error_result) \
64 do \
65 { \
66 (result) = (expression); \
67 } while ((result) == (error_result) && errno == EINTR)
68#else
69#define FMT_RETRY_VAL(result, expression, error_result) result = (expression)
70#endif
71
72#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
73
76
102template <typename Char>
104{
105private:
106 const Char* data_;
107
108public:
111 : data_(s)
112 {
113 }
114
120 basic_cstring_view(const std::basic_string<Char>& s)
121 : data_(s.c_str())
122 {
123 }
124
126 const Char* c_str() const
127 {
128 return data_;
129 }
130};
131
134
135template <typename Char>
136struct formatter<std::error_code, Char>
137{
138 template <typename ParseContext>
139 FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin())
140 {
141 return ctx.begin();
142 }
143
144 template <typename FormatContext>
145 FMT_CONSTEXPR auto format(const std::error_code& ec, FormatContext& ctx) const
146 -> decltype(ctx.out())
147 {
148 auto out = ctx.out();
149 out = detail::write_bytes(out, ec.category().name(),
151 out = detail::write<Char>(out, Char(':'));
152 out = detail::write<Char>(out, ec.value());
153 return out;
154 }
155};
156
157#ifdef _WIN32
158FMT_API const std::error_category& system_category() noexcept;
159
161// A converter from UTF-16 to UTF-8.
162// It is only provided for Windows since other systems support UTF-8 natively.
163class utf16_to_utf8
164{
165private:
166 memory_buffer buffer_;
167
168public:
169 utf16_to_utf8()
170 {
171 }
172 FMT_API explicit utf16_to_utf8(basic_string_view<wchar_t> s);
173 operator string_view() const
174 {
175 return string_view(&buffer_[0], size());
176 }
177 size_t size() const
178 {
179 return buffer_.size() - 1;
180 }
181 const char* c_str() const
182 {
183 return &buffer_[0];
184 }
185 std::string str() const
186 {
187 return std::string(&buffer_[0], size());
188 }
189
190 // Performs conversion returning a system error code instead of
191 // throwing exception on conversion error. This method may still throw
192 // in case of memory allocation error.
194};
195
196FMT_API void format_windows_error(buffer<char>& out, int error_code, const char* message) noexcept;
198
199FMT_API std::system_error vwindows_error(int error_code, string_view format_str, format_args args);
200
229template <typename... Args>
230std::system_error windows_error(int error_code, string_view message, const Args&... args)
231{
232 return vwindows_error(error_code, message, fmt::make_format_args(args...));
233}
234
235// Reports a Windows error without throwing an exception.
236// Can be used to report errors from destructors.
237FMT_API void report_windows_error(int error_code, const char* message) noexcept;
238#else
239inline const std::error_category& system_category() noexcept
240{
241 return std::system_category();
242}
243#endif // _WIN32
244
245// std::system is not available on some platforms such as iOS (#2248).
246#ifdef __OSX__
247template <typename S, typename... Args, typename Char = char_t<S>>
248void say(const S& format_str, Args&&... args)
249{
250 std::system(format("say \"{}\"", format(format_str, args...)).c_str());
251}
252#endif
253
254// A buffered file.
256{
257private:
258 FILE* file_;
259
260 friend class file;
261
262 explicit buffered_file(FILE* f)
263 : file_(f)
264 {
265 }
266
267public:
268 buffered_file(const buffered_file&) = delete;
269 void operator=(const buffered_file&) = delete;
270
271 // Constructs a buffered_file object which doesn't represent any file.
272 buffered_file() noexcept
273 : file_(nullptr)
274 {
275 }
276
277 // Destroys the object closing the file it represents if any.
279
280public:
281 buffered_file(buffered_file&& other) noexcept
282 : file_(other.file_)
283 {
284 other.file_ = nullptr;
285 }
286
288 {
289 close();
290 file_ = other.file_;
291 other.file_ = nullptr;
292 return *this;
293 }
294
295 // Opens a file.
297
298 // Closes the file.
300
301 // Returns the pointer to a FILE object representing this file.
302 FILE* get() const noexcept
303 {
304 return file_;
305 }
306
307 FMT_API int descriptor() const;
308
309 void vprint(string_view format_str, format_args args)
310 {
311 fmt::vprint(file_, format_str, args);
312 }
313
314 template <typename... Args>
315 inline void print(string_view format_str, const Args&... args)
316 {
317 vprint(format_str, fmt::make_format_args(args...));
318 }
319};
320
321#if FMT_USE_FCNTL
322// A file. Closed file is represented by a file object with descriptor -1.
323// Methods that are not declared with noexcept may throw
324// fmt::system_error in case of failure. Note that some errors such as
325// closing the file multiple times will cause a crash on Windows rather
326// than an exception. You can get standard behavior by overriding the
327// invalid parameter handler with _set_invalid_parameter_handler.
328class FMT_API file
329{
330private:
331 int fd_; // File descriptor.
332
333 // Constructs a file object with a given descriptor.
334 explicit file(int fd)
335 : fd_(fd)
336 {
337 }
338
339public:
340 // Possible values for the oflag argument to the constructor.
341 enum
342 {
343 RDONLY = FMT_POSIX(O_RDONLY), // Open for reading only.
344 WRONLY = FMT_POSIX(O_WRONLY), // Open for writing only.
345 RDWR = FMT_POSIX(O_RDWR), // Open for reading and writing.
346 CREATE = FMT_POSIX(O_CREAT), // Create if the file doesn't exist.
347 APPEND = FMT_POSIX(O_APPEND), // Open in append mode.
348 TRUNC = FMT_POSIX(O_TRUNC) // Truncate the content of the file.
349 };
350
351 // Constructs a file object which doesn't represent any file.
352 file() noexcept
353 : fd_(-1)
354 {
355 }
356
357 // Opens a file and constructs a file object representing this file.
358 file(cstring_view path, int oflag);
359
360public:
361 file(const file&) = delete;
362 void operator=(const file&) = delete;
363
364 file(file&& other) noexcept
365 : fd_(other.fd_)
366 {
367 other.fd_ = -1;
368 }
369
370 // Move assignment is not noexcept because close may throw.
371 file& operator=(file&& other)
372 {
373 close();
374 fd_ = other.fd_;
375 other.fd_ = -1;
376 return *this;
377 }
378
379 // Destroys the object closing the file it represents if any.
380 ~file() noexcept;
381
382 // Returns the file descriptor.
383 int descriptor() const noexcept
384 {
385 return fd_;
386 }
387
388 // Closes the file.
389 void close();
390
391 // Returns the file size. The size has signed type for consistency with
392 // stat::st_size.
393 long long size() const;
394
395 // Attempts to read count bytes from the file into the specified buffer.
396 size_t read(void* buffer, size_t count);
397
398 // Attempts to write count bytes from the specified buffer to the file.
399 size_t write(const void* buffer, size_t count);
400
401 // Duplicates a file descriptor with the dup function and returns
402 // the duplicate as a file object.
403 static file dup(int fd);
404
405 // Makes fd be the copy of this file descriptor, closing fd first if
406 // necessary.
407 void dup2(int fd);
408
409 // Makes fd be the copy of this file descriptor, closing fd first if
410 // necessary.
411 void dup2(int fd, std::error_code& ec) noexcept;
412
413 // Creates a pipe setting up read_end and write_end file objects for reading
414 // and writing respectively.
415 static void pipe(file& read_end, file& write_end);
416
417 // Creates a buffered_file object associated with this file and detaches
418 // this file object from the file.
419 buffered_file fdopen(const char* mode);
420};
421
422// Returns the memory page size.
423long getpagesize();
424
426
427struct buffer_size
428{
429 buffer_size() = default;
430 size_t value = 0;
431 buffer_size operator=(size_t val) const
432 {
433 auto bs = buffer_size();
434 bs.value = val;
435 return bs;
436 }
437};
438
439struct ostream_params
440{
441 int oflag = file::WRONLY | file::CREATE | file::TRUNC;
442 size_t buffer_size = BUFSIZ > 32768 ? BUFSIZ : 32768;
443
444 ostream_params()
445 {
446 }
447
448 template <typename... T>
449 ostream_params(T... params, int new_oflag)
450 : ostream_params(params...)
451 {
452 oflag = new_oflag;
453 }
454
455 template <typename... T>
456 ostream_params(T... params, detail::buffer_size bs)
457 : ostream_params(params...)
458 {
459 this->buffer_size = bs.value;
460 }
461
462// Intel has a bug that results in failure to deduce a constructor
463// for empty parameter packs.
464#if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 2000
465 ostream_params(int new_oflag)
466 : oflag(new_oflag)
467 {
468 }
469 ostream_params(detail::buffer_size bs)
470 : buffer_size(bs.value)
471 {
472 }
473#endif
474};
475
477
478// Added {} below to work around default constructor error known to
479// occur in Xcode versions 7.2.1 and 8.2.1.
480constexpr detail::buffer_size buffer_size{};
481
483class FMT_API ostream final : private detail::buffer<char>
484{
485private:
486 file file_;
487
488 void grow(size_t) override;
489
490 ostream(cstring_view path, const detail::ostream_params& params)
491 : file_(path, params.oflag)
492 {
493 set(new char[params.buffer_size], params.buffer_size);
494 }
495
496public:
497 ostream(ostream&& other)
498 : detail::buffer<char>(other.data(), other.size(), other.capacity()),
499 file_(std::move(other.file_))
500 {
501 other.clear();
502 other.set(nullptr, 0);
503 }
504 ~ostream()
505 {
506 flush();
507 delete[] data();
508 }
509
510 void flush()
511 {
512 if (size() == 0)
513 return;
514 file_.write(data(), size());
515 clear();
516 }
517
518 template <typename... T>
519 friend ostream output_file(cstring_view path, T... params);
520
521 void close()
522 {
523 flush();
524 file_.close();
525 }
526
531 template <typename... T>
532 void print(format_string<T...> fmt, T&&... args)
533 {
534 vformat_to(detail::buffer_appender<char>(*this), fmt,
535 fmt::make_format_args(args...));
536 }
537};
538
554template <typename... T>
555inline ostream output_file(cstring_view path, T... params)
556{
557 return {path, detail::ostream_params(params...)};
558}
559#endif // FMT_USE_FCNTL
560
563
564#endif // FMT_OS_H_
Definition os.h:104
basic_cstring_view(const std::basic_string< Char > &s)
Definition os.h:120
const Char * data_
Definition os.h:106
basic_cstring_view(const Char *s)
Definition os.h:110
const Char * c_str() const
Definition os.h:126
Definition core.h:2524
Definition core.h:483
Definition core.h:1032
void clear()
Definition core.h:1114
Definition os.h:256
void vprint(string_view format_str, format_args args)
Definition os.h:309
void operator=(const buffered_file &)=delete
FMT_API void close()
FMT_API int descriptor() const
FMT_API ~buffered_file() noexcept
friend class file
Definition os.h:260
FILE * get() const noexcept
Definition os.h:302
buffered_file(FILE *f)
Definition os.h:262
buffered_file() noexcept
Definition os.h:272
FMT_API buffered_file(cstring_view filename, cstring_view mode)
FILE * file_
Definition os.h:258
buffered_file(const buffered_file &)=delete
void print(string_view format_str, const Args &... args)
Definition os.h:315
buffered_file & operator=(buffered_file &&other)
Definition os.h:287
Definition core.h:1598
void print(std::FILE *f, const text_style &ts, const S &format_str, const Args &... args)
Definition color.h:601
void vformat_to(buffer< Char > &buf, const text_style &ts, basic_string_view< Char > format_str, basic_format_args< buffer_context< type_identity_t< Char > > > args)
Definition color.h:545
std::basic_string< Char > format(const text_style &ts, const S &format_str, const Args &... args)
Definition color.h:646
basic_string_view< char > string_view
Definition core.h:604
typename detail::char_t_impl< S >::type char_t
Definition core.h:759
#define FMT_END_DETAIL_NAMESPACE
Definition core.h:231
#define FMT_MODULE_EXPORT_BEGIN
Definition core.h:226
constexpr auto count() -> size_t
Definition core.h:1538
basic_format_string< char, type_identity_t< Args >... > format_string
Definition core.h:4059
#define FMT_CONSTEXPR
Definition core.h:106
#define FMT_BEGIN_NAMESPACE
Definition core.h:214
#define FMT_BEGIN_DETAIL_NAMESPACE
Definition core.h:228
#define FMT_API
Definition core.h:250
#define FMT_END_NAMESPACE
Definition core.h:219
#define FMT_MODULE_EXPORT_END
Definition core.h:227
#define out
Definition encodings.cpp:5
#define FMT_POSIX(call)
Definition os.h:43
const std::error_category & system_category() noexcept
Definition os.h:239
basic_cstring_view< wchar_t > wcstring_view
Definition os.h:133
basic_cstring_view< char > cstring_view
Definition os.h:132
basic_memory_buffer< char > memory_buffer
Definition format.h:1095
FMT_CONSTEXPR auto write(OutputIt out, Char value, const basic_format_specs< Char > &specs, locale_ref loc={}) -> OutputIt
Definition format.h:2272
Definition args.h:20
Definition bin_to_hex.h:111
Definition uuid.h:926
Definition core.h:2772
Definition format.h:1901
FMT_CONSTEXPR auto format(const std::error_code &ec, FormatContext &ctx) const -> decltype(ctx.out())
Definition os.h:145
FMT_CONSTEXPR auto parse(ParseContext &ctx) -> decltype(ctx.begin())
Definition os.h:139
Definition core.h:944
s
Definition tag_strings.h:47