MechSys  1.0
Computing library for simulations in continuum and discrete mechanics
/home/dorival/mechsys/lib/util/fatal.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines