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