]> git.ipfire.org Git - thirdparty/rrdtool-1.x.git/commitdiff
Build fixes tcl commands (#817)
authormedranocalvo <amcalvo@prs.de>
Tue, 12 Sep 2017 12:00:21 +0000 (14:00 +0200)
committerTobias Oetiker <tobi@oetiker.ch>
Tue, 12 Sep 2017 12:00:21 +0000 (14:00 +0200)
* Link to gthread-2.0 when g_thread_init needs to be invoked

See https://developer.gnome.org/glib/stable/glib-Deprecated-Thread-APIs.html#g-thread-init:

> To use g_thread_init() in your program, you have to link
> with the libraries that the command `pkg-config --libs
> gthread-2.0` outputs. This is not the case for all the other
> thread-related functions of GLib. Those can be used without having to
> link with the thread libraries.

* Support building in a separate directory

* bindings/tcl/Makefile.am: use a relative path to the shlib in pkgIndex.tcl

* Add rrd_info support in Tcl bindings

* Add rrd_first support in Tcl bindings

* Fix memory leak in Rrd_Lastupdate

bindings/tcl/Makefile.am
bindings/tcl/tclrrd.c
configure.ac
src/Makefile.am

index 4dabd48dbe408c6de7968bca54bc7dca7f038e86..721580bb32234fed6d341fdda84b46101f068c72 100644 (file)
@@ -24,10 +24,12 @@ if BUILD_TCL_SITE
 tclpkgdir = @TCL_PACKAGE_DIR@
 tclpkg_DATA = pkgIndex.tcl
 tclpkg_SCRIPTS = ifOctets.tcl
+tclpkg_rellibdir = $(libdir)
 else
-pkgindexdir = $(pkglibdir)
-pkgindex_DATA = pkgIndex.tcl
-pkgindex_SCRIPTS = ifOctets.tcl
+tclpkgdir = $(pkglibdir)
+tclpkg_DATA = pkgIndex.tcl
+tclpkg_SCRIPTS = ifOctets.tcl
+tclpkg_rellibdir = ..
 endif
 
 # Automake doesn't like `tclrrd$(VERSION)$(TCL_SHLIB_SUFFIX)' as
@@ -49,7 +51,7 @@ tclrrd.o: tclrrd.c
        $(CC) $(AM_CFLAGS) $(CFLAGS) $(TCL_SHLIB_CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -c $(srcdir)/tclrrd.c -DVERSION=\"$(VERSION)\"
 
 pkgIndex.tcl:
-       echo "package ifneeded Rrd $(VERSION) \"load $(libdir)/tclrrd$(VERSION)[info sharedlibextension]\"" > $@
+       echo "package ifneeded Rrd $(VERSION) [list load [file join \$$dir $(tclpkg_rellibdir)/tclrrd$(VERSION)[info sharedlibextension]]]" > $@
 
 install-exec-local: $(TCL_RRD_LIB)
        @$(NORMAL_INSTALL)
index d2f18b1608f78d52047f066d3cfcee68da5e0feb..a3b824f9fe74f09805549a4fd76ef5d33b23b162 100644 (file)
@@ -2,6 +2,7 @@
  * tclrrd.c -- A TCL interpreter extension to access the RRD library.
  *
  * Copyright (c) 1999,2000 Frank Strauss, Technical University of Braunschweig.
+ * Copyright (c) 2017 Patzschke + Rasp Software GmbH, Wiesbaden
  *
  * Thread-safe code copyright (c) 2005 Oleg Derevenetz, CenterTelecom Voronezh ISP.
  *
@@ -201,6 +202,57 @@ static int Rrd_Create(
     return TCL_OK;
 }
 
+/**
+ * Convert RRDtool info to a Tcl dictionary.
+ *
+ * @param data RRDtool info object
+ * @return Tcl dictionary
+ */
+static Tcl_Obj *
+convert_info(const rrd_info_t *data)
+{
+    Tcl_Obj *dictObj, *valueObj, *keyObj;
+
+    dictObj = Tcl_NewDictObj();
+
+    while (data) {
+        valueObj = NULL;
+
+        switch (data->type) {
+            case RD_I_VAL:
+                if (isnan(data->value.u_val)) {
+                   valueObj = Tcl_NewObj();
+                } else
+                   valueObj = Tcl_NewDoubleObj(data->value.u_val);
+                break;
+
+            case RD_I_CNT:
+            case RD_I_INT:
+               valueObj = Tcl_NewLongObj(data->value.u_cnt);
+                break;
+
+            case RD_I_STR:
+               valueObj = Tcl_NewStringObj(data->value.u_str, -1);
+                break;
+
+            case RD_I_BLO:
+               valueObj = Tcl_NewByteArrayObj(data->value.u_blo.ptr, data->value.u_blo.size);
+                break;
+
+            default:
+                break;
+        }
+
+        if (valueObj != NULL) {
+           keyObj = Tcl_NewStringObj(data->key, -1);
+           Tcl_DictObjPut(NULL, dictObj, keyObj, valueObj);
+       }
+
+        data = data->next;
+    }
+
+    return dictObj;
+}
 
 
 /* Thread-safe version */
@@ -256,6 +308,39 @@ static int Rrd_Flushcached(
 }
 
 
+/* Thread-safe version */
+static int Rrd_First(
+    ClientData __attribute__((unused)) clientData,
+    Tcl_Interp *interp,
+    int argc,
+    CONST84 char *argv[])
+{
+    time_t    t;
+    int rraindex = 0;
+
+    if (argc < 2 || argc > 3) {
+        Tcl_AppendResult(interp, "RRD Error: wrong # args filename ?rraindex?",
+                         (char *) NULL);
+        return TCL_ERROR;
+    }
+    if (Tcl_GetInt(interp, argv[2], &rraindex) != TCL_OK) {
+       return TCL_ERROR;
+    }
+
+    t = rrd_first_r(argv[1], rraindex);
+
+    if (rrd_test_error()) {
+        Tcl_AppendResult(interp, "RRD Error: ",
+                         rrd_get_error(), (char *) NULL);
+        rrd_clear_error();
+        return TCL_ERROR;
+    }
+
+    Tcl_SetObjResult(interp, Tcl_NewIntObj(t));
+
+    return TCL_OK;
+}
+
 /* Thread-safe version */
 static int Rrd_Last(
     ClientData __attribute__((unused)) clientData,
@@ -361,6 +446,41 @@ static int Rrd_Update(
     return TCL_OK;
 }
 
+static int Rrd_Info(
+    ClientData __attribute__((unused)) clientData,
+    Tcl_Interp *interp,
+    int argc,
+    CONST84 char *argv[])
+{
+    int status = TCL_OK;
+    rrd_info_t *data;
+    char **argv2;
+
+    /* TODO: support for rrdcached */
+    if (argc != 2) {
+        Tcl_AppendResult(interp, "RRD Error: needs a single rrd filename",
+                         (char *) NULL);
+        return TCL_ERROR;
+    }
+
+    argv2 = getopt_init(argc, argv);
+
+    data = rrd_info_r(argv2[1]);
+
+    if (data) {
+       Tcl_SetObjResult(interp, convert_info(data));
+       rrd_info_free(data);
+    } else {
+        Tcl_AppendResult(interp, "RRD Error: ",
+                         rrd_get_error(), (char *) NULL);
+       rrd_clear_error();
+       status = TCL_ERROR;
+    }
+
+    getopt_cleanup(argc, argv2);
+    return status;
+}
+
 static int Rrd_Lastupdate(
     ClientData __attribute__((unused)) clientData,
     Tcl_Interp *interp,
@@ -407,6 +527,7 @@ static int Rrd_Lastupdate(
             free(ds_namv);
         }
     }
+    getopt_cleanup(argc, argv2);
     return TCL_OK;
 }
 
@@ -650,7 +771,9 @@ typedef struct {
 static CmdInfo rrdCmds[] = {
     {"Rrd::create", Rrd_Create, 1}, /* Thread-safe version */
     {"Rrd::dump", Rrd_Dump, 0}, /* Thread-safe version */
+    {"Rrd::first", Rrd_First, 0}, /* Thread-safe version */
     {"Rrd::flushcached", Rrd_Flushcached, 0},
+    {"Rrd::info", Rrd_Info, 0}, /* Thread-safe version */
     {"Rrd::last", Rrd_Last, 0}, /* Thread-safe version */
     {"Rrd::lastupdate", Rrd_Lastupdate, 0}, /* Thread-safe version */
     {"Rrd::update", Rrd_Update, 1}, /* Thread-safe version */
index 6317eae7c9578e16333c2988467d93033da0a162..7ef8c01ac115a27d43276a419aea27a200bb04e8 100644 (file)
@@ -563,6 +563,16 @@ AM_CONDITIONAL(BUILD_RRDRESTORE,[test $enable_rrd_restore != no])
 
 EX_CHECK_ALL(glib-2.0,   glib_check_version,            glib.h,                 glib-2.0,    2.28.7, ftp://ftp.gtk.org/pub/glib/2.28/, "")
 
+AC_CACHE_CHECK([whether we need to include gthreads for g_thread_init],
+    [ac_cv_glibc_g_thread_init],
+    [AC_TRY_COMPILE([#include <glib.h>],
+                    [#if !GLIB_CHECK_VERSION(2, 32, 0)
+                     # error "glib needs g_thread_init"
+                     #endif],
+                     [AC_MSG_RESULT(no)],
+                     [EX_CHECK_ALL(gthread-2.0, g_thread_init, glib.h, gthread-2.0, x.x.x, "", "")
+                     AC_MSG_RESULT(yes)])])
+
 AC_CHECK_FUNC(g_regex_new,[
    AC_DEFINE(HAVE_G_REGEX_NEW,[1],[our glib has g_regex_new])
 ],[
index 1a605846a6b30b308715bd73b8fb2958bf0c233d..3be1b5f91899d4d69e849950369f151b6925a23f 100644 (file)
@@ -106,7 +106,7 @@ librrd_la_DEPENDENCIES    = librrdupd.la
 librrd_la_LIBADD          = librrdupd.la $(ALL_LIBS) $(LIBINTL)
 librrd_la_CFLAGS          = $(AM_CFLAGS) $(MULTITHREAD_CFLAGS)
 librrd_la_LDFLAGS         = $(MULTITHREAD_LDFLAGS) -version-info @LIBVERS@
-librrd_la_LDFLAGS         += -export-symbols librrd.sym
+librrd_la_LDFLAGS         += -export-symbols $(srcdir)/librrd.sym
 
 include_HEADERS        = rrd.h rrd_format.h rrd_client.h