python: Fixed more unicode related problems.
[collectd.git] / src / pyvalues.c
index d459ea9..c6b4032 100644 (file)
 
 #include "cpython.h"
 
-static char time_doc[] = "This is the Unix timestap of the time this value was read.\n"
-               "For dispatching values this can be set to 0 which means \"now\".\n"
-               "This means the time the value is actually dispatched, not the time\n"
-               "it was set to 0.";
-
-static char host_doc[] = "The hostname of the host this value was read from.\n"
-               "For dispatching this can be set to an empty string which means\n"
-               "the local hostname as defined in the collectd.conf.";
-
-static char type_doc[] = "The type of this value. This type has to be defined\n"
-               "in your types.db. Attempting to set it to any other value will\n"
-               "raise a TypeError exception.\n"
-               "Assigning a type is mandetory, calling dispatch without doing\n"
-               "so will raise a RuntimeError exception.";
-
-static char type_instance_doc[] = "";
-
-static char plugin_doc[] = "The name of the plugin that read the data. Setting this\n"
-               "member to an empty string will insert \"python\" upon dispatching.";
-
-static char plugin_instance_doc[] = "";
-
-static char PluginData_doc[] = "This is an internal class that is the base for Values\n"
-               "and Notification. It is pretty useless by itself and was therefore not\n"
-               "exported to the collectd module.";
-
-static PyObject *PluginData_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
-       PluginData *self;
-       
-       self = (PluginData *) type->tp_alloc(type, 0);
-       if (self == NULL)
-               return NULL;
-       
-       self->time = 0;
-       self->host[0] = 0;
-       self->plugin[0] = 0;
-       self->plugin_instance[0] = 0;
-       self->type[0] = 0;
-       self->type_instance[0] = 0;
-       return (PyObject *) self;
-}
-
-static int PluginData_init(PyObject *s, PyObject *args, PyObject *kwds) {
-       PluginData *self = (PluginData *) s;
-       double time = 0;
-       const char *type = "", *plugin_instance = "", *type_instance = "", *plugin = "", *host = "";
-       static char *kwlist[] = {"type", "plugin_instance", "type_instance",
-                       "plugin", "host", "time", NULL};
-       
-       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|sssssd", kwlist, &type,
-                       &plugin_instance, &type_instance, &plugin, &host, &time))
-               return -1;
-       
-       if (type[0] != 0 && plugin_get_ds(type) == NULL) {
-               PyErr_Format(PyExc_TypeError, "Dataset %s not found", type);
-               return -1;
-       }
-
-       sstrncpy(self->host, host, sizeof(self->host));
-       sstrncpy(self->plugin, plugin, sizeof(self->plugin));
-       sstrncpy(self->plugin_instance, plugin_instance, sizeof(self->plugin_instance));
-       sstrncpy(self->type, type, sizeof(self->type));
-       sstrncpy(self->type_instance, type_instance, sizeof(self->type_instance));
-       
-       self->time = time;
-       return 0;
-}
-
-static PyObject *PluginData_repr(PyObject *s) {
+static PyObject *cpy_common_repr(PyObject *s) {
        PyObject *ret, *tmp;
        static PyObject *l_type = NULL, *l_type_instance = NULL, *l_plugin = NULL, *l_plugin_instance = NULL;
-       static PyObject *l_host = NULL, *l_time = NULL, *l_closing = NULL;
+       static PyObject *l_host = NULL, *l_time = NULL;
        PluginData *self = (PluginData *) s;
        
        if (l_type == NULL)
@@ -118,8 +50,6 @@ static PyObject *PluginData_repr(PyObject *s) {
                l_host = cpy_string_to_unicode_or_bytes(",host=");
        if (l_time == NULL)
                l_time = cpy_string_to_unicode_or_bytes(",time=");
-       if (l_closing == NULL)
-               l_closing = cpy_string_to_unicode_or_bytes(")");
        
        if (!l_type || !l_type_instance || !l_plugin || !l_plugin_instance || !l_host || !l_time)
                return NULL;
@@ -177,6 +107,88 @@ static PyObject *PluginData_repr(PyObject *s) {
                        CPY_SUBSTITUTE(CPY_STRCAT, ret, ret, tmp);
                Py_XDECREF(tmp);
        }
+       return ret;
+}
+
+static char time_doc[] = "This is the Unix timestap of the time this value was read.\n"
+               "For dispatching values this can be set to 0 which means \"now\".\n"
+               "This means the time the value is actually dispatched, not the time\n"
+               "it was set to 0.";
+
+static char host_doc[] = "The hostname of the host this value was read from.\n"
+               "For dispatching this can be set to an empty string which means\n"
+               "the local hostname as defined in the collectd.conf.";
+
+static char type_doc[] = "The type of this value. This type has to be defined\n"
+               "in your types.db. Attempting to set it to any other value will\n"
+               "raise a TypeError exception.\n"
+               "Assigning a type is mandetory, calling dispatch without doing\n"
+               "so will raise a RuntimeError exception.";
+
+static char type_instance_doc[] = "";
+
+static char plugin_doc[] = "The name of the plugin that read the data. Setting this\n"
+               "member to an empty string will insert \"python\" upon dispatching.";
+
+static char plugin_instance_doc[] = "";
+
+static char PluginData_doc[] = "This is an internal class that is the base for Values\n"
+               "and Notification. It is pretty useless by itself and was therefore not\n"
+               "exported to the collectd module.";
+
+static PyObject *PluginData_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
+       PluginData *self;
+       
+       self = (PluginData *) type->tp_alloc(type, 0);
+       if (self == NULL)
+               return NULL;
+       
+       self->time = 0;
+       self->host[0] = 0;
+       self->plugin[0] = 0;
+       self->plugin_instance[0] = 0;
+       self->type[0] = 0;
+       self->type_instance[0] = 0;
+       return (PyObject *) self;
+}
+
+static int PluginData_init(PyObject *s, PyObject *args, PyObject *kwds) {
+       PluginData *self = (PluginData *) s;
+       double time = 0;
+       const char *type = "", *plugin_instance = "", *type_instance = "", *plugin = "", *host = "";
+       static char *kwlist[] = {"type", "plugin_instance", "type_instance",
+                       "plugin", "host", "time", NULL};
+       
+       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etetetetetd", kwlist, NULL, &type,
+                       NULL, &plugin_instance, NULL, &type_instance, NULL, &plugin, NULL, &host, &time))
+               return -1;
+       
+       if (type[0] != 0 && plugin_get_ds(type) == NULL) {
+               PyErr_Format(PyExc_TypeError, "Dataset %s not found", type);
+               return -1;
+       }
+
+       sstrncpy(self->host, host, sizeof(self->host));
+       sstrncpy(self->plugin, plugin, sizeof(self->plugin));
+       sstrncpy(self->plugin_instance, plugin_instance, sizeof(self->plugin_instance));
+       sstrncpy(self->type, type, sizeof(self->type));
+       sstrncpy(self->type_instance, type_instance, sizeof(self->type_instance));
+       
+       self->time = time;
+       return 0;
+}
+
+static PyObject *PluginData_repr(PyObject *s) {
+       PyObject *ret;
+       static PyObject *l_closing = NULL;
+       
+       if (l_closing == NULL)
+               l_closing = cpy_string_to_unicode_or_bytes(")");
+       
+       if (l_closing == NULL)
+               return NULL;
+       
+       ret = cpy_common_repr(s);
        CPY_SUBSTITUTE(CPY_STRCAT, ret, ret, l_closing);
        return ret;
 }
