Merge branch 'collectd-5.7'
[collectd.git] / src / curl_json.c
index 6f31145..a589cd6 100644 (file)
@@ -86,7 +86,6 @@ struct cj_s /* {{{ */
 
   yajl_handle yajl;
   c_avl_tree_t *tree;
-  cj_key_t *key;
   int depth;
   struct {
     union {
@@ -107,7 +106,11 @@ typedef unsigned int yajl_len_t;
 #endif
 
 static int cj_read(user_data_t *ud);
-static void cj_submit(cj_t *db, cj_key_t *key, value_t *value);
+static void cj_submit_impl(cj_t *db, cj_key_t *key, value_t *value);
+
+/* cj_submit is a function pointer to cj_submit_impl, allowing the unit-test to
+ * overwrite which function is called. */
+static void (*cj_submit)(cj_t *, cj_key_t *, value_t *) = cj_submit_impl;
 
 static size_t cj_curl_callback(void *buf, /* {{{ */
                                size_t size, size_t nmemb, void *user_data) {
@@ -440,6 +443,53 @@ static int cj_config_append_string(const char *name,
   return (0);
 } /* }}} int cj_config_append_string */
 
+/* cj_append_key adds key to the configuration stored in db.
+ *
+ * For example:
+ * "httpd/requests/count",
+ * "httpd/requests/current" ->
+ * { "httpd": { "requests": { "count": $key, "current": $key } } }
+ */
+static int cj_append_key(cj_t *db, cj_key_t *key) { /* {{{ */
+  if (db->tree == NULL)
+    db->tree = cj_avl_create();
+
+  c_avl_tree_t *tree = db->tree;
+
+  char const *start = key->path;
+  if (*start == '/')
+    ++start;
+
+  char const *end;
+  while ((end = strchr(start, '/')) != NULL) {
+    char name[PATH_MAX];
+
+    size_t len = end - start;
+    if (len == 0)
+      break;
+
+    len = COUCH_MIN(len, sizeof(name) - 1);
+    sstrncpy(name, start, len + 1);
+
+    c_avl_tree_t *value;
+    if (c_avl_get(tree, name, (void *)&value) != 0) {
+      value = cj_avl_create();
+      c_avl_insert(tree, strdup(name), value);
+    }
+
+    tree = value;
+    start = end + 1;
+  }
+
+  if (strlen(start) == 0) {
+    ERROR("curl_json plugin: invalid key: %s", key->path);
+    return -1;
+  }
+
+  c_avl_insert(tree, strdup(start), key);
+  return 0;
+} /* }}} int cj_append_key */
+
 static int cj_config_add_key(cj_t *db, /* {{{ */
                              oconfig_item_t *ci) {
   cj_key_t *key;
@@ -500,53 +550,13 @@ static int cj_config_add_key(cj_t *db, /* {{{ */
     return (-1);
   }
 
-  /* store path in a tree that will match the json map structure, example:
-   * "httpd/requests/count",
-   * "httpd/requests/current" ->
-   * { "httpd": { "requests": { "count": $key, "current": $key } } }
-   */
-  char *ptr;
-  char *name;
-  c_avl_tree_t *tree;
-
-  if (db->tree == NULL)
-    db->tree = cj_avl_create();
-
-  tree = db->tree;
-  ptr = key->path;
-  if (*ptr == '/')
-    ++ptr;
-
-  name = ptr;
-  while ((ptr = strchr(name, '/')) != NULL) {
-    char ent[PATH_MAX];
-    c_avl_tree_t *value;
-    size_t len;
-
-    len = ptr - name;
-    if (len == 0)
-      break;
-
-    len = COUCH_MIN(len, sizeof(ent) - 1);
-    sstrncpy(ent, name, len + 1);
-
-    if (c_avl_get(tree, ent, (void *)&value) != 0) {
-      value = cj_avl_create();
-      c_avl_insert(tree, strdup(ent), value);
-    }
-
-    tree = value;
-    name = ptr + 1;
-  }
-
-  if (strlen(name) == 0) {
-    ERROR("curl_json plugin: invalid key: %s", key->path);
+  status = cj_append_key(db, key);
+  if (status != 0) {
     cj_key_free(key);
-    return (-1);
+    return -1;
   }
 
-  c_avl_insert(tree, strdup(name), key);
-  return (status);
+  return 0;
 } /* }}} int cj_config_add_key */
 
 static int cj_init_curl(cj_t *db) /* {{{ */
@@ -774,7 +784,7 @@ static const char *cj_host(cj_t *db) /* {{{ */
   return db->host;
 } /* }}} cj_host */
 
-static void cj_submit(cj_t *db, cj_key_t *key, value_t *value) /* {{{ */
+static void cj_submit_impl(cj_t *db, cj_key_t *key, value_t *value) /* {{{ */
 {
   value_list_t vl = VALUE_LIST_INIT;
 
@@ -798,13 +808,14 @@ static void cj_submit(cj_t *db, cj_key_t *key, value_t *value) /* {{{ */
     vl.interval = db->interval;
 
   plugin_dispatch_values(&vl);
-} /* }}} int cj_submit */
+} /* }}} int cj_submit_impl */
 
 static int cj_sock_perform(cj_t *db) /* {{{ */
 {
   char errbuf[1024];
-  struct sockaddr_un sa_unix = {0};
-  sa_unix.sun_family = AF_UNIX;
+  struct sockaddr_un sa_unix = {
+      .sun_family = AF_UNIX,
+  };
   sstrncpy(sa_unix.sun_path, db->sock, sizeof(sa_unix.sun_path));
 
   int fd = socket(AF_UNIX, SOCK_STREAM, 0);
@@ -930,7 +941,6 @@ static int cj_read(user_data_t *ud) /* {{{ */
   db->depth = 0;
   memset(&db->state, 0, sizeof(db->state));
   db->state[db->depth].tree = db->tree;
-  db->key = NULL;
 
   return cj_perform(db);
 } /* }}} int cj_read */
@@ -947,5 +957,3 @@ void module_register(void) {
   plugin_register_complex_config("curl_json", cj_config);
   plugin_register_init("curl_json", cj_init);
 } /* void module_register */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */