filter out duplicate changes when using uci_set to change option values
[project/uci.git] / uci_internal.h
index fdaf04a..111982e 100644 (file)
@@ -42,7 +42,8 @@ struct uci_parse_context
 __plugin void *uci_malloc(struct uci_context *ctx, size_t size);
 __plugin void *uci_realloc(struct uci_context *ctx, void *ptr, size_t size);
 __plugin char *uci_strdup(struct uci_context *ctx, const char *str);
-__plugin void uci_add_history(struct uci_context *ctx, struct uci_list *list, int cmd, char *section, char *option, char *value);
+__plugin bool uci_validate_str(const char *str, bool name);
+__plugin void uci_add_history(struct uci_context *ctx, struct uci_list *list, int cmd, const char *section, const char *option, const char *value);
 __plugin void uci_free_history(struct uci_history *h);
 __plugin struct uci_package *uci_alloc_package(struct uci_context *ctx, const char *name);
 
@@ -110,15 +111,16 @@ struct uci_backend _var = {               \
 #define UCI_HANDLE_ERR(ctx) do {       \
        DPRINTF("ENTER: %s\n", __func__); \
        int __val = 0;                  \
-       ctx->errno = 0;                 \
+       ctx->err = 0;                   \
        if (!ctx)                       \
                return UCI_ERR_INVAL;   \
-       if (!ctx->internal)             \
+       if (!ctx->internal && !ctx->nested) \
                __val = setjmp(ctx->trap); \
        ctx->internal = false;          \
+       ctx->nested = false;            \
        if (__val) {                    \
                DPRINTF("LEAVE: %s, ret=%d\n", __func__, __val); \
-               ctx->errno = __val;     \
+               ctx->err = __val;       \
                return __val;           \
        }                               \
 } while (0)
@@ -135,7 +137,7 @@ struct uci_backend _var = {         \
        memcpy(__old_trap, ctx->trap, sizeof(ctx->trap)); \
        __val = setjmp(ctx->trap);      \
        if (__val) {                    \
-               ctx->errno = __val;     \
+               ctx->err = __val;       \
                memcpy(ctx->trap, __old_trap, sizeof(ctx->trap)); \
                goto handler;           \
        }
@@ -154,6 +156,18 @@ struct uci_backend _var = {                \
        func(ctx, __VA_ARGS__);         \
 } while (0)
 
+/**
+ * UCI_NESTED: Do an normal nested call of a public API function
+ * 
+ * Sets Exception handling to passthrough mode.
+ * Allows API functions to change behavior compared to public use
+ */
+#define UCI_NESTED(func, ctx, ...) do { \
+       ctx->nested = true;             \
+       func(ctx, __VA_ARGS__);         \
+} while (0)
+
+
 /*
  * check the specified condition.
  * throw an invalid argument exception if it's false