src/daemon/common.c: avoid leaking cap_header in error condition
[collectd.git] / src / pyconfig.c
index 6f03da9..83748b4 100644 (file)
  * DEALINGS IN THE SOFTWARE.
  *
  * Authors:
- *   Sven Trenkel <collectd at semidefinite.de>  
+ *   Sven Trenkel <collectd at semidefinite.de>
  **/
 
 #include <Python.h>
 #include <structmember.h>
 
 #include "collectd.h"
+
 #include "common.h"
 
 #include "cpython.h"
@@ -57,11 +58,11 @@ static char children_doc[] = "This is a tuple of child nodes. For most nodes thi
 
 static PyObject *Config_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
        Config *self;
-       
+
        self = (Config *) type->tp_alloc(type, 0);
        if (self == NULL)
                return NULL;
-       
+
        self->parent = NULL;
        self->key = NULL;
        self->values = NULL;
@@ -73,11 +74,11 @@ static int Config_init(PyObject *s, PyObject *args, PyObject *kwds) {
        PyObject *key = NULL, *parent = NULL, *values = NULL, *children = NULL, *tmp;
        Config *self = (Config *) s;
        static char *kwlist[] = {"key", "parent", "values", "children", NULL};
-       
+
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OOO", kwlist,
                        &key, &parent, &values, &children))
                return -1;
-       
+
        if (!IS_BYTES_OR_UNICODE(key)) {
                PyErr_SetString(PyExc_TypeError, "argument 1 must be str");
                Py_XDECREF(parent);
@@ -118,11 +119,31 @@ static int Config_init(PyObject *s, PyObject *args, PyObject *kwds) {
        return 0;
 }
 
-/*static PyObject *Config_repr(PyObject *s) {
+static PyObject *Config_repr(PyObject *s) {
        Config *self = (Config *) s;
-       
-       return PyString_FromFormat("<collectd.Config %snode %s>", self->parent == Py_None ? "root " : "", PyString_AsString(PyObject_Str(self->key)));
-}*/
+       PyObject *ret = NULL;
+       static PyObject *node_prefix = NULL, *root_prefix = NULL, *ending = NULL;
+
+       /* This is ok because we have the GIL, so this is thread-save by default. */
+       if (node_prefix == NULL)
+               node_prefix = cpy_string_to_unicode_or_bytes("<collectd.Config node ");
+       if (root_prefix == NULL)
+               root_prefix = cpy_string_to_unicode_or_bytes("<collectd.Config root node ");
+       if (ending == NULL)
+               ending = cpy_string_to_unicode_or_bytes(">");
+       if (node_prefix == NULL || root_prefix == NULL || ending == NULL)
+               return NULL;
+
+       ret = PyObject_Str(self->key);
+       CPY_SUBSTITUTE(PyObject_Repr, ret, ret);
+       if (self->parent == NULL || self->parent == Py_None)
+               CPY_STRCAT(&ret, root_prefix);
+       else
+               CPY_STRCAT(&ret, node_prefix);
+       CPY_STRCAT(&ret, ending);
+
+       return ret;
+}
 
 static int Config_traverse(PyObject *self, visitproc visit, void *arg) {
        Config *c = (Config *) self;
@@ -130,8 +151,7 @@ static int Config_traverse(PyObject *self, visitproc visit, void *arg) {
        Py_VISIT(c->key);
        Py_VISIT(c->values);
        Py_VISIT(c->children);
-       return 0;
-}
+       return 0;}
 
 static int Config_clear(PyObject *self) {
        Config *c = (Config *) self;
@@ -165,7 +185,7 @@ PyTypeObject ConfigType = {
        0,                         /* tp_getattr */
        0,                         /* tp_setattr */
        0,                         /* tp_compare */
-       0/*Config_repr*/,               /* tp_repr */
+       Config_repr,               /* tp_repr */
        0,                         /* tp_as_number */
        0,                         /* tp_as_sequence */
        0,                         /* tp_as_mapping */