@@ -342,26 +354,30 @@ static PyObject *Values_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
 static int Values_init(PyObject *s, PyObject *args, PyObject *kwds) {
        Values *self = (Values *) s;
-       int interval = 0, ret;
+       int interval = 0;
        double time = 0;
        PyObject *values = NULL, *tmp;
        const char *type = "", *plugin_instance = "", *type_instance = "", *plugin = "", *host = "";
        static char *kwlist[] = {"type", "values", "plugin_instance", "type_instance",
                        "plugin", "host", "time", "interval", NULL};
        
-       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|sOssssdi", kwlist,
-                       &type, &values, &plugin_instance, &type_instance,
-                       &plugin, &host, &time, &interval))
+       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetdi", kwlist,
+                       NULL, &type, &values, NULL, &plugin_instance, NULL, &type_instance,
+                       NULL, &plugin, NULL, &host, &time, &interval))
                return -1;
        
-       tmp = Py_BuildValue("sssssd", type, plugin_instance, type_instance, plugin, host, time);
-       if (tmp == NULL)
-               return -1;
-       ret = PluginDataType.tp_init(s, tmp, NULL);
-       Py_DECREF(tmp);
-       if (ret != 0)
+       if (type[0] != 0 && plugin_get_ds(type) == NULL) {
+               PyErr_Format(PyExc_TypeError, "Dataset %s not found", type);
                return -1;
-       
+       }
+
+       sstrncpy(self->data.host, host, sizeof(self->data.host));
+       sstrncpy(self->data.plugin, plugin, sizeof(self->data.plugin));
+       sstrncpy(self->data.plugin_instance, plugin_instance, sizeof(self->data.plugin_instance));
+       sstrncpy(self->data.type, type, sizeof(self->data.type));
+       sstrncpy(self->data.type_instance, type_instance, sizeof(self->data.type_instance));
+       self->data.time = time;
+
        if (values == NULL) {
                values = PyList_New(0);
                PyErr_Clear();
@@ -394,9 +410,9 @@ static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
        
        static char *kwlist[] = {"type", "values", "plugin_instance", "type_instance",
                        "plugin", "host", "time", "interval", NULL};
-       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|sOzsssdi", kwlist,
-                       &type, &values, &plugin_instance, &type_instance,
-                       &plugin, &host, &time, &interval))
+       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetdi", kwlist,
+                       NULL, &type, &values, NULL, &plugin_instance, NULL, &type_instance,
+                       NULL, &plugin, NULL, &host, &time, &interval))
                return NULL;
 
        if (type[0] == 0) {
@@ -494,9 +510,9 @@ static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) {
        
        static char *kwlist[] = {"destination", "type", "values", "plugin_instance", "type_instance",
                        "plugin", "host", "time", "interval", NULL};
-       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|sOssssdi", kwlist,
-                       &type, &values, &plugin_instance, &type_instance,
-                       &plugin, &host, &time, &interval))
+       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetdi", kwlist,
+                       NULL, &type, &values, NULL, &plugin_instance, NULL, &type_instance,
+                       NULL, &plugin, NULL, &host, &time, &interval))
                return NULL;
 
        if (type[0] == 0) {
@@ -576,25 +592,40 @@ static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) {
        Py_RETURN_NONE;
 }
 
