Skip to content

Commit

Permalink
Merge pull request #23 from cspiegel/fix-exceptions
Browse files Browse the repository at this point in the history
[Bocfel] Fix exception handling
  • Loading branch information
angstsmurf authored Feb 2, 2021
2 parents 848d1fe + 6eb1891 commit fdffe94
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 20 deletions.
24 changes: 6 additions & 18 deletions terps/bocfel/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,26 +319,14 @@ bool zterp_io_close_memory(zterp_io *io, uint8_t **buf, long *n)
return true;
}

/* Turn on “exception handling” for this I/O object. After calling this
* function, all future I/O calls which return a bool will now instead
* cause this function to return false in case of error. Simple usage:
*
* if(!zterp_io_try(io)) return ERROR;
* // call I/O functions here
*
* This *only* affects boolean functions. Those which return non-boolean
* values, such as zterp_io_write() and zterp_io_getc() are unaffected.
* This may be inconsistent, at least for zterp_io_getc(), which can
* return a failure condition, but non-boolean functions are not
* currently used with exception handling, so it’s not relevant.
*/
bool zterp_io_try(zterp_io *io)
void zterp_io_set_exception_mode(zterp_io *io, bool mode)
{
io->exception_mode = true;

if(setjmp(io->exception) != 0) return false;
io->exception_mode = mode;
}

return true;
jmp_buf *zterp_io_get_exception(zterp_io *io)
{
return &io->exception;
}

static bool wrap(zterp_io *io, bool b)
Expand Down
26 changes: 25 additions & 1 deletion terps/bocfel/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#ifndef ZTERP_IO_H
#define ZTERP_IO_H

#include <setjmp.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
Expand All @@ -24,13 +25,36 @@ enum zterp_io_purpose
ZTERP_IO_INPUT,
};

void zterp_io_set_exception_mode(zterp_io *, bool);
jmp_buf *zterp_io_get_exception(zterp_io *);

/* Turn on “exception handling” for this I/O object. After calling this
* macro, all future I/O calls which return a bool will now instead
* cause this macro to set “ok” to false in case of error. Simple usage:
*
* bool ok;
* zterp_io_try(io, ok);
* if (!ok) return ERROR;
* // call I/O functions here
*
* This *only* affects boolean functions. Those which return non-boolean
* values, such as zterp_io_write() and zterp_io_getc() are unaffected.
* This may be inconsistent, at least for zterp_io_getc(), which can
* return a failure condition, but non-boolean functions are not
* currently used with exception handling, so it’s not relevant.
*/
#define zterp_io_try(io, ok) do { \
zterp_io_set_exception_mode(io, true); \
if (setjmp(*zterp_io_get_exception(io)) != 0) ok = false; \
else ok = true; \
} while (false)

zterp_io *zterp_io_open(const char *, enum zterp_io_mode, enum zterp_io_purpose);
zterp_io *zterp_io_open_memory(const void *, size_t);
zterp_io *zterp_io_stdin(void);
zterp_io *zterp_io_stdout(void);
void zterp_io_close(zterp_io *);
bool zterp_io_close_memory(zterp_io *, uint8_t **, long *);
bool zterp_io_try(zterp_io *);
bool zterp_io_seek(zterp_io *, long, int);
long zterp_io_tell(zterp_io *);
size_t zterp_io_read(zterp_io *, void *, size_t);
Expand Down
4 changes: 3 additions & 1 deletion terps/bocfel/stack.c
Original file line number Diff line number Diff line change
Expand Up @@ -747,8 +747,10 @@ static void write_chunk(zterp_io *io, char (*(*writefunc)(zterp_io *))[5])
bool save_quetzal(zterp_io *savefile, bool is_meta, bool store_history)
{
long file_size;
bool ok;

if(!zterp_io_try(savefile)) return false;
zterp_io_try(savefile, ok);
if (!ok) return false;

zterp_io_write_exact(savefile, "FORM", 4);
zterp_io_write32(savefile, 0); /* to be filled in */
Expand Down

0 comments on commit fdffe94

Please sign in to comment.