mirror of
https://github.com/kevinbentley/Descent3.git
synced 2025-01-22 11:28:56 +00:00
f7b7f18e0d
Reworked ASSERT() and Int3() macros to use SDL_assert(). SDL_assert() allows to debug break from user decision. Major reorganizing platform-dependent code to make it platform-independent.
275 lines
7.3 KiB
C++
275 lines
7.3 KiB
C++
/*
|
|
* Descent 3
|
|
* Copyright (C) 2024 Parallax Software
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
--- HISTORICAL COMMENTS FOLLOW ---
|
|
|
|
* $Logfile: /DescentIII/Main/misc/error.cpp $
|
|
* $Revision: 26 $
|
|
* $Date: 10/09/01 5:40p $
|
|
* $Author: Matt $
|
|
*
|
|
* Error-handling functions
|
|
*
|
|
* $Log: /DescentIII/Main/misc/error.cpp $
|
|
*
|
|
* 26 10/09/01 5:40p Matt
|
|
* Made -nocrashbox work in release build.
|
|
*
|
|
* 25 9/15/01 1:46p Kevin
|
|
* Added -nocrashbox to suppress crash dialog box
|
|
*
|
|
* 24 4/19/00 5:23p Matt
|
|
* From Duane for 1.4
|
|
* Changed to Mac error exit message
|
|
*
|
|
* 23 5/05/99 5:22p Samir
|
|
* exit(0) instead of exit(1) and other stuff to see why error isn't
|
|
* exiting in release?
|
|
*
|
|
* 22 4/14/99 1:35a Jeff
|
|
* fixed case mismatched #includes
|
|
*
|
|
* 21 4/01/99 4:50p Matt
|
|
* Took out Warning() function, chaning those calls to mprintf()
|
|
*
|
|
* 20 3/02/99 5:50p Kevin
|
|
* Ouch. Duplicate structures existed and were conflicting.
|
|
*
|
|
* 19 2/15/99 1:22p Kevin
|
|
* Changes for GameGauge
|
|
*
|
|
* 18 1/10/99 6:47a Jeff
|
|
* Changes made to get linux version to compile
|
|
*
|
|
* 17 11/01/98 1:58a Jeff
|
|
* converted the vsprintf calls to use the Pvsprintf, which is a safe
|
|
* vsprintf, no buffer overflows allowed
|
|
*
|
|
* 16 10/18/98 8:52p Matt
|
|
* Revamped debug/error system.
|
|
*
|
|
*/
|
|
|
|
#include <cstdarg>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
|
|
#include "debug.h"
|
|
#include "pserror.h"
|
|
|
|
#define MAX_MSG_LEN 2000
|
|
|
|
// Debug break chain handlers
|
|
void (*DebugBreak_callback_stop)() = nullptr;
|
|
void (*DebugBreak_callback_resume)() = nullptr;
|
|
|
|
// library initialized flag
|
|
static bool Error_initialized = false;
|
|
|
|
// message that is printed out when error occurs
|
|
static char Exit_message[MAX_MSG_LEN];
|
|
static char App_title[32];
|
|
static char Exit_title_str[64];
|
|
|
|
// error message output function
|
|
void error_Spew();
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// initializes error handler.
|
|
bool error_Init(bool debugger, const char *app_title) {
|
|
Debug_Init(debugger);
|
|
|
|
Error_initialized = true;
|
|
Exit_message[0] = 0;
|
|
|
|
strncpy(App_title, app_title, sizeof(App_title) - 1);
|
|
App_title[sizeof(App_title) - 1] = 0;
|
|
|
|
strncpy(Exit_title_str, app_title, sizeof(Exit_title_str) - 1);
|
|
Exit_title_str[sizeof(Exit_title_str) - 1] = 0;
|
|
|
|
atexit(error_Spew);
|
|
|
|
return true;
|
|
}
|
|
|
|
// exits the application and prints out a standard error message
|
|
void Error(const char *fmt, ...) {
|
|
std::va_list arglist;
|
|
|
|
strcpy(Exit_message, "Error: ");
|
|
|
|
va_start(arglist, fmt);
|
|
size_t exit_msg_len = strlen(Exit_message);
|
|
std::vsnprintf(Exit_message + exit_msg_len, MAX_MSG_LEN - exit_msg_len, fmt, arglist);
|
|
va_end(arglist);
|
|
|
|
snprintf(Exit_title_str, sizeof(Exit_title_str), "%s Error", App_title);
|
|
LOG_ERROR.printf("%s", Exit_message);
|
|
|
|
#ifdef _DEBUG
|
|
int answer = IDOK;
|
|
|
|
if (DebugBreak_callback_stop)
|
|
(*DebugBreak_callback_stop)();
|
|
|
|
if (Debug_break)
|
|
answer = Debug_ErrorBox(OSMBOX_ABORTRETRYIGNORE, Exit_title_str, Exit_message, "Press RETRY to debug.");
|
|
else
|
|
answer = Debug_ErrorBox(OSMBOX_OKCANCEL, Exit_title_str, Exit_message,
|
|
"Press OK to exit, CANCEL to ignore this error and continue.");
|
|
|
|
switch (answer) {
|
|
case IDRETRY:
|
|
SDL_TriggerBreakpoint(); // Step Out of this function to see where Error() was called
|
|
// fall into ignore/cancel case
|
|
case IDIGNORE:
|
|
case IDCANCEL:
|
|
if (DebugBreak_callback_resume)
|
|
(*DebugBreak_callback_resume)();
|
|
return;
|
|
case IDOK:
|
|
case IDABORT:
|
|
break; // do nothing, and exit below
|
|
}
|
|
|
|
// Clear the message, since we don't need to see it again when we exit
|
|
Exit_message[0] = 0;
|
|
|
|
#else
|
|
if (!Error_initialized)
|
|
error_Spew();
|
|
#endif
|
|
|
|
// Clear the DEBUG_BREAK() callbacks
|
|
SetDebugBreakHandlers(nullptr, nullptr);
|
|
|
|
// Leave the program
|
|
exit(0);
|
|
}
|
|
|
|
// Brings up an error message for an int3
|
|
void Int3MessageBox(const char *file, int line) {
|
|
#ifndef RELEASE
|
|
char title[128], message[500];
|
|
int answer;
|
|
|
|
snprintf(title, sizeof(title), "%s Debug Break", App_title);
|
|
snprintf(message, sizeof(message), "Int3 in %s:%d.", file, line);
|
|
|
|
if (DebugBreak_callback_stop)
|
|
(*DebugBreak_callback_stop)();
|
|
|
|
answer = Debug_ErrorBox(OSMBOX_YESNO, title, message, "It's probably safe to continue. Continue?");
|
|
|
|
if (answer == IDNO) {
|
|
SetDebugBreakHandlers(nullptr, nullptr);
|
|
exit(1);
|
|
}
|
|
|
|
if (DebugBreak_callback_resume)
|
|
(*DebugBreak_callback_resume)();
|
|
#endif
|
|
}
|
|
|
|
// prints out an assertion error
|
|
void AssertionFailed(const char *expstr, const char *file, int line) {
|
|
#ifndef RELEASE
|
|
char title[128], message[500];
|
|
int answer;
|
|
|
|
snprintf(title, sizeof(title), "%s Assertion Failed", App_title);
|
|
snprintf(message, sizeof(message), "Assertion failed: (%s)\n\nFile %s at line %d.", expstr, file, line);
|
|
|
|
if (DebugBreak_callback_stop)
|
|
(*DebugBreak_callback_stop)();
|
|
|
|
answer = Debug_ErrorBox(OSMBOX_YESNO, title, message, "Continue?");
|
|
|
|
if (answer == IDNO) {
|
|
SetDebugBreakHandlers(nullptr, nullptr);
|
|
exit(1);
|
|
}
|
|
|
|
if (DebugBreak_callback_resume)
|
|
(*DebugBreak_callback_resume)();
|
|
#endif // #ifndef RELEASE
|
|
}
|
|
|
|
// error message output function
|
|
void error_Spew() {
|
|
if (Exit_message[0])
|
|
Debug_MessageBox(OSMBOX_OK, Exit_title_str, Exit_message);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// MESSAGE BOX SYSTEM
|
|
|
|
char Messagebox_title[80] = "Message";
|
|
|
|
// Sets the title for future OutrageMessageBox() dialogs
|
|
void SetMessageBoxTitle(const char *title) { strncpy(Messagebox_title, title, sizeof(Messagebox_title)); }
|
|
|
|
#define BUF_LEN 1024
|
|
|
|
// Pops up a dialog box to display a message
|
|
void OutrageMessageBox(const char *str, ...) {
|
|
char buf[BUF_LEN];
|
|
std::va_list arglist;
|
|
int nchars;
|
|
|
|
va_start(arglist, str);
|
|
nchars = std::vsnprintf(buf, BUF_LEN, str, arglist);
|
|
va_end(arglist);
|
|
|
|
if (nchars >= BUF_LEN)
|
|
Debug_MessageBox(OSMBOX_OK, Messagebox_title,
|
|
"The dialog that follows this one overflowed its text buffer. The program may crash.");
|
|
|
|
Debug_MessageBox(OSMBOX_OK, Messagebox_title, buf);
|
|
}
|
|
|
|
int OutrageMessageBox(int type, const char *str, ...) {
|
|
char buf[BUF_LEN];
|
|
std::va_list arglist;
|
|
int os_flags = 0;
|
|
int nchars;
|
|
|
|
va_start(arglist, str);
|
|
nchars = std::vsnprintf(buf, BUF_LEN, str, arglist);
|
|
va_end(arglist);
|
|
|
|
if (type == MBOX_OK)
|
|
os_flags = OSMBOX_OK;
|
|
else if (type == MBOX_YESNO)
|
|
os_flags = OSMBOX_YESNO;
|
|
else if (type == MBOX_YESNOCANCEL)
|
|
os_flags = OSMBOX_YESNOCANCEL;
|
|
else if (type == MBOX_ABORTRETRYIGNORE)
|
|
os_flags = OSMBOX_ABORTRETRYIGNORE;
|
|
else
|
|
Int3();
|
|
|
|
if (nchars >= BUF_LEN)
|
|
Debug_MessageBox(OSMBOX_OK, Messagebox_title,
|
|
"The dialog that follows this one overflowed its text buffer. The program may crash.");
|
|
|
|
return Debug_MessageBox(os_flags, Messagebox_title, buf);
|
|
}
|