From: Florian Forster Date: Wed, 17 May 2017 06:40:59 +0000 (+0200) Subject: Merge remote-tracking branch 'github/pr/2277' X-Git-Tag: collectd-5.8.0~175 X-Git-Url: https://git.octo.it/?p=collectd.git;a=commitdiff_plain;h=6026e3162e522b133d10596710527d24c2921b55 Merge remote-tracking branch 'github/pr/2277' --- 6026e3162e522b133d10596710527d24c2921b55 diff --cc src/curl_json.c index a589cd65,9ec9f1e2..b9394c27 --- a/src/curl_json.c +++ b/src/curl_json.c @@@ -228,13 -195,13 +228,13 @@@ static void cj_advance_array(cj_t *db) #define CJ_CB_CONTINUE 1 static int cj_cb_boolean(void *ctx, int boolVal) { - cj_cb_inc_array_index(ctx, /* update_key = */ 0); + cj_advance_array(ctx); - return (CJ_CB_CONTINUE); + return CJ_CB_CONTINUE; } static int cj_cb_null(void *ctx) { - cj_cb_inc_array_index(ctx, /* update_key = */ 0); + cj_advance_array(ctx); - return (CJ_CB_CONTINUE); + return CJ_CB_CONTINUE; } static int cj_cb_number(void *ctx, const char *number, yajl_len_t number_len) { @@@ -247,33 -217,33 +247,31 @@@ memcpy(buffer, number, number_len); buffer[sizeof(buffer) - 1] = 0; - - if ((key == NULL) || !CJ_IS_KEY(key)) { - if (key != NULL && - !db->state[db->depth].in_array /*can be inhomogeneous*/) { - NOTICE("curl_json plugin: Found \"%s\", but the configuration expects" - " a map.", - buffer); - return CJ_CB_CONTINUE; - } -- - cj_cb_inc_array_index(ctx, /* update_key = */ 1); - key = db->state[db->depth].key; - if ((key == NULL) || !CJ_IS_KEY(key)) { - return CJ_CB_CONTINUE; - } - } else { - cj_cb_inc_array_index(ctx, /* update_key = */ 1); + if (key == NULL) { + /* no config for this element. */ + cj_advance_array(ctx); + return CJ_CB_CONTINUE; + } else if (!CJ_IS_KEY(key)) { + /* the config expects a map or an array. */ + NOTICE( + "curl_json plugin: Found \"%s\", but the configuration expects a map.", + buffer); + cj_advance_array(ctx); + return CJ_CB_CONTINUE; } - type = cj_get_type(key); - status = parse_value(buffer, &vt, type); + int type = cj_get_type(key); + value_t vt; + int status = parse_value(buffer, &vt, type); if (status != 0) { NOTICE("curl_json plugin: Unable to parse number: \"%s\"", buffer); + cj_advance_array(ctx); - return (CJ_CB_CONTINUE); + return CJ_CB_CONTINUE; } cj_submit(db, key, &vt); + cj_advance_array(ctx); - return (CJ_CB_CONTINUE); + return CJ_CB_CONTINUE; } /* int cj_cb_number */ /* Queries the key-tree of the parent context for "in_name" and, if found, @@@ -294,27 -289,29 +292,27 @@@ static int cj_cb_map_key(void *ctx, uns static int cj_cb_string(void *ctx, const unsigned char *val, yajl_len_t len) { /* Handle the string as if it was a number. */ - return (cj_cb_number(ctx, (const char *)val, len)); + return cj_cb_number(ctx, (const char *)val, len); } /* int cj_cb_string */ -static int cj_cb_start(void *ctx) { - cj_t *db = (cj_t *)ctx; - if (++db->depth >= YAJL_MAX_DEPTH) { - ERROR("curl_json plugin: %s depth exceeds max, aborting.", - db->url ? db->url : db->sock); - return CJ_CB_ABORT; - } - return CJ_CB_CONTINUE; -} - static int cj_cb_end(void *ctx) { cj_t *db = (cj_t *)ctx; db->state[db->depth].tree = NULL; - --db->depth; + db->depth--; + cj_advance_array(ctx); - return (CJ_CB_CONTINUE); + return CJ_CB_CONTINUE; } static int cj_cb_start_map(void *ctx) { - cj_cb_inc_array_index(ctx, /* update_key = */ 1); - return cj_cb_start(ctx); + cj_t *db = (cj_t *)ctx; + + if ((db->depth + 1) >= YAJL_MAX_DEPTH) { + ERROR("curl_json plugin: %s depth exceeds max, aborting.", + db->url ? db->url : db->sock); - return (CJ_CB_ABORT); ++ return CJ_CB_ABORT; + } + db->depth++; - return (CJ_CB_CONTINUE); ++ return CJ_CB_CONTINUE; } static int cj_cb_end_map(void *ctx) { return cj_cb_end(ctx); } @@@ -440,56 -430,9 +438,56 @@@ static int cj_config_append_string(cons *dest = temp; - return (0); + 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; @@@ -547,11 -490,50 +545,11 @@@ if (key->type == NULL) { WARNING("curl_json plugin: `Type' missing in `Key' block."); cj_key_free(key); - return (-1); + 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; } diff --cc src/testing.h index 96b6ba9c,a89f4629..d3da9db4 --- a/src/testing.h +++ b/src/testing.h @@@ -104,11 -104,10 +104,11 @@@ static int check_count__ = 0 do { \ double want__ = (double)expect; \ double got__ = (double)actual; \ - if (isnan(want__) && !isnan(got__)) { \ + if ((isnan(want__) && !isnan(got__)) || \ + (!isnan(want__) && isnan(got__))) { \ printf("not ok %i - %s = %.15g, want %.15g\n", ++check_count__, #actual, \ got__, want__); \ - return (-1); \ + return -1; \ } else if (!isnan(want__) && (((want__ - got__) < -DBL_PRECISION) || \ ((want__ - got__) > DBL_PRECISION))) { \ printf("not ok %i - %s = %.15g, want %.15g\n", ++check_count__, #actual, \