You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
344 lines
13 KiB
344 lines
13 KiB
/* -*- c++ -*- (enables emacs c++ mode) */
|
|
/*===========================================================================
|
|
|
|
Copyright (C) 2002-2015 Yves Renard
|
|
|
|
This file is a part of GETFEM++
|
|
|
|
Getfem++ is free software; you can redistribute it and/or modify it
|
|
under the terms of the GNU Lesser General Public License as published
|
|
by the Free Software Foundation; either version 3 of the License, or
|
|
(at your option) any later version along with the GCC Runtime Library
|
|
Exception either version 3.1 or (at your option) any later version.
|
|
This program is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
License and GCC Runtime Library Exception for more details.
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with this program; if not, write to the Free Software Foundation,
|
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
As a special exception, you may use this file as it is a part of a free
|
|
software library without restriction. Specifically, if other files
|
|
instantiate templates or use macros or inline functions from this file,
|
|
or you compile this file and link it with other files to produce an
|
|
executable, this file does not by itself cause the resulting executable
|
|
to be covered by the GNU Lesser General Public License. This exception
|
|
does not however invalidate any other reasons why the executable file
|
|
might be covered by the GNU Lesser General Public License.
|
|
|
|
===========================================================================*/
|
|
|
|
/** @file gmm_except.h
|
|
@author Yves Renard <Yves.Renard@insa-lyon.fr>
|
|
@author Julien Pommier <Julien.Pommier@insa-toulouse.fr>
|
|
@date September 01, 2002.
|
|
@brief Definition of basic exceptions.
|
|
*/
|
|
|
|
#ifndef GMM_EXCEPT_H__
|
|
#define GMM_EXCEPT_H__
|
|
|
|
//provides external implementation of gmm_exception and logging.
|
|
#ifndef EXTERNAL_EXCEPT_
|
|
|
|
#include "gmm_std.h"
|
|
|
|
namespace gmm {
|
|
|
|
/* *********************************************************************** */
|
|
/* Getfem++ generic errors. */
|
|
/* *********************************************************************** */
|
|
|
|
class gmm_error: public std::logic_error {
|
|
public:
|
|
gmm_error(const std::string& what_arg): std::logic_error (what_arg) {}
|
|
};
|
|
|
|
#ifdef GETFEM_HAVE_PRETTY_FUNCTION
|
|
# define GMM_PRETTY_FUNCTION __PRETTY_FUNCTION__
|
|
#else
|
|
# define GMM_PRETTY_FUNCTION ""
|
|
#endif
|
|
|
|
// Errors : GMM_THROW should not be used on its own.
|
|
// GMM_ASSERT1 : Non-maskable errors. Typically for in/ouput and
|
|
// when the test do not significantly reduces the performance.
|
|
// GMM_ASSERT2 : All tests which are potentially performance
|
|
// consuming. Not hidden by default. Hidden when NDEBUG is
|
|
// defined.
|
|
// GMM_ASSERT3 : For internal checks. Hidden by default. Active
|
|
// only when DEBUG_MODE is defined.
|
|
// __EXCEPTIONS is defined by gcc, _CPPUNWIND is defined by visual c++
|
|
#if defined(__EXCEPTIONS) || defined(_CPPUNWIND)
|
|
inline void short_error_throw(const char *file, int line, const char *func,
|
|
const char *errormsg) {
|
|
std::stringstream msg__;
|
|
msg__ << "Error in " << file << ", line " << line << " " << func
|
|
<< ": \n" << errormsg << std::ends;
|
|
throw gmm::gmm_error(msg__.str());
|
|
}
|
|
# define GMM_THROW_(type, errormsg) { \
|
|
std::stringstream msg__; \
|
|
msg__ << "Error in " << __FILE__ << ", line " \
|
|
<< __LINE__ << " " << GMM_PRETTY_FUNCTION << ": \n" \
|
|
<< errormsg << std::ends; \
|
|
throw (type)(msg__.str()); \
|
|
}
|
|
#else
|
|
#ifndef _MSC_VER
|
|
# define abort_no_return() ::abort()
|
|
#else
|
|
// apparently ::abort() on windows is not declared with __declspec(noreturn) so the compiler spits a lot of warnings when abort is used.
|
|
# define abort_no_return() { assert("GMM ABORT"==0); throw "GMM ABORT"; }
|
|
#endif
|
|
|
|
inline void short_error_throw(const char *file, int line, const char *func,
|
|
const char *errormsg) {
|
|
std::stringstream msg__;
|
|
msg__ << "Error in " << file << ", line " << line << " " << func
|
|
<< ": \n" << errormsg << std::ends;
|
|
std::cerr << msg__.str() << std::endl;
|
|
abort_no_return();
|
|
}
|
|
|
|
# define GMM_THROW_(type, errormsg) { \
|
|
std::stringstream msg__; \
|
|
msg__ << "Error in " << __FILE__ << ", line " \
|
|
<< __LINE__ << " " << GMM_PRETTY_FUNCTION << ": \n" \
|
|
<< errormsg; \
|
|
std::cerr << msg__.str() << std::endl; \
|
|
abort_no_return(); \
|
|
}
|
|
#endif
|
|
|
|
# define GMM_ASSERT1(test, errormsg) \
|
|
{ if (!(test)) GMM_THROW_(gmm::gmm_error, errormsg); }
|
|
|
|
// inline void GMM_THROW() IS_DEPRECATED;
|
|
inline void GMM_THROW() {}
|
|
#define GMM_THROW(a, b) { GMM_THROW_(a,b); gmm::GMM_THROW(); }
|
|
|
|
#if defined(NDEBUG)
|
|
# define GMM_ASSERT2(test, errormsg) {}
|
|
# define GMM_ASSERT3(test, errormsg) {}
|
|
#elif !defined(GMM_FULL_NDEBUG)
|
|
# define GMM_ASSERT2(test, errormsg) \
|
|
{ if (!(test)) GMM_THROW_(gmm::gmm_error, errormsg); }
|
|
# define GMM_ASSERT3(test, errormsg) \
|
|
{ if (!(test)) GMM_THROW_(gmm::gmm_error, errormsg); }
|
|
#else
|
|
# define GMM_ASSERT2(test, errormsg) \
|
|
{ if (!(test)) GMM_THROW_(gmm::gmm_error, errormsg); }
|
|
# define GMM_ASSERT3(test, errormsg)
|
|
#endif
|
|
|
|
/* *********************************************************************** */
|
|
/* Getfem++ warnings. */
|
|
/* *********************************************************************** */
|
|
|
|
// This allows to dynamically hide warnings
|
|
struct warning_level {
|
|
static int level(int l = -2)
|
|
{ static int level_ = 3; return (l != -2) ? (level_ = l) : level_; }
|
|
};
|
|
|
|
inline void set_warning_level(int l) { warning_level::level(std::max(0,l)); }
|
|
inline int get_warning_level(void) { return warning_level::level(-2); }
|
|
|
|
// This allows not to compile some Warnings
|
|
#ifndef GMM_WARNING_LEVEL
|
|
# define GMM_WARNING_LEVEL 4
|
|
#endif
|
|
|
|
// Warning levels : 0 always printed
|
|
// 1 very important : specify a possible error in the code.
|
|
// 2 important : specify a default of optimization for inst.
|
|
// 3 remark
|
|
// 4 ignored by default.
|
|
|
|
#define GMM_WARNING_MSG(level_, thestr) { \
|
|
std::stringstream msg__; \
|
|
msg__ << "Level " << level_ << " Warning in " << __FILE__ << ", line " \
|
|
<< __LINE__ << ": " << thestr; \
|
|
std::cerr << msg__.str() << std::endl; \
|
|
}
|
|
|
|
#define GMM_WARNING0(thestr) GMM_WARNING_MSG(0, thestr)
|
|
|
|
#if GMM_WARNING_LEVEL > 0
|
|
# define GMM_WARNING1(thestr) \
|
|
{ if (1 <= gmm::warning_level::level()) GMM_WARNING_MSG(1, thestr) }
|
|
#else
|
|
# define GMM_WARNING1(thestr) {}
|
|
#endif
|
|
|
|
#if GMM_WARNING_LEVEL > 1
|
|
# define GMM_WARNING2(thestr) \
|
|
{ if (2 <= gmm::warning_level::level()) GMM_WARNING_MSG(2, thestr) }
|
|
#else
|
|
# define GMM_WARNING2(thestr) {}
|
|
#endif
|
|
|
|
#if GMM_WARNING_LEVEL > 2
|
|
# define GMM_WARNING3(thestr) \
|
|
{ if (3 <= gmm::warning_level::level()) GMM_WARNING_MSG(3, thestr) }
|
|
#else
|
|
# define GMM_WARNING3(thestr) {}
|
|
#endif
|
|
|
|
#if GMM_WARNING_LEVEL > 3
|
|
# define GMM_WARNING4(thestr) \
|
|
{ if (4 <= gmm::warning_level::level()) GMM_WARNING_MSG(4, thestr) }
|
|
#else
|
|
# define GMM_WARNING4(thestr) {}
|
|
#endif
|
|
|
|
/* *********************************************************************** */
|
|
/* Getfem++ traces. */
|
|
/* *********************************************************************** */
|
|
|
|
// This allows to dynamically hide traces
|
|
struct traces_level {
|
|
static int level(int l = -2)
|
|
{ static int level_ = 3; return (l != -2) ? (level_ = l) : level_; }
|
|
};
|
|
|
|
inline void set_traces_level(int l) { traces_level::level(std::max(0,l)); }
|
|
|
|
// This allow not too compile some Warnings
|
|
#ifndef GMM_TRACES_LEVEL
|
|
# define GMM_TRACES_LEVEL 4
|
|
#endif
|
|
|
|
// Traces levels : 0 always printed
|
|
// 1 Susceptible to occur once in a program.
|
|
// 2 Susceptible to occur occasionnaly in a program (10).
|
|
// 3 Susceptible to occur often (100).
|
|
// 4 Susceptible to occur very often (>1000).
|
|
|
|
#define GMM_TRACE_MSG_MPI // for Parallelized version
|
|
#define GMM_TRACE_MSG(level_, thestr) { \
|
|
GMM_TRACE_MSG_MPI { \
|
|
std::stringstream msg__; \
|
|
msg__ << "Trace " << level_ << " in " << __FILE__ << ", line " \
|
|
<< __LINE__ << ": " << thestr; \
|
|
std::cout << msg__.str() << std::endl; \
|
|
} \
|
|
}
|
|
|
|
#define GMM_TRACE0(thestr) GMM_TRACE_MSG(0, thestr)
|
|
|
|
#if GMM_TRACES_LEVEL > 0
|
|
# define GMM_TRACE1(thestr) \
|
|
{ if (1 <= gmm::traces_level::level()) GMM_TRACE_MSG(1, thestr) }
|
|
#else
|
|
# define GMM_TRACE1(thestr) {}
|
|
#endif
|
|
|
|
#if GMM_TRACES_LEVEL > 1
|
|
# define GMM_TRACE2(thestr) \
|
|
{ if (2 <= gmm::traces_level::level()) GMM_TRACE_MSG(2, thestr) }
|
|
#else
|
|
# define GMM_TRACE2(thestr) {}
|
|
#endif
|
|
|
|
#if GMM_TRACES_LEVEL > 2
|
|
# define GMM_TRACE3(thestr) \
|
|
{ if (3 <= gmm::traces_level::level()) GMM_TRACE_MSG(3, thestr) }
|
|
#else
|
|
# define GMM_TRACE3(thestr) {}
|
|
#endif
|
|
|
|
#if GMM_TRACES_LEVEL > 3
|
|
# define GMM_TRACE4(thestr) \
|
|
{ if (4 <= gmm::traces_level::level()) GMM_TRACE_MSG(4, thestr) }
|
|
#else
|
|
# define GMM_TRACE4(thestr) {}
|
|
#endif
|
|
|
|
|
|
/* ********************************************************************* */
|
|
/* Definitions for compatibility with old versions. */
|
|
/* ********************************************************************* */
|
|
|
|
using std::invalid_argument;
|
|
|
|
struct dimension_error : public std::logic_error
|
|
{ dimension_error(const std::string& w): std::logic_error(w) {} };
|
|
struct file_not_found_error : public std::logic_error
|
|
{ file_not_found_error(const std::string& w): std::logic_error (w) {} };
|
|
struct internal_error : public std::logic_error
|
|
{ internal_error(const std::string& w): std::logic_error(w) {} };
|
|
struct failure_error : public std::logic_error
|
|
{ failure_error(const std::string& w): std::logic_error (w) {} };
|
|
struct not_linear_error : public std::logic_error
|
|
{ not_linear_error(const std::string& w): std::logic_error (w) {} };
|
|
struct to_be_done_error : public std::logic_error
|
|
{ to_be_done_error(const std::string& w): std::logic_error (w) {} };
|
|
|
|
#define GMM_STANDARD_CATCH_ERROR catch(std::logic_error e) \
|
|
{ \
|
|
std::cerr << "============================================\n"; \
|
|
std::cerr << "| An error has been detected !!! |\n"; \
|
|
std::cerr << "============================================\n"; \
|
|
std::cerr << e.what() << std::endl << std::endl; \
|
|
exit(1); \
|
|
} \
|
|
catch(std::runtime_error e) \
|
|
{ \
|
|
std::cerr << "============================================\n"; \
|
|
std::cerr << "| An error has been detected !!! |\n"; \
|
|
std::cerr << "============================================\n"; \
|
|
std::cerr << e.what() << std::endl << std::endl; \
|
|
exit(1); \
|
|
} \
|
|
catch(std::bad_alloc) { \
|
|
std::cerr << "============================================\n"; \
|
|
std::cerr << "| A bad allocation has been detected !!! |\n"; \
|
|
std::cerr << "============================================\n"; \
|
|
exit(1); \
|
|
} \
|
|
catch(std::bad_typeid) { \
|
|
std::cerr << "============================================\n"; \
|
|
std::cerr << "| A bad typeid has been detected !!! |\n"; \
|
|
std::cerr << "============================================\n"; \
|
|
exit(1); \
|
|
} \
|
|
catch(std::bad_exception) { \
|
|
std::cerr << "============================================\n"; \
|
|
std::cerr << "| A bad exception has been detected !!! |\n"; \
|
|
std::cerr << "============================================\n"; \
|
|
exit(1); \
|
|
} \
|
|
catch(std::bad_cast) { \
|
|
std::cerr << "============================================\n"; \
|
|
std::cerr << "| A bad cast has been detected !!! |\n"; \
|
|
std::cerr << "============================================\n"; \
|
|
exit(1); \
|
|
} \
|
|
catch(...) { \
|
|
std::cerr << "============================================\n"; \
|
|
std::cerr << "| An unknown error has been detected !!! |\n"; \
|
|
std::cerr << "============================================\n"; \
|
|
exit(1); \
|
|
}
|
|
// catch(ios_base::failure) {
|
|
// std::cerr << "============================================\n";
|
|
// std::cerr << "| A ios_base::failure has been detected !!!|\n";
|
|
// std::cerr << "============================================\n";
|
|
// exit(1);
|
|
// }
|
|
|
|
#if defined(__GNUC__) && (__GNUC__ > 3)
|
|
# define GMM_SET_EXCEPTION_DEBUG \
|
|
std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
|
|
#else
|
|
# define GMM_SET_EXCEPTION_DEBUG
|
|
#endif
|
|
|
|
}
|
|
#else
|
|
#include <external_except.h>
|
|
#endif /* EXTERNAL_EXCEPT_*/
|
|
#endif /* GMM_EXCEPT_H__ */
|