Merge remote-tracking branch 'origin/release-4-6' into HEAD
[alexxy/gromacs.git] / src / gromacs / utility / exceptions.cpp
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11  * Copyright (c) 2001-2009, The GROMACS development team,
12  * check out http://www.gromacs.org for more information.
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * If you want to redistribute modifications, please consider that
20  * scientific software is very special. Version control is crucial -
21  * bugs must be traceable. We will be happy to consider code for
22  * inclusion in the official distribution, but derived work must not
23  * be called official GROMACS. Details are found in the README & COPYING
24  * files - if they are missing, get the official version at www.gromacs.org.
25  *
26  * To help us fund GROMACS development, we humbly ask that you cite
27  * the papers on the package - you can find them in the top README file.
28  *
29  * For more info, check our website at http://www.gromacs.org
30  */
31 /*! \internal \file
32  * \brief
33  * Implements classes and functions in exceptions.h.
34  *
35  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36  * \ingroup module_utility
37  */
38 #include "gromacs/utility/exceptions.h"
39
40 #include <boost/exception/get_error_info.hpp>
41
42 #include "gromacs/utility/errorcodes.h"
43
44 #include "errorformat.h"
45
46 namespace gmx
47 {
48
49 /********************************************************************
50  * GromacsException
51  */
52
53 GromacsException::GromacsException(const std::string &reason)
54 {
55     *this << errinfo_message(reason);
56 }
57
58 const char *GromacsException::what() const throw()
59 {
60     const std::string *msg = boost::get_error_info<errinfo_message>(*this);
61     return msg != NULL ? msg->c_str() : "No reason provided";
62 }
63
64 /********************************************************************
65  * Derived exception classes
66  */
67
68 int FileIOError::errorCode() const
69 {
70     return eeFileIO;
71 }
72
73 int InvalidInputError::errorCode() const
74 {
75     return eeInvalidInput;
76 }
77
78 int InconsistentInputError::errorCode() const
79 {
80     return eeInconsistentInput;
81 }
82
83 int SimulationInstabilityError::errorCode() const
84 {
85     return eeInstability;
86 }
87
88 int InternalError::errorCode() const
89 {
90     return eeInternalError;
91 }
92
93 int APIError::errorCode() const
94 {
95     return eeAPIError;
96 }
97
98 int NotImplementedError::errorCode() const
99 {
100     return eeNotImplemented;
101 }
102
103
104 /********************************************************************
105  * Global functions
106  */
107
108 void printFatalErrorMessage(FILE *fp, const std::exception &ex)
109 {
110     const char *title = "Unknown exception";
111     const GromacsException *gmxEx = dynamic_cast<const GromacsException *>(&ex);
112     // TODO: Also treat common standard exceptions
113     if (gmxEx != NULL)
114     {
115         title = getErrorCodeString(gmxEx->errorCode());
116     }
117     else if (dynamic_cast<const std::bad_alloc *>(&ex) != NULL)
118     {
119         title = "Memory allocation failed";
120     }
121     // We can't call get_error_info directly on ex since our internal boost
122     // needs to be compiled with BOOST_NO_RTTI. So we do the dynamic_cast
123     // here instead.
124     const char *const *funcPtr = NULL;
125     const char *const *filePtr = NULL;
126     const int         *linePtr = NULL;
127     const boost::exception *boostEx = dynamic_cast<const boost::exception *>(&ex);
128     if (boostEx != NULL)
129     {
130         funcPtr = boost::get_error_info<boost::throw_function>(*boostEx);
131         filePtr = boost::get_error_info<boost::throw_file>(*boostEx);
132         linePtr = boost::get_error_info<boost::throw_line>(*boostEx);
133     }
134     // TODO: Treat errno information in boost exceptions
135     internal::printFatalError(fp, title, ex.what(),
136                               funcPtr != NULL ? *funcPtr : NULL,
137                               filePtr != NULL ? *filePtr : NULL,
138                               linePtr != NULL ? *linePtr : 0);
139 }
140
141 } // namespace gmx