1 /*
2  * Copyright (C) 2017 Matthieu Gautier <mgautier@kymeria.fr>
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
11  * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
12  * NON-INFRINGEMENT.  See the GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
17  *
18  */
19 
20 #ifndef DEBUG_H_
21 #define DEBUG_H_
22 
23 #include <iostream>
24 #include <sstream>
25 #include <stdlib.h>
26 
27 #if defined (NDEBUG)
28 # define ASSERT(left, operator, right) (void(0))
29 #else
30 
31 #if !defined(_WIN32) && !defined(__APPLE__) && !defined(__ANDROID__)
32 #include <execinfo.h>
33 #endif
34 
35 template<typename T, typename U>
_on_assert_fail(const char * vara,const char * op,const char * varb,T a,U b,const char * file,int line)36 void _on_assert_fail(const char* vara, const char* op, const char* varb,
37                      T a, U b, const char* file, int line)  {
38   std::ostringstream ss;
39   ss << "\nAssertion failed at "<< file << ":" << line << "\n " <<
40       vara << "[" << a << "] " << op << " " << varb << "[" << b << "]";
41   std::cerr << ss.str() << std::endl;
42 
43 #if !defined(_WIN32) && !defined(__APPLE__) && !defined(__ANDROID__)
44   void *callstack[64];
45   size_t size;
46   size = backtrace(callstack, 64);
47   char** strings = backtrace_symbols(callstack, size);
48   for (size_t i=0; i<size; i++) {
49     std::cerr << strings[i] << std::endl;
50   }
51   free(strings);
52 #endif
53   throw std::runtime_error(ss.str());
54 }
55 
56 # define ASSERT(left, operator, right) do { auto _left = left; auto _right = right; if (!((_left) operator (_right))) _on_assert_fail(#left, #operator, #right, _left, _right, __FILE__, __LINE__);  } while(0)
57 
58 #endif
59 
60 #endif
61