Add support for verbose asserts.
Use for test/exec DoCommand mismatches.
This commit is contained in:
@@ -26,6 +26,8 @@
|
|||||||
#include "signal_func.h"
|
#include "signal_func.h"
|
||||||
#include "core/backup_type.hpp"
|
#include "core/backup_type.hpp"
|
||||||
#include "object_base.h"
|
#include "object_base.h"
|
||||||
|
#include "newgrf_text.h"
|
||||||
|
#include "string_func.h"
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
|
|
||||||
@@ -735,7 +737,9 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd,
|
|||||||
* test and execution have yielded the same result,
|
* test and execution have yielded the same result,
|
||||||
* i.e. cost and error state are the same. */
|
* i.e. cost and error state are the same. */
|
||||||
if (!test_and_exec_can_differ) {
|
if (!test_and_exec_can_differ) {
|
||||||
assert(res.GetCost() == res2.GetCost() && res.Failed() == res2.Failed()); // sanity check
|
assert_msg(res.GetCost() == res2.GetCost() && res.Failed() == res2.Failed(),
|
||||||
|
"Command: cmd: 0x%X (%s), Test: %s, Exec: %s", cmd, GetCommandName(cmd),
|
||||||
|
res.AllocSummaryMessage(GB(cmd, 16, 16)), res2.AllocSummaryMessage(GB(cmd, 16, 16))); // sanity check
|
||||||
} else if (res2.Failed()) {
|
} else if (res2.Failed()) {
|
||||||
return_dcpi(res2);
|
return_dcpi(res2);
|
||||||
}
|
}
|
||||||
@@ -803,3 +807,34 @@ void CommandCost::UseTextRefStack(const GRFFile *grffile, uint num_registers)
|
|||||||
textref_stack[i] = _temp_store.GetValue(0x100 + i);
|
textref_stack[i] = _temp_store.GetValue(0x100 + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *CommandCost::AllocSummaryMessage(StringID cmd_msg) const
|
||||||
|
{
|
||||||
|
char buf[DRAW_STRING_BUFFER];
|
||||||
|
this->WriteSummaryMessage(buf, lastof(buf), cmd_msg);
|
||||||
|
return stredup(buf, lastof(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
int CommandCost::WriteSummaryMessage(char *buf, char *last, StringID cmd_msg) const
|
||||||
|
{
|
||||||
|
if (this->Succeeded()) {
|
||||||
|
return seprintf(buf, last, "Success: cost: " OTTD_PRINTF64, (int64) this->GetCost());
|
||||||
|
} else {
|
||||||
|
if (this->textref_stack_size > 0) StartTextRefStackUsage(this->textref_stack_grffile, this->textref_stack_size, textref_stack);
|
||||||
|
|
||||||
|
char *b = buf;
|
||||||
|
b += seprintf(b, last, "Failed: cost: " OTTD_PRINTF64, (int64) this->GetCost());
|
||||||
|
if (cmd_msg != 0) {
|
||||||
|
b += seprintf(b, last, " ");
|
||||||
|
b = GetString(b, cmd_msg, last);
|
||||||
|
}
|
||||||
|
if (this->message != INVALID_STRING_ID) {
|
||||||
|
b += seprintf(b, last, " ");
|
||||||
|
b = GetString(b, this->message, last);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->textref_stack_size > 0) StopTextRefStackUsage();
|
||||||
|
|
||||||
|
return b - buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -162,6 +162,21 @@ public:
|
|||||||
{
|
{
|
||||||
return !this->success;
|
return !this->success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param cmd_msg optional failure string as passed to DoCommand
|
||||||
|
* @return an allocated string summarising the command result
|
||||||
|
*/
|
||||||
|
char *AllocSummaryMessage(StringID cmd_msg = 0) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a string summarising the command result
|
||||||
|
* @param buf buffer to write to
|
||||||
|
* @param last last byte in buffer
|
||||||
|
* @param cmd_msg optional failure string as passed to DoCommand
|
||||||
|
* @return the number of bytes written
|
||||||
|
*/
|
||||||
|
int WriteSummaryMessage(char *buf, char *last, StringID cmd_msg = 0) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -123,6 +123,25 @@ void CDECL error(const char *s, ...)
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CDECL assert_msg_error(int line, const char *file, const char *expr, const char *str, ...)
|
||||||
|
{
|
||||||
|
va_list va;
|
||||||
|
char buf[2048];
|
||||||
|
|
||||||
|
char *b = buf;
|
||||||
|
b += seprintf(b, lastof(buf), "Assertion failed at line %i of %s: %s\n\t", line, file, expr);
|
||||||
|
|
||||||
|
va_start(va, str);
|
||||||
|
vseprintf(b, lastof(buf), str, va);
|
||||||
|
va_end(va);
|
||||||
|
|
||||||
|
ShowOSErrorBox(buf, true);
|
||||||
|
|
||||||
|
/* Set the error message for the crash log and then invoke it. */
|
||||||
|
CrashLog::SetErrorMessage(buf);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows some information on the console/a popup box depending on the OS.
|
* Shows some information on the console/a popup box depending on the OS.
|
||||||
* @param str the text to show.
|
* @param str the text to show.
|
||||||
|
@@ -446,6 +446,7 @@ assert_compile(SIZE_MAX >= UINT32_MAX);
|
|||||||
|
|
||||||
void NORETURN CDECL usererror(const char *str, ...) WARN_FORMAT(1, 2);
|
void NORETURN CDECL usererror(const char *str, ...) WARN_FORMAT(1, 2);
|
||||||
void NORETURN CDECL error(const char *str, ...) WARN_FORMAT(1, 2);
|
void NORETURN CDECL error(const char *str, ...) WARN_FORMAT(1, 2);
|
||||||
|
void NORETURN CDECL assert_msg_error(int line, const char *file, const char *expr, const char *str, ...) WARN_FORMAT(4, 5);
|
||||||
#define NOT_REACHED() error("NOT_REACHED triggered at line %i of %s", __LINE__, __FILE__)
|
#define NOT_REACHED() error("NOT_REACHED triggered at line %i of %s", __LINE__, __FILE__)
|
||||||
|
|
||||||
/* For non-debug builds with assertions enabled use the special assertion handler:
|
/* For non-debug builds with assertions enabled use the special assertion handler:
|
||||||
@@ -460,6 +461,9 @@ void NORETURN CDECL error(const char *str, ...) WARN_FORMAT(1, 2);
|
|||||||
/* Asserts are enabled if NDEBUG isn't defined, or if we are using MSVC and WITH_ASSERT is defined. */
|
/* Asserts are enabled if NDEBUG isn't defined, or if we are using MSVC and WITH_ASSERT is defined. */
|
||||||
#if !defined(NDEBUG) || (defined(_MSC_VER) && defined(WITH_ASSERT))
|
#if !defined(NDEBUG) || (defined(_MSC_VER) && defined(WITH_ASSERT))
|
||||||
#define OTTD_ASSERT
|
#define OTTD_ASSERT
|
||||||
|
#define assert_msg(expression, ...) if (!(expression)) assert_msg_error(__LINE__, __FILE__, #expression, __VA_ARGS__);
|
||||||
|
#else
|
||||||
|
#define assert_msg(expression, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MORPHOS) || defined(__NDS__) || defined(__DJGPP__)
|
#if defined(MORPHOS) || defined(__NDS__) || defined(__DJGPP__)
|
||||||
|
Reference in New Issue
Block a user