Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7640 views
1
#include "mupdf/fitz.h"
2
3
#ifdef USE_OUTPUT_DEBUG_STRING
4
#include <windows.h>
5
#endif
6
7
/* Warning context */
8
9
void fz_var_imp(void *var)
10
{
11
UNUSED(var); /* Do nothing */
12
}
13
14
void fz_flush_warnings(fz_context *ctx)
15
{
16
if (ctx->warn->count > 1)
17
{
18
fprintf(stderr, "warning: ... repeated %d times ...\n", ctx->warn->count);
19
LOGE("warning: ... repeated %d times ...\n", ctx->warn->count);
20
}
21
ctx->warn->message[0] = 0;
22
ctx->warn->count = 0;
23
}
24
25
void fz_warn(fz_context *ctx, const char *fmt, ...)
26
{
27
va_list ap;
28
char buf[sizeof ctx->warn->message];
29
30
va_start(ap, fmt);
31
vsnprintf(buf, sizeof buf, fmt, ap);
32
va_end(ap);
33
#ifdef USE_OUTPUT_DEBUG_STRING
34
OutputDebugStringA(buf);
35
OutputDebugStringA("\n");
36
#endif
37
38
if (!strcmp(buf, ctx->warn->message))
39
{
40
ctx->warn->count++;
41
}
42
else
43
{
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);
48
ctx->warn->count = 1;
49
}
50
}
51
52
/* Error context */
53
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.
56
*
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.
62
* else
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.
68
* else
69
* catch region entered with code = 3. OK
70
* else
71
* if (no always block present)
72
* catch region not entered as code = 0. OK.
73
* else
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.
79
* else
80
* catch region entered with code = 1.
81
*/
82
83
FZ_NORETURN static void throw(fz_error_context *ex);
84
85
static void throw(fz_error_context *ex)
86
{
87
if (ex->top >= 0)
88
{
89
fz_longjmp(ex->stack[ex->top].buffer, ex->stack[ex->top].code + 2);
90
}
91
else
92
{
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");
99
#endif
100
exit(EXIT_FAILURE);
101
}
102
}
103
104
int fz_push_try(fz_error_context *ex)
105
{
106
assert(ex);
107
ex->top++;
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);
120
return 0;
121
}
122
123
int fz_caught(fz_context *ctx)
124
{
125
assert(ctx && ctx->error && ctx->error->errcode >= FZ_ERROR_NONE);
126
return ctx->error->errcode;
127
}
128
129
const char *fz_caught_message(fz_context *ctx)
130
{
131
assert(ctx && ctx->error && ctx->error->errcode >= FZ_ERROR_NONE);
132
return ctx->error->message;
133
}
134
135
void fz_throw(fz_context *ctx, int code, const char *fmt, ...)
136
{
137
va_list args;
138
ctx->error->errcode = code;
139
va_start(args, fmt);
140
vsnprintf(ctx->error->message, sizeof ctx->error->message, fmt, args);
141
va_end(args);
142
143
if (code != FZ_ERROR_ABORT)
144
{
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");
152
#endif
153
}
154
155
throw(ctx->error);
156
}
157
158
void fz_rethrow(fz_context *ctx)
159
{
160
assert(ctx && ctx->error && ctx->error->errcode >= FZ_ERROR_NONE);
161
throw(ctx->error);
162
}
163
164
void fz_rethrow_message(fz_context *ctx, const char *fmt, ...)
165
{
166
va_list args;
167
168
assert(ctx && ctx->error && ctx->error->errcode >= FZ_ERROR_NONE);
169
170
va_start(args, fmt);
171
vsnprintf(ctx->error->message, sizeof ctx->error->message, fmt, args);
172
va_end(args);
173
174
if (ctx->error->errcode != FZ_ERROR_ABORT)
175
{
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");
183
#endif
184
}
185
186
throw(ctx->error);
187
}
188
189
void fz_rethrow_if(fz_context *ctx, int err)
190
{
191
assert(ctx && ctx->error && ctx->error->errcode >= FZ_ERROR_NONE);
192
if (ctx->error->errcode == err)
193
fz_rethrow(ctx);
194
}
195
196