![]() |
MechSys
1.0
Computing library for simulations in continuum and discrete mechanics
|
00001 /************************************************************************ 00002 * MechSys - Open Library for Mechanical Systems * 00003 * Copyright (C) 2005 Dorival M. Pedroso, Raul Durand * 00004 * Copyright (C) 2009 Sergio Galindo * 00005 * * 00006 * This program is free software: you can redistribute it and/or modify * 00007 * it under the terms of the GNU General Public License as published by * 00008 * the Free Software Foundation, either version 3 of the License, or * 00009 * any later version. * 00010 * * 00011 * This program is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00014 * GNU General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU General Public License * 00017 * along with this program. If not, see <http://www.gnu.org/licenses/> * 00018 ************************************************************************/ 00019 00020 #ifndef MECHSYS_FATAL_H 00021 #define MECHSYS_FATAL_H 00022 00023 // Std lib 00024 #include <iostream> // for cout 00025 #include <cstdarg> // for va_list, va_start, va_end 00026 #include <exception> 00027 00028 // MechSys 00029 #include <mechsys/util/string.h> 00030 00031 // Global variable to tell 'catch' that parallel code is activated 00032 bool MECHSYS_CATCH_PARALLEL = false; 00033 00034 // MPI 00035 #ifdef HAS_MPI 00036 #include <mpi.h> 00037 #define MECHSYS_FINALIZE if (MECHSYS_CATCH_PARALLEL) MPI::COMM_WORLD.Abort(666); return 1; 00038 #define MECHSYS_MPI_CATCH catch (MPI::Exception e) { printf("%sFatal: MPI Error # %d : %s%s\n",TERM_RED,e.Get_error_code(),e.Get_error_string(),TERM_RST); MECHSYS_FINALIZE } 00039 #define MECHSYS_MPI_INIT MPI::Init(argc, argv); \ 00040 MPI::COMM_WORLD.Set_errhandler(MPI::ERRORS_THROW_EXCEPTIONS); 00041 #else 00042 #define MECHSYS_FINALIZE return 1; 00043 #define MECHSYS_MPI_CATCH 00044 #define MECHSYS_MPI_INIT 00045 #endif 00046 00047 // Boost::Python 00048 #ifdef USE_BOOST_PYTHON 00049 #include <boost/python/errors.hpp> 00050 #include <boost/python/str.hpp> 00051 namespace BPy = boost::python; 00052 #define MECHSYS_BPY_CATCH catch (BPy::error_already_set) { printf("%sFatal: ",TERM_RED); PyErr_Print(); printf("%s\n",TERM_RST); MECHSYS_FINALIZE } 00053 #else 00054 #define MECHSYS_BPY_CATCH 00055 #endif 00056 00057 // Catch structure 00058 #define MECHSYS_CATCH catch (Fatal * e) { e->Cout(); delete e; MECHSYS_FINALIZE } \ 00059 catch (char const * m) { printf("%sFatal: %s%s\n",TERM_RED,m ,TERM_RST); MECHSYS_FINALIZE } \ 00060 catch (std::exception & e) { printf("%sFatal: %s%s\n",TERM_RED,e.what(),TERM_RST); MECHSYS_FINALIZE } \ 00061 MECHSYS_MPI_CATCH \ 00062 MECHSYS_BPY_CATCH \ 00063 catch (...) { printf("%sFatal: Some exception (...) occurred%s\n",TERM_RED,TERM_RST); MECHSYS_FINALIZE } 00064 00065 class Fatal 00066 { 00067 public: 00068 // Constructor 00069 Fatal (String const & Fmt, ...); 00070 00071 // Methods 00072 void Cout () const { printf("%sFatal: %s%s\n", TERM_RED, _msg.CStr(), TERM_RST); } 00073 String Msg () const { return _msg; } 00074 00075 private: 00076 String _msg; 00077 }; 00078 00079 00081 00082 00083 inline Fatal::Fatal(String const & Fmt, ...) 00084 { 00085 va_list arg_list; 00086 va_start (arg_list, Fmt); 00087 _msg.PrintfV (Fmt, arg_list); 00088 va_end (arg_list); 00089 } 00090 00091 00092 #ifdef USE_BOOST_PYTHON 00093 00094 void PyExceptTranslator (Fatal * e) 00095 { 00096 PyErr_SetString(PyExc_UserWarning, e->Msg().CStr()); 00097 delete e; 00098 } 00099 00100 #endif // USE_BOOST_PYTHON 00101 00102 00103 #endif // MECHSYS_FATAL_H