]>
git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/fmt/include/fmt/posix.h
1 // A C++ interface to POSIX functions.
3 // Copyright (c) 2012 - 2016, Victor Zverovich
4 // All rights reserved.
6 // For the license information refer to format.h.
11 #if defined(__MINGW32__) || defined(__CYGWIN__)
12 // Workaround MinGW bug https://sourceforge.net/p/mingw/bugs/2024/.
13 # undef __STRICT_ANSI__
17 #include <fcntl.h> // for O_RDONLY
18 #include <locale.h> // for locale_t
20 #include <stdlib.h> // for strtod_l
24 #if defined __APPLE__ || defined(__FreeBSD__)
25 # include <xlocale.h> // for LC_NUMERIC_MASK on OS X
31 # if defined(_WIN32) && !defined(__MINGW32__)
32 // Fix warnings about deprecated symbols.
33 # define FMT_POSIX(call) _##call
35 # define FMT_POSIX(call) call
39 // Calls to system functions are wrapped in FMT_SYSTEM for testability.
41 # define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
43 # define FMT_SYSTEM(call) call
45 // Fix warnings about deprecated symbols.
46 # define FMT_POSIX_CALL(call) ::_##call
48 # define FMT_POSIX_CALL(call) ::call
52 // Retries the expression while it evaluates to error_result and errno
55 # define FMT_RETRY_VAL(result, expression, error_result) \
57 result = (expression); \
58 } while (result == error_result && errno == EINTR)
60 # define FMT_RETRY_VAL(result, expression, error_result) result = (expression)
63 #define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
69 A reference to a null-terminated string. It can be constructed from a C
70 string or ``std::string``.
72 You can use one of the following typedefs for common character types:
74 +---------------+-----------------------------+
76 +===============+=============================+
77 | cstring_view | basic_cstring_view<char> |
78 +---------------+-----------------------------+
79 | wcstring_view | basic_cstring_view<wchar_t> |
80 +---------------+-----------------------------+
82 This class is most useful as a parameter type to allow passing
83 different types of strings to a function, for example::
85 template <typename... Args>
86 std::string format(cstring_view format_str, const Args & ... args);
89 format(std::string("{}"), 42);
92 template <typename Char
>
93 class basic_cstring_view
{
98 /** Constructs a string reference object from a C string. */
99 basic_cstring_view(const Char
*s
) : data_(s
) {}
103 Constructs a string reference from an ``std::string`` object.
106 basic_cstring_view(const std::basic_string
<Char
> &s
) : data_(s
.c_str()) {}
108 /** Returns the pointer to a C string. */
109 const Char
*c_str() const { return data_
; }
112 typedef basic_cstring_view
<char> cstring_view
;
113 typedef basic_cstring_view
<wchar_t> wcstring_view
;
121 explicit error_code(int value
= 0) FMT_NOEXCEPT
: value_(value
) {}
123 int get() const FMT_NOEXCEPT
{ return value_
; }
127 class buffered_file
{
133 explicit buffered_file(FILE *f
) : file_(f
) {}
136 // Constructs a buffered_file object which doesn't represent any file.
137 buffered_file() FMT_NOEXCEPT
: file_(FMT_NULL
) {}
139 // Destroys the object closing the file it represents if any.
140 FMT_API
~buffered_file() FMT_NOEXCEPT
;
143 buffered_file(const buffered_file
&) = delete;
144 void operator=(const buffered_file
&) = delete;
148 buffered_file(buffered_file
&&other
) FMT_NOEXCEPT
: file_(other
.file_
) {
149 other
.file_
= FMT_NULL
;
152 buffered_file
& operator=(buffered_file
&&other
) {
155 other
.file_
= FMT_NULL
;
160 FMT_API
buffered_file(cstring_view filename
, cstring_view mode
);
163 FMT_API
void close();
165 // Returns the pointer to a FILE object representing this file.
166 FILE *get() const FMT_NOEXCEPT
{ return file_
; }
168 // We place parentheses around fileno to workaround a bug in some versions
169 // of MinGW that define fileno as a macro.
170 FMT_API
int (fileno
)() const;
172 void vprint(string_view format_str
, format_args args
) {
173 fmt::vprint(file_
, format_str
, args
);
176 template <typename
... Args
>
177 inline void print(string_view format_str
, const Args
& ... args
) {
178 vprint(format_str
, make_format_args(args
...));
182 // A file. Closed file is represented by a file object with descriptor -1.
183 // Methods that are not declared with FMT_NOEXCEPT may throw
184 // fmt::system_error in case of failure. Note that some errors such as
185 // closing the file multiple times will cause a crash on Windows rather
186 // than an exception. You can get standard behavior by overriding the
187 // invalid parameter handler with _set_invalid_parameter_handler.
190 int fd_
; // File descriptor.
192 // Constructs a file object with a given descriptor.
193 explicit file(int fd
) : fd_(fd
) {}
196 // Possible values for the oflag argument to the constructor.
198 RDONLY
= FMT_POSIX(O_RDONLY
), // Open for reading only.
199 WRONLY
= FMT_POSIX(O_WRONLY
), // Open for writing only.
200 RDWR
= FMT_POSIX(O_RDWR
) // Open for reading and writing.
203 // Constructs a file object which doesn't represent any file.
204 file() FMT_NOEXCEPT
: fd_(-1) {}
206 // Opens a file and constructs a file object representing this file.
207 FMT_API
file(cstring_view path
, int oflag
);
210 file(const file
&) = delete;
211 void operator=(const file
&) = delete;
214 file(file
&&other
) FMT_NOEXCEPT
: fd_(other
.fd_
) {
218 file
& operator=(file
&&other
) {
225 // Destroys the object closing the file it represents if any.
226 FMT_API
~file() FMT_NOEXCEPT
;
228 // Returns the file descriptor.
229 int descriptor() const FMT_NOEXCEPT
{ return fd_
; }
232 FMT_API
void close();
234 // Returns the file size. The size has signed type for consistency with
236 FMT_API
long long size() const;
238 // Attempts to read count bytes from the file into the specified buffer.
239 FMT_API
std::size_t read(void *buffer
, std::size_t count
);
241 // Attempts to write count bytes from the specified buffer to the file.
242 FMT_API
std::size_t write(const void *buffer
, std::size_t count
);
244 // Duplicates a file descriptor with the dup function and returns
245 // the duplicate as a file object.
246 FMT_API
static file
dup(int fd
);
248 // Makes fd be the copy of this file descriptor, closing fd first if
250 FMT_API
void dup2(int fd
);
252 // Makes fd be the copy of this file descriptor, closing fd first if
254 FMT_API
void dup2(int fd
, error_code
&ec
) FMT_NOEXCEPT
;
256 // Creates a pipe setting up read_end and write_end file objects for reading
257 // and writing respectively.
258 FMT_API
static void pipe(file
&read_end
, file
&write_end
);
260 // Creates a buffered_file object associated with this file and detaches
261 // this file object from the file.
262 FMT_API buffered_file
fdopen(const char *mode
);
265 // Returns the memory page size.
268 #if (defined(LC_NUMERIC_MASK) || defined(_MSC_VER)) && \
269 !defined(__ANDROID__) && !defined(__CYGWIN__) && !defined(__OpenBSD__) && \
270 !defined(__NEWLIB_H__)
275 // A "C" numeric locale.
279 typedef _locale_t locale_t
;
281 enum { LC_NUMERIC_MASK
= LC_NUMERIC
};
283 static locale_t
newlocale(int category_mask
, const char *locale
, locale_t
) {
284 return _create_locale(category_mask
, locale
);
287 static void freelocale(locale_t locale
) {
288 _free_locale(locale
);
291 static double strtod_l(const char *nptr
, char **endptr
, _locale_t locale
) {
292 return _strtod_l(nptr
, endptr
, locale
);
298 Locale(const Locale
&) = delete;
299 void operator=(const Locale
&) = delete;
302 typedef locale_t Type
;
304 Locale() : locale_(newlocale(LC_NUMERIC_MASK
, "C", FMT_NULL
)) {
306 FMT_THROW(system_error(errno
, "cannot create locale"));
308 ~Locale() { freelocale(locale_
); }
310 Type
get() const { return locale_
; }
312 // Converts string to floating-point number and advances str past the end
313 // of the parsed input.
314 double strtod(const char *&str
) const {
315 char *end
= FMT_NULL
;
316 double result
= strtod_l(str
, &end
, locale_
);
324 #endif // FMT_POSIX_H_