1 #include "mupdf/fitz.h"
3 #ifdef USE_OUTPUT_DEBUG_STRING
9 void fz_var_imp(void *var)
11 UNUSED(var); /* Do nothing */
14 void fz_flush_warnings(fz_context *ctx)
16 if (ctx->warn->count > 1)
18 fprintf(stderr, "warning: ... repeated %d times ...\n", ctx->warn->count);
19 LOGE("warning: ... repeated %d times ...\n", ctx->warn->count);
21 ctx->warn->message[0] = 0;
25 void fz_warn(fz_context *ctx, const char *fmt, ...)
28 char buf[sizeof ctx->warn->message];
31 vsnprintf(buf, sizeof buf, fmt, ap);
33 #ifdef USE_OUTPUT_DEBUG_STRING
34 OutputDebugStringA(buf);
35 OutputDebugStringA("\n");
38 if (!strcmp(buf, ctx->warn->message))
44 fz_flush_warnings(ctx);
45 fprintf(stderr, "warning: %s\n", buf);
46 LOGE("warning: %s\n", buf);
47 fz_strlcpy(ctx->warn->message, buf, sizeof ctx->warn->message);
54 /* When we first setjmp, code is set to 0. Whenever we throw, we add 2 to
55 * this code. Whenever we enter the always block, we add 1.
57 * fz_push_try sets code to 0.
58 * If (fz_throw called within fz_try)
59 * fz_throw makes code = 2.
60 * If (no always block present)
61 * enter catch region with code = 2. OK.
63 * fz_always entered as code < 3; Makes code = 3;
64 * if (fz_throw called within fz_always)
65 * fz_throw makes code = 5
66 * fz_always is not reentered.
67 * catch region entered with code = 5. OK.
69 * catch region entered with code = 3. OK
71 * if (no always block present)
72 * catch region not entered as code = 0. OK.
74 * fz_always entered as code < 3. makes code = 1
75 * if (fz_throw called within fz_always)
76 * fz_throw makes code = 3;
77 * fz_always NOT entered as code >= 3
78 * catch region entered with code = 3. OK.
80 * catch region entered with code = 1.
83 FZ_NORETURN static void throw(fz_error_context *ex);
85 static void throw(fz_error_context *ex)
89 fz_longjmp(ex->stack[ex->top].buffer, ex->stack[ex->top].code + 2);
93 fprintf(stderr, "uncaught exception: %s\n", ex->message);
94 LOGE("uncaught exception: %s\n", ex->message);
95 #ifdef USE_OUTPUT_DEBUG_STRING
96 OutputDebugStringA("uncaught exception: ");
97 OutputDebugStringA(ex->message);
98 OutputDebugStringA("\n");
104 int fz_push_try(fz_error_context *ex)
108 /* Normal case, get out of here quick */
109 if (ex->top < nelem(ex->stack)-1)
110 return 1; /* We exit here, and the setjmp sets the code to 0 */
111 /* We reserve the top slot on the exception stack purely to cope with
112 * the case when we overflow. If we DO hit this, then we 'throw'
113 * immediately - returning 0 stops the setjmp happening and takes us
114 * direct to the always/catch clauses. */
115 assert(ex->top == nelem(ex->stack)-1);
116 strcpy(ex->message, "exception stack overflow!");
117 ex->stack[ex->top].code = 2;
118 fprintf(stderr, "error: %s\n", ex->message);
119 LOGE("error: %s\n", ex->message);
123 int fz_caught(fz_context *ctx)
125 assert(ctx && ctx->error && ctx->error->errcode >= FZ_ERROR_NONE);
126 return ctx->error->errcode;
129 const char *fz_caught_message(fz_context *ctx)
131 assert(ctx && ctx->error && ctx->error->errcode >= FZ_ERROR_NONE);
132 return ctx->error->message;
135 void fz_throw(fz_context *ctx, int code, const char *fmt, ...)
138 ctx->error->errcode = code;
140 vsnprintf(ctx->error->message, sizeof ctx->error->message, fmt, args);
143 if (code != FZ_ERROR_ABORT)
145 fz_flush_warnings(ctx);
146 fprintf(stderr, "error: %s\n", ctx->error->message);
147 LOGE("error: %s\n", ctx->error->message);
148 #ifdef USE_OUTPUT_DEBUG_STRING
149 OutputDebugStringA("error: ");
150 OutputDebugStringA(ctx->error->message);
151 OutputDebugStringA("\n");
158 void fz_rethrow(fz_context *ctx)
160 assert(ctx && ctx->error && ctx->error->errcode >= FZ_ERROR_NONE);
164 void fz_rethrow_message(fz_context *ctx, const char *fmt, ...)
168 assert(ctx && ctx->error && ctx->error->errcode >= FZ_ERROR_NONE);
171 vsnprintf(ctx->error->message, sizeof ctx->error->message, fmt, args);
174 if (ctx->error->errcode != FZ_ERROR_ABORT)
176 fz_flush_warnings(ctx);
177 fprintf(stderr, "error: %s\n", ctx->error->message);
178 LOGE("error: %s\n", ctx->error->message);
179 #ifdef USE_OUTPUT_DEBUG_STRING
180 OutputDebugStringA("error: ");
181 OutputDebugStringA(ctx->error->message);
182 OutputDebugStringA("\n");
189 void fz_rethrow_if(fz_context *ctx, int err)
191 assert(ctx && ctx->error && ctx->error->errcode >= FZ_ERROR_NONE);
192 if (ctx->error->errcode == err)