-/*static PyObject *Values_repr(PyObject *s) {
-       PyObject *ret, *valuestring = NULL;
+static PyObject *Values_repr(PyObject *s) {
+       PyObject *ret, *tmp;
+       static PyObject *l_interval = NULL, *l_values = NULL, *l_closing = NULL;
        Values *self = (Values *) s;
        
-       if (self->values != NULL)
-               valuestring = PyObject_Repr(self->values);
-       if (valuestring == NULL)
+       if (l_interval == NULL)
+               l_interval = cpy_string_to_unicode_or_bytes(",interval=");
+       if (l_values == NULL)
+               l_values = cpy_string_to_unicode_or_bytes(",values=");
+       if (l_closing == NULL)
+               l_closing = cpy_string_to_unicode_or_bytes(")");
+       
+       if (l_interval == NULL || l_values == NULL || l_closing == NULL)
                return NULL;
        
-       ret = PyString_FromFormat("collectd.Values(type='%s%s%s%s%s%s%s%s%s',time=%lu,interval=%i,values=%s)", self->data.type,
-                       *self->data.type_instance ? "',type_instance='" : "", self->data.type_instance,
-                       *self->data.plugin ? "',plugin='" : "", self->data.plugin,
-                       *self->data.plugin_instance ? "',plugin_instance='" : "", self->data.plugin_instance,
-                       *self->data.host ? "',host='" : "", self->data.host,
-                       (long unsigned) self->data.time, self->interval,
-                       valuestring ? cpy_unicode_or_bytes_to_string(valuestring) : "[]");
-       Py_XDECREF(valuestring);
+       ret = cpy_common_repr(s);
+       if (self->interval != 0) {
+               CPY_SUBSTITUTE(CPY_STRCAT, ret, ret, l_interval);
+               tmp = PyInt_FromLong(self->interval);
+               CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp);
+               if (tmp)
+                       CPY_SUBSTITUTE(CPY_STRCAT, ret, ret, tmp);
+               Py_XDECREF(tmp);
+       }
+       if (self->values != NULL && PySequence_Length(self->values) > 0) {
+               CPY_SUBSTITUTE(CPY_STRCAT, ret, ret, l_values);
+               tmp = PyObject_Repr(self->values);
+               if (tmp)
+                       CPY_SUBSTITUTE(CPY_STRCAT, ret, ret, tmp);
+               Py_XDECREF(tmp);
+       }
+       CPY_SUBSTITUTE(CPY_STRCAT, ret, ret, l_closing);
        return ret;
-}*/
+}
 
 static int Values_traverse(PyObject *self, visitproc visit, void *arg) {
        Values *v = (Values *) self;
@@ -635,7 +666,7 @@ PyTypeObject ValuesType = {
        0,                         /* tp_getattr */
        0,                         /* tp_setattr */
        0,                         /* tp_compare */
-       0/*Values_repr*/,               /* tp_repr */
+       Values_repr,               /* tp_repr */
        0,                         /* tp_as_number */
        0,                         /* tp_as_sequence */
        0,                         /* tp_as_mapping */
@@ -679,27 +710,30 @@ static char Notification_doc[] = "The Notification class is a wrapper around the
 
 static int Notification_init(PyObject *s, PyObject *args, PyObject *kwds) {
        Notification *self = (Notification *) s;
-       PyObject *tmp;
-       int severity = 0, ret;
+       int severity = 0;
        double time = 0;
        const char *message = "";
        const char *type = "", *plugin_instance = "", *type_instance = "", *plugin = "", *host = "";
        static char *kwlist[] = {"type", "message", "plugin_instance", "type_instance",
                        "plugin", "host", "time", "severity", NULL};
        
-       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ssssssdi", kwlist,
-                       &type, &message, &plugin_instance, &type_instance,
-                       &plugin, &host, &time, &severity))
+       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etetetetetetdi", kwlist,
+                       NULL, &type, NULL, &message, NULL, &plugin_instance, NULL, &type_instance,
+                       NULL, &plugin, NULL, &host, &time, &severity))
                return -1;
        
