Merge branch 'collectd-5.5' into collectd-5.6
[collectd.git] / src / tail_csv.c
index 919f948..206f103 100644 (file)
@@ -22,6 +22,7 @@
  **/
 
 #include "collectd.h"
+
 #include "plugin.h" /* plugin_register_*, plugin_dispatch_values */
 #include "common.h" /* auxiliary functions */
 #include "utils_tail.h"
 #include <string.h>
 
 struct metric_definition_s {
-    char *name;
-    char *type;
-    char *instance;
-    int data_source_type;
-    int value_from;
+    char   *name;
+    char   *type;
+    char   *instance;
+    int     data_source_type;
+    ssize_t value_from;
     struct metric_definition_s *next;
 };
 typedef struct metric_definition_s metric_definition_t;
 
 struct instance_definition_s {
-    char *instance;
-    char *path;
-    cu_tail_t *tail;
+    char                 *instance;
+    char                 *path;
+    cu_tail_t            *tail;
     metric_definition_t **metric_list;
-    size_t metric_list_len;
-    cdtime_t interval;
-    int time_from;
+    size_t                metric_list_len;
+    cdtime_t              interval;
+    ssize_t               time_from;
     struct instance_definition_s *next;
 };
 typedef struct instance_definition_s instance_definition_t;
