This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git


The following commit(s) were added to refs/heads/master by this push:
     new 34b32c4  sys/config: Extended callbacks
34b32c4 is described below

commit 34b32c4c2f68da3fe80276ded7b0e62f0c319e5d
Author: Christopher Collins <ccoll...@apache.org>
AuthorDate: Fri Feb 7 11:19:13 2020 -0800

    sys/config: Extended callbacks
    
    The four conf_handler callbacks (get, set, commit, and export) do not
    accept a `void *arg` parameter.  This means every config group must
    define a dedicated set of callback functions, making it impossible wrap
    the config API in a generic way.
    
    This commit allows config groups to be defined as "extended".  An
    extended config group uses slightly different callbacks.  These
    callbacks do take a `void *arg` parameter.
    
    To define an extended config group, set its `ch_ext` member to 1.
---
 sys/config/include/config/config.h | 42 +++++++++++++++--
 sys/config/src/config.c            | 97 +++++++++++++++++++++++++++++++++-----
 sys/config/src/config_cli.c        |  4 +-
 sys/config/src/config_priv.h       |  6 +++
 sys/config/src/config_store.c      | 17 +++----
 5 files changed, 137 insertions(+), 29 deletions(-)

diff --git a/sys/config/include/config/config.h 
b/sys/config/include/config/config.h
index 71491e4..116f629 100644
--- a/sys/config/include/config/config.h
+++ b/sys/config/include/config/config.h
@@ -26,6 +26,7 @@
 
 #include <os/queue.h>
 #include <stdint.h>
+#include <stdbool.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -114,6 +115,7 @@ typedef enum conf_export_tgt conf_export_tgt_t;
  * @return A pointer to val or NULL if error.
  */
 typedef char *(*conf_get_handler_t)(int argc, char **argv, char *val, int 
val_len_max);
+typedef char *(*conf_get_handler_ext_t)(int argc, char **argv, char *val, int 
val_len_max, void *arg);
 
 /**
  * Set the configuration variable pointed to by argc and argv.  See
@@ -128,6 +130,7 @@ typedef char *(*conf_get_handler_t)(int argc, char **argv, 
char *val, int val_le
  * @return 0 on success, non-zero error code on failure.
  */
 typedef int (*conf_set_handler_t)(int argc, char **argv, char *val);
+typedef int (*conf_set_handler_ext_t)(int argc, char **argv, char *val, void 
*arg);
 
 /**
  * Commit shadow configuration state to the active configuration.
@@ -135,6 +138,7 @@ typedef int (*conf_set_handler_t)(int argc, char **argv, 
char *val);
  * @return 0 on success, non-zero error code on failure.
  */
 typedef int (*conf_commit_handler_t)(void);
+typedef int (*conf_commit_handler_ext_t)(void *arg);
 
 /**
  * Called per-configuration variable being exported.
@@ -154,7 +158,9 @@ typedef void (*conf_export_func_t)(char *name, char *val);
  * @return 0 on success, non-zero error code on failure.
  */
 typedef int (*conf_export_handler_t)(conf_export_func_t export_func,
-        conf_export_tgt_t tgt);
+                                     conf_export_tgt_t tgt);
+typedef int (*conf_export_handler_ext_t)(conf_export_func_t export_func,
+                                         conf_export_tgt_t tgt, void *arg);
 
 /**
  * Configuration handler, used to register a config item/subtree.
@@ -165,14 +171,40 @@ struct conf_handler {
      * The name of the conifguration item/subtree
      */
     char *ch_name;
+
+    /**
+     * Whether to use the extended callbacks.
+     * false: standard
+     * true:  extended
+     */
+    bool ch_ext;
+
     /** Get configuration value */
-    conf_get_handler_t ch_get;
+    union {
+        conf_get_handler_t ch_get;
+        conf_get_handler_ext_t ch_get_ext;
+    };
+
     /** Set configuration value */