-       tmp = Py_BuildValue("sssssd", type, plugin_instance, type_instance, plugin, host, time);
-       if (tmp == NULL)
-               return -1;
-       ret = PluginDataType.tp_init(s, tmp, NULL);
-       Py_DECREF(tmp);
-       if (ret != 0)
+       if (type[0] != 0 && plugin_get_ds(type) == NULL) {
+               PyErr_Format(PyExc_TypeError, "Dataset %s not found", type);
                return -1;
-       
+       }
+
+       sstrncpy(self->data.host, host, sizeof(self->data.host));
+       sstrncpy(self->data.plugin, plugin, sizeof(self->data.plugin));
+       sstrncpy(self->data.plugin_instance, plugin_instance, sizeof(self->data.plugin_instance));
+       sstrncpy(self->data.type, type, sizeof(self->data.type));
+       sstrncpy(self->data.type_instance, type_instance, sizeof(self->data.type_instance));
+       self->data.time = time;
+
        sstrncpy(self->message, message, sizeof(self->message));
        self->severity = severity;
        return 0;
@@ -720,9 +754,9 @@ static PyObject *Notification_dispatch(Notification *self, PyObject *args, PyObj
        
        static char *kwlist[] = {"type", "message", "plugin_instance", "type_instance",
                        "plugin", "host", "time", "severity", NULL};
-       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ssssssdi", kwlist,
-                       &type, &message, &plugin_instance, &type_instance,
-                       &plugin, &host, &t, &severity))
+       if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etetetetetetdi", kwlist,
+                       NULL, &type, NULL, &message, NULL, &plugin_instance, NULL, &type_instance,
+                       NULL, &plugin, NULL, &host, &t, &severity))
                return NULL;
 
        if (type[0] == 0) {