SoPlex Documentation
Loading...
Searching...
No Matches
posix.h
Go to the documentation of this file.
1// A C++ interface to POSIX functions.
2//
3// Copyright (c) 2012 - 2016, Victor Zverovich
4// All rights reserved.
5//
6// For the license information refer to format.h.
7
8#ifndef FMT_POSIX_H_
9#define FMT_POSIX_H_
10
11#if defined(__MINGW32__) || defined(__CYGWIN__)
12// Workaround MinGW bug https://sourceforge.net/p/mingw/bugs/2024/.
13# undef __STRICT_ANSI__
14#endif
15
16#include <cerrno>
17#include <clocale> // for locale_t
18#include <cstdio>
19#include <cstdlib> // for strtod_l
20
21#include <cstddef>
22
23#if defined __APPLE__ || defined(__FreeBSD__)
24# include <xlocale.h> // for LC_NUMERIC_MASK on OS X
25#endif
26
27#include "format.h"
28
29// UWP doesn't provide _pipe.
30#if FMT_HAS_INCLUDE("winapifamily.h")
31# include <winapifamily.h>
32#endif
33#if FMT_HAS_INCLUDE("fcntl.h") && \
34 (!defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
35# include <fcntl.h> // for O_RDONLY
36# define FMT_USE_FCNTL 1
37#else
38# define FMT_USE_FCNTL 0
39#endif
40
41#ifndef FMT_POSIX
42# if defined(_WIN32) && !defined(__MINGW32__)
43// Fix warnings about deprecated symbols.
44# define FMT_POSIX(call) _##call
45# else
46# define FMT_POSIX(call) call
47# endif
48#endif
49
50// Calls to system functions are wrapped in FMT_SYSTEM for testability.
51#ifdef FMT_SYSTEM
52# define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
53#else
54# define FMT_SYSTEM(call) call
55# ifdef _WIN32
56// Fix warnings about deprecated symbols.
57# define FMT_POSIX_CALL(call) ::_##call
58# else
59# define FMT_POSIX_CALL(call) ::call
60# endif
61#endif
62
63// Retries the expression while it evaluates to error_result and errno
64// equals to EINTR.
65#ifndef _WIN32
66# define FMT_RETRY_VAL(result, expression, error_result) \
67 do { \
68 (result) = (expression); \
69 } while ((result) == (error_result) && errno == EINTR)
70#else
71# define FMT_RETRY_VAL(result, expression, error_result) result = (expression)
72#endif
73
74#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
75
77
78/**
79 \rst
80 A reference to a null-terminated string. It can be constructed from a C
81 string or ``std::string``.
82
83 You can use one of the following type aliases for common character types:
84
85 +---------------+-----------------------------+
86 | Type | Definition |
87 +===============+=============================+
88 | cstring_view | basic_cstring_view<char> |
89 +---------------+-----------------------------+
90 | wcstring_view | basic_cstring_view<wchar_t> |
91 +---------------+-----------------------------+
92
93 This class is most useful as a parameter type to allow passing
94 different types of strings to a function, for example::
95
96 template <typename... Args>
97 std::string format(cstring_view format_str, const Args & ... args);
98
99 format("{}", 42);
100 format(std::string("{}"), 42);
101 \endrst
102 */
103template <typename Char> class basic_cstring_view {
104 private:
105 const Char* data_;
106
107 public:
108 /** Constructs a string reference object from a C string. */
109 basic_cstring_view(const Char* s) : data_(s) {}
110
111 /**
112 \rst
113 Constructs a string reference from an ``std::string`` object.
114 \endrst
115 */
116 basic_cstring_view(const std::basic_string<Char>& s) : data_(s.c_str()) {}
117
118 /** Returns the pointer to a C string. */
119 const Char* c_str() const { return data_; }
120};
121
124
125// An error code.
127 private:
129
130 public:
131 explicit error_code(int value = 0) FMT_NOEXCEPT : value_(value) {}
132
133 int get() const FMT_NOEXCEPT { return value_; }
134};
135
136// A buffered file.
138 private:
139 FILE* file_;
140
141 friend class file;
142
143 explicit buffered_file(FILE* f) : file_(f) {}
144
145 public:
146 buffered_file(const buffered_file&) = delete;
147 void operator=(const buffered_file&) = delete;
148
149 // Constructs a buffered_file object which doesn't represent any file.
151
152 // Destroys the object closing the file it represents if any.
154
155 public:
157 other.file_ = nullptr;
158 }
159
161 close();
162 file_ = other.file_;
163 other.file_ = nullptr;
164 return *this;
165 }
166
167 // Opens a file.
169
170 // Closes the file.
172
173 // Returns the pointer to a FILE object representing this file.
174 FILE* get() const FMT_NOEXCEPT { return file_; }
175
176 // We place parentheses around fileno to workaround a bug in some versions
177 // of MinGW that define fileno as a macro.
178 FMT_API int(fileno)() const;
179
180 void vprint(string_view format_str, format_args args) {
181 fmt::vprint(file_, format_str, args);
182 }
183
184 template <typename... Args>
185 inline void print(string_view format_str, const Args&... args) {
186 vprint(format_str, make_format_args(args...));
187 }
188};
189
190#if FMT_USE_FCNTL
191// A file. Closed file is represented by a file object with descriptor -1.
192// Methods that are not declared with FMT_NOEXCEPT may throw
193// fmt::system_error in case of failure. Note that some errors such as
194// closing the file multiple times will cause a crash on Windows rather
195// than an exception. You can get standard behavior by overriding the
196// invalid parameter handler with _set_invalid_parameter_handler.
197class file {
198 private:
199 int fd_; // File descriptor.
200
201 // Constructs a file object with a given descriptor.
202 explicit file(int fd) : fd_(fd) {}
203
204 public:
205 // Possible values for the oflag argument to the constructor.
206 enum {
207 RDONLY = FMT_POSIX(O_RDONLY), // Open for reading only.
208 WRONLY = FMT_POSIX(O_WRONLY), // Open for writing only.
209 RDWR = FMT_POSIX(O_RDWR) // Open for reading and writing.
210 };
211
212 // Constructs a file object which doesn't represent any file.
213 file() FMT_NOEXCEPT : fd_(-1) {}
214
215 // Opens a file and constructs a file object representing this file.
216 FMT_API file(cstring_view path, int oflag);
217
218 public:
219 file(const file&) = delete;
220 void operator=(const file&) = delete;
221
222 file(file&& other) FMT_NOEXCEPT : fd_(other.fd_) { other.fd_ = -1; }
223
224 file& operator=(file&& other) FMT_NOEXCEPT {
225 close();
226 fd_ = other.fd_;
227 other.fd_ = -1;
228 return *this;
229 }
230
231 // Destroys the object closing the file it represents if any.
232 FMT_API ~file() FMT_NOEXCEPT;
233
234 // Returns the file descriptor.
235 int descriptor() const FMT_NOEXCEPT { return fd_; }
236
237 // Closes the file.
238 FMT_API void close();
239
240 // Returns the file size. The size has signed type for consistency with
241 // stat::st_size.
242 FMT_API long long size() const;
243
244 // Attempts to read count bytes from the file into the specified buffer.
245 FMT_API std::size_t read(void* buffer, std::size_t count);
246
247 // Attempts to write count bytes from the specified buffer to the file.
248 FMT_API std::size_t write(const void* buffer, std::size_t count);
249
250 // Duplicates a file descriptor with the dup function and returns
251 // the duplicate as a file object.
252 FMT_API static file dup(int fd);
253
254 // Makes fd be the copy of this file descriptor, closing fd first if
255 // necessary.
256 FMT_API void dup2(int fd);
257
258 // Makes fd be the copy of this file descriptor, closing fd first if
259 // necessary.
260 FMT_API void dup2(int fd, error_code& ec) FMT_NOEXCEPT;
261
262 // Creates a pipe setting up read_end and write_end file objects for reading
263 // and writing respectively.
264 FMT_API static void pipe(file& read_end, file& write_end);
265
266 // Creates a buffered_file object associated with this file and detaches
267 // this file object from the file.
268 FMT_API buffered_file fdopen(const char* mode);
269};
270
271// Returns the memory page size.
272long getpagesize();
273#endif // FMT_USE_FCNTL
274
275#ifdef FMT_LOCALE
276// A "C" numeric locale.
277class Locale {
278 private:
279# ifdef _WIN32
280 using locale_t = _locale_t;
281
282 enum { LC_NUMERIC_MASK = LC_NUMERIC };
283
284 static locale_t newlocale(int category_mask, const char* locale, locale_t) {
285 return _create_locale(category_mask, locale);
286 }
287
288 static void freelocale(locale_t locale) { _free_locale(locale); }
289
290 static double strtod_l(const char* nptr, char** endptr, _locale_t locale) {
291 return _strtod_l(nptr, endptr, locale);
292 }
293# endif
294
295 locale_t locale_;
296
297 public:
298 using type = locale_t;
299 Locale(const Locale&) = delete;
300 void operator=(const Locale&) = delete;
301
302 Locale() : locale_(newlocale(LC_NUMERIC_MASK, "C", nullptr)) {
303 if (!locale_) FMT_THROW(system_error(errno, "cannot create locale"));
304 }
305 ~Locale() { freelocale(locale_); }
306
307 type get() const { return locale_; }
308
309 // Converts string to floating-point number and advances str past the end
310 // of the parsed input.
311 double strtod(const char*& str) const {
312 char* end = nullptr;
313 double result = strtod_l(str, &end, locale_);
314 str = end;
315 return result;
316 }
317};
318#endif // FMT_LOCALE
320
321#endif // FMT_POSIX_H_
const Char * c_str() const
Definition posix.h:119
basic_cstring_view(const Char *s)
Definition posix.h:109
basic_cstring_view(const std::basic_string< Char > &s)
Definition posix.h:116
const Char * data_
Definition posix.h:105
FILE * get() const FMT_NOEXCEPT
Definition posix.h:174
void print(string_view format_str, const Args &... args)
Definition posix.h:185
FMT_API buffered_file(cstring_view filename, cstring_view mode)
void vprint(string_view format_str, format_args args)
Definition posix.h:180
friend class file
Definition posix.h:141
FILE * file_
Definition posix.h:139
FMT_API void close()
void operator=(const buffered_file &)=delete
buffered_file & operator=(buffered_file &&other)
Definition posix.h:160
FMT_API int fileno() const
FMT_API ~buffered_file() FMT_NOEXCEPT
buffered_file(const buffered_file &)=delete
buffered_file(FILE *f)
Definition posix.h:143
buffered_file() FMT_NOEXCEPT
Definition posix.h:150
int get() const FMT_NOEXCEPT
Definition posix.h:133
error_code(int value=0) FMT_NOEXCEPT
Definition posix.h:131
int value_
Definition posix.h:128
format_arg_store< Context, Args... > make_format_args(const Args &... args)
Definition core.h:1225
#define FMT_BEGIN_NAMESPACE
Definition core.h:163
#define FMT_API
Definition core.h:177
#define FMT_END_NAMESPACE
Definition core.h:158
#define FMT_NOEXCEPT
Definition core.h:116
#define FMT_THROW(x)
Definition format.h:97
void write(std::basic_ostream< Char > &os, buffer< Char > &buf)
Definition ostream.h:78
#define FMT_POSIX(call)
Definition posix.h:46