WireCellToolkit
Wire Cell Simulation, Signal Process and Reconstruction Toolki for Liquid Argon Detectors
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 <errno.h>
17 #include <fcntl.h> // for O_RDONLY
18 #include <locale.h> // for locale_t
19 #include <stdio.h>
20 #include <stdlib.h> // for strtod_l
21 
22 #include <cstddef>
23 
24 #if defined __APPLE__ || defined(__FreeBSD__)
25 # include <xlocale.h> // for LC_NUMERIC_MASK on OS X
26 #endif
27 
28 #include "format.h"
29 
30 #ifndef FMT_POSIX
31 # if defined(_WIN32) && !defined(__MINGW32__)
32 // Fix warnings about deprecated symbols.
33 # define FMT_POSIX(call) _##call
34 # else
35 # define FMT_POSIX(call) call
36 # endif
37 #endif
38 
39 // Calls to system functions are wrapped in FMT_SYSTEM for testability.
40 #ifdef FMT_SYSTEM
41 # define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
42 #else
43 # define FMT_SYSTEM(call) call
44 # ifdef _WIN32
45 // Fix warnings about deprecated symbols.
46 # define FMT_POSIX_CALL(call) ::_##call
47 # else
48 # define FMT_POSIX_CALL(call) ::call
49 # endif
50 #endif
51 
52 // Retries the expression while it evaluates to error_result and errno
53 // equals to EINTR.
54 #ifndef _WIN32
55 # define FMT_RETRY_VAL(result, expression, error_result) \
56  do { \
57  result = (expression); \
58  } while (result == error_result && errno == EINTR)
59 #else
60 # define FMT_RETRY_VAL(result, expression, error_result) result = (expression)
61 #endif
62 
63 #define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
64 
66 
92 template <typename Char>
94  private:
95  const Char *data_;
96 
97  public:
99  basic_cstring_view(const Char *s) : data_(s) {}
100 
106  basic_cstring_view(const std::basic_string<Char> &s) : data_(s.c_str()) {}
107 
109  const Char *c_str() const { return data_; }
110 };
111 
114 
115 // An error code.
116 class error_code {
117  private:
118  int value_;
119 
120  public:
121  explicit error_code(int value = 0) FMT_NOEXCEPT : value_(value) {}
122 
123  int get() const FMT_NOEXCEPT { return value_; }
124 };
125 
126 // A buffered file.
128  private:
129  FILE *file_;
130 
131  friend class file;
132 
133  explicit buffered_file(FILE *f) : file_(f) {}
134 
135  public:
136  // Constructs a buffered_file object which doesn't represent any file.
138 
139  // Destroys the object closing the file it represents if any.
141 
142  private:
143  buffered_file(const buffered_file &) = delete;
144  void operator=(const buffered_file &) = delete;
145 
146 
147  public:
148  buffered_file(buffered_file &&other) FMT_NOEXCEPT : file_(other.file_) {
149  other.file_ = FMT_NULL;
150  }
151 
153  close();
154  file_ = other.file_;
155  other.file_ = FMT_NULL;
156  return *this;
157  }
158 
159  // Opens a file.
161 
162  // Closes the file.
163  FMT_API void close();
164 
165  // Returns the pointer to a FILE object representing this file.
166  FILE *get() const FMT_NOEXCEPT { return file_; }
167 
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;
171 
173  fmt::vprint(file_, format_str, args);
174  }
175 
176  template <typename... Args>
177  inline void print(string_view format_str, const Args & ... args) {
178  vprint(format_str, make_format_args(args...));
179  }
180 };
181 
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.
188 class file {
189  private:
190  int fd_; // File descriptor.
191 
192  // Constructs a file object with a given descriptor.
193  explicit file(int fd) : fd_(fd) {}
194 
195  public:
196  // Possible values for the oflag argument to the constructor.
197  enum {
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.
201  };
202 
203  // Constructs a file object which doesn't represent any file.
204  file() FMT_NOEXCEPT : fd_(-1) {}
205 
206  // Opens a file and constructs a file object representing this file.
207  FMT_API file(cstring_view path, int oflag);
208 
209  private:
210  file(const file &) = delete;
211  void operator=(const file &) = delete;
212 
213  public:
214  file(file &&other) FMT_NOEXCEPT : fd_(other.fd_) {
215  other.fd_ = -1;
216  }
217 
218  file& operator=(file &&other) {
219  close();
220  fd_ = other.fd_;
221  other.fd_ = -1;
222  return *this;
223  }
224 
225  // Destroys the object closing the file it represents if any.
226  FMT_API ~file() FMT_NOEXCEPT;
227 
228  // Returns the file descriptor.
229  int descriptor() const FMT_NOEXCEPT { return fd_; }
230 
231  // Closes the file.
232  FMT_API void close();
233 
234  // Returns the file size. The size has signed type for consistency with
235  // stat::st_size.
236  FMT_API long long size() const;
237 
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);
240 
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);
243 
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);
247 
248  // Makes fd be the copy of this file descriptor, closing fd first if
249  // necessary.
250  FMT_API void dup2(int fd);
251 
252  // Makes fd be the copy of this file descriptor, closing fd first if
253  // necessary.
254  FMT_API void dup2(int fd, error_code &ec) FMT_NOEXCEPT;
255 
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);
259 
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);
263 };
264 
265 // Returns the memory page size.
266 long getpagesize();
267 
268 #if (defined(LC_NUMERIC_MASK) || defined(_MSC_VER)) && \
269  !defined(__ANDROID__) && !defined(__CYGWIN__) && !defined(__OpenBSD__) && \
270  !defined(__NEWLIB_H__)
271 # define FMT_LOCALE
272 #endif
273 
274 #ifdef FMT_LOCALE
275 // A "C" numeric locale.
276 class Locale {
277  private:
278 # ifdef _MSC_VER
279  typedef _locale_t locale_t;
280 
281  enum { LC_NUMERIC_MASK = LC_NUMERIC };
282 
283  static locale_t newlocale(int category_mask, const char *locale, locale_t) {
284  return _create_locale(category_mask, locale);
285  }
286 
287  static void freelocale(locale_t locale) {
288  _free_locale(locale);
289  }
290 
291  static double strtod_l(const char *nptr, char **endptr, _locale_t locale) {
292  return _strtod_l(nptr, endptr, locale);
293  }
294 # endif
295 
296  locale_t locale_;
297 
298  Locale(const Locale &) = delete;
299  void operator=(const Locale &) = delete;
300 
301  public:
302  typedef locale_t Type;
303 
304  Locale() : locale_(newlocale(LC_NUMERIC_MASK, "C", FMT_NULL)) {
305  if (!locale_)
306  FMT_THROW(system_error(errno, "cannot create locale"));
307  }
308  ~Locale() { freelocale(locale_); }
309 
310  Type get() const { return locale_; }
311 
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_);
317  str = end;
318  return result;
319  }
320 };
321 #endif // FMT_LOCALE
323 
324 #endif // FMT_POSIX_H_
long getpagesize()
basic_cstring_view(const Char *s)
Definition: posix.h:99
Definition: posix.h:188
basic_cstring_view< wchar_t > wcstring_view
Definition: posix.h:113
const S & format_str
Definition: format.h:3342
FMT_API void close()
void write(std::basic_ostream< Char > &os, basic_buffer< Char > &buf)
Definition: ostream.h:76
#define FMT_END_NAMESPACE
Definition: core.h:153
#define FMT_THROW(x)
Definition: format.h:115
FMT_CONSTEXPR auto end(const C &c) -> decltype(c.end())
Definition: format.h:257
#define FMT_POSIX(call)
Definition: posix.h:35
format_arg_store< Context, Args... > make_format_args(const Args &... args)
Definition: core.h:1199
#define FMT_API
Definition: core.h:166
basic_cstring_view< char > cstring_view
Definition: posix.h:112
file() FMT_NOEXCEPT
Definition: posix.h:204
buffered_file() FMT_NOEXCEPT
Definition: posix.h:137
int descriptor() const FMT_NOEXCEPT
Definition: posix.h:229
#define FMT_NULL
Definition: core.h:107
void vprint(std::FILE *f, const text_style &ts, const S &format, basic_format_args< typename buffer_context< Char >::type > args)
Definition: color.h:517
void print(string_view format_str, const Args &... args)
Definition: posix.h:177
buffered_file & operator=(buffered_file &&other)
Definition: posix.h:152
basic_cstring_view(const std::basic_string< Char > &s)
Definition: posix.h:106
void vprint(string_view format_str, format_args args)
Definition: posix.h:172
#define FMT_NOEXCEPT
Definition: core.h:140
error_code(int value=0) FMT_NOEXCEPT
Definition: posix.h:121
file & operator=(file &&other)
Definition: posix.h:218
buffered_file(buffered_file &&other) FMT_NOEXCEPT
Definition: posix.h:148
const Char * c_str() const
Definition: posix.h:109
const Args & args
Definition: core.h:1496
file(file &&other) FMT_NOEXCEPT
Definition: posix.h:214