I thought that it would be nice to be able to pass
[rrdtool.git] / bindings / python / rrdtoolmodule.c
index 1b85f96..6cc22ad 100644 (file)
@@ -58,28 +58,59 @@ static int create_args(
     int *argc,
     char ***argv)
 {
-    PyObject *o;
-    int       size, i;
-
-    size = PyTuple_Size(args);
+    PyObject *o, *lo;
+    int       args_count,
+              argv_count,
+              element_count,
+              i, j;
+
+    args_count = PyTuple_Size(args);
+    element_count = 0;
+    for (i = 0; i < args_count; i++) {
+        o = PyTuple_GET_ITEM(args, i);
+        if (PyString_Check(o))
+            element_count++;
+        else if (PyList_CheckExact(o))
+                element_count += PyList_Size(o);
+             else {
+                 PyErr_Format(PyExc_TypeError, "argument %d must be string or list of strings", i);
+                 return -1;
+             }
+    }
+   
     *argv = PyMem_New(char *,
-                      size + 1);
+                      element_count + 1);
 
     if (*argv == NULL)
         return -1;
 
-    for (i = 0; i < size; i++) {
+    argv_count = 0;
+    for (i = 0; i < args_count; i++) {
         o = PyTuple_GET_ITEM(args, i);
-        if (PyString_Check(o))
-            (*argv)[i + 1] = PyString_AS_STRING(o);
-        else {
-            PyMem_Del(*argv);
-            PyErr_Format(PyExc_TypeError, "argument %d must be string", i);
-            return -1;
-        }
+        if (PyString_Check(o)) {
+            argv_count++;
+            (*argv)[argv_count] = PyString_AS_STRING(o);
+        } else if (PyList_CheckExact(o))
+                   for (j = 0; j < PyList_Size(o); j++) {
+                       lo = PyList_GetItem(o, j);
+                       if (PyString_Check(lo)) {
+                           argv_count++;
+                           (*argv)[argv_count] = PyString_AS_STRING(lo);
+                       } else {
+                             PyMem_Del(*argv);
+                             PyErr_Format(PyExc_TypeError, "element %d in argument %d must be string", j, i);
+                             return -1;
+                       }
+                   }
+               else {
+                   PyMem_Del(*argv);
+                   PyErr_Format(PyExc_TypeError, "argument %d must be string or list of strings", i);
+                   return -1;
+               }
     }
+
     (*argv)[0] = command;
-    *argc = size + 1;
+    *argc = element_count + 1;
 
     /* reset getopt state */
     opterr = optind = 0;
@@ -184,7 +215,7 @@ static PyObject *PyRRD_fetch(
         unsigned long i, j, row;
         rrd_value_t dv;
 
-        row = ((end - start) / step + 1);
+        row = (end - start) / step;
 
         r = PyTuple_New(3);
         range_tup = PyTuple_New(3);
@@ -516,6 +547,34 @@ static PyObject *PyRRD_updatev(
     return r;
 }
 
+static char PyRRD_flush__doc__[] =
+  "flush(args..): flush RRD files from memory\n"
+  "   flush [--daemon address] file [file ...]";
+
+static PyObject *PyRRD_flush(
+    PyObject UNUSED(*self),
+    PyObject * args)
+{
+    PyObject *r;
+    int       argc;
+    char    **argv;
+
+    if (create_args("flush", args, &argc, &argv) < 0)
+        return NULL;
+
+    if (rrd_cmd_flush(argc, argv) != 0) {
+        PyErr_SetString(ErrorObject, rrd_get_error());
+        rrd_clear_error();
+        r = NULL;
+    } else {
+        Py_INCREF(Py_None);
+        r = Py_None;
+    }
+
+    destroy_args(&argv);
+    return r;
+}
+
 /* List of methods defined in the module */
 #define meth(name, func, doc) {name, (PyCFunction)func, METH_VARARGS, doc}
 
@@ -531,6 +590,7 @@ static PyMethodDef _rrdtool_methods[] = {
     meth("info", PyRRD_info, PyRRD_info__doc__),
     meth("graphv", PyRRD_graphv, PyRRD_graphv__doc__),
     meth("updatev", PyRRD_updatev, PyRRD_updatev__doc__),
+    meth("flush", PyRRD_flush, PyRRD_flush__doc__),
     {NULL, NULL, 0, NULL}
 };