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 "romload.h"
|
||||||
#include "sound/samples.h"
|
#include "sound/samples.h"
|
||||||
|
|
||||||
|
#include <new>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#ifdef MESS
|
#ifdef MESS
|
||||||
@ -111,13 +112,15 @@ static const options_entry cli_options[] =
|
|||||||
|
|
||||||
int cli_execute(int argc, char **argv, const options_entry *osd_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 *gamename = astring_alloc();
|
||||||
astring *exename = astring_alloc();
|
astring *exename = astring_alloc();
|
||||||
const char *gamename_option;
|
const char *gamename_option;
|
||||||
const game_driver *driver;
|
const game_driver *driver;
|
||||||
int result;
|
int result = MAMERR_FATALERROR;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
/* initialize the options manager and add the CLI-specific options */
|
/* initialize the options manager and add the CLI-specific options */
|
||||||
options = mame_options_init(osd_options);
|
options = mame_options_init(osd_options);
|
||||||
options_add_entries(options, cli_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 */
|
/* run the game */
|
||||||
result = mame_execute(options);
|
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:
|
error:
|
||||||
/* free our options and exit */
|
/* free our options and exit */
|
||||||
|
if (options != NULL)
|
||||||
options_free(options);
|
options_free(options);
|
||||||
astring_free(gamename);
|
astring_free(gamename);
|
||||||
astring_free(exename);
|
astring_free(exename);
|
||||||
|
@ -133,11 +133,11 @@ int config_load_settings(running_machine *machine)
|
|||||||
astring_free(fname);
|
astring_free(fname);
|
||||||
|
|
||||||
if (filerr != FILERR_NONE)
|
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 */
|
/* load the XML */
|
||||||
if (!config_load_xml(machine, file, CONFIG_TYPE_CONTROLLER))
|
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);
|
mame_fclose(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
mame_execute() [mame.c]
|
mame_execute() [mame.c]
|
||||||
- calls mame_validitychecks() [validity.c] to perform validity checks on all compiled drivers
|
- 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)
|
- begins resource tracking (level 1)
|
||||||
- calls create_machine [mame.c] to initialize the running_machine structure
|
- calls create_machine [mame.c] to initialize the running_machine structure
|
||||||
- calls init_machine() [mame.c]
|
- calls init_machine() [mame.c]
|
||||||
@ -87,8 +86,8 @@
|
|||||||
#include "streams.h"
|
#include "streams.h"
|
||||||
#include "debug/debugcon.h"
|
#include "debug/debugcon.h"
|
||||||
|
|
||||||
|
#include <new>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <setjmp.h>
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
@ -153,10 +152,6 @@ struct _mame_private
|
|||||||
region_info * regionlist;
|
region_info * regionlist;
|
||||||
tagmap * regionmap;
|
tagmap * regionmap;
|
||||||
|
|
||||||
/* error recovery and exiting */
|
|
||||||
jmp_buf fatal_error_jmpbuf;
|
|
||||||
int fatal_error_jmpbuf_valid;
|
|
||||||
|
|
||||||
/* random number seed */
|
/* random number seed */
|
||||||
UINT32 rand_seed;
|
UINT32 rand_seed;
|
||||||
|
|
||||||
@ -298,10 +293,8 @@ int mame_execute(core_options *options)
|
|||||||
|
|
||||||
init_resource_tracking();
|
init_resource_tracking();
|
||||||
|
|
||||||
/* use setjmp/longjmp for deep error recovery */
|
/* use try/catch for deep error recovery */
|
||||||
mame->fatal_error_jmpbuf_valid = TRUE;
|
try
|
||||||
error = setjmp(mame->fatal_error_jmpbuf);
|
|
||||||
if (error == 0)
|
|
||||||
{
|
{
|
||||||
int settingsloaded;
|
int settingsloaded;
|
||||||
|
|
||||||
@ -372,7 +365,23 @@ int mame_execute(core_options *options)
|
|||||||
nvram_save(machine);
|
nvram_save(machine);
|
||||||
config_save_settings(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 */
|
/* call all exit callbacks registered */
|
||||||
for (cb = mame->exit_callback_list; cb; cb = cb->next)
|
for (cb = mame->exit_callback_list; cb; cb = cb->next)
|
||||||
@ -1119,56 +1128,6 @@ void mame_printf_log(const char *format, ...)
|
|||||||
MISCELLANEOUS
|
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
|
popmessage - pop up a user-visible message
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <exception>
|
||||||
#include "osdcomm.h"
|
#include "osdcomm.h"
|
||||||
#include "bitmap.h"
|
#include "bitmap.h"
|
||||||
#include "coreutil.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
|
FUNCTION PROTOTYPES
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
/* Used by assert(), so definition here instead of mame.h */
|
DECL_NORETURN void fatalerror(const char *format, ...) ATTR_PRINTF(1,2) ATTR_NORETURN;
|
||||||
DECL_NORETURN void CLIB_DECL fatalerror(const char *text, ...) 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;
|
||||||
DECL_NORETURN void CLIB_DECL fatalerror_exitcode(running_machine *machine, int exitcode, const char *text, ...) 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 */
|
/* population count */
|
||||||
INLINE int popcount(UINT32 val)
|
inline int popcount(UINT32 val)
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
@ -344,7 +409,7 @@ INLINE int popcount(UINT32 val)
|
|||||||
|
|
||||||
|
|
||||||
/* convert a series of 32 bits into a float */
|
/* convert a series of 32 bits into a float */
|
||||||
INLINE float u2f(UINT32 v)
|
inline float u2f(UINT32 v)
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
float ff;
|
float ff;
|
||||||
@ -356,7 +421,7 @@ INLINE float u2f(UINT32 v)
|
|||||||
|
|
||||||
|
|
||||||
/* convert a float into a series of 32 bits */
|
/* convert a float into a series of 32 bits */
|
||||||
INLINE UINT32 f2u(float f)
|
inline UINT32 f2u(float f)
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
float ff;
|
float ff;
|
||||||
@ -368,7 +433,7 @@ INLINE UINT32 f2u(float f)
|
|||||||
|
|
||||||
|
|
||||||
/* convert a series of 64 bits into a double */
|
/* convert a series of 64 bits into a double */
|
||||||
INLINE double u2d(UINT64 v)
|
inline double u2d(UINT64 v)
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
double dd;
|
double dd;
|
||||||
@ -380,7 +445,7 @@ INLINE double u2d(UINT64 v)
|
|||||||
|
|
||||||
|
|
||||||
/* convert a double into a series of 64 bits */
|
/* convert a double into a series of 64 bits */
|
||||||
INLINE UINT64 d2u(double d)
|
inline UINT64 d2u(double d)
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
double dd;
|
double dd;
|
||||||
|
Loading…
Reference in New Issue
Block a user