1 /*
2  *  This file is part of libcxxsupport.
3  *
4  *  libcxxsupport is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  libcxxsupport is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with libcxxsupport; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 
19 /*
20  *  libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
21  *  and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
22  *  (DLR).
23  */
24 
25 /*! \file error_handling.h
26  *  Utilities for error reporting
27  *
28  *  Copyright (C) 2003-2011 Max-Planck-Society
29  *  Authors: Reinhard Hell, Martin Reinecke
30  */
31 
32 #ifndef PLANCK_ERROR_HANDLING_H
33 #define PLANCK_ERROR_HANDLING_H
34 
35 #include <string>
36 #include <iostream>
37 
38 #if defined (__GNUC__)
39 #define PLANCK_FUNC_NAME__ __PRETTY_FUNCTION__
40 #else
41 #define PLANCK_FUNC_NAME__ 0
42 #endif
43 
44 void planck_failure__(const char *file, int line, const char *func,
45   const std::string &msg);
46 void planck_failure__(const char *file, int line, const char *func,
47   const char *msg);
48 void killjob__();
49 
50 class PlanckError
51   {
52   private:
53     std::string msg;
54 
55   public:
56     explicit PlanckError(const std::string &message);
57     explicit PlanckError(const char *message);
58 
what()59     virtual const char* what() const
60       { return msg.c_str(); }
61 
62     virtual ~PlanckError();
63   };
64 
65 /*! \defgroup errorgroup Error handling */
66 /*! \{ */
67 
68 /*! Writes diagnostic output and exits with an error status. */
69 #define planck_fail(msg) \
70 do { planck_failure__(__FILE__,__LINE__,PLANCK_FUNC_NAME__,msg); \
71 throw PlanckError(msg); } while(0)
72 
73 /*! Throws a PlanckError without diagnostic message. */
74 #define planck_fail_quietly(msg) \
75 do { throw PlanckError(msg); } while(0)
76 
77 /*! Writes diagnostic output and exits with an error status if \a testval
78     is \a false. */
79 #define planck_assert(testval,msg) \
80 do { if (testval); else planck_fail(msg); } while(0)
81 
82 /*! Macro for improving error diagnostics. Should be placed immediately
83     after the opening brace of \c main(). Must be used in conjunction with
84     \c PLANCK_DIAGNOSIS_END. */
85 #define PLANCK_DIAGNOSIS_BEGIN try {
86 /*! Macro for improving error diagnostics. Should be placed immediately
87     before the closing brace of \c main(). Must be used in conjunction with
88     \c PLANCK_DIAGNOSIS_BEGIN. */
89 #define PLANCK_DIAGNOSIS_END \
90 } \
91 catch (PlanckError &) \
92   { killjob__(); /* no need for further diagnostics; they were shown already */ } \
93 catch (std::exception &e) \
94   { std::cerr << "std::exception: " << e.what() << std::endl; killjob__(); } \
95 catch (...) \
96   { std::cerr << "Unknown exception" << std::endl; killjob__(); }
97 
98 /*! \} */
99 
100 #endif
101