summaryrefslogtreecommitdiff
path: root/source/fitz/error.c
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2017-09-06 17:03:04 +0200
committerTor Andersson <tor.andersson@artifex.com>2018-10-26 15:29:11 +0200
commitb3ceba9fa1d19c1004aec38b0a8870154a865ea4 (patch)
treebc94d586b4fc6af72ba347ebf1d8ef5c4fd74c61 /source/fitz/error.c
parent4f8796cafcd5c15247fb85e7febd1bb591d0a853 (diff)
downloadmupdf-b3ceba9fa1d19c1004aec38b0a8870154a865ea4.tar.xz
Rewrite try/always/catch macros to allow fz_context to be opaque.
Hide fz_stack_slot and exception handling details too. Also make sure we have an initialized jmp_buf so we can safely throw from the always block even in the exception stack overflow case.
Diffstat (limited to 'source/fitz/error.c')
-rw-r--r--source/fitz/error.c60
1 files changed, 34 insertions, 26 deletions
diff --git a/source/fitz/error.c b/source/fitz/error.c
index fe1045dd..8f4d6f50 100644
--- a/source/fitz/error.c
+++ b/source/fitz/error.c
@@ -123,19 +123,17 @@ FZ_NORETURN static void throw(fz_context *ctx)
}
}
-/* Only called when we hit the bottom of the exception stack.
- * Do the same as fz_throw, but don't actually throw. */
-static int fz_fake_throw(fz_context *ctx, int code, const char *fmt, ...)
+void *fz_push_try(fz_context *ctx)
{
- va_list args;
- ctx->error->errcode = code;
- va_start(args, fmt);
- fz_vsnprintf(ctx->error->message, sizeof ctx->error->message, fmt, args);
- ctx->error->message[sizeof(ctx->error->message) - 1] = 0;
- va_end(args);
-
- if (code != FZ_ERROR_ABORT)
+ /* If we would overflow the exception stack, throw an exception instead
+ * of entering the try block. We assume that we always have room for
+ * 1 extra level on the stack here - i.e. we throw the error on us
+ * starting to use the last level. */
+ if (ctx->error->top + 2 >= ctx->error->stack + nelem(ctx->error->stack))
{
+ ctx->error->errcode = FZ_ERROR_GENERIC;
+ fz_strlcpy(ctx->error->message, "exception stack overflow!", sizeof ctx->error->message);
+
fz_flush_warnings(ctx);
fprintf(stderr, "error: %s\n", ctx->error->message);
#ifdef USE_OUTPUT_DEBUG_STRING
@@ -146,27 +144,37 @@ static int fz_fake_throw(fz_context *ctx, int code, const char *fmt, ...)
#ifdef USE_ANDROID_LOG
__android_log_print(ANDROID_LOG_ERROR, "libmupdf", "%s", ctx->error->message);
#endif
+
+ /* We need to arrive in the always/catch block as if throw had taken place. */
+ ctx->error->top++;
+ ctx->error->top->code = 2;
+ }
+ else
+ {
+ ctx->error->top++;
+ ctx->error->top->code = 0;
}
+ return ctx->error->top->buffer;
+}
- /* We need to arrive in the always/catch block as if throw
- * had taken place. */
- ctx->error->top++;
- ctx->error->top->code = 2;
- return 0;
+int fz_do_try(fz_context *ctx)
+{
+ return ctx->error->top->code == 0;
}
-int fz_push_try(fz_context *ctx)
+int fz_do_always(fz_context *ctx)
{
- /* If we would overflow the exception stack, throw an exception instead
- * of entering the try block. We assume that we always have room for
- * 1 extra level on the stack here - i.e. we throw the error on us
- * starting to use the last level. */
- if (ctx->error->top + 2 >= ctx->error->stack + nelem(ctx->error->stack))
- return fz_fake_throw(ctx, FZ_ERROR_GENERIC, "exception stack overflow!");
+ if (ctx->error->top->code < 3)
+ {
+ ctx->error->top->code++;
+ return 1;
+ }
+ return 0;
+}
- ctx->error->top++;
- ctx->error->top->code = 0;
- return 1;
+int fz_do_catch(fz_context *ctx)
+{
+ return (ctx->error->top--)->code > 1;
}
int fz_caught(fz_context *ctx)