1 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2    Copyright (c) 2012-2021 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 #include "Exception.h"
23 
24 #if defined(__PLUMED_HAS_EXECINFO)
25 #include <execinfo.h>
26 #endif
27 
28 #include <cstdio>
29 #include <cstring>
30 #include <cstdlib>
31 
32 using namespace std;
33 namespace PLMD {
34 
Exception()35 Exception::Exception():
36   note(true)
37 {
38 #ifdef __PLUMED_HAS_EXECINFO
39   {
40     void* callstack[128];
41     int frames = backtrace(callstack, 128);
42     char** strs = backtrace_symbols(callstack, frames);
43     for (int i = 0; i < frames; ++i) {stackString+=strs[i]; stackString+="\n";}
44     free(strs);
45   }
46 #endif
47   const char* env=getenv("PLUMED_STACK_TRACE");
48   if(stackString.length()>0 && env && !strcmp(env,"yes")) {
49     msg+="\n\n********** STACK DUMP **********\n";
50     msg+=stackString;
51     msg+="\n********** END STACK DUMP **********\n";
52   }
53   msg+="\n+++ PLUMED error";
54 }
55 
operator <<(const std::string & msg)56 Exception& Exception::operator<<(const std::string&msg)
57 {
58   if(msg.length()>0) {
59     if(note) this->msg +="\n+++ message follows +++\n";
60     this->msg +=msg;
61     note=false;
62   }
63   return *this;
64 }
65 
operator <<(const Location & loc)66 Exception& Exception::operator<<(const Location&loc)
67 {
68   if(loc.file) {
69     char cline[1000];
70     sprintf(cline,"%u",loc.line);
71     this->msg += "\n+++ at ";
72     this->msg += loc.file;
73     this->msg += ":";
74     this->msg += cline;
75     if(loc.pretty && loc.pretty[0]) {
76       this->msg += ", function ";
77       this->msg += loc.pretty;
78     }
79   }
80   note=true;
81   return *this;
82 }
83 
operator <<(const Assertion & as)84 Exception& Exception::operator<<(const Assertion&as)
85 {
86   if(as.assertion) {
87     this->msg += "\n+++ assertion failed: ";
88     this->msg += as.assertion;
89   }
90   note=true;
91   return *this;
92 }
93 
94 }
95 
96 
97