mirror of https://github.com/OpenTTD/OpenTTD
(svn r10923) -Codechange: use 'real' exception handling in saveload code
parent
9c75e6d87b
commit
6a13dd4aa6
|
@ -27,7 +27,6 @@
|
||||||
#include "variables.h"
|
#include "variables.h"
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
#include "strings.h"
|
#include "strings.h"
|
||||||
#include <setjmp.h>
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
extern const uint16 SAVEGAME_VERSION = 73;
|
extern const uint16 SAVEGAME_VERSION = 73;
|
||||||
|
@ -68,7 +67,6 @@ static struct {
|
||||||
void (*excpt_uninit)(); ///< the function to execute on any encountered error
|
void (*excpt_uninit)(); ///< the function to execute on any encountered error
|
||||||
StringID error_str; ///< the translateable error message to show
|
StringID error_str; ///< the translateable error message to show
|
||||||
char *extra_msg; ///< the error message
|
char *extra_msg; ///< the error message
|
||||||
jmp_buf excpt; ///< @todo used to jump to "exception handler"; really ugly
|
|
||||||
} _sl;
|
} _sl;
|
||||||
|
|
||||||
|
|
||||||
|
@ -143,7 +141,7 @@ static void NORETURN SlError(StringID string, const char *extra_msg = NULL)
|
||||||
_sl.error_str = string;
|
_sl.error_str = string;
|
||||||
free(_sl.extra_msg);
|
free(_sl.extra_msg);
|
||||||
_sl.extra_msg = (extra_msg == NULL) ? NULL : strdup(extra_msg);
|
_sl.extra_msg = (extra_msg == NULL) ? NULL : strdup(extra_msg);
|
||||||
longjmp(_sl.excpt, 0);
|
throw std::exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Read in a single byte from file. If the temporary buffer is full,
|
/** Read in a single byte from file. If the temporary buffer is full,
|
||||||
|
@ -1521,23 +1519,7 @@ static SaveOrLoadResult SaveFileToDisk(bool threaded)
|
||||||
uint32 hdr[2];
|
uint32 hdr[2];
|
||||||
|
|
||||||
_sl.excpt_uninit = NULL;
|
_sl.excpt_uninit = NULL;
|
||||||
/* XXX - Setup setjmp error handler if an error occurs anywhere deep during
|
try {
|
||||||
* loading/saving execute a longjmp() and continue execution here */
|
|
||||||
if (setjmp(_sl.excpt)) {
|
|
||||||
AbortSaveLoad();
|
|
||||||
if (_sl.excpt_uninit != NULL) _sl.excpt_uninit();
|
|
||||||
|
|
||||||
ShowInfo(GetSaveLoadErrorString());
|
|
||||||
fprintf(stderr, GetSaveLoadErrorString());
|
|
||||||
|
|
||||||
if (threaded) {
|
|
||||||
OTTD_SendThreadMessage(MSG_OTTD_SAVETHREAD_ERROR);
|
|
||||||
} else {
|
|
||||||
SaveFileError();
|
|
||||||
}
|
|
||||||
return SL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt = GetSavegameFormat(_savegame_format);
|
fmt = GetSavegameFormat(_savegame_format);
|
||||||
|
|
||||||
/* We have written our stuff to memory, now write it to file! */
|
/* We have written our stuff to memory, now write it to file! */
|
||||||
|
@ -1571,6 +1553,21 @@ static SaveOrLoadResult SaveFileToDisk(bool threaded)
|
||||||
if (threaded) OTTD_SendThreadMessage(MSG_OTTD_SAVETHREAD_DONE);
|
if (threaded) OTTD_SendThreadMessage(MSG_OTTD_SAVETHREAD_DONE);
|
||||||
|
|
||||||
return SL_OK;
|
return SL_OK;
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
AbortSaveLoad();
|
||||||
|
if (_sl.excpt_uninit != NULL) _sl.excpt_uninit();
|
||||||
|
|
||||||
|
ShowInfo(GetSaveLoadErrorString());
|
||||||
|
fprintf(stderr, GetSaveLoadErrorString());
|
||||||
|
|
||||||
|
if (threaded) {
|
||||||
|
OTTD_SendThreadMessage(MSG_OTTD_SAVETHREAD_ERROR);
|
||||||
|
} else {
|
||||||
|
SaveFileError();
|
||||||
|
}
|
||||||
|
return SL_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* SaveFileToDiskThread(void *arg)
|
static void* SaveFileToDiskThread(void *arg)
|
||||||
|
@ -1616,22 +1613,8 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb)
|
||||||
return SL_OK;
|
return SL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX - Setup setjmp error handler if an error occurs anywhere deep during
|
|
||||||
* loading/saving execute a longjmp() and continue execution here */
|
|
||||||
_sl.excpt_uninit = NULL;
|
_sl.excpt_uninit = NULL;
|
||||||
if (setjmp(_sl.excpt)) {
|
try {
|
||||||
AbortSaveLoad();
|
|
||||||
|
|
||||||
/* deinitialize compressor. */
|
|
||||||
if (_sl.excpt_uninit != NULL) _sl.excpt_uninit();
|
|
||||||
|
|
||||||
/* Skip the "color" character */
|
|
||||||
ShowInfoF(GetSaveLoadErrorString() + 3);
|
|
||||||
|
|
||||||
/* A saver/loader exception!! reinitialize all variables to prevent crash! */
|
|
||||||
return (mode == SL_LOAD) ? SL_REINIT : SL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
_sl.fh = (mode == SL_SAVE) ? FioFOpenFile(filename, "wb", sb) : FioFOpenFile(filename, "rb", sb);
|
_sl.fh = (mode == SL_SAVE) ? FioFOpenFile(filename, "wb", sb) : FioFOpenFile(filename, "rb", sb);
|
||||||
|
|
||||||
/* Make it a little easier to load savegames from the console */
|
/* Make it a little easier to load savegames from the console */
|
||||||
|
@ -1678,9 +1661,9 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb)
|
||||||
}
|
}
|
||||||
} else { /* LOAD game */
|
} else { /* LOAD game */
|
||||||
assert(mode == SL_LOAD);
|
assert(mode == SL_LOAD);
|
||||||
#ifdef DEBUG_DUMP_COMMANDS
|
#ifdef DEBUG_DUMP_COMMANDS
|
||||||
debug_dump_commands("ddc:load:%s\n", filename);
|
debug_dump_commands("ddc:load:%s\n", filename);
|
||||||
#endif /* DUMP_COMMANDS */
|
#endif /* DUMP_COMMANDS */
|
||||||
|
|
||||||
if (fread(hdr, sizeof(hdr), 1, _sl.fh) != 1) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
|
if (fread(hdr, sizeof(hdr), 1, _sl.fh) != 1) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
|
||||||
|
|
||||||
|
@ -1689,13 +1672,13 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb)
|
||||||
/* No loader found, treat as version 0 and use LZO format */
|
/* No loader found, treat as version 0 and use LZO format */
|
||||||
if (fmt == endof(_saveload_formats)) {
|
if (fmt == endof(_saveload_formats)) {
|
||||||
DEBUG(sl, 0, "Unknown savegame type, trying to load it as the buggy format");
|
DEBUG(sl, 0, "Unknown savegame type, trying to load it as the buggy format");
|
||||||
#if defined(WINCE)
|
#if defined(WINCE)
|
||||||
/* Of course some system had not to support rewind ;) */
|
/* Of course some system had not to support rewind ;) */
|
||||||
fseek(_sl.fh, 0L, SEEK_SET);
|
fseek(_sl.fh, 0L, SEEK_SET);
|
||||||
clearerr(_sl.fh);
|
clearerr(_sl.fh);
|
||||||
#else
|
#else
|
||||||
rewind(_sl.fh);
|
rewind(_sl.fh);
|
||||||
#endif
|
#endif
|
||||||
_sl_version = 0;
|
_sl_version = 0;
|
||||||
_sl_minor_version = 0;
|
_sl_minor_version = 0;
|
||||||
fmt = _saveload_formats + 1; // LZO
|
fmt = _saveload_formats + 1; // LZO
|
||||||
|
@ -1750,6 +1733,19 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb)
|
||||||
}
|
}
|
||||||
|
|
||||||
return SL_OK;
|
return SL_OK;
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
AbortSaveLoad();
|
||||||
|
|
||||||
|
/* deinitialize compressor. */
|
||||||
|
if (_sl.excpt_uninit != NULL) _sl.excpt_uninit();
|
||||||
|
|
||||||
|
/* Skip the "color" character */
|
||||||
|
ShowInfoF(GetSaveLoadErrorString() + 3);
|
||||||
|
|
||||||
|
/* A saver/loader exception!! reinitialize all variables to prevent crash! */
|
||||||
|
return (mode == SL_LOAD) ? SL_REINIT : SL_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Do a save when exiting the game (patch option) _patches.autosave_on_exit */
|
/** Do a save when exiting the game (patch option) _patches.autosave_on_exit */
|
||||||
|
|
Loading…
Reference in New Issue