perl plugin: Don't do any type conversion in pplugin_register_data_set().
[collectd.git] / src / perl.c
index 2946ab3..c032694 100644 (file)
@@ -245,7 +245,7 @@ static int hv2data_source (pTHX_ HV *hash, data_source_t *ds)
        else
                ds->max = NAN;
        return 0;
-} /* static data_source_t *hv2data_source (HV *) */
+} /* static int hv2data_source (HV *, data_source_t *) */
 
 static int av2value (pTHX_ char *name, AV *array, value_t *value, int len)
 {
@@ -289,6 +289,120 @@ static int av2value (pTHX_ char *name, AV *array, value_t *value, int len)
        return len;
 } /* static int av2value (char *, AV *, value_t *, int) */
 
+/*
+ * value list:
+ * {
+ *   values => [ @values ],
+ *   time   => $time,
+ *   host   => $host,
+ *   plugin => $plugin,
+ *   plugin_instance => $pinstance,
+ *   type_instance   => $tinstance,
+ * }
+ */
+static int hv2value_list (pTHX_ HV *hash, value_list_t *vl)
+{
+       SV **tmp;
+
+       if ((NULL == hash) || (NULL == vl))
+               return -1;
+
+       if (NULL == (tmp = hv_fetch (hash, "type", 4, 0))) {
+               log_err ("hv2value_list: No type given.");
+               return -1;
+       }
+
+       sstrncpy (vl->type, SvPV_nolen (*tmp), sizeof (vl->type));
+
+       if ((NULL == (tmp = hv_fetch (hash, "values", 6, 0)))
+                       || (! (SvROK (*tmp) && (SVt_PVAV == SvTYPE (SvRV (*tmp)))))) {
+               log_err ("hv2value_list: No valid values given.");
+               return -1;
+       }
+
+       {
+               AV  *array = (AV *)SvRV (*tmp);
+               int len    = av_len (array) + 1;
+
+               if (len <= 0)
+                       return -1;
+
+               vl->values     = (value_t *)smalloc (len * sizeof (value_t));
+               vl->values_len = av2value (aTHX_ vl->type, (AV *)SvRV (*tmp),
+                               vl->values, len);
+
+               if (-1 == vl->values_len) {
+                       sfree (vl->values);
+                       return -1;
+               }
+       }
+
+       if (NULL != (tmp = hv_fetch (hash, "time", 4, 0))) {
+               vl->time = (time_t)SvIV (*tmp);
+       }
+
+       if (NULL != (tmp = hv_fetch (hash, "host", 4, 0))) {
+               sstrncpy (vl->host, SvPV_nolen (*tmp), sizeof (vl->host));
+       }
+       else {
+               sstrncpy (vl->host, hostname_g, sizeof (vl->host));
+       }
+
+       if (NULL != (tmp = hv_fetch (hash, "plugin", 6, 0)))
+               sstrncpy (vl->plugin, SvPV_nolen (*tmp), sizeof (vl->plugin));
+
+       if (NULL != (tmp = hv_fetch (hash, "plugin_instance", 15, 0)))
+               sstrncpy (vl->plugin_instance, SvPV_nolen (*tmp),
+                               sizeof (vl->plugin_instance));
+
+       if (NULL != (tmp = hv_fetch (hash, "type_instance", 13, 0)))
+               sstrncpy (vl->type_instance, SvPV_nolen (*tmp),
+                               sizeof (vl->type_instance));
+       return 0;
+} /* static int hv2value_list (pTHX_ HV *, value_list_t *) */
+
+static int av2data_set (pTHX_ AV *array, char *name, data_set_t *ds)
+{
+       int len, i;
+
+       if ((NULL == array) || (NULL == name) || (NULL == ds))
+               return -1;
+
+       len = av_len (array);
+
+       if (-1 == len) {
+               log_err ("av2data_set: Invalid data set.");
+               return -1;
+       }
+
+       ds->ds = (data_source_t *)smalloc ((len + 1) * sizeof (data_source_t));
+       ds->ds_num = len + 1;
+
+       for (i = 0; i <= len; ++i) {
+               SV **elem = av_fetch (array, i, 0);
+
+               if (NULL == elem) {
+                       log_err ("av2data_set: Failed to fetch data source %i.", i);
+                       return -1;
+               }
+
+               if (! (SvROK (*elem) && (SVt_PVHV == SvTYPE (SvRV (*elem))))) {
+                       log_err ("av2data_set: Invalid data source.");
+                       return -1;
+               }
+
+               if (-1 == hv2data_source (aTHX_ (HV *)SvRV (*elem), &ds->ds[i]))
+                       return -1;
+
+               log_debug ("av2data_set: "
+                               "DS.name = \"%s\", DS.type = %i, DS.min = %f, DS.max = %f",
+                               ds->ds[i].name, ds->ds[i].type, ds->ds[i].min, ds->ds[i].max);
+       }
+
+       sstrncpy (ds->type, name, sizeof (ds->type));
+       return 0;
+} /* static int av2data_set (pTHX_ AV *, data_set_t *) */
+
 static int data_set2av (pTHX_ data_set_t *ds, AV *array)
 {
        int i = 0;
@@ -521,52 +635,19 @@ static char *get_module_name (char *buf, size_t buf_len, const char *module) {
  */
 static int pplugin_register_data_set (pTHX_ char *name, AV *dataset)
 {
-       int len = -1;
        int ret = 0;
-       int i   = 0;
 
-       data_source_t *ds  = NULL;
-       data_set_t    *set = NULL;
+       data_set_t ds;
 
        if ((NULL == name) || (NULL == dataset))
                return -1;
 
-       len = av_len (dataset);
-
-       if (-1 == len)
+       if (0 != av2data_set (aTHX_ dataset, name, &ds))
                return -1;
 
-       ds  = (data_source_t *)smalloc ((len + 1) * sizeof (data_source_t));
-       set = (data_set_t *)smalloc (sizeof (data_set_t));
-
-       for (i = 0; i <= len; ++i) {
-               SV **elem = av_fetch (dataset, i, 0);
+       ret = plugin_register_data_set (&ds);
 
-               if (NULL == elem)
-                       return -1;
-
-               if (! (SvROK (*elem) && (SVt_PVHV == SvTYPE (SvRV (*elem))))) {
-                       log_err ("pplugin_register_data_set: Invalid data source.");
-                       return -1;
-               }
-
-               if (-1 == hv2data_source (aTHX_ (HV *)SvRV (*elem), &ds[i]))
-                       return -1;
-
-               log_debug ("pplugin_register_data_set: "
-                               "DS.name = \"%s\", DS.type = %i, DS.min = %f, DS.max = %f",
-                               ds[i].name, ds[i].type, ds[i].min, ds[i].max);
-       }
-
-       sstrncpy (set->type, name, sizeof (set->type));
-
-       set->ds_num = len + 1;
-       set->ds = ds;
-
-       ret = plugin_register_data_set (set);
-
-       free (ds);
-       free (set);
+       free (ds.ds);
        return ret;
 } /* static int pplugin_register_data_set (char *, SV *) */
 
@@ -582,89 +663,22 @@ static int pplugin_unregister_data_set (char *name)
 
 /*
  * Submit the values to the write functions.
- *
- * value list:
- * {
- *   values => [ @values ],
- *   time   => $time,
- *   host   => $host,
- *   plugin => $plugin,
- *   plugin_instance => $pinstance,
- *   type_instance   => $tinstance,
- * }
  */
 static int pplugin_dispatch_values (pTHX_ HV *values)
 {
-       value_list_t list = VALUE_LIST_INIT;
-       value_t      *val = NULL;
-
-       SV **tmp = NULL;
+       value_list_t vl = VALUE_LIST_INIT;
 
        int ret = 0;
 
        if (NULL == values)
                return -1;
 
-       if (NULL == (tmp = hv_fetch (values, "type", 4, 0))) {
-               log_err ("pplugin_dispatch_values: No type given.");
-               return -1;
-       }
-
-       sstrncpy (list.type, SvPV_nolen (*tmp), sizeof (list.type));
-
-       if ((NULL == (tmp = hv_fetch (values, "values", 6, 0)))
-                       || (! (SvROK (*tmp) && (SVt_PVAV == SvTYPE (SvRV (*tmp)))))) {
-               log_err ("pplugin_dispatch_values: No valid values given.");
+       if (0 != hv2value_list (aTHX_ values, &vl))
                return -1;
-       }
-
-       {
-               AV  *array = (AV *)SvRV (*tmp);
-               int len    = av_len (array) + 1;
-
-               if (len <= 0)
-                       return -1;
-
-               val = (value_t *)smalloc (len * sizeof (value_t));
-
-               list.values_len = av2value (aTHX_ list.type, (AV *)SvRV (*tmp),
-                               val, len);
-               list.values = val;
 
-               if (-1 == list.values_len) {
-                       sfree (val);
-                       return -1;
-               }
-       }
-
-       if (NULL != (tmp = hv_fetch (values, "time", 4, 0))) {
-               list.time = (time_t)SvIV (*tmp);
-       }
-       else {
-               list.time = time (NULL);
-       }
-
-       if (NULL != (tmp = hv_fetch (values, "host", 4, 0))) {
-               sstrncpy (list.host, SvPV_nolen (*tmp), sizeof (list.host));
-       }
-       else {
-               sstrncpy (list.host, hostname_g, sizeof (list.host));
-       }
-
-       if (NULL != (tmp = hv_fetch (values, "plugin", 6, 0)))
-               sstrncpy (list.plugin, SvPV_nolen (*tmp), sizeof (list.plugin));
+       ret = plugin_dispatch_values (&vl);
 
-       if (NULL != (tmp = hv_fetch (values, "plugin_instance", 15, 0)))
-               sstrncpy (list.plugin_instance, SvPV_nolen (*tmp),
-                               sizeof (list.plugin_instance));
-
-       if (NULL != (tmp = hv_fetch (values, "type_instance", 13, 0)))
-               sstrncpy (list.type_instance, SvPV_nolen (*tmp),
-                               sizeof (list.type_instance));
-
-       ret = plugin_dispatch_values (&list);
-
-       sfree (val);
+       sfree (vl.values);
        return ret;
 } /* static int pplugin_dispatch_values (char *, HV *) */
 
@@ -1092,7 +1106,7 @@ static XS (Collectd_plugin_log)
                XSRETURN_EMPTY;
        }
 
-       plugin_log (SvIV (ST (0)), SvPV_nolen (ST (1)));
+       plugin_log (SvIV (ST (0)), "%s", SvPV_nolen (ST (1)));
        XSRETURN_YES;
 } /* static XS (Collectd_plugin_log) */
 
@@ -1790,7 +1804,7 @@ static int perl_config (oconfig_item_t *ci)
 
        for (i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *c = ci->children + i;
-               int current_status;
+               int current_status = 0;
 
                if (NULL != perl_threads)
                        aTHX = PERL_GET_CONTEXT;
@@ -1806,7 +1820,10 @@ static int perl_config (oconfig_item_t *ci)
                else if (0 == strcasecmp (c->key, "Plugin"))
                        current_status = perl_config_plugin (aTHX_ c);
                else
+               {
                        log_warn ("Ignoring unknown config key \"%s\".", c->key);
+                       current_status = 0;
+               }
 
                /* fatal error - it's up to perl_config_* to clean up */
                if (0 > current_status) {