Scippy

SoPlex

Sequential object-oriented simPlex

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  */
103 template <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.
126 class error_code {
127  private:
128  int value_;
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.
150  buffered_file() FMT_NOEXCEPT : file_(nullptr) {}
151 
152  // Destroys the object closing the file it represents if any.
154 
155  public:
156  buffered_file(buffered_file&& other) FMT_NOEXCEPT : file_(other.file_) {
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.
171  FMT_API void close();
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.
197 class 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.
272 long getpagesize();
273 #endif // FMT_USE_FCNTL
274 
275 #ifdef FMT_LOCALE
276 // A "C" numeric locale.
277 class 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_
#define FMT_BEGIN_NAMESPACE
Definition: core.h:163
void print(string_view format_str, const Args &... args)
Definition: posix.h:185
buffered_file() FMT_NOEXCEPT
Definition: posix.h:150
basic_cstring_view(const std::basic_string< Char > &s)
Definition: posix.h:116
const Char * c_str() const
Definition: posix.h:119
#define FMT_THROW(x)
Definition: format.h:94
#define FMT_END_NAMESPACE
Definition: core.h:158
format_arg_store< Context, Args... > make_format_args(const Args &... args)
Definition: core.h:1225
type
Definition: core.h:687
void vprint(std::FILE *f, const text_style &ts, const S &format, basic_format_args< buffer_context< Char >> args)
Definition: color.h:502
void vprint(string_view format_str, format_args args)
Definition: posix.h:180
#define FMT_API
Definition: core.h:177
#define FMT_POSIX(call)
Definition: posix.h:46
basic_cstring_view(const Char *s)
Definition: posix.h:109
#define FMT_NOEXCEPT
Definition: core.h:114
error_code(int value=0) FMT_NOEXCEPT
Definition: posix.h:131
const Char * data_
Definition: posix.h:105
buffered_file(FILE *f)
Definition: posix.h:143
void write(std::basic_ostream< Char > &os, buffer< Char > &buf)
Definition: ostream.h:78
int value_
Definition: posix.h:128
buffered_file & operator=(buffered_file &&other)
Definition: posix.h:160
FILE * file_
Definition: posix.h:139
buffered_file(buffered_file &&other) FMT_NOEXCEPT
Definition: posix.h:156