mirror of
https://github.com/holub/mame
synced 2025-05-22 13:48:55 +03:00
Get rid of setjmp/longjmp for error handling in favor of exceptions.
Fatalerror now maps to throwing an exception. Requires a full recompile.
This commit is contained in:
parent
7e88358737
commit
200b21dff7
@ -20,6 +20,7 @@
|
||||
#include "romload.h"
|
||||
#include "sound/samples.h"
|
||||
|
||||
#include <new>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef MESS
|
||||
@ -111,13 +112,15 @@ static const options_entry cli_options[] =
|
||||
|
||||
int cli_execute(int argc, char **argv, const options_entry *osd_options)
|
||||
{
|
||||
core_options *options;
|
||||
core_options *options = NULL;
|
||||
astring *gamename = astring_alloc();
|
||||
astring *exename = astring_alloc();
|
||||
const char *gamename_option;
|
||||
const game_driver *driver;
|
||||
int result;
|
||||
int result = MAMERR_FATALERROR;
|
||||
|
||||
try
|
||||
{
|
||||
/* initialize the options manager and add the CLI-specific options */
|
||||
options = mame_options_init(osd_options);
|
||||
options_add_entries(options, cli_options);
|
||||
@ -168,9 +171,29 @@ int cli_execute(int argc, char **argv, const options_entry *osd_options)
|
||||
|
||||
/* run the game */
|
||||
result = mame_execute(options);
|
||||
}
|
||||
catch (emu_fatalerror &fatal)
|
||||
{
|
||||
fprintf(stderr, "%s\n", fatal.string());
|
||||
if (fatal.exitcode() != 0)
|
||||
result = fatal.exitcode();
|
||||
}
|
||||
catch (emu_exception &exception)
|
||||
{
|
||||
fprintf(stderr, "Caught unhandled emulator exception\n");
|
||||
}
|
||||
catch (std::bad_alloc &)
|
||||
{
|
||||
fprintf(stderr, "Out of memory!\n");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
fprintf(stderr, "Caught unhandled exception\n");
|
||||
}
|
||||
|
||||
error:
|
||||
/* free our options and exit */
|
||||
if (options != NULL)
|
||||
options_free(options);
|
||||
astring_free(gamename);
|
||||
astring_free(exename);
|
||||
|
@ -133,11 +133,11 @@ int config_load_settings(running_machine *machine)
|
||||
astring_free(fname);
|
||||
|
||||
if (filerr != FILERR_NONE)
|
||||
fatalerror("Could not load controller file %s.cfg", controller);
|
||||
throw emu_fatalerror("Could not load controller file %s.cfg", controller);
|
||||
|
||||
/* load the XML */
|
||||
if (!config_load_xml(machine, file, CONFIG_TYPE_CONTROLLER))
|
||||
fatalerror("Could not load controller file %s.cfg", controller);
|
||||
throw emu_fatalerror("Could not load controller file %s.cfg", controller);
|
||||
mame_fclose(file);
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
mame_execute() [mame.c]
|
||||
- calls mame_validitychecks() [validity.c] to perform validity checks on all compiled drivers
|
||||
- calls setjmp to prepare for deep error handling
|
||||
- begins resource tracking (level 1)
|
||||
- calls create_machine [mame.c] to initialize the running_machine structure
|
||||
- calls init_machine() [mame.c]
|
||||
@ -87,8 +86,8 @@
|
||||
#include "streams.h"
|
||||
#include "debug/debugcon.h"
|
||||
|
||||
#include <new>
|
||||
#include <stdarg.h>
|
||||
#include <setjmp.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
@ -153,10 +152,6 @@ struct _mame_private
|
||||
region_info * regionlist;
|
||||
tagmap * regionmap;
|
||||
|
||||
/* error recovery and exiting */
|
||||
jmp_buf fatal_error_jmpbuf;
|
||||
int fatal_error_jmpbuf_valid;
|
||||
|
||||
/* random number seed */
|
||||
UINT32 rand_seed;
|
||||
|
||||
@ -298,10 +293,8 @@ int mame_execute(core_options *options)
|
||||
|
||||
init_resource_tracking();
|
||||
|
||||
/* use setjmp/longjmp for deep error recovery */
|
||||
mame->fatal_error_jmpbuf_valid = TRUE;
|
||||
error = setjmp(mame->fatal_error_jmpbuf);
|
||||
if (error == 0)
|
||||
/* use try/catch for deep error recovery */
|
||||
try
|
||||
{
|
||||
int settingsloaded;
|
||||
|
||||
@ -372,7 +365,23 @@ int mame_execute(core_options *options)
|
||||
nvram_save(machine);
|
||||
config_save_settings(machine);
|
||||
}
|
||||
mame->fatal_error_jmpbuf_valid = FALSE;
|
||||
catch (emu_fatalerror &fatal)
|
||||
{
|
||||
mame_printf_error("%s\n", fatal.string());
|
||||
error = MAMERR_FATALERROR;
|
||||
if (fatal.exitcode() != 0)
|
||||
error = fatal.exitcode();
|
||||
}
|
||||
catch (emu_exception &exception)
|
||||
{
|
||||
mame_printf_error("Caught unhandled emulator exception\n");
|
||||
error = MAMERR_FATALERROR;
|
||||
}
|
||||
catch (std::bad_alloc &)
|
||||
{
|
||||
mame_printf_error("Out of memory!\n");
|
||||
error = MAMERR_FATALERROR;
|
||||
}
|
||||
|
||||
/* call all exit callbacks registered */
|
||||
for (cb = mame->exit_callback_list; cb; cb = cb->next)
|
||||
@ -1119,56 +1128,6 @@ void mame_printf_log(const char *format, ...)
|
||||
MISCELLANEOUS
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
fatalerror - print a message and escape back
|
||||
to the OSD layer
|
||||
-------------------------------------------------*/
|
||||
|
||||
DECL_NORETURN static void fatalerror_common(running_machine *machine, int exitcode, const char *buffer) ATTR_NORETURN;
|
||||
|
||||
static void fatalerror_common(running_machine *machine, int exitcode, const char *buffer)
|
||||
{
|
||||
/* output and return */
|
||||
mame_printf_error("%s\n", giant_string_buffer);
|
||||
|
||||
/* break into the debugger if attached */
|
||||
osd_break_into_debugger(giant_string_buffer);
|
||||
|
||||
/* longjmp back if we can; otherwise, exit */
|
||||
if (machine != NULL && machine->mame_data != NULL && machine->mame_data->fatal_error_jmpbuf_valid)
|
||||
longjmp(machine->mame_data->fatal_error_jmpbuf, exitcode);
|
||||
else
|
||||
exit(exitcode);
|
||||
}
|
||||
|
||||
|
||||
void CLIB_DECL fatalerror(const char *text, ...)
|
||||
{
|
||||
running_machine *machine = global_machine;
|
||||
va_list arg;
|
||||
|
||||
/* dump to the buffer; assume no one writes >2k lines this way */
|
||||
va_start(arg, text);
|
||||
vsnprintf(giant_string_buffer, GIANT_STRING_BUFFER_SIZE, text, arg);
|
||||
va_end(arg);
|
||||
|
||||
fatalerror_common(machine, MAMERR_FATALERROR, giant_string_buffer);
|
||||
}
|
||||
|
||||
|
||||
void CLIB_DECL fatalerror_exitcode(running_machine *machine, int exitcode, const char *text, ...)
|
||||
{
|
||||
va_list arg;
|
||||
|
||||
/* dump to the buffer; assume no one writes >2k lines this way */
|
||||
va_start(arg, text);
|
||||
vsnprintf(giant_string_buffer, GIANT_STRING_BUFFER_SIZE, text, arg);
|
||||
va_end(arg);
|
||||
|
||||
fatalerror_common(machine, exitcode, giant_string_buffer);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
popmessage - pop up a user-visible message
|
||||
-------------------------------------------------*/
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <exception>
|
||||
#include "osdcomm.h"
|
||||
#include "bitmap.h"
|
||||
#include "coreutil.h"
|
||||
@ -318,13 +320,76 @@ inline void operator--(type &value, int) { value = (type)((int)value - 1); }
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
EXCEPTION CLASSES
|
||||
***************************************************************************/
|
||||
|
||||
// emu_exception is the base class for all emu-related exceptions
|
||||
class emu_exception : public std::exception
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
// emu_fatalerror is a generic fatal exception that provides an error string
|
||||
class emu_fatalerror : public emu_exception
|
||||
{
|
||||
public:
|
||||
emu_fatalerror(const char *format, ...)
|
||||
: m_exitcode(0)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
sprintf(m_text, format, ap);
|
||||
va_end(ap);
|
||||
osd_break_into_debugger(m_text);
|
||||
}
|
||||
|
||||
emu_fatalerror(const char *format, va_list ap)
|
||||
: m_exitcode(0)
|
||||
{
|
||||
vsprintf(m_text, format, ap);
|
||||
osd_break_into_debugger(m_text);
|
||||
}
|
||||
|
||||
emu_fatalerror(int _exitcode, const char *format, va_list ap)
|
||||
: m_exitcode(_exitcode)
|
||||
{
|
||||
vsprintf(m_text, format, ap);
|
||||
osd_break_into_debugger(m_text);
|
||||
}
|
||||
|
||||
const char *string() const { return m_text; }
|
||||
int exitcode() const { return m_exitcode; }
|
||||
|
||||
private:
|
||||
char m_text[1024];
|
||||
int m_exitcode;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
FUNCTION PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
/* Used by assert(), so definition here instead of mame.h */
|
||||
DECL_NORETURN void CLIB_DECL fatalerror(const char *text, ...) ATTR_PRINTF(1,2) ATTR_NORETURN;
|
||||
DECL_NORETURN void CLIB_DECL fatalerror_exitcode(running_machine *machine, int exitcode, const char *text, ...) ATTR_PRINTF(3,4) ATTR_NORETURN;
|
||||
DECL_NORETURN void fatalerror(const char *format, ...) ATTR_PRINTF(1,2) ATTR_NORETURN;
|
||||
DECL_NORETURN void fatalerror_exitcode(running_machine *machine, int exitcode, const char *format, ...) ATTR_PRINTF(3,4) ATTR_NORETURN;
|
||||
|
||||
inline void fatalerror(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
throw emu_fatalerror(format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
inline void fatalerror_exitcode(running_machine *machine, int exitcode, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
throw emu_fatalerror(exitcode, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -333,7 +398,7 @@ DECL_NORETURN void CLIB_DECL fatalerror_exitcode(running_machine *machine, int e
|
||||
***************************************************************************/
|
||||
|
||||
/* population count */
|
||||
INLINE int popcount(UINT32 val)
|
||||
inline int popcount(UINT32 val)
|
||||
{
|
||||
int count;
|
||||
|
||||
@ -344,7 +409,7 @@ INLINE int popcount(UINT32 val)
|
||||
|
||||
|
||||
/* convert a series of 32 bits into a float */
|
||||
INLINE float u2f(UINT32 v)
|
||||
inline float u2f(UINT32 v)
|
||||
{
|
||||
union {
|
||||
float ff;
|
||||
@ -356,7 +421,7 @@ INLINE float u2f(UINT32 v)
|
||||
|
||||
|
||||
/* convert a float into a series of 32 bits */
|
||||
INLINE UINT32 f2u(float f)
|
||||
inline UINT32 f2u(float f)
|
||||
{
|
||||
union {
|
||||
float ff;
|
||||
@ -368,7 +433,7 @@ INLINE UINT32 f2u(float f)
|
||||
|
||||
|
||||
/* convert a series of 64 bits into a double */
|
||||
INLINE double u2d(UINT64 v)
|
||||
inline double u2d(UINT64 v)
|
||||
{
|
||||
union {
|
||||
double dd;
|
||||
@ -380,7 +445,7 @@ INLINE double u2d(UINT64 v)
|
||||
|
||||
|
||||
/* convert a double into a series of 64 bits */
|
||||
INLINE UINT64 d2u(double d)
|
||||
inline UINT64 d2u(double d)
|
||||
{
|
||||
union {
|
||||
double dd;
|
||||
|
Loading…
Reference in New Issue
Block a user