]> git.lyx.org Git - lyx.git/blob - src/support/lassert.cpp
Provide proper fallback if a bibliography processor is not found
[lyx.git] / src / support / lassert.cpp
1 /**
2  * \file lassert.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author André Pönitz
7  * \author Peter Kümmel
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13 #include <lassert.h>
14
15 #include "support/convert.h"
16 #include "support/debug.h"
17 #include "support/docstring.h"
18 #include "support/ExceptionMessage.h"
19 #include "support/gettext.h"
20 #include "support/lstrings.h"
21
22 #include <boost/assert.hpp>
23
24 #include <QString>
25
26 #ifdef LYX_CALLSTACK_PRINTING
27 #include <cstdio>
28 #include <cstdlib>
29 #include <execinfo.h>
30 #include <cxxabi.h>
31 #endif
32
33
34 namespace lyx {
35
36 using namespace std;
37 using namespace support;
38
39
40 void doAssertWithCallstack(bool value)
41 {
42         if (!value) {
43                 printCallStack();
44                 BOOST_ASSERT(false);
45         }
46 }
47
48
49 void doAssert(char const * expr, char const * file, long line)
50 {
51         LYXERR0("ASSERTION " << expr << " VIOLATED IN " << file << ":" << line);
52         // comment this out if not needed
53         doAssertWithCallstack(false);
54 }
55
56
57 docstring formatHelper(docstring const & msg,
58         char const * expr, char const * file, long line)
59 {
60         docstring const d = _("Assertion %1$s violated in\nfile: %2$s, line: %3$s");
61         LYXERR0("ASSERTION " << expr << " VIOLATED IN " << file << ":" << line);
62
63         return bformat(d, from_ascii(expr), from_ascii(file),
64                 convert<docstring>(line)) + '\n' + msg;
65 }
66
67
68 void doWarnIf(char const * expr, char const * file, long line)
69 {
70         docstring const d = _("It should be safe to continue, but you\nmay wish to save your work and restart LyX.");
71         // comment this out if not needed
72         doAssertWithCallstack(false);
73         throw ExceptionMessage(WarningException, _("Warning!"),
74                 formatHelper(d, expr, file, line));
75 }
76
77
78 void doBufErr(char const * expr, char const * file, long line)
79 {
80         docstring const d = _("There has been an error with this document.\nLyX will attempt to close it safely.");
81         // comment this out if not needed
82         doAssertWithCallstack(false);
83         throw ExceptionMessage(BufferException, _("Buffer Error!"),
84                 formatHelper(d, expr, file, line));
85 }
86
87
88 void doAppErr(char const * expr, char const * file, long line)
89 {
90         docstring const d = _("LyX has encountered an application error\nand will now shut down.");
91         // comment this out if not needed
92         doAssertWithCallstack(false);
93         throw ExceptionMessage(ErrorException, _("Fatal Exception!"),
94                 formatHelper(d, expr, file, line));
95 }
96
97
98 docstring printCallStack()
99 {
100 #ifndef LYX_CALLSTACK_PRINTING
101         return docstring();
102 #else
103         const int depth = 200;
104
105         // get void*'s for all entries on the stack
106         void* array[depth];
107         size_t size = backtrace(array, depth);
108
109         char** messages = backtrace_symbols(array, size);
110
111         docstring bt;
112         for (size_t i = 1; i < size && messages != NULL; i++) {
113                 const std::string orig(messages[i]);
114                 char* mangled = 0;
115                 for (char *p = messages[i]; *p; ++p) {
116                         if (*p == '(') {
117                                 *p = 0;
118                                 mangled = p + 1;
119                         } else if (*p == '+') {
120                                 *p = 0;
121                                 break;
122                         }
123                 }
124                 int status = 0;
125                 const char* demangled = abi::__cxa_demangle(mangled, 0, 0, &status);
126                 const QByteArray line = QString("(%1) %2: %3\n").arg(i, 3).arg(messages[i])
127                                                                 .arg(demangled ? demangled : orig.c_str()).toLocal8Bit();
128                 free((void*)demangled);
129
130                 fprintf(stderr, "%s", line.constData());
131                 bt += from_local8bit(line.constData());
132         }
133                 return bt;
134 #endif
135 }
136
137 } // namespace lyx