Coverage Report

Created: 2023-12-08 07:00

/src/mcl/include/cybozu/exception.hpp
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
/**
3
  @file
4
  @brief definition of abstruct exception class
5
  @author MITSUNARI Shigeo(@herumi)
6
*/
7
#ifdef CYBOZU_MINIMUM_EXCEPTION
8
9
#include <cybozu/inttype.hpp>
10
11
namespace cybozu {
12
13
namespace exception {
14
inline const char *makeString(const char *, size_t)
15
{
16
  return "";
17
}
18
19
} // cybozu::exception
20
21
class Exception {
22
public:
23
  explicit Exception(const char* = 0, bool = true)
24
  {
25
  }
26
  ~Exception() CYBOZU_NOEXCEPT {}
27
  const char *what() const CYBOZU_NOEXCEPT { return "cybozu:Exception"; }
28
  template<class T>
29
  Exception& operator<<(const T&)
30
  {
31
    return *this;
32
  }
33
};
34
35
} // cybozu
36
37
#else
38
39
#include <string>
40
#include <algorithm>
41
#include <sstream>
42
#include <errno.h>
43
#include <stdio.h>
44
#ifdef _WIN32
45
  #ifndef WIN32_LEAN_AND_MEAN
46
    #define WIN32_LEAN_AND_MEAN
47
  #endif
48
  #include <windows.h>
49
#else
50
  #include <string.h> // for strerror_r
51
#endif
52
#include <cybozu/inttype.hpp>
53
#ifdef CYBOZU_EXCEPTION_WITH_STACKTRACE
54
  #include <cybozu/stacktrace.hpp>
