From: medranocalvo Date: Tue, 12 Sep 2017 12:00:21 +0000 (+0200) Subject: Build fixes tcl commands (#817) X-Git-Tag: v1.7.1~114 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e35d46043afe8aa201191be01748c39e05a14085;p=thirdparty%2Frrdtool-1.x.git Build fixes tcl commands (#817) * 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 --- diff --git a/bindings/tcl/Makefile.am b/bindings/tcl/Makefile.am index 4dabd48d..721580bb 100644 --- a/bindings/tcl/Makefile.am +++ b/bindings/tcl/Makefile.am @@ -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) diff --git a/bindings/tcl/tclrrd.c b/bindings/tcl/tclrrd.c index d2f18b16..a3b824f9 100644 --- a/bindings/tcl/tclrrd.c +++ b/bindings/tcl/tclrrd.c @@ -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 */ diff --git a/configure.ac b/configure.ac index 6317eae7..7ef8c01a 100644 --- a/configure.ac +++ b/configure.ac @@ -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 ], + [#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]) ],[ diff --git a/src/Makefile.am b/src/Makefile.am index 1a605846..3be1b5f9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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