-    conf_set_handler_t ch_set;
+    union {
+        conf_set_handler_t ch_set;
+        conf_set_handler_ext_t ch_set_ext;
+    };
+
     /** Commit configuration value */
-    conf_commit_handler_t ch_commit;
+    union {
+        conf_commit_handler_t ch_commit;
+        conf_commit_handler_ext_t ch_commit_ext;
+    };
+
     /** Export configuration value */
-    conf_export_handler_t ch_export;
+    union {
+        conf_export_handler_t ch_export;
+        conf_export_handler_ext_t ch_export_ext;
+    };
+
+    /** Custom argument that gets passed to the extended callbacks */
+    void *ch_arg;
 };
 
 void conf_init(void);
diff --git a/sys/config/src/config.c b/sys/config/src/config.c
index cd0bae2..a1b08e0 100644
--- a/sys/config/src/config.c
+++ b/sys/config/src/config.c
@@ -309,6 +309,84 @@ conf_str_from_bytes(void *vp, int vp_len, char *buf, int 
buf_len)
     return buf;
 }
 
+/**
+ * Executes a conf_handler's "get" callback and returns the result.
+ */
+static char *
+conf_get_cb(struct conf_handler *ch, int argc, char **argv, char *val,
+            int val_len_max)
+{
+    if (ch->ch_ext) {
+        if (ch->ch_get_ext != NULL) {
+            return ch->ch_get_ext(argc, argv, val, val_len_max, ch->ch_arg);
+        }
+    } else {
+        if (ch->ch_get != NULL) {
+            return ch->ch_get(argc, argv, val, val_len_max);
+        }
+    }
+
+    return NULL;
+}
+
+/**
+ * Executes a conf_handler's "set" callback and returns the result.
+ */
+static int
+conf_set_cb(struct conf_handler *ch, int argc, char **argv, char *val)
+{
+    if (ch->ch_ext) {
+        if (ch->ch_set_ext != NULL) {
+            return ch->ch_set_ext(argc, argv, val, ch->ch_arg);
+        }
+    } else {
+        if (ch->ch_set != NULL) {
+            return ch->ch_set(argc, argv, val);
+        }
+    }
+
+    return OS_ERROR;
+}
+
+/**
+ * Executes a conf_handler's "commit" callback and returns the result.
+ */
+static int
+conf_commit_cb(struct conf_handler *ch)
+{
+    if (ch->ch_ext) {
+        if (ch->ch_commit_ext != NULL) {
+            return ch->ch_commit_ext(ch->ch_arg);
+        }
+    } else {
+        if (ch->ch_commit != NULL) {
+            return ch->ch_commit();
+        }
+    }
+
+    return 0;
+}
+
+/**
+ * Executes a conf_handler's "export" callback and returns the result.
+ */
+int
+conf_export_cb(struct conf_handler *ch, conf_export_func_t export_func,
+               conf_export_tgt_t tgt)
+{
+    if (ch->ch_ext) {
+        if (ch->ch_export_ext != NULL) {
+            return ch->ch_export_ext(export_func, tgt, ch->ch_arg);
+        }
+    } else {
+        if (ch->ch_export != NULL) {
+            return ch->ch_export(export_func, tgt);
+        }
+    }
+
+    return 0;
+}
+
 int
 conf_set_value(char *name, char *val_str)
 {
@@ -323,7 +401,9 @@ conf_set_value(char *name, char *val_str)
         rc = OS_INVALID_PARM;
         goto out;
     }
-    rc = ch->ch_set(name_argc - 1, &name_argv[1], val_str);
+
+    rc = conf_set_cb(ch, name_argc - 1, &name_argv[1], val_str);
+
 out:
     conf_unlock();
     return rc;
@@ -349,15 +429,14 @@ conf_get_value(char *name, char *buf, int buf_len)
         goto out;
     }
 