55
#endif
56
57
namespace cybozu {
58
59
const bool DontThrow = true;
60
61
namespace exception {
62
63
/* get max 16 characters to avoid buffer overrun */
64
inline std::string makeString(const char *str, size_t size)
65
0
{
66
0
  return std::string(str, std::min<size_t>(size, 16));
67
0
}
68
69
#ifdef _WIN32
70
inline std::string wstr2str(const std::wstring& wstr)
71
{
72
  std::string str;
73
  for (size_t i = 0; i < wstr.size(); i++) {
74
    uint16_t c = wstr[i];
75
    if (c < 0x80) {
76
      str += char(c);
77
    } else {
78
      char buf[16];
79
      CYBOZU_SNPRINTF(buf, sizeof(buf), "\\u%04x", c);
80
      str += buf;
81
    }
82
  }
83
  return str;
84
}
85
#endif
86
87
} // cybozu::exception
88
89
/**
90
  convert errno to string
91
  @param err [in] errno
92
  @note for both windows and linux
93
*/
94
inline std::string ConvertErrorNoToString(int err)
95
0
{
96
0
  char errBuf[256];
97
0
  std::string ret;
98
0
#ifdef _WIN32
99
0
  if (strerror_s(errBuf, sizeof(errBuf), err) == 0) {
100
0
    ret = errBuf;
101
0
  } else {
102
0
    ret = "err";
103
0
  }
104
0
#elif defined(_GNU_SOURCE)
105
0
  ret = ::strerror_r(err, errBuf, sizeof(errBuf));
106
0
#else
107
0
  if (strerror_r(err, errBuf, sizeof(errBuf)) == 0) {
108
0
    ret = errBuf;
109
0
  } else {
110
0
    ret = "err";
111
0
  }
112
0
#endif
113
0
  char buf2[64];
114
0
  CYBOZU_SNPRINTF(buf2, sizeof(buf2), "(%d)", err);
115
0
  ret += buf2;
116
0
  return ret;
117
0
}
118
119
class Exception : public std::exception {
120
  mutable std::string str_;
121
#ifdef CYBOZU_EXCEPTION_WITH_STACKTRACE
122
  mutable std::string stackTrace_;
123
#endif
124
public:
125
  explicit Exception(const std::string& name = "", bool enableStackTrace = true)
126
    : str_(name)
127
19.5k
  {
128
#ifdef CYBOZU_EXCEPTION_WITH_STACKTRACE
129
    if (enableStackTrace) stackTrace_ = cybozu::StackTrace().toString();
130
#else
131
19.5k
    cybozu::disable_warning_unused_variable(enableStackTrace);
132
19.5k
#endif
133
19.5k
  }
134
57.5k
  ~Exception() CYBOZU_NOEXCEPT {}
135
0
  const char *what() const CYBOZU_NOEXCEPT { return toString().c_str(); }
136
  const std::string& toString() const CYBOZU_NOEXCEPT
137
0
  {
138
#ifdef CYBOZU_EXCEPTION_WITH_STACKTRACE
139
    try {
140
      if (!stackTrace_.empty()) {
141
#ifdef CYBOZU_STACKTRACE_ONELINE
142
        str_ += "\n<<<STACKTRACE>>> ";
143
        str_ += stackTrace_;
144
#else
145
        str_ += "\n<<<STACKTRACE\n";
146
        str_ += stackTrace_;
147
        str_ += "\n>>>STACKTRACE";
148
#endif
149
      }
150
    } catch (...) {
151
    }
152
    stackTrace_.clear();
153
#endif
154
0
    return str_;
155
0
  }
156
  Exception& operator<<(const char *s)
157
35.2k
  {
158
35.2k
    str_ += ':';
159
35.2k
    str_ += s;
160
35.2k
    return *this;
161
35.2k
  }
162
  Exception& operator<<(const std::string& s)
163
35.2k
  {
164
35.2k
    return operator<<(s.c_str());
165
35.2k
  }
166
#ifdef _WIN32
167
  Exception& operator<<(const std::wstring& s)
168
  {
169
    return operator<<(cybozu::exception::wstr2str(s));
170
  }
171
#endif
172
  template<class T>
173
  Exception& operator<<(const T& x)
174
35.2k
  {
175
35.2k
    std::ostringstream os;
176
35.2k
    os << x;
177
35.2k
    return operator<<(os.str());
178
35.2k
  }
cybozu::Exception& cybozu::Exception::operator<< <mcl::FpT<mcl::bn::local::FpTag, 384ul> >(mcl::FpT<mcl::bn::local::FpTag, 384ul> const&)
Line
Count
Source
174
13.9k
  {
175
13.9k
    std::ostringstream os;
176
13.9k
    os << x;
177
13.9k
    return operator<<(os.str());
178
13.9k
  }
cybozu::Exception& cybozu::Exception::operator<< <int>(int const&)
Line
Count
Source
174
3.86k
  {
175
3.86k
    std::ostringstream os;
176
3.86k
    os << x;
177
3.86k
    return operator<<(os.str());
178
3.86k
  }
cybozu::Exception& cybozu::Exception::operator<< <mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> > >(mcl::Fp2T<mcl::FpT<mcl::bn::local::FpTag, 384ul> > const&)
Line
Count
Source
174
17.4k
  {
175
17.4k
    std::ostringstream os;
176
17.4k
    os << x;
177
17.4k
    return operator<<(os.str());
178
17.4k
  }
Unexecuted instantiation: cybozu::Exception& cybozu::Exception::operator<< <unsigned long>(unsigned long const&)
179
};
180
181
class ErrorNo {
182
public:
183
#ifdef _WIN32
184
  typedef unsigned int NativeErrorNo;
185
#else
186
  typedef int NativeErrorNo;
187
#endif
188
  explicit ErrorNo(NativeErrorNo err)
189
    : err_(err)
190
0
  {
191
0
  }
192
  ErrorNo()
193
    : err_(getLatestNativeErrorNo())
194
0
  {
195
0
  }
196
  NativeErrorNo getLatestNativeErrorNo() const
197
0
  {
198
0
#ifdef _WIN32
199
0
    return ::GetLastError();
200
0
#else
201
0
    return errno;
202
0
#endif
203
0
  }
204
  /**
205
    convert NativeErrNo to string(maybe UTF8)
206
    @note Linux   : same as ConvertErrorNoToString
207
        Windows : for Win32 API(use en-us)
208
  */
209
  std::string toString() const
210
0
  {
211
0
#ifdef _WIN32
212
0
    const int msgSize = 256;
213
0
    wchar_t msg[msgSize];
214
0
    int size = FormatMessageW(
215
0
      FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
216
0
      0,
217
0
      err_,
218
0
      MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
219
0
      msg,
220
0
      msgSize,
221
0
      NULL
222
0
    );
223
0
    if (size <= 0) return "";
224
0
    // remove last "\r\n"
225
0
    if (size > 2 && msg[size - 2] == '\r') {
226
0
      msg[size - 2] = 0;
227
0
      size -= 2;
228
0
    }
229
0
    std::string ret;
230
0
    ret.resize(size);
231
0
    // assume ascii only
232
0
    for (int i = 0; i < size; i++) {
233
0
      ret[i] = (char)msg[i];
234
0
    }
235
0
    char buf2[64];
236
0
    CYBOZU_SNPRINTF(buf2, sizeof(buf2), "(%u)", err_);
237
0
    ret += buf2;
238
0
    return ret;
239
0
#else
240
0
    return ConvertErrorNoToString(err_);
241
0
#endif
242
0
  }
243
private:
244
  NativeErrorNo err_;
245
};
246
247
inline std::ostream& operator<<(std::ostream& os, const cybozu::ErrorNo& self)
248
0
{
249
0
  return os << self.toString();
250
0
}
251
252
} // cybozu
253
#endif