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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: ncbidiag.hpp,v $
  4.  * PRODUCTION Revision 1000.4  2004/06/01 19:07:58  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.72
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. #ifndef CORELIB___NCBIDIAG__HPP
  10. #define CORELIB___NCBIDIAG__HPP
  11. /*  $Id: ncbidiag.hpp,v 1000.4 2004/06/01 19:07:58 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 ncbidiag.hpp
  41. ///
  42. ///   Defines NCBI C++ diagnostic APIs, classes, and macros.
  43. ///
  44. ///   More elaborate documentation could be found in:
  45. ///     http://www.ncbi.nlm.nih.gov/IEB/ToolBox/CPP_DOC/
  46. ///            programming_manual/diag.html
  47. #include <corelib/ncbistre.hpp>
  48. #include <list>
  49. #include <map>
  50. #include <stdexcept>
  51. /** @addtogroup Diagnostics
  52.  *
  53.  * @{
  54.  */
  55. BEGIN_NCBI_SCOPE
  56. /// Error posting with file, line number information but without error codes.
  57. ///
  58. /// @sa
  59. ///   ERR_POST_EX macro
  60. #define ERR_POST(message) 
  61.     ( NCBI_NS_NCBI::CNcbiDiag(__FILE__, __LINE__) << message << NCBI_NS_NCBI::Endm )
  62. /// Log message only without severity, location, prefix information.
  63. ///
  64. /// @sa
  65. ///   LOG_POST_EX macro
  66. #define LOG_POST(message) 
  67.     ( NCBI_NS_NCBI::CNcbiDiag(eDiag_Error, eDPF_Log) << message << NCBI_NS_NCBI::Endm )
  68. /// Error posting with error codes.
  69. ///
  70. /// @sa
  71. ///   ERR_POST
  72. #define ERR_POST_EX(err_code, err_subcode, message) 
  73.     ( NCBI_NS_NCBI::CNcbiDiag(__FILE__, __LINE__) << NCBI_NS_NCBI::ErrCode(err_code, err_subcode) << message << NCBI_NS_NCBI::Endm )
  74. /// Log posting with error codes.
  75. ///
  76. /// @sa
  77. ///   LOG_POST
  78. #define LOG_POST_EX(err_code, err_subcode, message) 
  79.     ( NCBI_NS_NCBI::CNcbiDiag(eDiag_Error, eDPF_Log) << NCBI_NS_NCBI::ErrCode(err_code, err_subcode) << message << NCBI_NS_NCBI::Endm )
  80. #define LOG_POST_N_TIMES(count, message) 
  81.     do { 
  82.         static volatile int sx_to_show = count; 
  83.         int to_show = sx_to_show; 
  84.         if ( to_show > 0 ) { 
  85.             LOG_POST(message); 
  86.             sx_to_show = to_show - 1; 
  87.         } 
  88.     } while ( false )
  89. #define ERR_POST_N_TIMES(count, message) 
  90.     do { 
  91.         static volatile int sx_to_show = count; 
  92.         int to_show = sx_to_show; 
  93.         if ( to_show > 0 ) { 
  94.             ERR_POST(message); 
  95.             sx_to_show = to_show - 1; 
  96.         } 
  97.     } while ( false )
  98. #define LOG_POST_ONCE(message) LOG_POST_N_TIMES(1, message)
  99. #define ERR_POST_ONCE(message) ERR_POST_N_TIMES(1, message)
  100. /// Severity level for the posted diagnostics.
  101. enum EDiagSev {
  102.     eDiag_Info = 0, ///< Informational message
  103.     eDiag_Warning,  ///< Warning message
  104.     eDiag_Error,    ///< Error message
  105.     eDiag_Critical, ///< Critical error message
  106.     eDiag_Fatal,    ///< Fatal error -- guarantees exit(or abort)
  107.     eDiag_Trace,    ///< Trace message
  108.     // Limits
  109.     eDiagSevMin = eDiag_Info,  ///< Verbosity level for min. severity
  110.     eDiagSevMax = eDiag_Trace  ///< Verbosity level for max. severity
  111. };
  112. /// Severity level change state.
  113. enum EDiagSevChange {
  114.     eDiagSC_Unknown, ///< Status of changing severity is unknown (first call)
  115.     eDiagSC_Disable, ///< Disable change severity level 
  116.     eDiagSC_Enable   ///< Enable change severity level 
  117. };
  118. /// Which parts of the diagnostic context should be posted.
  119. ///
  120. /// Generic appearance of the posted message is as follows:
  121. ///
  122. ///   "<file>", line <line>: <severity>: (<err_code>.<err_subcode>)
  123. ///    [<prefix1>::<prefix2>::<prefixN>] <message>n
  124. ///    <err_code_message>n
  125. ///    <err_code_explanation>
  126. ///
  127. /// Example: 
  128. ///
  129. /// - If all flags are set, and prefix string is set to "My prefix", and
  130. ///   ERR_POST(eDiag_Warning, "Take care!"):
  131. ///   "/home/iam/myfile.cpp", line 33: Warning: (2.11) [aa::bb::cc] Take care!
  132. ///
  133. /// @sa
  134. ///   SDiagMessage::Compose()
  135. enum EDiagPostFlag {
  136.     eDPF_File               = 0x1, ///< Set by default #if _DEBUG; else not set
  137.     eDPF_LongFilename       = 0x2, ///< Set by default #if _DEBUG; else not set
  138.     eDPF_Line               = 0x4, ///< Set by default #if _DEBUG; else not set
  139.     eDPF_Prefix             = 0x8, ///< Set by default (always)
  140.     eDPF_Severity           = 0x10,  ///< Set by default (always)
  141.     eDPF_ErrCode            = 0x20,  ///< Set by default (always)
  142.     eDPF_ErrSubCode         = 0x40,  ///< Set by default (always)
  143.     eDPF_ErrCodeMessage     = 0x100, ///< Set by default (always)
  144.     eDPF_ErrCodeExplanation = 0x200, ///< Set by default (always)
  145.     eDPF_ErrCodeUseSeverity = 0x400, ///< Set by default (always)
  146.     eDPF_DateTime           = 0x80,  ///< Include date and time
  147.     /// Set all flags.
  148.     eDPF_All                = 0x3FFF,
  149.     // "Unusual" flags -- not included in eDPF_All
  150.     eDPF_OmitInfoSev        = 0x4000, ///< No sev. indication if eDiag_Info 
  151.     eDPF_PreMergeLines      = 0x10000,///< Remove EOLs before calling handler
  152.     eDPF_MergeLines         = 0x20000,///< Ask diag.handlers to remove EOLs
  153.     /// Default flags to use when tracing.
  154.     eDPF_Trace              = 0x1F,
  155.     /// Print the posted message only; without severity, location, prefix, etc.
  156.     eDPF_Log                = 0x0,
  157.     /// Use global default flags (merge with).
  158.     /// @sa SetDiagPostFlag(), UnsetDiagPostFlag(), IsSetDiagPostFlag()
  159.     eDPF_Default            = 0x8000
  160. };
  161. typedef int TDiagPostFlags;  ///< Binary OR of "EDiagPostFlag"
  162. // Forward declaration of some classes.
  163. class CDiagBuffer;
  164. class CDiagErrCodeInfo;
  165. /////////////////////////////////////////////////////////////////////////////
  166. ///
  167. /// ErrCode --
  168. ///
  169. /// Define composition of error code.
  170. ///
  171. /// Currently the error code is an ordered pair of <code, subcode> numbers.
  172. class ErrCode
  173. {
  174. public:
  175.     /// Constructor.
  176.     ErrCode(int code, int subcode = 0)
  177.         : m_Code(code), m_SubCode(subcode)
  178.     { }
  179.     int m_Code;         ///< Major error code number
  180.     int m_SubCode;      ///< Minor error code number
  181. };
  182. class CException;
  183. /////////////////////////////////////////////////////////////////////////////
  184. ///
  185. /// CNcbiDiag --
  186. ///
  187. /// Define the main NCBI Diagnostic class.
  188. class CNcbiDiag
  189. {
  190. public:
  191.     /// Constructor.
  192.     NCBI_XNCBI_EXPORT
  193.     CNcbiDiag(EDiagSev       sev        = eDiag_Error,  ///< Severity level
  194.               TDiagPostFlags post_flags = eDPF_Default  ///< What info.
  195.              );
  196.     /// Constructor -- includes file and line# information.
  197.     NCBI_XNCBI_EXPORT
  198.     CNcbiDiag(const char*    file,    ///< File to write diag. messages
  199.               size_t         line,    ///< Line number
  200.               EDiagSev       sev          = eDiag_Error,  ///< Severity level
  201.               TDiagPostFlags post_flags = eDPF_Default  ///< What info.
  202.              );
  203.     /// Destructor.
  204.     ~CNcbiDiag(void);
  205.     /// Put object to be formatted to diagnostic stream.
  206.     // Some compilers need to see the body right away, but others need
  207.     // to meet CDiagBuffer first.
  208.     template<class X> const CNcbiDiag& operator<< (const X& x) const
  209. #ifdef NCBI_COMPILER_MSVC
  210.     {
  211.         m_Buffer.Put(*this, x);
  212.         return *this;
  213.     }
  214. #else
  215.       ;
  216. #  define NCBIDIAG_DEFER_GENERIC_PUT
  217. #endif
  218.     /// Insert specified error code into diagnostic stream.
  219.     ///
  220.     /// Example:
  221.     ///   CNcbiDiag() << ErrCode(5,3);
  222.     const CNcbiDiag& operator<< (const ErrCode& err_code) const;
  223.     /// Report specified exception to diagnostic stream.
  224.     NCBI_XNCBI_EXPORT
  225.     const CNcbiDiag& operator<< (const CException& ex) const;
  226.     /// Function-based manipulators.
  227.     const CNcbiDiag& operator<< (const CNcbiDiag& (*f)(const CNcbiDiag&))
  228.         const
  229.     {
  230.         return f(*this);
  231.     }
  232.     // Output manipulators for CNcbiDiag.
  233.     /// Reset the content of current message.
  234.     friend const CNcbiDiag& Reset  (const CNcbiDiag& diag);
  235.     /// Flush current message, start new one.
  236.     friend const CNcbiDiag& Endm   (const CNcbiDiag& diag);
  237.     /// Flush current message, then  set a severity for the next diagnostic
  238.     /// message to Info.
  239.     friend const CNcbiDiag& Info    (const CNcbiDiag& diag);
  240.     /// Flush current message, then  set a severity for the next diagnostic
  241.     /// message to Warning.
  242.     friend const CNcbiDiag& Warning (const CNcbiDiag& diag);
  243.     /// Flush current message, then  set a severity for the next diagnostic
  244.     /// message to Error.
  245.     friend const CNcbiDiag& Error   (const CNcbiDiag& diag);
  246.     /// Flush current message, then  set a severity for the next diagnostic
  247.     /// message to Critical.
  248.     friend const CNcbiDiag& Critical(const CNcbiDiag& diag);
  249.     /// Flush current message, then  set a severity for the next diagnostic
  250.     /// message to Fatal.
  251.     friend const CNcbiDiag& Fatal   (const CNcbiDiag& diag);
  252.     /// Flush current message, then  set a severity for the next diagnostic
  253.     /// message to Trace.
  254.     friend const CNcbiDiag& Trace   (const CNcbiDiag& diag);
  255.     /// Get a common symbolic name for the severity levels.
  256.     static const char* SeverityName(EDiagSev sev);
  257.     /// Get severity from string.
  258.     ///
  259.     /// @param str_sev
  260.     ///   Can be the numeric value or a symbolic name (see
  261.     ///   CDiagBuffer::sm_SeverityName[]).
  262.     /// @param sev
  263.     ///   Severity level. 
  264.     /// @return
  265.     ///   Return TRUE if severity level known; FALSE, otherwise.
  266.     static bool StrToSeverityLevel(const char* str_sev, EDiagSev& sev);
  267.     /// Set file name to post.
  268.     NCBI_XNCBI_EXPORT
  269.     const CNcbiDiag& SetFile(const char* file) const;
  270.     /// Set line number for post.
  271.     const CNcbiDiag& SetLine(size_t line) const;
  272.     /// Set error code and subcode numbers.
  273.     const CNcbiDiag& SetErrorCode(int code = 0, int subcode = 0) const;
  274.     /// Get severity of the current message.
  275.     EDiagSev GetSeverity(void) const;
  276.     /// Get file used for the current message.
  277.     const char* GetFile(void) const;
  278.     /// Get line number for the current message.
  279.     size_t GetLine(void) const;
  280.     /// Get error code of the current message.
  281.     int GetErrorCode(void) const;
  282.     /// Get error subcode of the current message.
  283.     int GetErrorSubCode(void) const;
  284.     /// Get post flags for the current message.
  285.     /// If the post flags have "eDPF_Default" set, then in the returned flags
  286.     /// it will be reset and substituted by current default flags.
  287.     TDiagPostFlags GetPostFlags(void) const;
  288.     /// Display fatal error message.
  289.     NCBI_XNCBI_EXPORT
  290.     static void DiagFatal(const char* file, size_t line,
  291.                           const char* message);
  292.     /// Display trouble error message.
  293.     NCBI_XNCBI_EXPORT
  294.     static void DiagTrouble(const char* file, size_t line);
  295.     /// Assert specfied expression and report results.
  296.     NCBI_XNCBI_EXPORT
  297.     static void DiagAssert(const char* file, size_t line,
  298.                            const char* expression);
  299.     /// Display validation message.
  300.     NCBI_XNCBI_EXPORT
  301.     static void DiagValidate(const char* file, size_t line,
  302.                              const char* expression, const char* message);
  303. private:
  304.     mutable EDiagSev       m_Severity;   ///< Severity level of current msg.
  305.     mutable char           m_File[256];  ///< File name
  306.     mutable size_t         m_Line;       ///< Line number
  307.     mutable int            m_ErrCode;    ///< Error code
  308.     mutable int            m_ErrSubCode; ///< Error subcode
  309.             CDiagBuffer&   m_Buffer;     ///< This thread's error msg. buffer
  310.     mutable TDiagPostFlags m_PostFlags;  ///< Bitwise OR of "EDiagPostFlag"
  311.     /// Private copy constructor to prohibit copy.
  312.     CNcbiDiag(const CNcbiDiag&);
  313.     /// Private assignment operator to prohibit assignment.
  314.     CNcbiDiag& operator= (const CNcbiDiag&);
  315. };
  316. /////////////////////////////////////////////////////////////////////////////
  317. // ATTENTION:  the following functions are application-wide, i.e they
  318. //             are not local for a particular thread
  319. /////////////////////////////////////////////////////////////////////////////
  320. /// Check if a specified flag is set.
  321. ///
  322. /// @param flag
  323. ///   Flag to check
  324. /// @param flags
  325. ///   If eDPF_Default is set for "flags" then use the current global flags on
  326. ///   its place (merged with other flags from "flags").
  327. /// @return
  328. ///   "TRUE" if the specified "flag" is set in global "flags" that describes
  329. ///   the post settings.
  330. /// @sa SetDiagPostFlag(), UnsetDiagPostFlag()
  331. inline bool IsSetDiagPostFlag(EDiagPostFlag  flag, 
  332.                               TDiagPostFlags flags = eDPF_Default);
  333. /// Set global post flags to "flags".
  334. /// If "flags" have flag eDPF_Default set, it will be replaced by the
  335. /// current global post flags.
  336. /// @return
  337. ///   Previously set flags
  338. NCBI_XNCBI_EXPORT
  339. extern TDiagPostFlags SetDiagPostAllFlags(TDiagPostFlags flags);
  340. /// Set the specified flag (globally).
  341. NCBI_XNCBI_EXPORT
  342. extern void SetDiagPostFlag(EDiagPostFlag flag);
  343. /// Unset the specified flag (globally).
  344. NCBI_XNCBI_EXPORT
  345. extern void UnsetDiagPostFlag(EDiagPostFlag flag);
  346. /// Versions of the above for extra trace flags.
  347. NCBI_XNCBI_EXPORT
  348. extern TDiagPostFlags SetDiagTraceAllFlags(TDiagPostFlags flags);
  349. NCBI_XNCBI_EXPORT
  350. extern void SetDiagTraceFlag(EDiagPostFlag flag);
  351. NCBI_XNCBI_EXPORT
  352. extern void UnsetDiagTraceFlag(EDiagPostFlag flag);
  353. /// Specify a string to prefix all subsequent error postings with.
  354. NCBI_XNCBI_EXPORT
  355. extern void SetDiagPostPrefix(const char* prefix);
  356. /// Push a string to the list of message prefixes.
  357. NCBI_XNCBI_EXPORT
  358. extern void PushDiagPostPrefix(const char* prefix);
  359. /// Pop a string from the list of message prefixes.
  360. NCBI_XNCBI_EXPORT
  361. extern void PopDiagPostPrefix(void);
  362. /////////////////////////////////////////////////////////////////////////////
  363. ///
  364. /// CDiagAutoPrefix --
  365. ///
  366. /// Define the auxiliary class to temporarily add a prefix.
  367. class NCBI_XNCBI_EXPORT CDiagAutoPrefix
  368. {
  369. public:
  370.     /// Constructor.
  371.     CDiagAutoPrefix(const string& prefix);
  372.     /// Constructor.
  373.     CDiagAutoPrefix(const char*   prefix);
  374.     /// Remove the prefix automagically, when the object gets out of scope.
  375.     ~CDiagAutoPrefix(void);
  376. };
  377. /// Diagnostic post severity level.
  378. ///
  379. /// The value of DIAG_POST_LEVEL can be a digital value (0-9) or 
  380. /// string value from CDiagBuffer::sm_SeverityName[].
  381. #define DIAG_POST_LEVEL "DIAG_POST_LEVEL"
  382. /// Set severity of post messages.
  383. ///
  384. /// This function has effect only if:
  385. ///   - Environment variable $DIAG_POST_LEVEL is not set, and
  386. ///   - Registry value of DIAG_POST_LEVEL, section DEBUG is not set 
  387. ///
  388. /// Do not post messages where severity is less than "min_sev"
  389. /// @return
  390. ///   Return previous post-level.
  391. NCBI_XNCBI_EXPORT
  392. extern EDiagSev SetDiagPostLevel(EDiagSev post_sev = eDiag_Error);
  393. /// Disable change the diagnostic post level.
  394. ///
  395. /// Consecutive using SetDiagPostLevel() will not have effect.
  396. NCBI_XNCBI_EXPORT
  397. extern bool DisableDiagPostLevelChange(bool disable_change = true);
  398. /// Sets and locks the level, combining the previous two calls.
  399. NCBI_XNCBI_EXPORT
  400. extern void SetDiagFixedPostLevel(EDiagSev post_sev);
  401. /// Set the "die" (abort) level for the program.
  402. ///
  403. /// Abort the application if severity is >= "max_sev".
  404. /// Throw an exception if die_sev is not in the range
  405. /// [eDiagSevMin..eDiag_Fatal].
  406. /// @return
  407. ///   Return previous die-level.
  408. NCBI_XNCBI_EXPORT
  409. extern EDiagSev SetDiagDieLevel(EDiagSev die_sev = eDiag_Fatal);
  410. /// Ignore the die level settings.
  411. ///
  412. /// WARNING!!! -- not recommended for use unless you are real desperate:
  413. /// By passing TRUE to this function you can make your application
  414. /// never exit/abort regardless of the level set by SetDiagDieLevel().
  415. /// But be warned this is usually a VERY BAD thing to do!
  416. /// -- because any library code counts on at least "eDiag_Fatal" to exit
  417. /// unconditionally, and thus what happens after "eDiag_Fatal" is posted is
  418. /// in general totally unpredictable! Therefore, use it on your own risk.
  419. NCBI_XNCBI_EXPORT
  420. extern void IgnoreDiagDieLevel(bool ignore, EDiagSev* prev_sev = 0);
  421. /// Abort handler function type.
  422. typedef void (*FAbortHandler)(void);
  423. /// Set/unset abort handler.
  424. ///
  425. /// If "func"==0 use default handler.
  426. NCBI_XNCBI_EXPORT
  427. extern void SetAbortHandler(FAbortHandler func = 0);
  428. /// Smart abort function.
  429. ///
  430. /// Processes user abort handler and does not popup assert windows
  431. /// if specified (environment variable DIAG_SILENT_ABORT is "Y" or "y").
  432. NCBI_XNCBI_EXPORT
  433. extern void Abort(void);
  434. /// Diagnostic trace setting.
  435. #define DIAG_TRACE "DIAG_TRACE"
  436. /// Which setting disables/enables posting of "eDiag_Trace" messages.
  437. ///
  438. /// By default, trace messages are disabled unless:
  439. /// - Environment variable $DIAG_TRACE is set (to any value), or
  440. /// - Registry value of DIAG_TRACE, section DEBUG is set (to any value)
  441. enum EDiagTrace {
  442.     eDT_Default = 0,  ///< Restores the default tracing context
  443.     eDT_Disable,      ///< Ignore messages of severity "eDiag_Trace"
  444.     eDT_Enable        ///< Enable messages of severity "eDiag_Trace"
  445. };
  446. /// Set the diagnostic trace settings.
  447. NCBI_XNCBI_EXPORT
  448. extern void SetDiagTrace(EDiagTrace how, EDiagTrace dflt = eDT_Default);
  449. /////////////////////////////////////////////////////////////////////////////
  450. ///
  451. /// SDiagMessage --
  452. ///
  453. /// Diagnostic message structure.
  454. ///
  455. /// Defines structure of the "data" message that is used with message handler
  456. /// function("func"),  and destructor("cleanup").
  457. /// The "func(..., data)" to be called when any instance of "CNcbiDiagBuffer"
  458. /// has a new diagnostic message completed and ready to post.
  459. /// "cleanup(data)" will be called whenever this hook gets replaced and
  460. /// on the program termination.
  461. /// NOTE 1:  "func()", "cleanup()" and "g_SetDiagHandler()" calls are
  462. ///          MT-protected, so that they would never be called simultaneously
  463. ///          from different threads.
  464. /// NOTE 2:  By default, the errors will be written to standard error stream.
  465. struct NCBI_XNCBI_EXPORT SDiagMessage {
  466.     /// Initalize SDiagMessage fields.
  467.     SDiagMessage(EDiagSev severity, const char* buf, size_t len,
  468.                  const char* file = 0, size_t line = 0,
  469.                  TDiagPostFlags flags = eDPF_Default, const char* prefix = 0,
  470.                  int err_code = 0, int err_subcode = 0,
  471.                  const char* err_text = 0);
  472.     mutable EDiagSev m_Severity;   ///< Severity level
  473.     const char*      m_Buffer;     ///< Not guaranteed to be ''-terminated!
  474.     size_t           m_BufferLen;  ///< Length of m_Buffer
  475.     const char*      m_File;       ///< File name
  476.     size_t           m_Line;       ///< Line number in file
  477.     int              m_ErrCode;    ///< Error code
  478.     int              m_ErrSubCode; ///< Sub Error code
  479.     TDiagPostFlags   m_Flags;      ///< Bitwise OR of "EDiagPostFlag"
  480.     const char*      m_Prefix;     ///< Prefix string
  481.     const char*      m_ErrText;    ///< Sometimes 'error' has no numeric code,
  482.                                    ///< but can be represented as text
  483.     // Compose a message string in the standard format(see also "flags"):
  484.     //    "<file>", line <line>: <severity>: [<prefix>] <message> [EOL]
  485.     // and put it to string "str", or write to an output stream "os".
  486.     /// Which write flags should be output in diagnostic message.
  487.     enum EDiagWriteFlags {
  488.         fNone   = 0x0,      ///< No flags
  489.         fNoEndl = 0x01      ///< No end of line
  490.     };
  491.     typedef int TDiagWriteFlags; /// Binary OR of "EDiagWriteFlags"
  492.     /// Write to string.
  493.     void Write(string& str, TDiagWriteFlags flags = fNone) const;
  494.     
  495.     /// Write to stream.
  496.     CNcbiOstream& Write(CNcbiOstream& os, TDiagWriteFlags flags = fNone) const;
  497.     CNcbiOstream& x_Write(CNcbiOstream& os, TDiagWriteFlags flags = fNone) const;
  498. };
  499. /// Insert message in output stream.
  500. inline CNcbiOstream& operator<< (CNcbiOstream& os, const SDiagMessage& mess) {
  501.     return mess.Write(os);
  502. }
  503. /////////////////////////////////////////////////////////////////////////////
  504. ///
  505. /// CDiagHandler --
  506. ///
  507. /// Base diagnostic handler class.
  508. class NCBI_XNCBI_EXPORT CDiagHandler
  509. {
  510. public:
  511.     /// Destructor.
  512.     virtual ~CDiagHandler(void) {}
  513.     /// Post message to handler.
  514.     virtual void Post(const SDiagMessage& mess) = 0;
  515. };
  516. /// Diagnostic handler function type.
  517. typedef void (*FDiagHandler)(const SDiagMessage& mess);
  518. /// Diagnostic cleanup function type.
  519. typedef void (*FDiagCleanup)(void* data);
  520. /// Set the diagnostic handler using the specified diagnostic handler class.
  521. NCBI_XNCBI_EXPORT
  522. extern void SetDiagHandler(CDiagHandler* handler,
  523.                            bool can_delete = true);
  524. /// Get the currently set diagnostic handler class.
  525. NCBI_XNCBI_EXPORT
  526. extern CDiagHandler* GetDiagHandler(bool take_ownership = false);
  527. /// Set the diagnostic handler using the specified diagnostic handler
  528. /// and cleanup functions.
  529. NCBI_XNCBI_EXPORT
  530. extern void SetDiagHandler(FDiagHandler func,
  531.                            void*        data,
  532.                            FDiagCleanup cleanup);
  533. /// Check if diagnostic handler is set.
  534. ///
  535. /// @return 
  536. ///   Return TRUE if user has ever set (or unset) diag. handler.
  537. NCBI_XNCBI_EXPORT
  538. extern bool IsSetDiagHandler(void);
  539. /////////////////////////////////////////////////////////////////////////////
  540. ///
  541. /// CStreamDiagHandler --
  542. ///
  543. /// Specialization of "CDiagHandler" for the stream-based diagnostics.
  544. class NCBI_XNCBI_EXPORT CStreamDiagHandler : public CDiagHandler
  545. {
  546. public:
  547.     /// Constructor.
  548.     ///
  549.     /// This does *not* own the stream; users will need to clean it up
  550.     /// themselves if appropriate. 
  551.     /// @param os
  552.     ///   Output stream.
  553.     /// @param quick_flush
  554.     ///   Do stream flush after every message. 
  555.     CStreamDiagHandler(CNcbiOstream* os, bool quick_flush = true)
  556.         : m_Stream(os), m_QuickFlush(quick_flush) {}
  557.     /// Post message to the handler.
  558.     virtual void Post(const SDiagMessage& mess);
  559.     NCBI_XNCBI_EXPORT friend bool IsDiagStream(const CNcbiOstream* os);
  560. protected:
  561.     CNcbiOstream* m_Stream;         ///< Diagnostic stream
  562. private:
  563.     bool          m_QuickFlush;     ///< Quick flush of stream flag
  564. };
  565. /// Set diagnostic stream.
  566. ///
  567. /// Error diagnostics are written to output stream "os".
  568. /// This uses the SetDiagHandler() functionality.
  569. NCBI_XNCBI_EXPORT
  570. extern void SetDiagStream
  571. (CNcbiOstream* os,
  572.  bool          quick_flush  = true,///< Do stream flush after every message
  573.  FDiagCleanup  cleanup      = 0,   ///< Call "cleanup(cleanup_data)" if diag.
  574.  void*         cleanup_data = 0    ///< Stream is changed (see SetDiagHandler)
  575.  );
  576. // Return TRUE if "os" is the current diag. stream.
  577. NCBI_XNCBI_EXPORT 
  578. extern bool IsDiagStream(const CNcbiOstream* os);
  579. /////////////////////////////////////////////////////////////////////////////
  580. ///
  581. /// CDiagFactory --
  582. ///
  583. /// Diagnostic handler factory.
  584. class NCBI_XNCBI_EXPORT CDiagFactory
  585. {
  586. public:
  587.     /// Factory method interface.
  588.     virtual CDiagHandler* New(const string& s) = 0;
  589. };
  590. /////////////////////////////////////////////////////////////////////////////
  591. ///
  592. /// CDiagRestorer --
  593. ///
  594. /// Auxiliary class to limit the duration of changes to diagnostic settings.
  595. class NCBI_XNCBI_EXPORT CDiagRestorer
  596. {
  597. public:
  598.     CDiagRestorer (void); ///< Captures current settings
  599.     ~CDiagRestorer(void); ///< Restores captured settings
  600. private:
  601.     /// Private new operator.
  602.     ///
  603.     /// Prohibit dynamic allocation because there's no good reason to allow
  604.     /// it, and out-of-order destruction is problematic.
  605.     void* operator new      (size_t)  { throw runtime_error("forbidden"); }
  606.     /// Private new[] operator.
  607.     ///
  608.     /// Prohibit dynamic allocation because there's no good reason to allow
  609.     /// it, and out-of-order destruction is problematic.
  610.     void* operator new[]    (size_t)  { throw runtime_error("forbidden"); }
  611.     /// Private delete operator.
  612.     ///
  613.     /// Prohibit dynamic deallocation (and allocation) because there's no
  614.     /// good reason to allow it, and out-of-order destruction is problematic.
  615.     void  operator delete   (void*)   { throw runtime_error("forbidden"); }
  616.     /// Private delete[] operator.
  617.     ///
  618.     /// Prohibit dynamic deallocation (and allocation) because there's no
  619.     /// good reason to allow it, and out-of-order destruction is problematic.
  620.     void  operator delete[] (void*)   { throw runtime_error("forbidden"); }
  621.     string            m_PostPrefix;         ///< Message prefix
  622.     list<string>      m_PrefixList;         ///< List of prefixs
  623.     TDiagPostFlags    m_PostFlags;          ///< Post flags
  624.     EDiagSev          m_PostSeverity;       ///< Post severity
  625.     EDiagSevChange    m_PostSeverityChange; ///< Severity change
  626.     EDiagSev          m_DieSeverity;        ///< Die level severity
  627.     EDiagTrace        m_TraceDefault;       ///< Default trace setting
  628.     bool              m_TraceEnabled;       ///< Trace enabled?
  629.     CDiagHandler*     m_Handler;            ///< Class handler
  630.     bool              m_CanDeleteHandler;   ///< Can handler be deleted?
  631.     CDiagErrCodeInfo* m_ErrCodeInfo;        ///< Error code information
  632.     bool              m_CanDeleteErrCodeInfo; 
  633.                                        ///< Can error code info. be deleted?
  634. };
  635. /////////////////////////////////////////////////////////////////////////////
  636. ///
  637. /// SDiagErrCodeDescription --
  638. ///
  639. /// Structure used to store the errors code and subcode description.
  640. struct NCBI_XNCBI_EXPORT SDiagErrCodeDescription {
  641.     /// Constructor.
  642.     SDiagErrCodeDescription(void);
  643.     /// Destructor.
  644.     SDiagErrCodeDescription(const string& message,     ///< Message
  645.                             const string& explanation, ///< Explanation of msg.
  646.                             int           severity = -1
  647.                                                        ///< Do not override
  648.                                                        ///< if set to -1
  649.                            )
  650.         : m_Message(message),
  651.           m_Explanation(explanation),
  652.           m_Severity(severity)
  653.     {
  654.         return;
  655.     }
  656. public:
  657.     string m_Message;     ///< Error message (short)
  658.     string m_Explanation; ///< Error message (with detailed explanation)
  659.     int    m_Severity;    
  660.                           ///< Message severity (if less that 0, then use
  661.                           ///< current diagnostic severity level)
  662. };
  663. /////////////////////////////////////////////////////////////////////////////
  664. ///
  665. /// CDiagErrCodeInfo --
  666. ///
  667. /// Stores mapping of error codes and their descriptions.
  668. class NCBI_XNCBI_EXPORT CDiagErrCodeInfo
  669. {
  670. public:
  671.     /// Constructor.
  672.     CDiagErrCodeInfo(void);
  673.     /// Constructor -- can throw runtime_error.
  674.     CDiagErrCodeInfo(const string& file_name);  
  675.     /// Constructor -- can throw runtime_error.
  676.     CDiagErrCodeInfo(CNcbiIstream& is);
  677.     /// Destructor.
  678.     ~CDiagErrCodeInfo(void);
  679.     /// Read error description from specified file.
  680.     ///
  681.     /// Read error descriptions from the specified file,
  682.     /// store it in memory.
  683.     bool Read(const string& file_name);
  684.     /// Read error description from specified stream.
  685.     ///
  686.     /// Read error descriptions from the specified stream,
  687.     /// store it in memory.
  688.     bool Read(CNcbiIstream& is);
  689.     
  690.     /// Delete all stored error descriptions from memory.
  691.     void Clear(void);
  692.     /// Get description for specified error code.
  693.     ///
  694.     /// Get description message for the error by its code.
  695.     /// @return
  696.     ///   TRUE if error description exists for this code;
  697.     ///   return FALSE otherwise.
  698.     bool GetDescription(const ErrCode&           err_code, 
  699.                         SDiagErrCodeDescription* description) const;
  700.     /// Set error description for specified error code.
  701.     ///
  702.     /// If description for this code already exist, then it
  703.     /// will be overwritten.
  704.     void SetDescription(const ErrCode&                 err_code, 
  705.                         const SDiagErrCodeDescription& description);
  706.     /// Check if error description exists.
  707.     ///
  708.     ///  Return TRUE if description for specified error code exists, 
  709.     /// otherwise return FALSE.
  710.     bool HaveDescription(const ErrCode& err_code) const;
  711. private:
  712.     /// Define map for error messages.
  713.     typedef map<ErrCode, SDiagErrCodeDescription> TInfo;
  714.     /// Map storing error codes and descriptions.
  715.     TInfo m_Info;
  716. };
  717. /// Diagnostic message file.
  718. #define DIAG_MESSAGE_FILE "MessageFile"
  719. /// Set handler for processing error codes.
  720. ///
  721. /// By default this handler is unset. 
  722. /// NcbiApplication can init itself only if registry key DIAG_MESSAGE_FILE
  723. /// section DEBUG) is specified. The value of this key should be a name 
  724. /// of the file with the error codes explanations.
  725. /// @sa
  726. ///   http://www.ncbi.nlm.nih.gov/IEB/ToolBox/CPP_DOC/programming_manual/diag.html#errcodes
  727. NCBI_XNCBI_EXPORT
  728. extern void SetDiagErrCodeInfo(CDiagErrCodeInfo* info,
  729.                                bool              can_delete = true);
  730. /// Indicates whether an error-code processing handler has been set.
  731. NCBI_XNCBI_EXPORT
  732. extern bool IsSetDiagErrCodeInfo();
  733. /// Get handler for processing error codes.
  734. NCBI_XNCBI_EXPORT
  735. extern CDiagErrCodeInfo* GetDiagErrCodeInfo(bool take_ownership = false);
  736. /* @} */
  737. ///////////////////////////////////////////////////////
  738. // All inline function implementations and internal data
  739. // types, etc. are in this file
  740. #include <corelib/ncbidiag.inl>
  741. END_NCBI_SCOPE
  742. /*
  743.  * ==========================================================================
  744.  *
  745.  * $Log: ncbidiag.hpp,v $
  746.  * Revision 1000.4  2004/06/01 19:07:58  gouriano
  747.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.72
  748.  *
  749.  * Revision 1.72  2004/04/26 19:28:24  ucko
  750.  * Make previous change compiler-dependent due to MSVC bugginess.
  751.  *
  752.  * Revision 1.71  2004/04/26 14:35:47  ucko
  753.  * Move CNcbiDiag::operator<< to ncbidiag.inl to make GCC 3.4 happy.
  754.  *
  755.  * Revision 1.70  2004/03/18 20:19:48  gouriano
  756.  * make it possible to convert multi-line diagnostic message into single-line
  757.  *
  758.  * Revision 1.69  2004/03/16 15:35:19  vasilche
  759.  * Added LOG_POST_ONCE and ERR_POST_ONCE macros
  760.  *
  761.  * Revision 1.68  2004/03/12 21:16:56  gorelenk
  762.  * Added NCBI_XNCBI_EXPORT to member-function SetFile of class CNcbiDiag.
  763.  *
  764.  * Revision 1.67  2004/03/10 18:40:21  gorelenk
  765.  * Added/Removed NCBI_XNCBI_EXPORT prefixes.
  766.  *
  767.  * Revision 1.66  2004/03/10 17:34:05  gorelenk
  768.  * Removed NCBI_XNCBI_EXPORT prefix for classes members-functions
  769.  * that are implemented as a inline functions.
  770.  *
  771.  * Revision 1.65  2004/01/28 14:49:04  ivanov
  772.  * Added export specifier to SDiagErrCodeDescription
  773.  *
  774.  * Revision 1.64  2004/01/27 17:04:10  ucko
  775.  * Don't attempt to declare references as mutable -- the referents are fixed,
  776.  * and one can always change their contents through any non-const reference.
  777.  * (IBM's VisualAge compiler forbids such declarations.)
  778.  * Add missing declarations for SetDiagFixedPostLevel and IsSetDiagErrCodeInfo.
  779.  *
  780.  * Revision 1.63  2003/11/12 20:30:25  ucko
  781.  * Make extra flags for severity-trace messages tunable.
  782.  *
  783.  * Revision 1.62  2003/11/07 13:04:45  ivanov
  784.  * Added export specifier for SDiagMessage
  785.  *
  786.  * Revision 1.61  2003/11/06 21:40:34  vakatov
  787.  * A somewhat more natural handling of the 'eDPF_Default' flag -- replace
  788.  * it by the current global flags, then merge these with other flags (if any)
  789.  *
  790.  * Revision 1.60  2003/08/01 14:16:27  siyan
  791.  * Fixed error in CDiagFactory documentation.
  792.  *
  793.  * Revision 1.59  2003/07/21 18:42:29  siyan
  794.  * Documentation changes.
  795.  *
  796.  * Revision 1.58  2003/04/25 20:52:34  lavr
  797.  * Introduce draft version of IgnoreDiagDieLevel()
  798.  *
  799.  * Revision 1.57  2003/04/25 16:00:03  vakatov
  800.  * Document an ugly, absolutely not recommended for use, very special case
  801.  * for SetDiagDieLevel() which prevents the application from exiting when
  802.  * an error with FATAL severity is posted.
  803.  *
  804.  * Revision 1.56  2003/04/11 17:55:44  lavr
  805.  * Proper indentation of some fragments
  806.  *
  807.  * Revision 1.55  2003/03/31 15:36:51  siyan
  808.  * Added doxygen support
  809.  *
  810.  * Revision 1.54  2002/12/18 22:53:21  dicuccio
  811.  * Added export specifier for building DLLs in windows.  Added global list of
  812.  * all such specifiers in mswin_exports.hpp, included through ncbistl.hpp
  813.  *
  814.  * Revision 1.53  2002/09/24 18:28:20  vasilche
  815.  * Fixed behavour of CNcbiDiag::DiagValidate() in release mode
  816.  *
  817.  * Revision 1.52  2002/09/19 20:05:41  vasilche
  818.  * Safe initialization of static mutexes
  819.  *
  820.  * Revision 1.51  2002/09/16 20:49:06  vakatov
  821.  * Cosmetics and comments
  822.  *
  823.  * Revision 1.50  2002/08/20 19:13:09  gouriano
  824.  * added DiagWriteFlags into SDiagMessage::Write
  825.  *
  826.  * Revision 1.49  2002/08/16 15:02:50  ivanov
  827.  * Added class CDiagAutoPrefix
  828.  *
  829.  * Revision 1.48  2002/08/01 18:48:07  ivanov
  830.  * Added stuff to store and output error verbose messages for error codes
  831.  *
  832.  * Revision 1.47  2002/07/15 18:17:50  gouriano
  833.  * renamed CNcbiException and its descendents
  834.  *
  835.  * Revision 1.46  2002/07/10 16:18:42  ivanov
  836.  * Added CNcbiDiag::StrToSeverityLevel().
  837.  * Rewrite and rename SetDiagFixedStrPostLevel() -> SetDiagFixedPostLevel()
  838.  *
  839.  * Revision 1.45  2002/07/09 16:38:00  ivanov
  840.  * Added GetSeverityChangeEnabledFirstTime().
  841.  * Fix usage forced set severity post level from environment variable
  842.  * to work without NcbiApplication::AppMain()
  843.  *
  844.  * Revision 1.44  2002/07/02 18:26:08  ivanov
  845.  * Added CDiagBuffer::DisableDiagPostLevelChange()
  846.  *
  847.  * Revision 1.43  2002/06/26 18:36:37  gouriano
  848.  * added CNcbiException class
  849.  *
  850.  * Revision 1.42  2002/04/23 19:57:25  vakatov
  851.  * Made the whole CNcbiDiag class "mutable" -- it helps eliminate
  852.  * numerous warnings issued by SUN Forte6U2 compiler.
  853.  * Do not use #NO_INCLASS_TMPL anymore -- apparently all modern
  854.  * compilers seem to be supporting in-class template methods.
  855.  *
  856.  * Revision 1.41  2002/04/16 18:38:02  ivanov
  857.  * SuppressDiagPopupMessages() moved to "test/test_assert.h"
  858.  *
  859.  * Revision 1.40  2002/04/11 20:39:16  ivanov
  860.  * CVS log moved to end of the file
  861.  *
  862.  * Revision 1.39  2002/04/11 19:58:03  ivanov
  863.  * Added function SuppressDiagPopupMessages()
  864.  *
  865.  * Revision 1.38  2002/04/10 14:45:04  ivanov
  866.  * Abort() moved from static to extern and added to header file
  867.  *
  868.  * Revision 1.37  2002/04/01 22:34:35  ivanov
  869.  * Added SetAbortHandler() function to set user abort handler
  870.  *
  871.  * Revision 1.36  2002/02/07 19:45:53  ucko
  872.  * Optionally transfer ownership in GetDiagHandler.
  873.  *
  874.  * Revision 1.35  2001/11/14 15:14:58  ucko
  875.  * Revise diagnostic handling to be more object-oriented.
  876.  *
  877.  * Revision 1.34  2001/10/29 15:37:29  ucko
  878.  * Rewrite dummy new/delete bodies to avoid GCC warnings.
  879.  *
  880.  * Revision 1.33  2001/10/29 15:25:55  ucko
  881.  * Give (prohibited) CDiagRestorer::new/delete dummy bodies.
  882.  *
  883.  * Revision 1.32  2001/10/29 15:16:11  ucko
  884.  * Preserve default CGI diagnostic settings, even if customized by app.
  885.  *
  886.  * Revision 1.31  2001/10/16 23:44:04  vakatov
  887.  * + SetDiagPostAllFlags()
  888.  *
  889.  * Revision 1.30  2001/08/09 16:24:05  lavr
  890.  * Added eDPF_OmitInfoSev to log message format flags
  891.  *
  892.  * Revision 1.29  2001/07/26 21:28:49  lavr
  893.  * Remove printing DateTime stamp by default
  894.  *
  895.  * Revision 1.28  2001/07/25 19:12:41  lavr
  896.  * Added date/time stamp for message logging
  897.  *
  898.  * Revision 1.27  2001/06/14 03:37:28  vakatov
  899.  * For the ErrCode manipulator, use CNcbiDiag:: method rather than a friend
  900.  *
  901.  * Revision 1.26  2001/06/13 23:19:36  vakatov
  902.  * Revamped previous revision (prefix and error codes)
  903.  *
  904.  * Revision 1.25  2001/06/13 20:51:52  ivanov
  905.  * + PushDiagPostPrefix(), PopPushDiagPostPrefix() - stack post prefix messages.
  906.  * + ERR_POST_EX, LOG_POST_EX - macros for posting with error codes.
  907.  * + ErrCode(code[,subcode]) - CNcbiDiag error code manipulator.
  908.  * + eDPF_ErrCode, eDPF_ErrSubCode - new post flags.
  909.  *
  910.  * Revision 1.24  2001/05/17 14:50:58  lavr
  911.  * Typos corrected
  912.  *
  913.  * Revision 1.23  2000/11/29 16:58:23  vakatov
  914.  * Added LOG_POST() macro -- to print the posted message only
  915.  *
  916.  * Revision 1.22  2000/10/24 19:54:44  vakatov
  917.  * Diagnostics to go to CERR by default (was -- disabled by default)
  918.  *
  919.  * Revision 1.21  2000/04/18 19:50:10  vakatov
  920.  * Get rid of the old-fashioned C-like "typedef enum {...} E;"
  921.  *
  922.  * Revision 1.20  2000/04/04 22:31:57  vakatov
  923.  * SetDiagTrace() -- auto-set basing on the application
  924.  * environment and/or registry
  925.  *
  926.  * Revision 1.19  2000/03/10 14:17:40  vasilche
  927.  * Added missing namespace specifier to macro.
  928.  *
  929.  * Revision 1.18  2000/02/18 16:54:02  vakatov
  930.  * + eDiag_Critical
  931.  *
  932.  * Revision 1.17  2000/01/20 16:52:29  vakatov
  933.  * SDiagMessage::Write() to replace SDiagMessage::Compose()
  934.  * + operator<<(CNcbiOstream& os, const SDiagMessage& mess)
  935.  * + IsSetDiagHandler(), IsDiagStream()
  936.  *
  937.  * Revision 1.16  1999/12/29 22:30:22  vakatov
  938.  * Use "exit()" rather than "abort()" in non-#_DEBUG mode
  939.  *
  940.  * Revision 1.15  1999/12/28 18:55:24  vasilche
  941.  * Reduced size of compiled object files:
  942.  * 1. avoid inline or implicit virtual methods (especially destructors).
  943.  * 2. avoid std::string's methods usage in inline methods.
  944.  * 3. avoid string literals ("xxx") in inline methods.
  945.  *
  946.  * Revision 1.14  1999/12/27 19:44:15  vakatov
  947.  * Fixes for R1.13:
  948.  * ERR_POST() -- use eDPF_Default rather than eDPF_Trace;  forcibly flush
  949.  * ("<< Endm") the diag. stream. Get rid of the eDPF_CopyFilename, always
  950.  * make a copy of the file name.
  951.  *
  952.  * Revision 1.13  1999/09/27 16:23:20  vasilche
  953.  * Changed implementation of debugging macros (_TRACE, _THROW*, _ASSERT etc),
  954.  * so that they will be much easier for compilers to eat.
  955.  *
  956.  * Revision 1.12  1999/05/04 00:03:06  vakatov
  957.  * Removed the redundant severity arg from macro ERR_POST()
  958.  *
  959.  * Revision 1.11  1999/04/30 19:20:57  vakatov
  960.  * Added more details and more control on the diagnostics
  961.  * See #ERR_POST, EDiagPostFlag, and ***DiagPostFlag()
  962.  *
  963.  * Revision 1.10  1999/03/15 16:08:09  vakatov
  964.  * Fixed "{...}" macros to "do {...} while(0)" lest it to mess up with "if"s
  965.  *
  966.  * Revision 1.9  1999/03/12 18:04:06  vakatov
  967.  * Added ERR_POST macro to perform a plain "standard" error posting
  968.  *
  969.  * Revision 1.8  1998/12/30 21:52:16  vakatov
  970.  * Fixed for the new SunPro 5.0 beta compiler that does not allow friend
  971.  * templates and member(in-class) templates
  972.  *
  973.  * Revision 1.7  1998/12/28 17:56:27  vakatov
  974.  * New CVS and development tree structure for the NCBI C++ projects
  975.  *
  976.  * Revision 1.6  1998/11/06 22:42:37  vakatov
  977.  * Introduced BEGIN_, END_ and USING_ NCBI_SCOPE macros to put NCBI C++
  978.  * API to namespace "ncbi::" and to use it by default, respectively
  979.  * Introduced THROWS_NONE and THROWS(x) macros for the exception
  980.  * specifications
  981.  * Other fixes and rearrangements throughout the most of "corelib" code
  982.  *
  983.  * Revision 1.5  1998/11/04 23:46:35  vakatov
  984.  * Fixed the "ncbidbg/diag" header circular dependencies
  985.  *
  986.  * Revision 1.4  1998/11/03 20:51:24  vakatov
  987.  * Adaptation for the SunPro compiler glitchs(see conf. #NO_INCLASS_TMPL)
  988.  *
  989.  * Revision 1.3  1998/10/30 20:08:20  vakatov
  990.  * Fixes to (first-time) compile and test-run on MSVS++
  991.  *
  992.  * Revision 1.2  1998/10/27 23:06:58  vakatov
  993.  * Use NCBI C++ interface to iostream's
  994.  * ==========================================================================
  995.  */
  996. #endif  /* CORELIB___NCBIDIAG__HPP */