| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- #include "fitz-internal.h"
- /* Warning context */
- void fz_var_imp(void *var)
- {
- UNUSED(var); /* Do nothing */
- }
- void fz_flush_warnings(fz_context *ctx)
- {
- if (ctx->warn->count > 1)
- {
- fprintf(stderr, "warning: ... repeated %d times ...\n", ctx->warn->count);
- LOGE("warning: ... repeated %d times ...\n", ctx->warn->count);
- }
- ctx->warn->message[0] = 0;
- ctx->warn->count = 0;
- }
- void fz_warn(fz_context *ctx, const char *fmt, ...)
- {
- va_list ap;
- char buf[sizeof ctx->warn->message];
- va_start(ap, fmt);
- vsnprintf(buf, sizeof buf, fmt, ap);
- va_end(ap);
- if (!strcmp(buf, ctx->warn->message))
- {
- ctx->warn->count++;
- }
- else
- {
- fz_flush_warnings(ctx);
- fprintf(stderr, "warning: %s\n", buf);
- LOGE("warning: %s\n", buf);
- fz_strlcpy(ctx->warn->message, buf, sizeof ctx->warn->message);
- ctx->warn->count = 1;
- }
- }
- /* Error context */
- /* When we first setjmp, code is set to 0. Whenever we throw, we add 2 to
- * this code. Whenever we enter the always block, we add 1.
- *
- * fz_push_try sets code to 0.
- * If (fz_throw called within fz_try)
- * fz_throw makes code = 2.
- * If (no always block present)
- * enter catch region with code = 2. OK.
- * else
- * fz_always entered as code < 3; Makes code = 3;
- * if (fz_throw called within fz_always)
- * fz_throw makes code = 5
- * fz_always is not reentered.
- * catch region entered with code = 5. OK.
- * else
- * catch region entered with code = 3. OK
- * else
- * if (no always block present)
- * catch region not entered as code = 0. OK.
- * else
- * fz_always entered as code < 3. makes code = 1
- * if (fz_throw called within fz_always)
- * fz_throw makes code = 3;
- * fz_always NOT entered as code >= 3
- * catch region entered with code = 3. OK.
- * else
- * catch region entered with code = 1.
- */
- static void throw(fz_error_context *ex)
- {
- if (ex->top >= 0) {
- fz_longjmp(ex->stack[ex->top].buffer, ex->stack[ex->top].code + 2);
- } else {
- fprintf(stderr, "uncaught exception: %s\n", ex->message);
- LOGE("uncaught exception: %s\n", ex->message);
- exit(EXIT_FAILURE);
- }
- }
- int fz_push_try(fz_error_context *ex)
- {
- assert(ex);
- ex->top++;
- /* Normal case, get out of here quick */
- if (ex->top < nelem(ex->stack)-1)
- return 1; /* We exit here, and the setjmp sets the code to 0 */
- /* We reserve the top slot on the exception stack purely to cope with
- * the case when we overflow. If we DO hit this, then we 'throw'
- * immediately - returning 0 stops the setjmp happening and takes us
- * direct to the always/catch clauses. */
- assert(ex->top == nelem(ex->stack)-1);
- strcpy(ex->message, "exception stack overflow!");
- ex->stack[ex->top].code = 2;
- fprintf(stderr, "error: %s\n", ex->message);
- LOGE("error: %s\n", ex->message);
- return 0;
- }
- const char *fz_caught(fz_context *ctx)
- {
- assert(ctx);
- assert(ctx->error);
- return ctx->error->message;
- }
- void fz_throw(fz_context *ctx, const char *fmt, ...)
- {
- va_list args;
- va_start(args, fmt);
- vsnprintf(ctx->error->message, sizeof ctx->error->message, fmt, args);
- va_end(args);
- fz_flush_warnings(ctx);
- fprintf(stderr, "error: %s\n", ctx->error->message);
- LOGE("error: %s\n", ctx->error->message);
- throw(ctx->error);
- }
- void fz_rethrow(fz_context *ctx)
- {
- throw(ctx->error);
- }
|