You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

328 lines
9.4 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: unixstl/error/exceptions.hpp
  3. *
  4. * Purpose: unix_exception class, and its policy class
  5. *
  6. * Created: 19th June 2004
  7. * Updated: 11th May 2010
  8. *
  9. * Home: http://stlsoft.org/
  10. *
  11. * Copyright (c) 2004-2010, Matthew Wilson and Synesis Software
  12. * All rights reserved.
  13. *
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions are met:
  16. *
  17. * - Redistributions of source code must retain the above copyright notice, this
  18. * list of conditions and the following disclaimer.
  19. * - Redistributions in binary form must reproduce the above copyright notice,
  20. * this list of conditions and the following disclaimer in the documentation
  21. * and/or other materials provided with the distribution.
  22. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
  23. * any contributors may be used to endorse or promote products derived from
  24. * this software without specific prior written permission.
  25. *
  26. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  27. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  30. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  31. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  32. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  33. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  34. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  35. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36. * POSSIBILITY OF SUCH DAMAGE.
  37. *
  38. * ////////////////////////////////////////////////////////////////////// */
  39. /** \file unixstl/error/exceptions.hpp
  40. *
  41. * \brief [C++ only] Definition of the unixstl::unix_exception and exception
  42. * class and the unixstl::unix_exception_policy exception policy class
  43. * (\ref group__library__error "Error" Library).
  44. */
  45. #ifndef UNIXSTL_INCL_UNIXSTL_ERROR_HPP_EXCEPTIONS
  46. #define UNIXSTL_INCL_UNIXSTL_ERROR_HPP_EXCEPTIONS
  47. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  48. # define UNIXSTL_VER_UNIXSTL_ERROR_HPP_EXCEPTIONS_MAJOR 4
  49. # define UNIXSTL_VER_UNIXSTL_ERROR_HPP_EXCEPTIONS_MINOR 2
  50. # define UNIXSTL_VER_UNIXSTL_ERROR_HPP_EXCEPTIONS_REVISION 5
  51. # define UNIXSTL_VER_UNIXSTL_ERROR_HPP_EXCEPTIONS_EDIT 53
  52. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  53. /* /////////////////////////////////////////////////////////////////////////
  54. * Compatibility
  55. */
  56. /*
  57. [DocumentationStatus:Ready]
  58. */
  59. /* /////////////////////////////////////////////////////////////////////////
  60. * Includes
  61. */
  62. #ifndef UNIXSTL_INCL_UNIXSTL_H_UNIXSTL
  63. # include <unixstl/unixstl.h>
  64. #endif /* !UNIXSTL_INCL_UNIXSTL_H_UNIXSTL */
  65. #ifndef STLSOFT_INCL_STLSOFT_ERROR_HPP_EXCEPTIONS
  66. # include <stlsoft/error/exceptions.hpp> // for null_exception_policy
  67. #endif /* !STLSOFT_INCL_STLSOFT_ERROR_HPP_EXCEPTIONS */
  68. #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_EXCEPTION_STRING
  69. # include <stlsoft/util/exception_string.hpp>
  70. #endif /* !STLSOFT_INCL_STLSOFT_UTIL_HPP_EXCEPTION_STRING */
  71. #ifndef STLSOFT_INCL_STLSOFT_INTERNAL_H_SAFESTR
  72. # include <stlsoft/internal/safestr.h>
  73. #endif /* !STLSOFT_INCL_STLSOFT_INTERNAL_H_SAFESTR */
  74. #ifndef STLSOFT_INCL_H_ERRNO
  75. # define STLSOFT_INCL_H_ERRNO
  76. # include <errno.h>
  77. #endif /* !STLSOFT_INCL_H_ERRNO */
  78. #ifndef STLSOFT_INCL_H_STRING
  79. # define STLSOFT_INCL_H_STRING
  80. # include <string.h>
  81. #endif /* !STLSOFT_INCL_H_STRING */
  82. /* /////////////////////////////////////////////////////////////////////////
  83. * Namespace
  84. */
  85. #ifndef _UNIXSTL_NO_NAMESPACE
  86. # if defined(_STLSOFT_NO_NAMESPACE) || \
  87. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  88. /* There is no stlsoft namespace, so must define ::unixstl */
  89. namespace unixstl
  90. {
  91. # else
  92. /* Define stlsoft::unixstl_project */
  93. namespace stlsoft
  94. {
  95. namespace unixstl_project
  96. {
  97. # endif /* _STLSOFT_NO_NAMESPACE */
  98. #endif /* !_UNIXSTL_NO_NAMESPACE */
  99. /* /////////////////////////////////////////////////////////////////////////
  100. * Classes
  101. */
  102. /** \brief General exception class for UNIX operating system failures.
  103. *
  104. * \ingroup group__library__error
  105. *
  106. */
  107. class unix_exception
  108. : public stlsoft_ns_qual(os_exception)
  109. {
  110. /// \name Types
  111. /// @{
  112. protected:
  113. typedef stlsoft_ns_qual(exception_string) string_type;
  114. public:
  115. typedef stlsoft_ns_qual(os_exception) parent_class_type;
  116. typedef int error_code_type;
  117. typedef unix_exception class_type;
  118. /// @}
  119. /// \name Construction
  120. /// @{
  121. public:
  122. ss_explicit_k unix_exception(error_code_type err)
  123. : m_reason()
  124. , m_errorCode(err)
  125. {}
  126. unix_exception(char const* reason, error_code_type err)
  127. : m_reason(class_type::create_reason_(reason, err))
  128. , m_errorCode(err)
  129. {}
  130. protected:
  131. unix_exception(string_type const& reason, error_code_type err)
  132. : m_reason(reason)
  133. , m_errorCode(err)
  134. {}
  135. public:
  136. /// Destructor
  137. ///
  138. /// \note This does not do have any implementation, but is required to placate
  139. /// the Comeau and GCC compilers, which otherwise complain about mismatched
  140. /// exception specifications between this class and its parent
  141. virtual ~unix_exception() stlsoft_throw_0()
  142. {}
  143. /// @}
  144. /// \name Accessors
  145. /// @{
  146. public:
  147. virtual char const* what() const stlsoft_throw_0()
  148. {
  149. if(!m_reason.empty())
  150. {
  151. return m_reason.c_str();
  152. }
  153. else
  154. {
  155. char const* s = this->strerror();
  156. UNIXSTL_ASSERT(NULL != s);
  157. return (*s != '\0') ? s : "UNIX system error";
  158. }
  159. }
  160. /// The error code associated with the exception
  161. error_code_type get_error_code() const
  162. {
  163. return m_errorCode;
  164. }
  165. /// [DEPRECATED] The error code associated with the exception
  166. ///
  167. /// \deprecated Use get_error_code() instead.
  168. error_code_type get_errno() const
  169. {
  170. return get_error_code();
  171. }
  172. /// [DEPRECATED] String form of the contained error code
  173. ///
  174. /// \deprecated This method <em>will</em> be removed in a future version.
  175. char const* strerror() const
  176. {
  177. return strerror_(m_errorCode);
  178. }
  179. /// @}
  180. /// \name Implementation
  181. /// @{
  182. private:
  183. static char const* strerror_(int code)
  184. {
  185. #if defined(STLSOFT_USING_SAFE_STR_FUNCTIONS) && \
  186. defined(STLSOFT_COMPILER_IS_MSVC)
  187. # pragma warning(push)
  188. # pragma warning(disable : 4996 )
  189. #endif /* STLSOFT_USING_SAFE_STR_FUNCTIONS && STLSOFT_COMPILER_IS_MSVC */
  190. return ::strerror(code);
  191. #if defined(STLSOFT_USING_SAFE_STR_FUNCTIONS) && \
  192. defined(STLSOFT_COMPILER_IS_MSVC)
  193. # pragma warning(pop)
  194. #endif /* STLSOFT_USING_SAFE_STR_FUNCTIONS && STLSOFT_COMPILER_IS_MSVC */
  195. }
  196. static string_type create_reason_(char const* reason, error_code_type err)
  197. {
  198. if( err == ENOMEM ||
  199. NULL == reason ||
  200. '\0' == reason[0])
  201. {
  202. return string_type();
  203. }
  204. else
  205. {
  206. strerror_(0); // need to flush the errno
  207. string_type r(reason);
  208. char const* s = strerror_(err);
  209. UNIXSTL_ASSERT(NULL != s);
  210. if(*s != '\0')
  211. {
  212. return r + ": " + s;
  213. }
  214. return r;
  215. }
  216. }
  217. /// @}
  218. /// \name Members
  219. /// @{
  220. private:
  221. const string_type m_reason;
  222. error_code_type m_errorCode;
  223. /// @}
  224. /// \name Not to be implemented
  225. /// @{
  226. private:
  227. class_type& operator =(class_type const&);
  228. /// @}
  229. };
  230. /* /////////////////////////////////////////////////////////////////////////
  231. * Policies
  232. */
  233. /** \brief The NULL exception type. It does not throw, and its throw type is empty.
  234. *
  235. * \ingroup group__library__error
  236. *
  237. */
  238. // [[synesis:class:exception-policy: unix_exception_policy]]
  239. struct unix_exception_policy
  240. {
  241. /// \name Member Types
  242. /// @{
  243. public:
  244. /// The thrown type
  245. typedef unix_exception thrown_type;
  246. typedef int error_code_type;
  247. /// @}
  248. /// \name Operators
  249. /// @{
  250. public:
  251. /// Function call operator, taking no parameters
  252. void operator ()() const
  253. {
  254. STLSOFT_THROW_X(thrown_type(errno));
  255. }
  256. /// Function call operator, taking one parameter
  257. void operator ()(error_code_type err) const
  258. {
  259. STLSOFT_THROW_X(thrown_type(err));
  260. }
  261. /// Function call operator, taking two parameters
  262. void operator ()(char const* reason, error_code_type err) const
  263. {
  264. STLSOFT_THROW_X(thrown_type(reason, err));
  265. }
  266. /// @}
  267. };
  268. ////////////////////////////////////////////////////////////////////////////
  269. // Unit-testing
  270. #ifdef STLSOFT_UNITTEST
  271. # include "./unittest/exceptions_unittest_.h"
  272. #endif /* STLSOFT_UNITTEST */
  273. /* ////////////////////////////////////////////////////////////////////// */
  274. #ifndef _UNIXSTL_NO_NAMESPACE
  275. # if defined(_STLSOFT_NO_NAMESPACE) || \
  276. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  277. } // namespace unixstl
  278. # else
  279. } // namespace unixstl_project
  280. } // namespace stlsoft
  281. # endif /* _STLSOFT_NO_NAMESPACE */
  282. #endif /* !_UNIXSTL_NO_NAMESPACE */
  283. /* ////////////////////////////////////////////////////////////////////// */
  284. #endif /* !UNIXSTL_INCL_UNIXSTL_ERROR_HPP_EXCEPTIONS */
  285. /* ///////////////////////////// end of file //////////////////////////// */