X-Git-Url: https://git.archive.openwrt.org/?p=project%2Fuci.git;a=blobdiff_plain;f=err.h;h=9dd5a59ff083ee0570c518940549f2f90aad2247;hp=469164cd635724e1248a0e5c57a27170f2cdfc2f;hb=e6279f87129e65c469a29d606a4b6afd7b7207b8;hpb=4cec5755115eb3c48dc50dfcc5558f71f00d59c6 diff --git a/err.h b/err.h index 469164c..9dd5a59 100644 --- a/err.h +++ b/err.h @@ -36,9 +36,10 @@ * * NB: this does not handle recursion at all. Calling externally visible * functions from other uci functions is only allowed at the end of the - * calling function. + * calling function, or by wrapping the function call in UCI_TRAP_SAVE + * and UCI_TRAP_RESTORE. */ -#define UCI_HANDLE_ERR(ctx) do { \ +#define UCI_HANDLE_ERR(ctx) do { \ int __val; \ if (!ctx) \ return UCI_ERR_INVAL; \ @@ -50,6 +51,26 @@ } while (0) /* + * In a block enclosed by UCI_TRAP_SAVE and UCI_TRAP_RESTORE, all exceptions + * are intercepted and redirected to the label specified in 'handler' + * after UCI_TRAP_RESTORE, or when reaching the 'handler' label, the old + * exception handler is restored + */ +#define UCI_TRAP_SAVE(ctx, handler) do { \ + jmp_buf __old_trap; \ + int __val; \ + memcpy(__old_trap, ctx->trap, sizeof(ctx->trap)); \ + __val = setjmp(ctx->trap); \ + if (__val) { \ + ctx->errno = __val; \ + memcpy(ctx->trap, __old_trap, sizeof(ctx->trap)); \ + goto handler; \ + } +#define UCI_TRAP_RESTORE(ctx) \ + memcpy(ctx->trap, __old_trap, sizeof(ctx->trap)); \ +} while(0) + +/* * check the specified condition. * throw an invalid argument exception if it's false */