configure.in: Add check for libgnutls.
[collectd.git] / src / pyconfig.c
index 63b44f8..b5c01aa 100644 (file)
@@ -1,3 +1,29 @@
+/**
+ * collectd - src/pyconfig.c
+ * Copyright (C) 2009  Sven Trenkel
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *   Sven Trenkel <collectd at semidefinite.de>  
+ **/
+
 #include <Python.h>
 #include <structmember.h>
 
@@ -6,7 +32,7 @@
 
 #include "cpython.h"
 
-static const char Config_doc[] = "This represents a piece of collectd's config file.\n"
+static char config_doc[] = "This represents a piece of collectd's config file.\n"
                "It is passed to scripts with config callbacks (see \"register_config\")\n"
                "and is of little use if created somewhere else.\n"
                "\n"
@@ -48,10 +74,17 @@ static int Config_init(PyObject *s, PyObject *args, PyObject *kwds) {
        Config *self = (Config *) s;
        static char *kwlist[] = {"key", "parent", "values", "children", NULL};
        
-       if (!PyArg_ParseTupleAndKeywords(args, kwds, "S|OOO", kwlist,
+       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);
+               Py_XDECREF(values);
+               Py_XDECREF(children);
+               return -1;
+       }
        if (values == NULL) {
                values = PyTuple_New(0);
                PyErr_Clear();
@@ -87,8 +120,28 @@ static int Config_init(PyObject *s, PyObject *args, PyObject *kwds) {
 
 static PyObject *Config_repr(PyObject *s) {
        Config *self = (Config *) s;
+       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 PyString_FromFormat("<collectd.Config %snode %s>", self->parent == Py_None ? "root " : "", PyString_AsString(PyObject_Str(self->key)));
+       return ret;
 }
 
 static int Config_traverse(PyObject *self, visitproc visit, void *arg) {
@@ -97,8 +150,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;
@@ -123,8 +175,7 @@ static PyMemberDef Config_members[] = {
 };
 
 PyTypeObject ConfigType = {
-       PyObject_HEAD_INIT(NULL)
-       0,                         /* Always 0 */
+       CPY_INIT_TYPE
        "collectd.Config",         /* tp_name */
        sizeof(Config),            /* tp_basicsize */
        0,                         /* Will be filled in later */
@@ -144,7 +195,7 @@ PyTypeObject ConfigType = {
        0,                         /* tp_setattro */
        0,                         /* tp_as_buffer */
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
-       Config_doc,                /* tp_doc */
+       config_doc,                /* tp_doc */
        Config_traverse,           /* tp_traverse */
        Config_clear,              /* tp_clear */
        0,                         /* tp_richcompare */