@@ -85,7 +86,7 @@ static int tcsv_submit (instance_definition_t *id,
 static cdtime_t parse_time (char const *tbuf)
 {
     double t;
-    char *endptr = 0;
+    char *endptr = NULL;
 
     errno = 0;
     t = strtod (tbuf, &endptr);
@@ -100,37 +101,37 @@ static int tcsv_read_metric (instance_definition_t *id,
         char **fields, size_t fields_num)
 {
     value_t v;
-    cdtime_t t;
+    cdtime_t t = 0;
     int status;
 
     if (md->data_source_type == -1)
         return (EINVAL);
 
-    if (md->value_from >= fields_num)
-        return (EINVAL);
-
-    if (id->time_from >= 0 && (id->time_from >= fields_num))
+    assert (md->value_from >= 0);
+    if (((size_t) md->value_from) >= fields_num)
         return (EINVAL);
 
-    t = 0;
-    if (id->time_from >= 0)
-        t = parse_time (fields[id->time_from]);
-
     status = parse_value (fields[md->value_from], &v, md->data_source_type);
     if (status != 0)
         return (status);
 
+    if (id->time_from >= 0) {
+        if (((size_t) id->time_from) >= fields_num)
+            return (EINVAL);
+        t = parse_time (fields[id->time_from]);
+    }
+
     return (tcsv_submit (id, md, v, t));
 }
 
-static _Bool tcsv_check_index (int index, size_t fields_num, char const *name)
+static _Bool tcsv_check_index (ssize_t index, size_t fields_num, char const *name)
 {
     if (index < 0)
         return 1;
     else if (((size_t) index) < fields_num)
         return 1;
 
-    ERROR ("tail_csv plugin: Metric \"%s\": Request for index %i when "
+    ERROR ("tail_csv plugin: Metric \"%s\": Request for index %zd when "
             "only %zu fields are available.",
             name, index, fields_num);
     return (0);
@@ -267,36 +268,31 @@ static void tcsv_metric_definition_destroy(void *arg){
     tcsv_metric_definition_destroy (next);
 }
 
-static int tcsv_config_get_index(oconfig_item_t *ci, int *ret_index) {
-    int index;
-
+static int tcsv_config_get_index(oconfig_item_t *ci, ssize_t *ret_index) {
     if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)){
         WARNING("tail_csv plugin: The \"%s\" config option needs exactly one "
                 "integer argument.", ci->key);
         return (-1);
     }
 
-    index = (int) ci->values[0].value.number;
-    if (index < 0) {
+    if (ci->values[0].value.number < 0) {
         WARNING("tail_csv plugin: The \"%s\" config option must be positive "
                 "(or zero).", ci->key);
         return (-1);
     }
 
-    *ret_index = index;
+    *ret_index = (ssize_t) ci->values[0].value.number;
     return (0);
 }
 
 /* Parse metric  */
 static int tcsv_config_add_metric(oconfig_item_t *ci){
     metric_definition_t *md;
-    int status = 0;
-    int i;
+    int status;
 
-    md = (metric_definition_t *)malloc(sizeof(*md));
+    md = calloc(1, sizeof(*md));
     if (md == NULL)
         return (-1);
-    memset(md, 0, sizeof(*md));
     md->name = NULL;
     md->type = NULL;
     md->instance = NULL;
@@ -310,7 +306,7 @@ static int tcsv_config_add_metric(oconfig_item_t *ci){
         return (-1);
     }
 
-    for (i = 0; i < ci->children_num; ++i){
+    for (int i = 0; i < ci->children_num; ++i){
         oconfig_item_t *option = ci->children + i;
 
         if (strcasecmp("Type", option->key) == 0)
@@ -380,7 +376,6 @@ static int tcsv_config_add_instance_collect(instance_definition_t *id, oconfig_i
     metric_definition_t *metric;
     metric_definition_t **metric_list;
     size_t metric_list_size;
-    int i;
 
     if (ci->values_num < 1) {
         WARNING("tail_csv plugin: The `Collect' config option needs at least one argument.");
@@ -393,7 +388,7 @@ static int tcsv_config_add_instance_collect(instance_definition_t *id, oconfig_i
         return (-1);
     id->metric_list = metric_list;
 
-    for (i = 0; i < ci->values_num; i++) {
+    for (int i = 0; i < ci->values_num; i++) {
         char *metric_name;
 
         if (ci->values[i].type != OCONFIG_TYPE_STRING) {
@@ -423,17 +418,13 @@ static int tcsv_config_add_file(oconfig_item_t *ci)
 {
     instance_definition_t* id;
     int status = 0;
-    int i;
 
     /* Registration variables */
     char cb_name[DATA_MAX_NAME_LEN];
-    user_data_t cb_data;
-    struct timespec cb_interval;
 
-    id = malloc(sizeof(*id));
+    id = calloc(1, sizeof(*id));
     if (id == NULL)
         return (-1);
-    memset(id, 0, sizeof(*id));
     id->instance = NULL;
     id->path = NULL;
     id->metric_list = NULL;
@@ -449,7 +440,7 @@ static int tcsv_config_add_file(oconfig_item_t *ci)
     /* Use default interval. */
     id->interval = plugin_get_interval();
 
-    for (i = 0; i < ci->children_num; ++i){
+    for (int i = 0; i < ci->children_num; ++i){
         oconfig_item_t *option = ci->children + i;
         status = 0;
 
@@ -490,11 +481,13 @@ static int tcsv_config_add_file(oconfig_item_t *ci)
     }
 
     ssnprintf (cb_name, sizeof (cb_name), "tail_csv/%s", id->path);
-    memset(&cb_data, 0, sizeof(cb_data));
-    cb_data.data = id;
-    cb_data.free_func = tcsv_instance_definition_destroy;
-    CDTIME_T_TO_TIMESPEC(id->interval, &cb_interval);
-    status = plugin_register_complex_read(NULL, cb_name, tcsv_read, &cb_interval, &cb_data);
+
+    user_data_t ud = {
+        .data = id,
+        .free_func = tcsv_instance_definition_destroy
+    };
+
+    status = plugin_register_complex_read(NULL, cb_name, tcsv_read, id->interval, &ud);
 
     if (status != 0){
         ERROR("tail_csv plugin: Registering complex read function failed.");
@@ -507,8 +500,7 @@ static int tcsv_config_add_file(oconfig_item_t *ci)
 
 /* Parse blocks */
 static int tcsv_config(oconfig_item_t *ci){
-    int i;
-    for (i = 0; i < ci->children_num; ++i){
+    for (int i = 0; i < ci->children_num; ++i){
         oconfig_item_t *child = ci->children + i;
         if (strcasecmp("Metric", child->key) == 0)
             tcsv_config_add_metric(child);
@@ -544,7 +536,7 @@ static int tcsv_init(void) { /* {{{ */
         }
         else if (ds->ds_num != 1)
         {
-            ERROR ("tail_csv plugin: The type \"%s\" has %i data sources. "
+            ERROR ("tail_csv plugin: The type \"%s\" has %zu data sources. "
                     "Only types with a single data source are supported.",
                     ds->type, ds->ds_num);
             continue;