source: trunk/GDE/SINA/builddir/include/spdlog/fmt/bundled/posix.h

Last change on this file was 19170, checked in by westram, 2 years ago
  • sina source
    • unpack + remove tarball
    • no longer ignore sina builddir.
File size: 8.6 KB
Line 
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
65FMT_BEGIN_NAMESPACE
66
67/**
68  \rst
69  A reference to a null-terminated string. It can be constructed from a C
70  string or ``std::string``.
71
72  You can use one of the following typedefs for common character types:
73
74  +---------------+-----------------------------+
75  | Type          | Definition                  |
76  +===============+=============================+
77  | cstring_view  | basic_cstring_view<char>    |
78  +---------------+-----------------------------+
79  | wcstring_view | basic_cstring_view<wchar_t> |
80  +---------------+-----------------------------+
81
82  This class is most useful as a parameter type to allow passing
83  different types of strings to a function, for example::
84
85    template <typename... Args>
86    std::string format(cstring_view format_str, const Args & ... args);
87
88    format("{}", 42);
89    format(std::string("{}"), 42);
90  \endrst
91 */
92template <typename Char>
93class basic_cstring_view {
94 private:
95  const Char *data_;
96
97 public:
98  /** Constructs a string reference object from a C string. */
99  basic_cstring_view(const Char *s) : data_(s) {}
100
101  /**
102    \rst
103    Constructs a string reference from an ``std::string`` object.
104    \endrst
105   */
106  basic_cstring_view(const std::basic_string<Char> &s) : data_(s.c_str()) {}
107
108  /** Returns the pointer to a C string. */
109  const Char *c_str() const { return data_; }
110};
111
112typedef basic_cstring_view<char> cstring_view;
113typedef basic_cstring_view<wchar_t> wcstring_view;
114
115// An error code.
116class 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.
127class 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.
137  buffered_file() FMT_NOEXCEPT : file_(FMT_NULL) {}
138
139  // Destroys the object closing the file it represents if any.
140  FMT_API ~buffered_file() FMT_NOEXCEPT;
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
152  buffered_file& operator=(buffered_file &&other) {
153    close();
154    file_ = other.file_;
155    other.file_ = FMT_NULL;
156    return *this;
157  }
158
159  // Opens a file.
160  FMT_API buffered_file(cstring_view filename, cstring_view mode);
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
172  void vprint(string_view format_str, format_args args) {
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.
188class 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.
266long 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.
276class 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
322FMT_END_NAMESPACE
323
324#endif  // FMT_POSIX_H_
Note: See TracBrowser for help on using the repository browser.