Mercurial > molko
changeset 88:44de3c528b63
core: implement basic panic mechanism, continue #2484 @1h
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 12 Mar 2020 12:44:00 +0100 |
parents | ebbf35d90088 |
children | 30baadb6f6a2 |
files | .hgignore Makefile src/core/panic.c src/core/panic.h src/core/util.c tests/test-panic.c |
diffstat | 6 files changed, 185 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Wed Mar 11 20:36:10 2020 +0100 +++ b/.hgignore Thu Mar 12 12:44:00 2020 +0100 @@ -17,6 +17,7 @@ ^tests/test-error(\.exe)?$ ^tests/test-inventory(\.exe)?$ ^tests/test-map(\.exe)?$ +^tests/test-panic(\.exe)?$ ^tests/test-save(\.exe)?$ ^tests/test-script(\.exe)?$ ^tools/molko-map(\.exe)?$
--- a/Makefile Wed Mar 11 20:36:10 2020 +0100 +++ b/Makefile Thu Mar 12 12:44:00 2020 +0100 @@ -47,6 +47,7 @@ src/core/map_state.c \ src/core/message.c \ src/core/painter.c \ + src/core/panic.c \ src/core/save.c \ src/core/script.c \ src/core/sprite.c \ @@ -79,6 +80,7 @@ tests/test-error.c \ tests/test-inventory.c \ tests/test-map.c \ + tests/test-panic.c \ tests/test-save.c \ tests/test-script.c TESTS_INCS= -I extern/libgreatest -I src/core ${SDL_CFLAGS}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/panic.c Thu Mar 12 12:44:00 2020 +0100 @@ -0,0 +1,46 @@ +/* + * panic.c -- unrecoverable error handling + * + * Copyright (c) 2020 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <assert.h> + +#include "error.h" +#include "panic.h" + +void (*panic_handler)(void) = error_fatal; + +void +panic(const char *fmt, ...) +{ + assert(fmt); + + va_list ap; + + va_start(ap, fmt); + panicv(fmt, ap); + va_end(ap); +} + +void +panicv(const char *fmt, va_list ap) +{ + assert(fmt); + assert(panic_handler); + + error_vprintf(fmt, ap); + panic_handler(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/panic.h Thu Mar 12 12:44:00 2020 +0100 @@ -0,0 +1,72 @@ +/* + * panic.h -- unrecoverable error handling + * + * Copyright (c) 2020 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MOLKO_PANIC_H +#define MOLKO_PANIC_H + +/** + * \file panic.h + * \brief Unrecoverable error handling. + * \ingroup basics + * + * This set of functions should be used to detect runtime errors that are + * unexpected. They should be used only when the game cannot continue because + * it is in a unrecoverable state. + * + * Examples of appropriate use cases: + * + * - Game saved data is corrupt, + * - Assets are missing, + * - No more memory. + * + * In other contexts, use asserts to indicates programming error and + * appropriate solutions to recover the game otherwise. + */ + +#include <stdarg.h> + +/** + * \brief Global panic handler. + * + * The default implementation shows the last error and exit with code 1. + */ +extern void (*panic_handler)(void); + +/** + * Terminate the program using the \ref panic_handler routine. + * + * This function will first set the global error with the provided format + * string and then call the handler. + * + * \pre fmt != NULL + * \param fmt the printf(3) format string + */ +void +panic(const char *fmt, ...); + +/** + * Similar to \ref panic but with a va_list argument instead. + * + * \pre fmt != NULL + * \param fmt the printf(3) format string + * \param ap the arguments pointer + */ +void +panicv(const char *fmt, va_list ap); + +#endif /* !MOLKO_PANIC_H */
--- a/src/core/util.c Wed Mar 11 20:36:10 2020 +0100 +++ b/src/core/util.c Thu Mar 12 12:44:00 2020 +0100 @@ -22,8 +22,8 @@ #include <SDL.h> +#include "panic.h" #include "util.h" -#include "error.h" void * emalloc(size_t size) @@ -31,7 +31,7 @@ void *mem; if (!(mem = malloc(size))) - error_fatalf("%s\n", strerror(errno)); + panic("%s\n", strerror(errno)); return mem; } @@ -42,7 +42,7 @@ void *mem; if (!(mem = calloc(n, size))) - error_fatalf("%s\n", strerror(errno)); + panic("%s\n", strerror(errno)); return mem; } @@ -53,7 +53,7 @@ void *mem; if (!(mem = malloc(size))) - error_fatalf("%s\n", strerror(errno)); + panic("%s\n", strerror(errno)); return memcpy(mem, ptr, size); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-panic.c Thu Mar 12 12:44:00 2020 +0100 @@ -0,0 +1,60 @@ +/* + * test-panic.c -- test panic routines + * + * Copyright (c) 2020 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdbool.h> + +#define GREATEST_USE_ABBREVS 0 +#include <greatest.h> + +#include <error.h> +#include <panic.h> + +static bool handler_called; + +static void +handler(void) +{ + handler_called = true; +} + +GREATEST_TEST +basics_simple(void) +{ + panic_handler = handler; + handler_called = false; + + panic("this is an error"); + GREATEST_ASSERT(handler_called); + GREATEST_ASSERT_STR_EQ(error(), "this is an error"); + GREATEST_PASS(); +} + +GREATEST_SUITE(basics) +{ + GREATEST_RUN_TEST(basics_simple); +} + +GREATEST_MAIN_DEFS(); + +int +main(int argc, char **argv) +{ + GREATEST_MAIN_BEGIN(); + GREATEST_RUN_SUITE(basics); + GREATEST_MAIN_END(); +}