bpp-core3  3.0.0
Exceptions.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
5 #include <cxxabi.h> // for __cxa_demangle
6 #include <dlfcn.h> // for dladdr
7 #include <execinfo.h>
8 #include <iostream>
9 #include <string>
10 #include <utility>
11 
12 #include "Exceptions.h"
13 
14 namespace bpp
15 {
16 Exception::Exception(std::string text, int stack)
17  : message_(std::move(text))
18 {
19  void* buffer[stack];
20  char** strings;
21 
22  int nptrs = backtrace(buffer, stack);
23  /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
24  would produce similar output to the following: */
25 
26  strings = backtrace_symbols(buffer, nptrs);
27 
28  for (int j = 2; j < nptrs - 2; j++)
29  {
30  message_ += "\n\tfrom ";
31 
32  std::string beginName = "";
33 
34  // find parentheses of the function surrounding the mangled name:
35  // ./module(function(...)+0x15c) [0x8048a6d]
36  bool dep = false;
37 
38  for (char* p = strings[j]; *p; ++p)
39  {
40  if (*p == '+')
41  break;
42  if ((*p == '(') && !dep)
43  dep = true;
44  else if (dep)
45  beginName += *p;
46  }
47 
48  // mangled name is now in [begin_name, end_name), now apaply
49  // __cxa_demangle():
50 
51  int status;
52 
53  char* ret = abi::__cxa_demangle(beginName.c_str(),
54  NULL, NULL, &status);
55  beginName = "";
56  if (status == 0)
57  {
58  for (char* p = ret; *p; ++p) // look for "("
59  {
60  if (*p == '(')
61  break;
62  else
63  beginName += *p;
64  }
65 
66  message_ += beginName;
67  }
68  else
69  {
70  message_ += strings[j];
71  }
72  }
73 
74  free(strings);
75 }
76 
77 
78 const char* Exception::what() const noexcept { return message_.c_str(); }
79 const std::string& Exception::message() const noexcept { return message_; }
80 
81 IOException::IOException(std::string text)
82  : Exception(std::move(text))
83 {}
84 
86  : Exception(std::move(text))
87 {}
88 
90  : Exception(std::move(text))
91 {}
92 
93 BadIntegerException::BadIntegerException(std::string text, int badInt)
94  : Exception(text + " (" + std::to_string(badInt) + ")")
95  , badInt_(badInt)
96 {}
98 
99 BadNumberException::BadNumberException(std::string text, double badNumber)
100  : Exception(text + " (" + std::to_string(badNumber) + ")")
101  , badNumber_(badNumber)
102 {}
104 
105 NumberFormatException::NumberFormatException(std::string text, std::string badNumber)
106  : Exception(text + " (" + badNumber + ")")
107  , badNumber_(badNumber)
108 {}
109 const std::string& NumberFormatException::getBadNumber() const { return badNumber_; }
110 
111 IndexOutOfBoundsException::IndexOutOfBoundsException(std::string text, std::size_t badInt, std::size_t lowerBound,
112  std::size_t upperBound)
113  : Exception(std::to_string(badInt) + " out of [" + std::to_string(lowerBound) + ", " + std::to_string(upperBound) + "] " + std::move(text))
114  , badIndex_(badInt)
115  , bounds_{{lowerBound, upperBound}}
116 {}
117 
118 const std::array<std::size_t, 2>& IndexOutOfBoundsException::getBounds() const { return bounds_; }
119 std::size_t IndexOutOfBoundsException::getBadIndex() const { return badIndex_; }
120 
121 BadSizeException::BadSizeException(std::string text, std::size_t badSize, std::size_t correctSize)
122  : Exception("Incorrect size " + std::to_string(badSize) + ", expected " + std::to_string(correctSize) + ". " + text)
123  , badSize_(badSize)
124  , correctSize_(correctSize)
125 {}
126 std::size_t BadSizeException::getBadSize() const { return badSize_; }
127 std::size_t BadSizeException::getCorrectSize() const { return correctSize_; }
128 
129 OutOfRangeException::OutOfRangeException(std::string text, double badValue, double lowerBound, double upperBound)
130  : Exception(std::to_string(badValue) + " out of [" + std::to_string(lowerBound) + ", " +
131  std::to_string(upperBound) + "]" + std::move(text))
132  , badValue_(badValue)
133  , bounds_{{lowerBound, upperBound}}
134 {}
135 double OutOfRangeException::getBadValue() const { return badValue_; }
136 double OutOfRangeException::getLowerBound() const { return bounds_[0]; }
137 double OutOfRangeException::getUpperBound() const { return bounds_[1]; }
138 
140  : Exception(std::move(text))
141 {}
142 } // namespace bpp
const std::string & message() const noexcept
Access the message as a std::string.
Definition: Exceptions.cpp:79
Exception(std::string text, int stack=10)
Build a new Exception.
Definition: Exceptions.cpp:16
NotImplementedException(std::string text)
Build a new NotImplementedException.
Definition: Exceptions.cpp:139
std::size_t getBadSize() const
Definition: Exceptions.cpp:126
const char * what() const noexcept override
Method to get the message of the exception (STL method redefinition).
Definition: Exceptions.cpp:78
std::size_t badSize_
Definition: Exceptions.h:154
double getBadValue() const
Definition: Exceptions.cpp:135
const std::string & getBadNumber() const
Get the number that threw this exception.
Definition: Exceptions.cpp:109
std::array< double, 2 > bounds_
Definition: Exceptions.h:174
STL namespace.
double getUpperBound() const
Definition: Exceptions.cpp:137
double getLowerBound() const
Definition: Exceptions.cpp:136
std::size_t correctSize_
Definition: Exceptions.h:155
int getBadInteger() const
Get the integer that threw this exception.
Definition: Exceptions.cpp:97
std::size_t getCorrectSize() const
Definition: Exceptions.cpp:127
double getBadNumber() const
Get the number that threw this exception.
Definition: Exceptions.cpp:103
BadSizeException(std::string text, std::size_t badSize, std::size_t correctSize)
Build a new BadSizeException.
Definition: Exceptions.cpp:121
IndexOutOfBoundsException(std::string text, std::size_t badInt, std::size_t lowerBound, std::size_t upperBound)
Build a new IndexOutOfBoundsException.
Definition: Exceptions.cpp:111
IOException(std::string text)
Build a new IOException.
Definition: Exceptions.cpp:81
NumberFormatException(std::string text, std::string badNumber)
Build a new NumberFormatException.
Definition: Exceptions.cpp:105
std::string message_
Definition: Exceptions.h:23
std::array< std::size_t, 2 > bounds_
Definition: Exceptions.h:135
NullPointerException(std::string text)
Build a new NullPointerException.
Definition: Exceptions.cpp:85
Exception base class. Overload exception constructor (to control the exceptions mechanism). Destructor is already virtual (from std::exception)
Definition: Exceptions.h:20
std::size_t getBadIndex() const
Definition: Exceptions.cpp:119
OutOfRangeException(std::string text, double badValue, double lowerBound, double upperBound)
Build a new OutOfRangeException.
Definition: Exceptions.cpp:129
const std::array< std::size_t, 2 > & getBounds() const
Get the bounds.
Definition: Exceptions.cpp:118
ZeroDivisionException(std::string text)
Build a new ZeroDivisionException.
Definition: Exceptions.cpp:89
BadIntegerException(std::string text, int badInt)
Build a new BadIntegerException.
Definition: Exceptions.cpp:93
BadNumberException(std::string text, double badNumber)
Build a new BadNumberException.
Definition: Exceptions.cpp:99