move uci_list_configs to file.c
[project/uci.git] / err.h
diff --git a/err.h b/err.h
index 469164c..9dd5a59 100644 (file)
--- a/err.h
+++ b/err.h
  *
  * 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;   \
 } 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
  */