ncbiexpt.hpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:39k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: ncbiexpt.hpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 19:08:02  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.54
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. #ifndef NCBIEXPT__HPP
  10. #define NCBIEXPT__HPP
  11. /*  $Id: ncbiexpt.hpp,v 1000.3 2004/06/01 19:08:02 gouriano Exp $
  12.  * ===========================================================================
  13.  *
  14.  *                            PUBLIC DOMAIN NOTICE
  15.  *               National Center for Biotechnology Information
  16.  *
  17.  *  This software/database is a "United States Government Work" under the
  18.  *  terms of the United States Copyright Act.  It was written as part of
  19.  *  the author's official duties as a United States Government employee and
  20.  *  thus cannot be copyrighted.  This software/database is freely available
  21.  *  to the public for use. The National Library of Medicine and the U.S.
  22.  *  Government have not placed any restriction on its use or reproduction.
  23.  *
  24.  *  Although all reasonable efforts have been taken to ensure the accuracy
  25.  *  and reliability of the software and data, the NLM and the U.S.
  26.  *  Government do not and cannot warrant the performance or results that
  27.  *  may be obtained by using this software or data. The NLM and the U.S.
  28.  *  Government disclaim all warranties, express or implied, including
  29.  *  warranties of performance, merchantability or fitness for any particular
  30.  *  purpose.
  31.  *
  32.  *  Please cite the author in any work or product based on this material.
  33.  *
  34.  * ===========================================================================
  35.  *
  36.  * Author:  Denis Vakatov
  37.  *
  38.  *
  39.  */
  40. /// @file ncbiexpt.hpp
  41. /// Defines NCBI C++ exception handling.
  42. ///
  43. /// Contains support for the NCBI C++ exception handling mechanisms and
  44. /// auxiliary ad hoc macros to "catch" certain types of errors, and macros for
  45. /// the C++ exception specification.
  46. #include <corelib/ncbidiag.hpp>
  47. #include <errno.h>
  48. #include <string.h>
  49. #include <string>
  50. #include <stdexcept>
  51. #include <typeinfo>
  52. /** @addtogroup Exception
  53.  *
  54.  * @{
  55.  */
  56. BEGIN_NCBI_SCOPE
  57. #if (_MSC_VER >= 1200)
  58. #undef NCBI_USE_THROW_SPEC
  59. #endif
  60. /// Define THROWS macros for C++ exception specification.
  61. ///
  62. /// Define use of C++ exception specification mechanism:
  63. ///   "f(void) throw();"       <==  "f(void) THROWS_NONE;"
  64. ///   "g(void) throw(e1,e2);"  <==  "f(void) THROWS((e1,e2));"
  65. #if defined(NCBI_USE_THROW_SPEC)
  66. #  define THROWS_NONE throw()
  67. #  define THROWS(x) throw x
  68. #else
  69. #  define THROWS_NONE
  70. #  define THROWS(x)
  71. #endif
  72. /// ABORT_ON_THROW controls if program should be aborted.
  73. #define ABORT_ON_THROW "ABORT_ON_THROW"
  74. /// Specify whether to call "abort()" inside the DoThrowTraceAbort().
  75. ///
  76. /// By default, this feature is not activated unless
  77. /// -  environment variable $ABORT_ON_THROW is set (to any value), or
  78. /// -  registry value of ABORT_ON_THROW, section DEBUG is set (to any value)
  79. extern void SetThrowTraceAbort(bool abort_on_throw_trace);
  80. /// "abort()" the program if set by SetThrowTraceAbort() or $ABORT_ON_THROW.
  81. NCBI_XNCBI_EXPORT
  82. extern void DoThrowTraceAbort(void);
  83. /// Print the specified debug message.
  84. NCBI_XNCBI_EXPORT
  85. extern void DoDbgPrint(const char* file, int line, const char* message);
  86. /// Print the specified debug message.
  87. NCBI_XNCBI_EXPORT
  88. extern void DoDbgPrint(const char* file, int line, const string& message);
  89. /// Print the specified debug messages.
  90. NCBI_XNCBI_EXPORT
  91. extern void DoDbgPrint(const char* file, int line,
  92.                        const char* msg1, const char* msg2);
  93. #if defined(_DEBUG)
  94. /// Templated function for printing debug message.
  95. ///
  96. /// Print debug message for the specified exception type.
  97. template<typename T>
  98. inline
  99. const T& DbgPrint(const char* file, int line,
  100.                   const T& e, const char* e_str)
  101. {
  102.     DoDbgPrint(file, line, e_str, e.what());
  103.     return e;
  104. }
  105. /// Print debug message for "const char*" object.
  106. inline
  107. const char* DbgPrint(const char* file, int line,
  108.                      const char* e, const char* )
  109. {
  110.     DoDbgPrint(file, line, e);
  111.     return e;
  112. }
  113. /// Print debug message for "char*" object.
  114. inline
  115. char* DbgPrint(const char* file, int line,
  116.                char* e, const char* )
  117. {
  118.     DoDbgPrint(file, line, e);
  119.     return e;
  120. }
  121. /// Print debug message for "std::string" object.
  122. inline
  123. const string& DbgPrint(const char* file, int line,
  124.                        const string& e, const char* )
  125. {
  126.     DoDbgPrint(file, line, e);
  127.     return e;
  128. }
  129. /// Create diagnostic stream for printing specified message and "abort()" the
  130. /// program if set by SetThrowTraceAbort() or $ABORT_ON_THROW.
  131. ///
  132. /// @sa
  133. ///   SetThrowTraceAbort(), DoThrowTraceAbort()
  134. template<typename T>
  135. inline
  136. const T& DbgPrintP(const char* file, int line, const T& e, const char* e_str)
  137. {
  138.     CNcbiDiag(file, line, eDiag_Trace) << e_str << ": " << e;
  139.     DoThrowTraceAbort();
  140.     return e;
  141. }
  142. /// Create diagnostic stream for printing specified message.
  143. ///
  144. /// Similar to DbgPrintP except that "abort()" not executed.
  145. /// @sa
  146. ///   DbgPrintP()
  147. template<typename T>
  148. inline
  149. const T& DbgPrintNP(const char* file, int line, const T& e, const char* e_str)
  150. {
  151.     DoDbgPrint(file, line, e_str);
  152.     return e;
  153. }
  154. /// Rethrow trace.
  155. ///
  156. /// Reason for do {...} while in macro definition is to permit a natural
  157. /// syntax usage when a user wants to write something like:
  158. ///
  159. /// if (expression)
  160. ///     RETHROW_TRACE;
  161. /// else do_something_else;
  162. /// 
  163. /// Example:
  164. /// -  RETHROW_TRACE;
  165. #  define RETHROW_TRACE do { 
  166.     _TRACE("EXCEPTION: re-throw"); 
  167.     NCBI_NS_NCBI::DoThrowTraceAbort(); 
  168.     throw; 
  169. } while(0)
  170. /// Throw trace.
  171. ///
  172. /// Combines diagnostic message trace and exception throwing. First the
  173. /// diagnostic message is printed, and then exception is thrown.
  174. ///
  175. /// Argument can be a simple string, or an exception object.
  176. /// 
  177. /// Example:
  178. /// -  THROW0_TRACE("Throw just a string");
  179. /// -  THROW0_TRACE(runtime_error("message"));
  180. #  define THROW0_TRACE(exception_object) 
  181.     throw NCBI_NS_NCBI::DbgPrint(__FILE__, __LINE__, 
  182.         exception_object, #exception_object)
  183. /// Throw trace.
  184. ///
  185. /// Combines diagnostic message trace and exception throwing. First the
  186. /// diagnostic message is printed, and then exception is thrown.
  187. ///
  188. /// Argument can be any printable object; that is, any object with a defined
  189. /// output operator.
  190. ///
  191. /// Program may abort if so set by SetThrowTraceAbort() or $ABORT_ON_THROW.
  192. ///
  193. /// Example:
  194. /// -  THROW0p_TRACE(123);
  195. /// -  THROW0p_TRACE(complex(1,2));
  196. /// @sa
  197. ///   THROW0np_TRACE
  198. #  define THROW0p_TRACE(exception_object) 
  199.     throw NCBI_NS_NCBI::DbgPrintP(__FILE__, __LINE__, 
  200.         exception_object, #exception_object)
  201. /// Throw trace.
  202. ///
  203. /// Combines diagnostic message trace and exception throwing. First the
  204. /// diagnostic message is printed, and then exception is thrown.
  205. ///
  206. /// Argument can be any printable object; that is, any object with a defined
  207. /// output operator. 
  208. ///
  209. /// Similar to THROW0p_TRACE except that program is not "aborted" when
  210. /// exception is thrown, and argument type can be an aggregate type such as
  211. /// Vector<T> where T is a printable argument.
  212. ///
  213. /// Example:
  214. /// -  THROW0np_TRACE(vector<char>());
  215. /// @sa
  216. ///   THROW0p_TRACE
  217. #  define THROW0np_TRACE(exception_object) 
  218.     throw NCBI_NS_NCBI::DbgPrintNP(__FILE__, __LINE__, 
  219.         exception_object, #exception_object)
  220. /// Throw trace.
  221. ///
  222. /// Combines diagnostic message trace and exception throwing. First the
  223. /// diagnostic message is printed, and then exception is thrown.
  224. ///
  225. /// Arguments can be any exception class with the specified initialization
  226. /// argument. The class argument need not be derived from std::exception as
  227. /// a new class object is constructed using the specified class name and 
  228. /// initialization argument.
  229. ///
  230. /// Example:
  231. /// -  THROW1_TRACE(runtime_error, "Something is weird...");
  232. #  define THROW1_TRACE(exception_class, exception_arg) 
  233.     throw NCBI_NS_NCBI::DbgPrint(__FILE__, __LINE__, 
  234.         exception_class(exception_arg), #exception_class)
  235. /// Throw trace.
  236. ///
  237. /// Combines diagnostic message trace and exception throwing. First the
  238. /// diagnostic message is printed, and then exception is thrown.
  239. ///
  240. /// Arguments can be any exception class with a the specified initialization
  241. /// argument. The class argument need not be derived from std::exception as
  242. /// a new class object is constructed using the specified class name and 
  243. /// initialization argument.
  244. ///
  245. /// Program may abort if so set by SetThrowTraceAbort() or $ABORT_ON_THROW.
  246. ///
  247. /// Example:
  248. /// -  THROW1p_TRACE(int, 32);
  249. /// @sa
  250. ///   THROW1np_TRACE
  251. #  define THROW1p_TRACE(exception_class, exception_arg) 
  252.     throw NCBI_NS_NCBI::DbgPrintP(__FILE__, __LINE__, 
  253.         exception_class(exception_arg), #exception_class)
  254. /// Throw trace.
  255. ///
  256. /// Combines diagnostic message trace and exception throwing. First the
  257. /// diagnostic message is printed, and then exception is thrown.
  258. ///
  259. /// Arguments can be any exception class with a the specified initialization
  260. /// argument. The class argument need not be derived from std::exception as
  261. /// a new class object is constructed using the specified class name and 
  262. /// initialization argument.
  263. ///
  264. /// Similar to THROW1p_TRACE except that program is not "aborted" when
  265. /// exception is thrown, and argument type can be an aggregate type such as
  266. /// Vector<T> where T is a printable argument.
  267. ///
  268. /// Example:
  269. /// -  THROW1np_TRACE(CUserClass, "argument");
  270. #  define THROW1np_TRACE(exception_class, exception_arg) 
  271.     throw NCBI_NS_NCBI::DbgPrintNP(__FILE__, __LINE__, 
  272.         exception_class(exception_arg), #exception_class)
  273. /// Throw trace.
  274. ///
  275. /// Combines diagnostic message trace and exception throwing. First the
  276. /// diagnostic message is printed, and then exception is thrown.
  277. ///
  278. /// Arguments can be any exception class with a the specified initialization
  279. /// arguments. The class argument need not be derived from std::exception as
  280. /// a new class object is constructed using the specified class name and 
  281. /// initialization arguments.
  282. ///
  283. /// Similar to THROW1_TRACE except that the exception class can have multiple
  284. /// initialization arguments instead of just one.
  285. ///
  286. /// Example:
  287. /// -  THROW_TRACE(bad_alloc, ());
  288. /// -  THROW_TRACE(runtime_error, ("Something is weird..."));
  289. /// -  THROW_TRACE(CParseException, ("Some parse error", 123));
  290. /// @sa
  291. ///   THROW1_TRACE
  292. #  define THROW_TRACE(exception_class, exception_args) 
  293.     throw NCBI_NS_NCBI::DbgPrint(__FILE__, __LINE__, 
  294.         exception_class exception_args, #exception_class)
  295. /// Throw trace.
  296. ///
  297. /// Combines diagnostic message trace and exception throwing. First the
  298. /// diagnostic message is printed, and then exception is thrown.
  299. ///
  300. /// Arguments can be any exception class with a the specified initialization
  301. /// arguments. The class argument need not be derived from std::exception as
  302. /// a new class object is constructed using the specified class name and 
  303. /// initialization arguments.
  304. ///
  305. /// Program may abort if so set by SetThrowTraceAbort() or $ABORT_ON_THROW.
  306. ///
  307. /// Similar to THROW1p_TRACE except that the exception class can have multiple
  308. /// initialization arguments instead of just one.
  309. ///
  310. /// Example: 
  311. /// - THROWp_TRACE(complex, (2, 3));
  312. /// @sa
  313. ///   THROW1p_TRACE
  314. #  define THROWp_TRACE(exception_class, exception_args) 
  315.     throw NCBI_NS_NCBI::DbgPrintP(__FILE__, __LINE__, 
  316.         exception_class exception_args, #exception_class)
  317. /// Throw trace.
  318. ///
  319. /// Combines diagnostic message trace and exception throwing. First the
  320. /// diagnostic message is printed, and then exception is thrown.
  321. ///
  322. /// Arguments can be any exception class with a the specified initialization
  323. /// argument. The class argument need not be derived from std::exception as
  324. /// a new class object is constructed using the specified class name and 
  325. /// initialization argument.
  326. ///
  327. /// Argument type can be an aggregate type such as Vector<T> where T is a
  328. /// printable argument.
  329. ///
  330. /// Similar to THROWp_TRACE except that program is not "aborted" when
  331. /// exception is thrown.
  332. ///
  333. /// Example:
  334. /// -  THROWnp_TRACE(CUserClass, (arg1, arg2));
  335. #  define THROWnp_TRACE(exception_class, exception_args) 
  336.     throw NCBI_NS_NCBI::DbgPrintNP(__FILE__, __LINE__, 
  337.         exception_class exception_args, #exception_class)
  338. #else  /* _DEBUG */
  339. // No trace/debug versions of these macros.
  340. #  define RETHROW_TRACE 
  341.     throw
  342. #  define THROW0_TRACE(exception_object) 
  343.     throw exception_object
  344. #  define THROW0p_TRACE(exception_object) 
  345.     throw exception_object
  346. #  define THROW0np_TRACE(exception_object) 
  347.     throw exception_object
  348. #  define THROW1_TRACE(exception_class, exception_arg) 
  349.     throw exception_class(exception_arg)
  350. #  define THROW1p_TRACE(exception_class, exception_arg) 
  351.     throw exception_class(exception_arg)
  352. #  define THROW1np_TRACE(exception_class, exception_arg) 
  353.     throw exception_class(exception_arg)
  354. #  define THROW_TRACE(exception_class, exception_args) 
  355.     throw exception_class exception_args
  356. #  define THROWp_TRACE(exception_class, exception_args) 
  357.     throw exception_class exception_args
  358. #  define THROWnp_TRACE(exception_class, exception_args) 
  359.     throw exception_class exception_args
  360. #endif  /* else!_DEBUG */
  361. /// Standard handling of "exception"-derived exceptions.
  362. #define STD_CATCH(message) 
  363. catch (NCBI_NS_STD::exception& e) { 
  364.       NCBI_NS_NCBI::CNcbiDiag() << NCBI_NS_NCBI::Error 
  365.            << "[" << message << "]" << "Exception: " << e.what(); 
  366. }
  367. /// Standard handling of "exception"-derived exceptions; catches non-standard
  368. /// exceptiuons and generates "unknown exception" for all other exceptions.
  369. #define STD_CATCH_ALL(message) 
  370. STD_CATCH(message) 
  371.     catch (...) { 
  372.       NCBI_NS_NCBI::CNcbiDiag() << NCBI_NS_NCBI::Error 
  373.            << "[" << message << "]" << "Unknown exception"; 
  374. }
  375. /////////////////////////////////////////////////////////////////////////////
  376. // CException: useful macros
  377. /// Generic macro to throw an exception, given the exception class,
  378. /// error code and message string.
  379. #define NCBI_THROW(exception_class, err_code, message) 
  380.     throw exception_class(__FILE__, __LINE__, 
  381.         0,exception_class::err_code, (message))
  382. /// Generic macro to re-throw an exception.
  383. #define NCBI_RETHROW(prev_exception, exception_class, err_code, message) 
  384.     throw exception_class(__FILE__, __LINE__, 
  385.         &(prev_exception), exception_class::err_code, (message))
  386. /// Generic macro to re-throw the same exception.
  387. #define NCBI_RETHROW_SAME(prev_exception, message) 
  388.     do { prev_exception.AddBacklog(__FILE__, __LINE__, message); 
  389.     throw; }  while (0)
  390. /// Generate a report on the exception.
  391. #define NCBI_REPORT_EXCEPTION(title,ex) 
  392.     CExceptionReporter::ReportDefault(__FILE__,__LINE__,title,ex,eDPF_Default)
  393. /////////////////////////////////////////////////////////////////////////////
  394. // CException
  395. // Forward declaration of CExceptionReporter.
  396. class CExceptionReporter;
  397. /////////////////////////////////////////////////////////////////////////////
  398. ///
  399. /// CException --
  400. ///
  401. /// Define an extended exception class based on the C+++ std::exception.
  402. ///
  403. /// CException inherits its basic functionality from std::exception and
  404. /// defines additional generic error codes for applications, and error
  405. /// reporting capabilities.
  406. class NCBI_XNCBI_EXPORT CException : public std::exception
  407. {
  408. public:
  409.     /// Error types that an application can generate.
  410.     ///
  411.     /// Each derived class has its own error codes and their interpretations.
  412.     /// Define two generic error codes "eInvalid" and "eUnknown" to be used
  413.     /// by all NCBI applications.
  414.     enum EErrCode {
  415.         eInvalid = -1, ///< To be used ONLY as a return value;
  416.                        ///< please, NEVER throw an exception with this code.
  417.         eUnknown = 0   ///< Unknown exception.
  418.     };
  419.     typedef int TErrCode;
  420.     /// Constructor.
  421.     ///
  422.     /// When throwing an exception initially, "prev_exception" must be 0.
  423.     CException(const char* file, int line,
  424.                const CException* prev_exception,
  425.                EErrCode err_code,const string& message) throw();
  426.     /// Copy constructor.
  427.     CException(const CException& other) throw();
  428.     /// Add a message to backlog (to re-throw the same exception then).
  429.     void AddBacklog(const char* file, int line,const string& message);
  430.     // ---- Reporting --------------
  431.     /// Standard report (includes full backlog).
  432.     virtual const char* what(void) const throw();
  433.     /// Report the exception.
  434.     ///
  435.     /// Report the exception using "reporter" exception reporter.
  436.     /// If "reporter" is not specified (value 0), then use the default
  437.     /// reporter as set with CExceptionReporter::SetDefault.
  438.     void Report(const char* file, int line,
  439.                 const string& title, CExceptionReporter* reporter = 0,
  440.                 TDiagPostFlags flags = eDPF_Trace) const;
  441.     /// Report this exception only.
  442.     ///
  443.     /// Report as a string this exception only. No backlog is attached.
  444.     string ReportThis(TDiagPostFlags flags = eDPF_Trace) const;
  445.     /// Report all exceptions.
  446.     ///
  447.     /// Report as a string all exceptions. Include full backlog.
  448.     string ReportAll (TDiagPostFlags flags = eDPF_Trace) const;
  449.     /// Report "standard" attributes.
  450.     ///
  451.     /// Report "standard" attributes (file, line, type, err.code, user message)
  452.     /// into the "out" stream (this exception only, no backlog).
  453.     void ReportStd(ostream& out, TDiagPostFlags flags = eDPF_Trace) const;
  454.     /// Report "non-standard" attributes.
  455.     ///
  456.     /// Report "non-standard" attributes (those of derived class) into the
  457.     /// "out" stream.
  458.     virtual void ReportExtra(ostream& out) const;
  459.     /// Enable background reporting.
  460.     ///
  461.     /// If background reporting is enabled, then calling what() or ReportAll()
  462.     /// would also report exception to the default exception reporter.
  463.     /// @return
  464.     ///   The previous state of the flag.
  465.     static bool EnableBackgroundReporting(bool enable);
  466.     // ---- Attributes ---------
  467.     /// Get class name as a string.
  468.     virtual const char* GetType(void) const;
  469.     /// Get error code interpreted as text.
  470.     virtual const char* GetErrCodeString(void) const;
  471.     /// Get file name used for reporting.
  472.     const string& GetFile(void) const { return m_File; }
  473.     /// Get line number where error occurred.
  474.     int GetLine(void) const { return m_Line; }
  475.     /// Get error code.
  476.     TErrCode GetErrCode(void) const;
  477.     /// Get message string.
  478.     const string& GetMsg (void) const { return m_Msg;  }
  479.     /// Get "previous" exception from the backlog.
  480.     const CException* GetPredecessor(void) const { return m_Predecessor; }
  481.     /// Destructor.
  482.     virtual ~CException(void) throw();
  483. protected:
  484.     /// Constructor with no arguments.
  485.     ///
  486.     /// Required in case of multiple inheritance.
  487.     CException(void) throw();
  488.     /// Helper method for reporting to the system debugger.
  489.     virtual void x_ReportToDebugger(void) const;
  490.     /// Helper method for cloning the exception.
  491.     virtual const CException* x_Clone(void) const;
  492.     /// Helper method for initializing exception data.
  493.     virtual void x_Init(const string& file, int line,
  494.                         const string& message,
  495.                         const CException* prev_exception);
  496.     /// Helper method for copying exception data.
  497.     virtual void x_Assign(const CException& src);
  498.     
  499.     /// Helper method for assigning error code.
  500.     virtual void x_AssignErrCode(const CException& src);
  501.     /// Helper method for initializing error code.
  502.     virtual void x_InitErrCode(CException::EErrCode err_code);
  503.     /// Helper method for getting error code.
  504.     virtual int  x_GetErrCode(void) const { return m_ErrCode; }
  505. private:
  506.     string  m_File;                  ///< File to report on
  507.     int     m_Line;                  ///< Line number
  508.     int     m_ErrCode;               ///< Error code
  509.     string  m_Msg;                   ///< Message string
  510.     mutable string m_What;           ///< What type of exception
  511.     const CException* m_Predecessor; ///< Previous exception
  512.     mutable bool m_InReporter;       ///< Reporter flag
  513.     static  bool sm_BkgrEnabled;     ///< Background reporting enabled flag
  514.     /// Private assignment operator to prohibit assignment.
  515.     CException& operator= (const CException&) throw();
  516. };
  517. /// Return valid pointer to uppermost derived class only if "from" is _really_ 
  518. /// the object of the desired type.
  519. ///
  520. /// Do not cast to intermediate types (return NULL if such cast is attempted).
  521. template <class TTo, class TFrom>
  522. const TTo* UppermostCast(const TFrom& from)
  523. {
  524.     return typeid(from) == typeid(TTo) ? dynamic_cast<const TTo*>(&from) : 0;
  525. }
  526. /// Helper macro for default exception implementation.
  527. /// @sa
  528. ///   NCBI_EXCEPTION_DEFAULT
  529. #define NCBI_EXCEPTION_DEFAULT_IMPLEMENTATION(exception_class, base_class) 
  530.     { 
  531.         x_Init(file,line,message, prev_exception); 
  532.         x_InitErrCode((CException::EErrCode) err_code); 
  533.     } 
  534.     exception_class(const exception_class& other) throw() 
  535.        : base_class(other) 
  536.     { 
  537.         x_Assign(other); 
  538.     } 
  539.     virtual ~exception_class(void) throw() {} 
  540.     virtual const char* GetType(void) const {return #exception_class;} 
  541.     typedef int TErrCode; 
  542.     TErrCode GetErrCode(void) const 
  543.     { 
  544.         return typeid(*this) == typeid(exception_class) ? 
  545.             (TErrCode)x_GetErrCode() : (TErrCode)CException::eInvalid; 
  546.     } 
  547. protected: 
  548.     exception_class(void) throw() {} 
  549.     virtual const CException* x_Clone(void) const 
  550.     { 
  551.         return new exception_class(*this); 
  552.     } 
  553. private: 
  554.     /* for the sake of semicolon at the end of macro...*/ 
  555.     static void xx_unused_##exception_class(void)
  556. /// To help declare new exception class.
  557. ///
  558. /// This can be used ONLY if the derived class does not have any additional
  559. /// (non-standard) data members.
  560. #define NCBI_EXCEPTION_DEFAULT(exception_class, base_class) 
  561. public: 
  562.     exception_class(const char* file,int line, 
  563.         const CException* prev_exception, 
  564.         EErrCode err_code,const string& message) throw() 
  565.         : base_class(file, line, prev_exception, 
  566.             (base_class::EErrCode) CException::eInvalid, (message)) 
  567.     NCBI_EXCEPTION_DEFAULT_IMPLEMENTATION(exception_class, base_class)
  568. /// Helper macro added to support templatized exceptions.
  569. ///
  570. /// GCC starting from 3.2.2 warns about implicit typenames - this macro fixes
  571. /// the warning.
  572. #define NCBI_EXCEPTION_DEFAULT_IMPLEMENTATION_TEMPL(exception_class, base_class) 
  573.     { 
  574.         this->x_Init(file,line,message, prev_exception); 
  575.         this->x_InitErrCode((typename CException::EErrCode) err_code); 
  576.     } 
  577.     exception_class(const exception_class& other) throw() 
  578.        : base_class(other) 
  579.     { 
  580.         x_Assign(other); 
  581.     } 
  582.     virtual ~exception_class(void) throw() {} 
  583.     virtual const char* GetType(void) const {return #exception_class;} 
  584.     typedef int TErrCode; 
  585.     TErrCode GetErrCode(void) const 
  586.     { 
  587.         return typeid(*this) == typeid(exception_class) ? 
  588.             (TErrCode) this->x_GetErrCode() : 
  589.             (TErrCode) CException::eInvalid; 
  590.     } 
  591. protected: 
  592.     exception_class(void) throw() {} 
  593.     virtual const CException* x_Clone(void) const 
  594.     { 
  595.         return new exception_class(*this); 
  596.     } 
  597. private: 
  598.     /* for the sake of semicolon at the end of macro...*/ 
  599.    // static void xx_unused_##exception_class(void)
  600. /// Exception bug workaround for GCC version less than 3.00.
  601. ///
  602. /// GCC compiler v.2.95 has a bug: one should not use virtual base class in
  603. /// exception declarations - a program crashes when deleting such an exception
  604. /// (this is fixed in newer versions of the compiler).
  605. #if defined(NCBI_COMPILER_GCC)
  606. #  if NCBI_COMPILER_VERSION < 300
  607. #    define EXCEPTION_BUG_WORKAROUND
  608. #  endif
  609. #endif
  610. #if defined(EXCEPTION_BUG_WORKAROUND)
  611. #  define EXCEPTION_VIRTUAL_BASE
  612. #else
  613. #  define EXCEPTION_VIRTUAL_BASE virtual
  614. #endif
  615. /////////////////////////////////////////////////////////////////////////////
  616. ///
  617. /// CExceptionReporter --
  618. ///
  619. /// Define exception reporter.
  620. class NCBI_XNCBI_EXPORT CExceptionReporter
  621. {
  622. public:
  623.     /// Constructor.
  624.     CExceptionReporter(void);
  625.     /// Destructor.
  626.     virtual ~CExceptionReporter(void);
  627.     /// Set default reporter.
  628.     static void SetDefault(const CExceptionReporter* handler);
  629.     /// Get default reporter.
  630.     static const CExceptionReporter* GetDefault(void);
  631.     /// Enable/disable using default reporter.
  632.     ///
  633.     /// @return
  634.     ///   Previous state of this flag.
  635.     static bool EnableDefault(bool enable);
  636.     /// Report exception using default reporter.
  637.     static void ReportDefault(const char* file, int line,
  638.                               const string& title, const CException& ex,
  639.                               TDiagPostFlags flags = eDPF_Trace);
  640.     /// Report exception with _this_ reporter
  641.     virtual void Report(const char* file, int line,
  642.                         const string& title, const CException& ex,
  643.                         TDiagPostFlags flags = eDPF_Trace) const = 0;
  644. private:
  645.     static const CExceptionReporter* sm_DefHandler; ///< Default handler
  646.     static bool                      sm_DefEnabled; ///< Default enable flag
  647. };
  648. /////////////////////////////////////////////////////////////////////////////
  649. ///
  650. /// CExceptionReporterStream --
  651. ///
  652. /// Define exception reporter stream.
  653. class NCBI_XNCBI_EXPORT CExceptionReporterStream : public CExceptionReporter
  654. {
  655. public:
  656.     /// Constructor.
  657.     CExceptionReporterStream(ostream& out);
  658.     /// Destructor.
  659.     virtual ~CExceptionReporterStream(void);
  660.     /// Report specified exception on output stream.
  661.     virtual void Report(const char* file, int line,
  662.                         const string& title, const CException& ex,
  663.                         TDiagPostFlags flags = eDPF_Trace) const;
  664. private:
  665.     ostream& m_Out;   ///< Output stream
  666. };
  667. /////////////////////////////////////////////////////////////////////////////
  668. ///
  669. /// CCoreException --
  670. ///
  671. /// Define corelib exception.  CCoreException inherits its basic
  672. /// functionality from CException and defines additional error codes for
  673. /// applications.
  674. class NCBI_XNCBI_EXPORT CCoreException : EXCEPTION_VIRTUAL_BASE public CException
  675. {
  676. public:
  677.     /// Error types that  corelib can generate.
  678.     ///
  679.     /// These generic error conditions can occur for corelib applications. 
  680.     enum EErrCode {
  681.         eCore,          ///< Generic corelib error
  682.         eNullPtr,       ///< Null pointer error
  683.         eDll,           ///< Dll error
  684.         eInvalidArg     ///< Invalid argument error
  685.     };
  686.     /// Translate from the error code value to its string representation.
  687.     virtual const char* GetErrCodeString(void) const;
  688.     // Standard exception boilerplate code.
  689.     NCBI_EXCEPTION_DEFAULT(CCoreException, CException);
  690. };
  691. // Some implementations return char*, so strict compilers may refuse
  692. // to let them satisfy TStrerror without a wrapper.  However, they
  693. // don't all agree on what form the wrapper should take. :-/
  694. #ifdef NCBI_COMPILER_GCC
  695. inline
  696. const char* NcbiStrerror(int errnum) { return ::strerror(errnum); }
  697. #  define NCBI_STRERROR_WRAPPER NCBI_NS_NCBI::NcbiStrerror
  698. #else
  699. class CStrErrAdapt
  700. {
  701. public:
  702.     static const char* strerror(int errnum) { return ::strerror(errnum); }
  703. };
  704. #  define NCBI_STRERROR_WRAPPER NCBI_NS_NCBI::CStrErrAdapt::strerror
  705. #endif
  706. /////////////////////////////////////////////////////////////////////////////
  707. // Auxiliary exception classes:
  708. //   CErrnoException
  709. //   CParseException
  710. //
  711. /// Define function type for "strerror" function.
  712. typedef const char* (*TStrerror)(int errnum);
  713. /////////////////////////////////////////////////////////////////////////////
  714. ///
  715. /// CErrnoTemplExceptionEx --
  716. ///
  717. /// Define template class for easy generation of Errno-like exception classes.
  718. template <class TBase, TStrerror PErrstr=NCBI_STRERROR_WRAPPER >
  719. class CErrnoTemplExceptionEx : EXCEPTION_VIRTUAL_BASE public TBase
  720. {
  721. public:
  722.     /// Error type that an application can generate.
  723.     enum EErrCode {
  724.         eErrno          ///< Error code
  725.     };
  726.     /// Translate from the error code value to its string representation.
  727.     virtual const char* GetErrCodeString(void) const
  728.     {
  729.         switch (GetErrCode()) {
  730.         case eErrno: return "eErrno";
  731.         default:     return CException::GetErrCodeString();
  732.         }
  733.     }
  734.     /// Constructor.
  735.     CErrnoTemplExceptionEx(const char* file, int line,
  736.         const CException* prev_exception,
  737.         EErrCode err_code, const string& message) throw()
  738.           : TBase(file, line, prev_exception,
  739.             (typename TBase::EErrCode)(CException::eInvalid),
  740.             message)
  741.     {
  742.         m_Errno = errno;
  743.         this->x_Init(file, line, message + ": " + PErrstr(m_Errno),
  744.                      prev_exception);
  745.         this->x_InitErrCode((CException::EErrCode) err_code);
  746.     }
  747.     /// Constructor.
  748.     CErrnoTemplExceptionEx(const char* file,int line,
  749.         const CException* prev_exception,
  750.         EErrCode err_code, const string& message, 
  751.         int errnum
  752.         ) throw()
  753.           : TBase(file, line, prev_exception,
  754.             (typename TBase::EErrCode)(CException::eInvalid),
  755.             message),
  756.             m_Errno(errnum)
  757.     {
  758.         this->x_Init(file, line, message + ": " + PErrstr(m_Errno),
  759.                      prev_exception);
  760.         this->x_InitErrCode((CException::EErrCode) err_code);
  761.     }
  762.     /// Copy constructor.
  763.     CErrnoTemplExceptionEx(const CErrnoTemplExceptionEx<TBase, PErrstr>& other)
  764.         throw()
  765.         : TBase( other)
  766.     {
  767.         m_Errno = other.m_Errno;
  768.         x_Assign(other);
  769.     }
  770.     /// Destructor.
  771.     virtual ~CErrnoTemplExceptionEx(void) throw() {}
  772.     /// Report error number on stream.
  773.     virtual void ReportExtra(ostream& out) const
  774.     {
  775.         out << "m_Errno = " << m_Errno;
  776.     }
  777.     // Attributes.
  778.     /// Get type of class.
  779.     virtual const char* GetType(void) const { return "CErrnoTemplException"; }
  780.     typedef int TErrCode;
  781.     /// Get error code.
  782.     TErrCode GetErrCode(void) const
  783.     {
  784.         return typeid(*this) == 
  785.             typeid(CErrnoTemplExceptionEx<TBase, PErrstr>) ?
  786.                (TErrCode) this->x_GetErrCode() :
  787.                (TErrCode) CException::eInvalid;
  788.     }
  789.     /// Get error number.
  790.     int GetErrno(void) const throw() { return m_Errno; }
  791. protected:
  792.     /// Constructor.
  793.     CErrnoTemplExceptionEx(void) throw() { m_Errno = errno; }
  794.     /// Helper clone method.
  795.     virtual const CException* x_Clone(void) const
  796.     {
  797.         return new CErrnoTemplExceptionEx<TBase, PErrstr>(*this);
  798.     }
  799. private:
  800.     int m_Errno;        ///< Error number
  801. };
  802. /////////////////////////////////////////////////////////////////////////////
  803. ///
  804. /// CErrnoTemplException --
  805. ///
  806. /// Define template class for easy generation of Errno-like exception classes.
  807. template<class TBase> class CErrnoTemplException :
  808.                         public CErrnoTemplExceptionEx<TBase, NCBI_STRERROR_WRAPPER>
  809. {
  810. public:
  811.     /// Parent class type.
  812.     typedef CErrnoTemplExceptionEx<TBase, NCBI_STRERROR_WRAPPER> CParent;
  813.     /// Constructor.
  814.     CErrnoTemplException<TBase>(const char* file,int line,
  815.         const CException* prev_exception,
  816.         typename CParent::EErrCode err_code,const string& message) throw()
  817.         : CParent(file, line, prev_exception,
  818.                  (typename CParent::EErrCode) CException::eInvalid, message)
  819.     NCBI_EXCEPTION_DEFAULT_IMPLEMENTATION_TEMPL(CErrnoTemplException<TBase>,
  820.                                                 CParent)
  821. };
  822. /// Throw exception with extra parameter.
  823. ///
  824. /// Required to throw exceptions with one additional parameter
  825. /// (e.g. positional information for CParseException).
  826. #define NCBI_THROW2(exception_class, err_code, message, extra) 
  827.     throw exception_class(__FILE__, __LINE__, 
  828.         0,exception_class::err_code, (message), (extra))
  829. /// Re-throw exception with extra parameter.
  830. ///
  831. /// Required to re-throw exceptions with one additional parameter
  832. /// (e.g. positional information for CParseException).
  833. #define NCBI_RETHROW2(prev_exception,exception_class,err_code,message,extra) 
  834.     throw exception_class(__FILE__, __LINE__, 
  835.         &(prev_exception), exception_class::err_code, (message), (extra))
  836. /// Define exception default with one additional parameter.
  837. ///
  838. /// Required to define exception default with one additional parameter
  839. /// (e.g. derived from CParseException).
  840. #define NCBI_EXCEPTION_DEFAULT2(exception_class, base_class, extra_type) 
  841. public: 
  842.     exception_class(const char* file,int line, 
  843.         const CException* prev_exception, 
  844.         EErrCode err_code,const string& message, 
  845.         extra_type extra_param) throw() 
  846.         : base_class(file, line, prev_exception, 
  847.             (base_class::EErrCode) CException::eInvalid, 
  848.             (message), extra_param) 
  849.     NCBI_EXCEPTION_DEFAULT_IMPLEMENTATION(exception_class, base_class)
  850. END_NCBI_SCOPE
  851. /* @} */
  852. /*
  853.  * ===========================================================================
  854.  * $Log: ncbiexpt.hpp,v $
  855.  * Revision 1000.3  2004/06/01 19:08:02  gouriano
  856.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.54
  857.  *
  858.  * Revision 1.54  2004/05/11 15:55:47  gouriano
  859.  * Change GetErrCode method prototype to return TErrCode - to be able to
  860.  * safely cast EErrCode to an eInvalid
  861.  *
  862.  * Revision 1.53  2004/04/30 11:26:06  kuznets
  863.  * THROW spec macro disabled for MSVC (fixed some compiler warnings)
  864.  *
  865.  * Revision 1.52  2004/04/26 19:17:06  ucko
  866.  * Some compilers specifically preferred wrapping strerror with a class,
  867.  * so conditionalize use of a simple function on NCBI_COMPILER_GCC.
  868.  *
  869.  * Revision 1.51  2004/04/26 14:43:56  ucko
  870.  * Handle GCC 3.4's stricter treatment of templates:
  871.  * - Wrap strerror with an ordinary function rather than a static method.
  872.  * - Qualify dependent names with "this->" as needed.
  873.  * - Move CParseTemplException to ncbistr.hpp.
  874.  *
  875.  * Revision 1.50  2004/03/10 19:57:40  gorelenk
  876.  * Added NCBI_XNCBI_EXPORT prefix to function DoThrowTraceAbort.
  877.  *
  878.  * Revision 1.49  2003/12/22 20:20:12  ivanov
  879.  * Made all CException protected methods virtual
  880.  *
  881.  * Revision 1.48  2003/10/24 13:24:54  vasilche
  882.  * Moved body of virtual method to *.cpp file.
  883.  *
  884.  * Revision 1.47  2003/08/01 15:17:21  siyan
  885.  * Documentation changes. Removed superfluous (extra)
  886.  * "public" keyword in CErrnoTemplException.
  887.  *
  888.  * Revision 1.46  2003/05/27 15:19:55  kuznets
  889.  * Included <string.h> (declaration of 'strerror')
  890.  *
  891.  * Revision 1.45  2003/04/29 19:47:02  ucko
  892.  * KLUDGE: avoid inlining CStrErrAdapt::strerror with GCC 2.95 on OSF/1,
  893.  * due to a weird, apparently platform-specific, bug.
  894.  *
  895.  * Revision 1.44  2003/04/25 20:53:53  lavr
  896.  * Add eInvalidArg type of CCoreException
  897.  *
  898.  * Revision 1.43  2003/04/24 16:25:32  kuznets
  899.  * Farther templatefication of CErrnoTemplException,
  900.  * added CErrnoTemplExceptionEx.
  901.  * This will allow easy creation of Errno-like exception classes.
  902.  * Added NCBI_EXCEPTION_DEFAULT_IMPLEMENTATION_TEMPL macro
  903.  * (fixes some warning with templates compilation (gcc 3.2.2)).
  904.  *
  905.  * Revision 1.42  2003/03/31 16:40:21  siyan
  906.  * Added doxygen support
  907.  *
  908.  * Revision 1.41  2003/02/24 19:54:52  gouriano
  909.  * use template-based exceptions instead of errno and parse exceptions
  910.  *
  911.  * Revision 1.40  2003/02/14 19:31:23  gouriano
  912.  * added definition of templates for errno and parse exceptions
  913.  *
  914.  * Revision 1.39  2002/12/18 22:53:21  dicuccio
  915.  * Added export specifier for building DLLs in windows.  Added global list of
  916.  * all such specifiers in mswin_exports.hpp, included through ncbistl.hpp
  917.  *
  918.  * Revision 1.38  2002/08/20 19:13:47  gouriano
  919.  * added DiagPostFlags into CException reporting functions
  920.  *
  921.  * Revision 1.37  2002/08/06 14:08:30  gouriano
  922.  * introduced EXCEPTION_VIRTUAL_BASE macro to make doc++ happy
  923.  *
  924.  * Revision 1.36  2002/07/31 18:32:04  gouriano
  925.  * fix for virtual base classes
  926.  *
  927.  * Revision 1.35  2002/07/29 19:30:43  gouriano
  928.  * changes to allow multiple inheritance in CException classes
  929.  *
  930.  * Revision 1.33  2002/07/15 18:17:51  gouriano
  931.  * renamed CNcbiException and its descendents
  932.  *
  933.  * Revision 1.32  2002/07/11 19:33:11  gouriano
  934.  * minor fix in NCBI_EXCEPTION_DEFAULT definition
  935.  *
  936.  * Revision 1.31  2002/07/11 14:17:54  gouriano
  937.  * exceptions replaced by CNcbiException-type ones
  938.  *
  939.  * Revision 1.30  2002/06/27 18:55:32  gouriano
  940.  * added "title" parameter to report functions
  941.  *
  942.  * Revision 1.29  2002/06/27 18:26:23  vakatov
  943.  * Explicitly qualify "exception" with "std::" to avoid a silly name conflict
  944.  * with <math.h> for SUN Forte6u2 compiler
  945.  *
  946.  * Revision 1.28  2002/06/26 18:36:36  gouriano
  947.  * added CNcbiException class
  948.  *
  949.  * Revision 1.27  2002/04/11 20:39:17  ivanov
  950.  * CVS log moved to end of the file
  951.  *
  952.  * Revision 1.26  2001/12/03 22:24:14  vakatov
  953.  * Rollback R1.25
  954.  *
  955.  * Revision 1.25  2001/12/03 22:03:37  juran
  956.  * #include <corelib/ncbistl.hpp>
  957.  *
  958.  * Revision 1.24  2001/07/30 14:40:57  lavr
  959.  * eDiag_Trace and eDiag_Fatal always print as much as possible
  960.  *
  961.  * Revision 1.23  2001/05/21 21:44:43  vakatov
  962.  * SIZE_TYPE --> string::size_type
  963.  *
  964.  * Revision 1.22  2001/05/17 14:53:41  lavr
  965.  * Typos corrected
  966.  *
  967.  * Revision 1.21  2000/04/04 22:30:25  vakatov
  968.  * SetThrowTraceAbort() -- auto-set basing on the application
  969.  * environment and/or registry
  970.  *
  971.  * Revision 1.20  1999/12/29 13:58:37  vasilche
  972.  * Added THROWS_NONE.
  973.  *
  974.  * Revision 1.19  1999/12/28 21:04:14  vasilche
  975.  * Removed three more implicit virtual destructors.
  976.  *
  977.  * Revision 1.18  1999/12/28 18:55:25  vasilche
  978.  * Reduced size of compiled object files:
  979.  * 1. avoid inline or implicit virtual methods (especially destructors).
  980.  * 2. avoid std::string's methods usage in inline methods.
  981.  * 3. avoid string literals ("xxx") in inline methods.
  982.  *
  983.  * Revision 1.17  1999/11/18 20:12:40  vakatov
  984.  * DoDbgPrint() -- prototyped in both _DEBUG and NDEBUG
  985.  *
  986.  * Revision 1.16  1999/10/04 16:20:56  vasilche
  987.  * Added full set of macros THROW*_TRACE
  988.  *
  989.  * Revision 1.15  1999/09/27 16:23:20  vasilche
  990.  * Changed implementation of debugging macros (_TRACE, _THROW*, _ASSERT etc),
  991.  * so that they will be much easier for compilers to eat.
  992.  *
  993.  * Revision 1.14  1999/09/23 21:15:48  vasilche
  994.  * Added namespace modifiers.
  995.  *
  996.  * Revision 1.13  1999/06/11 16:33:10  vasilche
  997.  * Fixed THROWx_TRACE
  998.  *
  999.  * Revision 1.12  1999/06/11 16:20:22  vasilche
  1000.  * THROW_TRACE fixed for not very smart compiler like Sunpro
  1001.  *
  1002.  * Revision 1.11  1999/06/11 02:48:03  vakatov
  1003.  * [_DEBUG] Refined the output from THROW*_TRACE macro
  1004.  *
  1005.  * Revision 1.10  1999/05/04 00:03:07  vakatov
  1006.  * Removed the redundant severity arg from macro ERR_POST()
  1007.  *
  1008.  * Revision 1.9  1999/01/07 16:15:09  vakatov
  1009.  * Explicitly specify "NCBI_NS_NCBI::" in the preprocessor macros
  1010.  *
  1011.  * Revision 1.8  1999/01/04 22:41:41  vakatov
  1012.  * Do not use so-called "hardware-exceptions" as these are not supported
  1013.  * (on the signal level) by UNIX
  1014.  * Do not "set_unexpected()" as it works differently on UNIX and MSVC++
  1015.  *
  1016.  * Revision 1.7  1998/12/28 17:56:27  vakatov
  1017.  * New CVS and development tree structure for the NCBI C++ projects
  1018.  *
  1019.  * Revision 1.6  1998/12/01 01:19:47  vakatov
  1020.  * Moved <string> and <stdexcept> after the <ncbidiag.hpp> to avoid weird
  1021.  * conflicts under MSVC++ 6.0
  1022.  *
  1023.  * Revision 1.5  1998/11/24 17:51:26  vakatov
  1024.  * + CParseException
  1025.  * Removed "Ncbi" sub-prefix from the NCBI exception class names
  1026.  *
  1027.  * Revision 1.4  1998/11/10 01:17:36  vakatov
  1028.  * Cleaned, adopted to the standard NCBI C++ framework and incorporated
  1029.  * the "hardware exceptions" code and tests(originally written by
  1030.  * V.Sandomirskiy).
  1031.  * Only tested for MSVC++ compiler yet -- to be continued for SunPro...
  1032.  *
  1033.  * Revision 1.3  1998/11/06 22:42:38  vakatov
  1034.  * Introduced BEGIN_, END_ and USING_ NCBI_SCOPE macros to put NCBI C++
  1035.  * API to namespace "ncbi::" and to use it by default, respectively
  1036.  * Introduced THROWS_NONE and THROWS(x) macros for the exception
  1037.  * specifications
  1038.  * Other fixes and rearrangements throughout the most of "corelib" code
  1039.  *
  1040.  * ==========================================================================
  1041.  */
  1042. #endif  /* NCBIEXPT__HPP */