1 /* Copyright (C) 2001-2019 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied,
8    modified or distributed except as expressly authorized under the terms
9    of the license contained in the file LICENSE in this distribution.
10 
11    Refer to licensing information at http://www.artifex.com or contact
12    Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13    CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 
17 /* Error code definitions */
18 
19 #ifndef gserrors_INCLUDED
20 #  define gserrors_INCLUDED
21 
22 /* A procedure that may return an error always returns */
23 /* a non-negative value (zero, unless otherwise noted) for success, */
24 /* or negative for failure. */
25 /* We don't use a typedef internally to avoid a lot of casting. */
26 
27 enum gs_error_type {
28     gs_error_ok = 0,
29     gs_error_unknownerror = -1,	/* unknown error */
30     gs_error_dictfull = -2,
31     gs_error_dictstackoverflow = -3,
32     gs_error_dictstackunderflow = -4,
33     gs_error_execstackoverflow = -5,
34     gs_error_interrupt = -6,
35     gs_error_invalidaccess = -7,
36     gs_error_invalidexit = -8,
37     gs_error_invalidfileaccess = -9,
38     gs_error_invalidfont = -10,
39     gs_error_invalidrestore = -11,
40     gs_error_ioerror = -12,
41     gs_error_limitcheck = -13,
42     gs_error_nocurrentpoint = -14,
43     gs_error_rangecheck = -15,
44     gs_error_stackoverflow = -16,
45     gs_error_stackunderflow = -17,
46     gs_error_syntaxerror = -18,
47     gs_error_timeout = -19,
48     gs_error_typecheck = -20,
49     gs_error_undefined = -21,
50     gs_error_undefinedfilename = -22,
51     gs_error_undefinedresult = -23,
52     gs_error_unmatchedmark = -24,
53     gs_error_VMerror = -25,		/* must be the last Level 1 error */
54 
55         /* ------ Additional Level 2 errors (also in DPS, ------ */
56 
57     gs_error_configurationerror = -26,
58     gs_error_undefinedresource = -27,
59 
60     gs_error_unregistered = -28,
61     gs_error_invalidcontext = -29,
62 /* invalidid is for the NeXT DPS extension. */
63     gs_error_invalidid = -30,
64 
65         /* ------ Pseudo-errors used internally ------ */
66 
67     gs_error_hit_detected = -99,
68 
69     gs_error_Fatal = -100,
70 /*
71  * Internal code for the .quit operator.
72  * The real quit code is an integer on the operand stack.
73  * gs_interpret returns this only for a .quit with a zero exit code.
74  */
75     gs_error_Quit = -101,
76 
77 /*
78  * Internal code for a normal exit from the interpreter.
79  * Do not use outside of interp.c.
80  */
81     gs_error_InterpreterExit = -102,
82 
83 /* Need the remap color error for high level pattern support */
84     gs_error_Remap_Color = -103,
85 
86 /*
87  * Internal code to indicate we have underflowed the top block
88  * of the e-stack.
89  */
90     gs_error_ExecStackUnderflow = -104,
91 
92 /*
93  * Internal code for the vmreclaim operator with a positive operand.
94  * We need to handle this as an error because otherwise the interpreter
95  * won't reload enough of its state when the operator returns.
96  */
97     gs_error_VMreclaim = -105,
98 
99 /*
100  * Internal code for requesting more input from run_string.
101  */
102     gs_error_NeedInput = -106,
103 
104 /*
105  * Internal code for a normal exit when usage info is displayed.
106  * This allows Window versions of Ghostscript to pause until
107  * the message can be read.
108  */
109     gs_error_Info = -110,
110 
111 /* A special 'error', like reamp color above. This is used by a subclassing
112  * device to indicate that it has fully processed a device method, and parent
113  * subclasses should not perform any further action. Currently this is limited
114  * to compositor creation.
115  */
116     gs_error_handled = -111
117 };
118 
119 /* We do provide a typedef type for external API use */
120 typedef enum gs_error_type gs_error_t;
121 
122 int gs_log_error(int, const char *, int);
123 #if !defined(DEBUG) || defined(GS_THREADSAFE)
124 #  define gs_log_error(err, file, line) (err)
125 #endif
126 #ifdef GS_THREADSAFE
127 #define gs_note_error(err) (err)
128 #define return_error(err) return (err)
129 #else
130 #define gs_note_error(err) gs_log_error(err, __FILE__, __LINE__)
131 #define return_error(err) return gs_note_error(err)
132 #endif
133 
134 #if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
135 #  if defined(__GNUC__) && __GNUC__ >= 2
136 #    define __func__ __FUNCTION__
137 #  elif defined(__FUNCTION__)
138 #    define __func__ __FUNCTION__
139 #  elif defined(__FUNC__)
140 #    define __func__ __FUNC__
141 #  else
142 #    define __func__ "<unknown>"
143 #  endif
144 #endif
145 
146 /*
147  * Error reporting macros.
148  *
149  */
150 
151 #ifndef __printflike
152 #if __GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 7
153 #define __printflike(fmtarg, firstvararg) \
154     __attribute__((__format__ (__printf__, fmtarg, firstvararg)))
155 #else
156 #define __printflike(fmtarg, firstvararg)
157 #endif
158 #endif
159 
160 const char *gs_errstr(int code);
161 
162 #ifdef GS_THREADSAFE
163 /* In threadsafe builds, we just swallow errors unreported */
164 #define gs_throw_code(code) \
165     (code)
166 
167 #define gs_throw(code, fmt) \
168     (code)
169 #define gs_throw1(code, fmt, arg1) \
170     (code)
171 #define gs_throw2(code, fmt, arg1, arg2) \
172     (code)
173 #define gs_throw3(code, fmt, arg1, arg2, arg3) \
174     (code)
175 #define gs_throw4(code, fmt, arg1, arg2, arg3, arg4) \
176     (code)
177 #define gs_throw5(code, fmt, arg1, arg2, arg3, arg4, arg5) \
178     (code)
179 #define gs_throw6(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6) \
180     (code)
181 #define gs_throw7(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
182     (code)
183 #define gs_throw8(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
184     (code)
185 #define gs_throw9(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \
186     (code)
187 
188 /* Bubble the code up the stack
189 */
190 #define gs_rethrow_code(code) \
191     (code)
192 
193 #define gs_rethrow(code, fmt) \
194     (code)
195 #define gs_rethrow1(code, fmt, arg1) \
196     (code)
197 #define gs_rethrow2(code, fmt, arg1, arg2) \
198     (code)
199 #define gs_rethrow3(code, fmt, arg1, arg2, arg3) \
200     (code)
201 #define gs_rethrow4(code, fmt, arg1, arg2, arg3, arg4) \
202     (code)
203 #define gs_rethrow5(code, fmt, arg1, arg2, arg3, arg4, arg5) \
204     (code)
205 #define gs_rethrow6(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6) \
206     (code)
207 #define gs_rethrow7(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
208     (code)
209 #define gs_rethrow8(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
210     (code)
211 #define gs_rethrow9(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \
212     (code)
213 
214 /* This will cause trouble, as it implies you are fixing an error
215  * the system will spew messages
216  */
217 #define gs_catch(code, fmt) \
218     (code)
219 #define gs_catch1(code, fmt, arg1) \
220     (code)
221 #define gs_catch2(code, fmt, arg1, arg2) \
222     (code)
223 #define gs_catch3(code, fmt, arg1, arg2, arg3) \
224     (code)
225 #define gs_catch4(code, fmt, arg1, arg2, arg3, arg4) \
226     (code)
227 #define gs_catch5(code, fmt, arg1, arg2, arg3, arg4, arg5) \
228     (code)
229 #define gs_catch6(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6) \
230     (code)
231 #define gs_catch7(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
232     (code)
233 #define gs_catch8(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
234     (code)
235 #define gs_catch9(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \
236     (code)
237 
238 /* gs_warn is a printf
239  */
240 #define gs_warn(fmt) \
241     DO_NOTHING
242 #define gs_warn1(fmt, arg1) \
243     DO_NOTHING
244 #define gs_warn2(fmt, arg1, arg2) \
245     DO_NOTHING
246 #define gs_warn3(fmt, arg1, arg2, arg3) \
247     DO_NOTHING
248 #define gs_warn4(fmt, arg1, arg2, arg3, arg4) \
249     DO_NOTHING
250 #define gs_warn5(fmt, arg1, arg2, arg3, arg4, arg5) \
251     DO_NOTHING
252 #define gs_warn6(fmt, arg1, arg2, arg3, arg4, arg5, arg6) \
253     DO_NOTHING
254 #define gs_warn7(fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
255     DO_NOTHING
256 #define gs_warn8(fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
257     DO_NOTHING
258 #define gs_warn9(fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \
259     DO_NOTHING
260 #else
261 int gs_throw_imp(const char *func, const char *file, int line,
262         int op, int code, const char *fmt, ...) __printflike(6, 7);
263 
264 /* Use throw at origin of error
265 */
266 #define gs_throw_code(code) \
267     gs_throw1((code), "%s", gs_errstr((code)))
268 
269 #define gs_throw(code, fmt) \
270     gs_throw_imp(__func__, __FILE__, __LINE__, 0, code, fmt)
271 #define gs_throw1(code, fmt, arg1) \
272     gs_throw_imp(__func__, __FILE__, __LINE__, 0, code, fmt, arg1)
273 #define gs_throw2(code, fmt, arg1, arg2) \
274     gs_throw_imp(__func__, __FILE__, __LINE__, 0, code, fmt, arg1, arg2)
275 #define gs_throw3(code, fmt, arg1, arg2, arg3) \
276     gs_throw_imp(__func__, __FILE__, __LINE__, 0, code, fmt, arg1, arg2, arg3)
277 #define gs_throw4(code, fmt, arg1, arg2, arg3, arg4) \
278     gs_throw_imp(__func__, __FILE__, __LINE__, 0, code, fmt, arg1, arg2, arg3, arg4)
279 #define gs_throw5(code, fmt, arg1, arg2, arg3, arg4, arg5) \
280     gs_throw_imp(__func__, __FILE__, __LINE__, 0, code, fmt, arg1, arg2, arg3, arg4, arg5)
281 #define gs_throw6(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6) \
282     gs_throw_imp(__func__, __FILE__, __LINE__, 0, code, fmt, arg1, arg2, arg3, arg4, arg5, arg6)
283 #define gs_throw7(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
284     gs_throw_imp(__func__, __FILE__, __LINE__, 0, code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
285 #define gs_throw8(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
286     gs_throw_imp(__func__, __FILE__, __LINE__, 0, code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
287 #define gs_throw9(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \
288     gs_throw_imp(__func__, __FILE__, __LINE__, 0, code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
289 
290 /* Bubble the code up the stack
291 */
292 #define gs_rethrow_code(code) \
293     gs_rethrow1((code), "%s", gs_errstr((code)))
294 
295 #define gs_rethrow(code, fmt) \
296     gs_throw_imp(__func__, __FILE__, __LINE__, 1, code, fmt)
297 #define gs_rethrow1(code, fmt, arg1) \
298     gs_throw_imp(__func__, __FILE__, __LINE__, 1, code, fmt, arg1)
299 #define gs_rethrow2(code, fmt, arg1, arg2) \
300     gs_throw_imp(__func__, __FILE__, __LINE__, 1, code, fmt, arg1, arg2)
301 #define gs_rethrow3(code, fmt, arg1, arg2, arg3) \
302     gs_throw_imp(__func__, __FILE__, __LINE__, 1, code, fmt, arg1, arg2, arg3)
303 #define gs_rethrow4(code, fmt, arg1, arg2, arg3, arg4) \
304     gs_throw_imp(__func__, __FILE__, __LINE__, 1, code, fmt, arg1, arg2, arg3, arg4)
305 #define gs_rethrow5(code, fmt, arg1, arg2, arg3, arg4, arg5) \
306     gs_throw_imp(__func__, __FILE__, __LINE__, 1, code, fmt, arg1, arg2, arg3, arg4, arg5)
307 #define gs_rethrow6(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6) \
308     gs_throw_imp(__func__, __FILE__, __LINE__, 1, code, fmt, arg1, arg2, arg3, arg4, arg5, arg6)
309 #define gs_rethrow7(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
310     gs_throw_imp(__func__, __FILE__, __LINE__, 1, code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
311 #define gs_rethrow8(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
312     gs_throw_imp(__func__, __FILE__, __LINE__, 1, code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
313 #define gs_rethrow9(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \
314     gs_throw_imp(__func__, __FILE__, __LINE__, 1, code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
315 
316 /* This will cause trouble, as it implies you are fixing an error
317  * the system will spew messages
318  */
319 #define gs_catch(code, fmt) \
320     gs_throw_imp(__func__, __FILE__, __LINE__, 2, code, fmt)
321 #define gs_catch1(code, fmt, arg1) \
322     gs_throw_imp(__func__, __FILE__, __LINE__, 2, code, fmt, arg1)
323 #define gs_catch2(code, fmt, arg1, arg2) \
324     gs_throw_imp(__func__, __FILE__, __LINE__, 2, code, fmt, arg1, arg2)
325 #define gs_catch3(code, fmt, arg1, arg2, arg3) \
326     gs_throw_imp(__func__, __FILE__, __LINE__, 2, code, fmt, arg1, arg2, arg3)
327 #define gs_catch4(code, fmt, arg1, arg2, arg3, arg4) \
328     gs_throw_imp(__func__, __FILE__, __LINE__, 2, code, fmt, arg1, arg2, arg3, arg4)
329 #define gs_catch5(code, fmt, arg1, arg2, arg3, arg4, arg5) \
330     gs_throw_imp(__func__, __FILE__, __LINE__, 2, code, fmt, arg1, arg2, arg3, arg4, arg5)
331 #define gs_catch6(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6) \
332     gs_throw_imp(__func__, __FILE__, __LINE__, 2, code, fmt, arg1, arg2, arg3, arg4, arg5, arg6)
333 #define gs_catch7(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
334     gs_throw_imp(__func__, __FILE__, __LINE__, 2, code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
335 #define gs_catch8(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
336     gs_throw_imp(__func__, __FILE__, __LINE__, 2, code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
337 #define gs_catch9(code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \
338     gs_throw_imp(__func__, __FILE__, __LINE__, 2, code, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
339 
340 /* gs_warn is a printf
341  */
342 #define gs_warn(fmt) \
343     (void)gs_throw_imp(__func__, __FILE__, __LINE__, 3, 0, fmt)
344 #define gs_warn1(fmt, arg1) \
345     (void)gs_throw_imp(__func__, __FILE__, __LINE__, 3, 0, fmt, arg1)
346 #define gs_warn2(fmt, arg1, arg2) \
347     (void)gs_throw_imp(__func__, __FILE__, __LINE__, 3, 0, fmt, arg1, arg2)
348 #define gs_warn3(fmt, arg1, arg2, arg3) \
349     (void)gs_throw_imp(__func__, __FILE__, __LINE__, 3, 0, fmt, arg1, arg2, arg3)
350 #define gs_warn4(fmt, arg1, arg2, arg3, arg4) \
351     (void)gs_throw_imp(__func__, __FILE__, __LINE__, 3, 0, fmt, arg1, arg2, arg3, arg4)
352 #define gs_warn5(fmt, arg1, arg2, arg3, arg4, arg5) \
353     (void)gs_throw_imp(__func__, __FILE__, __LINE__, 3, 0, fmt, arg1, arg2, arg3, arg4, arg5)
354 #define gs_warn6(fmt, arg1, arg2, arg3, arg4, arg5, arg6) \
355     (void)gs_throw_imp(__func__, __FILE__, __LINE__, 3, 0, fmt, arg1, arg2, arg3, arg4, arg5, arg6)
356 #define gs_warn7(fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
357     (void)gs_throw_imp(__func__, __FILE__, __LINE__, 3, 0, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
358 #define gs_warn8(fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
359     (void)gs_throw_imp(__func__, __FILE__, __LINE__, 3, 0, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
360 #define gs_warn9(fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \
361     (void)gs_throw_imp(__func__, __FILE__, __LINE__, 3, 0, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
362 #endif
363 
364 /* just in case you don't know 0 means no error
365  * other return codes are errors.
366  */
367 #define gs_okay 0
368 
369 #endif /* gserrors_INCLUDED */
370