diff options
Diffstat (limited to 'fitz/fitz.h')
-rw-r--r-- | fitz/fitz.h | 128 |
1 files changed, 0 insertions, 128 deletions
diff --git a/fitz/fitz.h b/fitz/fitz.h index ddffa181..7a13ef75 100644 --- a/fitz/fitz.h +++ b/fitz/fitz.h @@ -139,134 +139,6 @@ struct fz_error_context_s void fz_var_imp(void *); #define fz_var(var) fz_var_imp((void *)&(var)) -/* - -MuPDF uses a set of exception handling macros to simplify error return -and cleanup. Conceptually, they work a lot like C++'s try/catch system, -but do not require any special compiler support. - -The basic formulation is as follows: - - fz_try(ctx) - { - // Try to perform a task. Never 'return', 'goto' or 'longjmp' out - // of here. 'break' may be used to safely exit (just) the try block - // scope. - } - fz_always(ctx) - { - // Any code here is always executed, regardless of whether an - // exception was thrown within the try or not. Never 'return', 'goto' - // or longjmp out from here. 'break' may be used to safely exit (just) - // the always block scope. - } - fz_catch(ctx) - { - // This code is called (after any always block) only if something - // within the fz_try block (including any functions it called) threw - // an exception. The code here is expected to handle the exception - // (maybe record/report the error, cleanup any stray state etc) and - // can then either exit the block, or pass on the exception to a - // higher level (enclosing) fz_try block (using fz_throw, or - // fz_rethrow). - } - -The fz_always block is optional, and can safely be omitted. - -The macro based nature of this system has 3 main limitations: - -1) Never return from within try (or 'goto' or longjmp out of it). - This upsets the internal housekeeping of the macros and will cause - problems later on. The code will detect such things happening, but - by then it is too late to give a helpful error report as to where the - original infraction occurred. - -2) The fz_try(ctx) { ... } fz_always(ctx) { ... } fz_catch(ctx) { ... } - is not one atomic C statement. That is to say, if you do: - - if (condition) - fz_try(ctx) { ... } - fz_catch(ctx) { ... } - - then you will not get what you want. Use the following instead: - - if (condition) { - fz_try(ctx) { ... } - fz_catch(ctx) { ... } - } - -3) The macros are implemented using setjmp and longjmp, and so the standard - C restrictions on the use of those functions apply to fz_try/fz_catch - too. In particular, any "truly local" variable that is set between the - start of fz_try and something in fz_try throwing an exception may become - undefined as part of the process of throwing that exception. - - As a way of mitigating this problem, we provide an fz_var() macro that - tells the compiler to ensure that that variable is not unset by the - act of throwing the exception. - -A model piece of code using these macros then might be: - - house build_house(plans *p) - { - material m = NULL; - walls w = NULL; - roof r = NULL; - house h = NULL; - tiles t = make_tiles(); - - fz_var(w); - fz_var(r); - fz_var(h); - - fz_try(ctx) - { - fz_try(ctx) - { - m = make_bricks(); - } - fz_catch(ctx) - { - // No bricks available, make do with straw? - m = make_straw(); - } - w = make_walls(m, p); - r = make_roof(m, t); - h = combine(w, r); // Note, NOT: return combine(w,r); - } - fz_always(ctx) - { - drop_walls(w); - drop_roof(r); - drop_material(m); - drop_tiles(t); - } - fz_catch(ctx) - { - fz_throw(ctx, "build_house failed"); - } - return h; - } - -Things to note about this: - -a) If make_tiles throws an exception, this will immediately be handled - by some higher level exception handler. If it succeeds, t will be - set before fz_try starts, so there is no need to fz_var(t); - -b) We try first off to make some bricks as our building material. If - this fails, we fall back to straw. If this fails, we'll end up in - the fz_catch, and the process will fail neatly. - -c) We assume in this code that combine takes new reference to both the - walls and the roof it uses, and therefore that w and r need to be - cleaned up in all cases. - -d) We assume the standard C convention that it is safe to destroy - NULL things. - -*/ - /* Exception macro definitions. Just treat these as a black box - pay no * attention to the man behind the curtain. */ |