#include <config.h>
+#include "support/convert.h"
#include "support/debug.h"
+#include "support/docstring.h"
+#include "support/ExceptionMessage.h"
+#include "support/gettext.h"
+#include "support/lstrings.h"
#include <boost/assert.hpp>
namespace lyx {
-void doAssert(char const * expr, char const * file, long line)
+using namespace std;
+using namespace support;
+
+// TODO Should we try to print the call stack in the course of these?
+
+void doAssert(char const * expr, char const * file, long line)
+{
+ LYXERR0("ASSERTION " << expr << " VIOLATED IN " << file << ":" << line);
+ // comment this out if not needed
+ BOOST_ASSERT(false);
+}
+
+
+docstring formatHelper(docstring const & msg,
+ char const * expr, char const * file, long line)
{
- // TODO Should we try to print the call stack before exiting?
+ static const docstring d =
+ from_ascii(N_("Assertion %1$s violated in\nfile: %2$s, line: %3$s"));
+
+ return bformat(d, from_ascii(expr), from_ascii(file),
+ convert<docstring>(line)) + '\n' + msg;
+}
+
+void doWarnIf(char const * expr, docstring const & msg, char const * file, long line)
+{
+ LYXERR0("ASSERTION " << expr << " VIOLATED IN " << file << ":" << line);
+ // comment this out if not needed
+ BOOST_ASSERT(false);
+ throw ExceptionMessage(WarningException, _("Warning!"),
+ formatHelper(msg, expr, file, line));
+}
+
+
+void doBufErr(char const * expr, docstring const & msg, char const * file, long line)
+{
+ LYXERR0("ASSERTION " << expr << " VIOLATED IN " << file << ":" << line);
+ // comment this out if not needed
+ BOOST_ASSERT(false);
+ throw ExceptionMessage(BufferException, _("Buffer Error!"),
+ formatHelper(msg, expr, file, line));
+}
+
+
+void doAppErr(char const * expr, docstring const & msg, char const * file, long line)
+{
LYXERR0("ASSERTION " << expr << " VIOLATED IN " << file << ":" << line);
// comment this out if not needed
BOOST_ASSERT(false);
+ throw ExceptionMessage(ErrorException, _("Fatal Exception!"),
+ formatHelper(msg, expr, file, line));
}
-// -*- C++ -*-
+
/**
* \file support/lassert.h
*
#define LASSERT_H
#ifdef __cplusplus
+
+#include "support/strfwd.h"
+
namespace lyx {
+/******************************************************************************
+
+LyX has five different macros that can be used to make assertions. The behave
+the same way in devel mode: They assert. The differences between them are how
+they behave in release mode.
+
+In order of increasing seriousness, they are:
+
+LATTEST(expr)
+ This macro should be used when one just wants to test expr. If devel mode,
+ this will lead to an assertion. In release mode, we will simply continue. So
+ LATTEST should be used only if you know, in advance, that it will be safe to
+ continue with the usual program flow, but failure of expr still means that
+ there is something that needs to be fixed.
+
+LASSERT(expr, escape)
+ This macro should be used when a failure of expr is not compatible with
+ continuing the ordinary program flow, but is something from which we can
+ recover. This might mean simply returning early from some routine; it might
+ mean resetting some variables to values known to be sane; it might mean
+ taking some other corrective action.
+
+LWARNIF(expr, msg)
+ This macro should be used when a failure of expr indicates that the current
+ operation cannot safely be completed. In release mode, it will abort that
+ operation and print a warning message to the user.
+
+LBUFERR(expr, msg)
+ This macro should be used when a failure of expr indicates a problem with a
+ Buffer or its related objects, e.g., a Cursor. In release mode, it throws a
+ BufferException, which will typically result in an emergency save of that
+ particular Buffer. The msg will be displayed to the user and so should be
+ internationalized.
+
+LAPPERR(expr, msg)
+ This macro should be used if a failure of expr is incompatible with LyX
+ continuing to operate at all. In release mode, this issues an ErrorException,
+ which typically results in an emergency shutdown. The msg will be displayed
+ to the user and so should be internationalized.
+
+******************************************************************************/
+
+
void doAssert(char const * expr, char const * file, long line);
+void doWarnIf(char const * expr, docstring const & msg, char const * file, long line);
+void doBufErr(char const * expr, docstring const & msg, char const * file, long line);
+void doAppErr(char const * expr, docstring const & msg, char const * file, long line);
/// Print demangled callstack to stderr
void printCallStack();
} // namespace lyx
+#define LATTEST(expr) \
+ if (expr) {} else { lyx::doAssert(#expr, __FILE__, __LINE__); }
+
#define LASSERT(expr, escape) \
if (expr) {} else { lyx::doAssert(#expr, __FILE__, __LINE__); escape; }
-#endif
+#define LWARNIF(expr, msg) \
+ if (expr) {} else { lyx::doWarnIf(#expr, msg, __FILE__, __LINE__); }
+
+#define LBUFERR(expr, msg) \
+ if (expr) {} else { lyx::doBufErr(#expr, msg, __FILE__, __LINE__); }
+
+#define LAPPERR(expr, msg) \
+ if (expr) {} else { lyx::doAppErr(#expr, msg, __FILE__, __LINE__); }
+
+#endif
#endif // LASSERT