-    if (!ch->ch_get) {
-        goto out;
-    }
-    rval = ch->ch_get(name_argc - 1, &name_argv[1], buf, buf_len);
+    rval = conf_get_cb(ch, name_argc - 1, &name_argv[1], buf, buf_len);
+
 out:
     conf_unlock();
     return rval;
 }
 
+
 int
 conf_commit(char *name)
 {
@@ -374,16 +453,12 @@ conf_commit(char *name)
             rc = OS_INVALID_PARM;
             goto out;
         }
-        if (ch->ch_commit) {
-            rc = ch->ch_commit();
-        } else {
-            rc = 0;
-        }
+        rc = conf_commit_cb(ch);
     } else {
         rc = 0;
         SLIST_FOREACH(ch, &conf_handlers, ch_list) {
             if (ch->ch_commit) {
-                rc2 = ch->ch_commit();
+                rc2 = conf_commit_cb(ch);
                 if (!rc) {
                     rc = rc2;
                 }
diff --git a/sys/config/src/config_cli.c b/sys/config/src/config_cli.c
index 87af242..bea8947 100644
--- a/sys/config/src/config_cli.c
+++ b/sys/config/src/config_cli.c
@@ -51,9 +51,7 @@ conf_dump_running(void)
 
     conf_lock();
     SLIST_FOREACH(ch, &conf_handlers, ch_list) {
-        if (ch->ch_export) {
-            ch->ch_export(conf_running_one, CONF_EXPORT_SHOW);
-        }
+        conf_export_cb(ch, conf_running_one, CONF_EXPORT_SHOW);
     }
     conf_unlock();
 }
diff --git a/sys/config/src/config_priv.h b/sys/config/src/config_priv.h
index 7ae6051..6b0178c 100644
--- a/sys/config/src/config_priv.h
+++ b/sys/config/src/config_priv.h
@@ -34,6 +34,12 @@ int conf_line_make2(char *dst, int dlen, const char *name, 
const char *value);
 struct conf_handler *conf_parse_and_lookup(char *name, int *name_argc,
                                            char *name_argv[]);
 
+/**
+ * Executes a conf_handler's "export" callback and returns the result.
+ */
+int conf_export_cb(struct conf_handler *ch, conf_export_func_t export_func,
+                   conf_export_tgt_t tgt);
+
 SLIST_HEAD(conf_store_head, conf_store);
 extern struct conf_store_head conf_load_srcs;
 SLIST_HEAD(conf_handler_head, conf_handler);
diff --git a/sys/config/src/config_store.c b/sys/config/src/config_store.c
index 68597eb..07b94d7 100644
--- a/sys/config/src/config_store.c
+++ b/sys/config/src/config_store.c
@@ -260,16 +260,15 @@ conf_save_tree(char *name)
     int rc;
 
     conf_lock();
+
     ch = conf_parse_and_lookup(name, &name_argc, name_argv);
     if (!ch) {
         rc = OS_INVALID_PARM;
         goto out;
     }
-    if (ch->ch_export) {
-        rc = ch->ch_export(conf_store_one, CONF_EXPORT_PERSIST);
-    } else {
-        rc = 0;
-    }
+
+    rc = conf_export_cb(ch, conf_store_one, CONF_EXPORT_PERSIST);
+
 out:
     conf_unlock();
     return rc;
@@ -300,11 +299,9 @@ conf_save(void)
     }
     rc = 0;
     SLIST_FOREACH(ch, &conf_handlers, ch_list) {
-        if (ch->ch_export) {
-            rc2 = ch->ch_export(conf_store_one, CONF_EXPORT_PERSIST);
-            if (!rc) {
-                rc = rc2;
-            }
+        rc2 = conf_export_cb(ch, conf_store_one, CONF_EXPORT_PERSIST);
+        if (!rc) {
+            rc = rc2;
         }
     }
     if (cs->cs_itf->csi_save_end) {

Reply via email to