LCOV - code coverage report
Current view: top level - tools - Exception.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 1 3 33.3 %
Date: 2020-11-18 11:20:57 Functions: 1 4 25.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2012-2019 The plumed team
       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
       4             : 
       5             :    See http://www.plumed.org for more information.
       6             : 
       7             :    This file is part of plumed, version 2.
       8             : 
       9             :    plumed is free software: you can redistribute it and/or modify
      10             :    it under the terms of the GNU Lesser General Public License as published by
      11             :    the Free Software Foundation, either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    plumed is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU Lesser General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU Lesser General Public License
      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      22             : #ifndef __PLUMED_tools_Exception_h
      23             : #define __PLUMED_tools_Exception_h
      24             : 
      25             : #include <string>
      26             : #include <stdexcept>
      27             : 
      28             : namespace PLMD {
      29             : 
      30             : /**
      31             : \ingroup TOOLBOX
      32             : Class to deal with Plumed runtime errors.
      33             : 
      34             : This class, or better the related macros, can be used to detect programming
      35             : errors. Typical cases are internal inconsistencies or errors in the plumed<->MD
      36             : interface. Mistakes made by final users (i.e. in the plumed.dat file)
      37             : should be documented in some better way (e.g. printing parts of the manual in the output).
      38             : 
      39             : To throw an error, just throw a c++ exception
      40             : \verbatim
      41             :   if(something_bad) throw Exception();
      42             : \endverbatim
      43             : or better add an error message to that
      44             : \verbatim
      45             :   if(something_bad) throw Exception("describe the error here);
      46             : \endverbatim
      47             : 
      48             : Even better, you can use the predefined macros
      49             : plumed_error(), plumed_assert(), plumed_merror() and plumed_massert(),
      50             : which add information about the exact location of the error in the file (filename, line
      51             : and, for g++, function name). Macros ending in "error" unconditionally throw
      52             : the exception, whereas macros ending in "assert" first perform a conditional check
      53             : (similarly to standard assert()). The extra "m" in the name means that an
      54             : extensive error message can be added.
      55             : \verbatim
      56             : // examples:
      57             :   plumed_assert(a>0);
      58             :   plumed_massert(a>0,"a should be larger than zero");
      59             :   if(a<=0) plumed_error();
      60             :   if(a<=0) plumed_merror("a should be larger than zero");
      61             : \endverbatim
      62             : The additional macros
      63             : plumed_dbg_assert() and plumed_dbg_massert() are similar
      64             : to plumed_assert() and plumed_massert() respectively, but the corresponding
      65             : check is only performed when NDEBUG macro is not defined. They should
      66             : be used when the check is expensive and should be skipped in production
      67             : code.
      68             : 
      69             : By default, execution is terminated imediately and a message is printed on stderr.
      70             : 
      71             : If PLUMED is compiled with -D__PLUMED_EXCEPTIONS execution will continue
      72             : and the exception will be passed to c++, so that it will be possible
      73             : to intercepted it at a higher level, even outside plumed.
      74             : E.g., in an external c++ code using PLUMED as a library, one can type
      75             : \verbatim
      76             :   try{
      77             :     plumed.cmd("setPrecision",n);
      78             :   } catch (std::exception & e) {
      79             :     printf("ee %s",e.what());
      80             :     exit(1);
      81             :   }
      82             : \endverbatim
      83             : This can be useful if an external code wants to exit in a controlled manner
      84             : (e.g. flushing files, printing the error message in a specific file, etc.)
      85             : but is anyway limited to c++ codes. Moreover,
      86             : since these errors are expected to be unrecoverable, the MD code will
      87             : usually not be able to do something more clever than exiting.
      88             : 
      89             : \note
      90             : In the future we might decide to extend the usage of exceptions to
      91             : detect recoverable errors (e.g. optional arguments not found, etc),
      92             : even if I am not fully convinced that this is a good idea.
      93             : Notice that sometime people claim that code compiled with exception enabled
      94             : is slower (GB)
      95             : */
      96             : class Exception : public std::exception
      97             : {
      98             : /// Stack trace at exception
      99             :   std::string stackString;
     100             : /// Reported message
     101             :   std::string msg;
     102             : /// Create stack trace
     103             :   static std::string trace();
     104             : /// Common tool, invoked by all the constructor to build the message string
     105             :   static std::string format(const std::string&,const std::string&,unsigned,const std::string&);
     106             : /// Method which aborts in case exceptions are disabled
     107             :   void abortIfExceptionsAreDisabled();
     108             : public:
     109             : /// Without message
     110             :   Exception();
     111             : /// With message
     112             :   explicit Exception(const std::string&);
     113             : /// With message plus file, line and function (meant to be used through a preprocessor macro)
     114             :   Exception(const std::string&,const std::string&,unsigned,const std::string&);
     115             : /// Returns the error message.
     116             : /// In case the environment variable PLUMED_STACK_TRACE is defined, the error
     117             : /// message will contain the stack trace as well.
     118           0 :   virtual const char* what() const throw() {return msg.c_str();}
     119             : /// Returns the stack trace
     120           0 :   virtual const char* stack() const throw() {return stackString.c_str();}
     121             : /// Destructor should be defined and should not throw other exceptions
     122          96 :   virtual ~Exception() throw() {}
     123             : };
     124             : 
     125             : // With GNU compiler, we can use __PRETTY_FUNCTION__ to get the function name
     126             : #if !defined(__PRETTY_FUNCTION__)
     127             : #define __PRETTY_FUNCTION__ ""
     128             : #endif
     129             : 
     130             : /// \relates PLMD::Exception
     131             : /// Just print file/line/function information and exit
     132             : #define plumed_error() throw PLMD::Exception("",__FILE__,__LINE__,__PRETTY_FUNCTION__)
     133             : /// \relates PLMD::Exception
     134             : /// Print file/line/function information plus msg and exit
     135             : #define plumed_merror(msg) throw PLMD::Exception(msg,__FILE__,__LINE__,__PRETTY_FUNCTION__)
     136             : /// \relates PLMD::Exception
     137             : /// Conditionally print file/line/function information and exit
     138             : #define plumed_assert(test) if(!(test)) throw PLMD::Exception("assertion failed " #test,__FILE__,__LINE__,__PRETTY_FUNCTION__)
     139             : /// \relates PLMD::Exception
     140             : /// Conditionally print file/line/function information plus msg and exit
     141             : #define plumed_massert(test,msg) if(!(test)) throw PLMD::Exception("assertion failed " #test ", " msg,__FILE__,__LINE__,__PRETTY_FUNCTION__)
     142             : 
     143             : #ifdef NDEBUG
     144             : #define plumed_dbg_assert(test)
     145             : #define plumed_dbg_massert(test,msg)
     146             : #else
     147             : /// \relates PLMD::Exception
     148             : /// Conditionally print file/line/function information and exit when NDEBUG flag is not present
     149             : #define plumed_dbg_assert(test) if(!(test)) throw PLMD::Exception("assertion failed " #test,__FILE__,__LINE__,__PRETTY_FUNCTION__)
     150             : /// \relates PLMD::Exception
     151             : /// Conditionally print file/line/function information plus msg and exit when NDEBUG flag is not present
     152             : #define plumed_dbg_massert(test,msg) if(!(test)) throw PLMD::Exception("assertion failed " #test ", " msg,__FILE__,__LINE__,__PRETTY_FUNCTION__)
     153             : #endif
     154             : 
     155             : }
     156             : #endif

Generated by: LCOV version 1.13