summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 7a942d2)
raw | patch | inline | side by side (parent: 7a942d2)
author | oetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa> | |
Wed, 27 Sep 2006 21:48:05 +0000 (21:48 +0000) | ||
committer | oetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa> | |
Wed, 27 Sep 2006 21:48:05 +0000 (21:48 +0000) |
git-svn-id: svn://svn.oetiker.ch/rrdtool/branches/1.2/program@901 a5681a0c-68f1-0310-ab6d-d61299d08faa
bindings/Makefile.am | patch | blob | history | |
bindings/ruby/CHANGES | [new file with mode: 0644] | patch | blob |
bindings/ruby/README | [new file with mode: 0644] | patch | blob |
bindings/ruby/extconf.rb | [new file with mode: 0644] | patch | blob |
bindings/ruby/main.c | [new file with mode: 0644] | patch | blob |
bindings/ruby/test.rb | [new file with mode: 0755] | patch | blob |
configure.ac | patch | blob | history |
diff --git a/bindings/Makefile.am b/bindings/Makefile.am
index 2bd1a207de2d171533fc1bb3de4dfe1517715e64..a095ef803b2c751d8915dc9088dbe31d7f2d6880 100644 (file)
--- a/bindings/Makefile.am
+++ b/bindings/Makefile.am
@@ -14,12 +14,20 @@ EXTRA_DIST = perl-piped/MANIFEST perl-piped/README perl-piped/Makefile.PL perl-p
# add the following to the all target
-all-local: @COMP_PERL@
+all-local: @COMP_PERL@ @COMP_RUBY@
install-data-local:
test -f perl-piped/Makefile && cd perl-piped && $(MAKE) install || true
test -f perl-shared/Makefile && cd perl-shared && $(MAKE) install || true
+ test -f ruby/Makefile && cd ruby && $(MAKE) EPREFIX=$(exec_prefix) $(RUBY_MAKE_OPTIONS) install || true
+# rules for buildung the ruby module
+ruby: ruby/Makefile
+ cd ruby && $(MAKE) EPREFIX=$(exec_prefix) $(RUBY_MAKE_OPTIONS)
+
+ruby/Makefile: ruby/extconf.rb
+ cd ruby && $(RUBY) extconf.rb
+
# rules for building the perl module
perl_piped: perl-piped/Makefile
cd perl-piped && $(MAKE)
test -f perl-piped/Makefile && rm perl-piped/Makefile || true
test -f perl-shared/Makefile && cd perl-shared && $(MAKE) clean || true
test -f perl-shared/Makefile && rm -f perl-shared/Makefile || true
+ test -f ruby/Makefile && rm -f ruby/Makefile || true
##END##
diff --git a/bindings/ruby/CHANGES b/bindings/ruby/CHANGES
--- /dev/null
+++ b/bindings/ruby/CHANGES
@@ -0,0 +1,3 @@
+2006-07-25 Loïs Lherbier
+ add y_min and y_max parameters to rrd_graph
+ update test.rb to send only strings to RRD.fetch
diff --git a/bindings/ruby/README b/bindings/ruby/README
--- /dev/null
+++ b/bindings/ruby/README
@@ -0,0 +1,22 @@
+#
+# ruby librrd bindings
+# author: Miles Egan <miles@caddr.com>
+#
+
+- Introduction
+
+This module provides ruby bindings for librrd, with functionality
+comparable to the native perl bindings. See test.rb for a script that
+exercises all ruby-librrd functionality.
+
+- Installation
+
+Installation is standard. Simply run:
+
+ruby extconf.rb
+make
+make install
+
+I hope this works for you. Please let me know if you have any
+problems or suggestions. Someday when I'm feeling less lazy I'll
+actually document this thing. Thanks to Tobi for rrdtool!
diff --git a/bindings/ruby/extconf.rb b/bindings/ruby/extconf.rb
--- /dev/null
+++ b/bindings/ruby/extconf.rb
@@ -0,0 +1,18 @@
+# $Id: extconf.rb,v 1.2 2001/11/28 18:30:16 miles Exp $
+# Lost ticket pays maximum rate.
+
+require 'mkmf'
+
+if /linux/ =~ RUBY_PLATFORM
+ $LDFLAGS += '-Wl,--rpath -Wl,$(EPREFIX)/lib'
+elsif /solaris/ =~ RUBY_PLATFORM
+ $LDFLAGS += '-R$(EPREFIX)/lib'
+elsif /hpux/ =~ RUBY_PLATFORM
+ $LDFLAGS += '+b$(EPREFIX)/lib';
+elsif /aix/ =~ RUBY_PLATFORM
+ $LDFLAGS += '-Wl,-blibpath:$(EPREFIX)/lib'
+end
+
+dir_config("rrd","../../src","../../src/.libs")
+have_library("rrd", "rrd_create")
+create_makefile("RRD")
diff --git a/bindings/ruby/main.c b/bindings/ruby/main.c
--- /dev/null
+++ b/bindings/ruby/main.c
@@ -0,0 +1,259 @@
+/* $Id$
+ * Substantial penalty for early withdrawal.
+ */
+
+#include <unistd.h>
+#include <ruby.h>
+#include <rrd.h>
+
+typedef struct string_arr_t {
+ int len;
+ char **strings;
+} string_arr;
+
+VALUE mRRD;
+VALUE rb_eRRDError;
+
+typedef int (*RRDFUNC)(int argc, char ** argv);
+#define RRD_CHECK_ERROR \
+ if (rrd_test_error()) \
+ rb_raise(rb_eRRDError, rrd_get_error()); \
+ rrd_clear_error();
+
+string_arr string_arr_new(VALUE rb_strings)
+{
+ string_arr a;
+ char buf[64];
+ int i;
+
+ Check_Type(rb_strings, T_ARRAY);
+ a.len = RARRAY(rb_strings)->len + 1;
+
+ a.strings = malloc(a.len * sizeof(char *));
+ a.strings[0] = "dummy"; /* first element is a dummy element */
+
+ for (i = 0; i < a.len - 1; i++) {
+ VALUE v = rb_ary_entry(rb_strings, i);
+ switch (TYPE(v)) {
+ case T_STRING:
+ a.strings[i + 1] = strdup(STR2CSTR(v));
+ break;
+ case T_FIXNUM:
+ snprintf(buf, 63, "%d", FIX2INT(v));
+ a.strings[i + 1] = strdup(buf);
+ break;
+ default:
+ rb_raise(rb_eTypeError, "invalid argument");
+ break;
+ }
+ }
+
+ return a;
+}
+
+void string_arr_delete(string_arr a)
+{
+ int i;
+
+ /* skip dummy first entry */
+ for (i = 1; i < a.len; i++) {
+ free(a.strings[i]);
+ }
+
+ free(a.strings);
+}
+
+void reset_rrd_state()
+{
+ optind = 0;
+ opterr = 0;
+ rrd_clear_error();
+}
+
+VALUE rrd_call(RRDFUNC func, VALUE args)
+{
+ string_arr a;
+
+ a = string_arr_new(args);
+ reset_rrd_state();
+ func(a.len, a.strings);
+ string_arr_delete(a);
+
+ RRD_CHECK_ERROR
+
+ return Qnil;
+}
+
+VALUE rb_rrd_create(VALUE self, VALUE args)
+{
+ return rrd_call(rrd_create, args);
+}
+
+VALUE rb_rrd_dump(VALUE self, VALUE args)
+{
+ return rrd_call(rrd_dump, args);
+}
+
+VALUE rb_rrd_fetch(VALUE self, VALUE args)
+{
+ string_arr a;
+ unsigned long i, j, k, step, ds_cnt;
+ rrd_value_t *raw_data;
+ char **raw_names;
+ VALUE data, names, result;
+ time_t start, end;
+
+ a = string_arr_new(args);
+ reset_rrd_state();
+ rrd_fetch(a.len, a.strings, &start, &end, &step, &ds_cnt, &raw_names, &raw_data);
+ string_arr_delete(a);
+
+ RRD_CHECK_ERROR
+
+ names = rb_ary_new();
+ for (i = 0; i < ds_cnt; i++) {
+ rb_ary_push(names, rb_str_new2(raw_names[i]));
+ free(raw_names[i]);
+ }
+ free(raw_names);
+
+ k = 0;
+ data = rb_ary_new();
+ for (i = start; i <= end; i += step) {
+ VALUE line = rb_ary_new2(ds_cnt);
+ for (j = 0; j < ds_cnt; j++) {
+ rb_ary_store(line, j, rb_float_new(raw_data[k]));
+ k++;
+ }
+ rb_ary_push(data, line);
+ }
+ free(raw_data);
+
+ result = rb_ary_new2(4);
+ rb_ary_store(result, 0, INT2FIX(start));
+ rb_ary_store(result, 1, INT2FIX(end));
+ rb_ary_store(result, 2, names);
+ rb_ary_store(result, 2, data);
+ return result;
+}
+
+VALUE rb_rrd_graph(VALUE self, VALUE args)
+{
+ string_arr a;
+ char **calcpr, **p;
+ VALUE result, print_results;
+ int i, xsize, ysize;
+ double ymin, ymax;
+
+ a = string_arr_new(args);
+ reset_rrd_state();
+ rrd_graph(a.len, a.strings, &calcpr, &xsize, &ysize, NULL, &ymin, &ymax);
+ string_arr_delete(a);
+
+ RRD_CHECK_ERROR
+
+ result = rb_ary_new2(3);
+ print_results = rb_ary_new();
+ p = calcpr;
+ for (p = calcpr; p && *p; p++) {
+ rb_ary_push(print_results, rb_str_new2(*p));
+ free(*p);
+ }
+ free(calcpr);
+ rb_ary_store(result, 0, print_results);
+ rb_ary_store(result, 1, INT2FIX(xsize));
+ rb_ary_store(result, 2, INT2FIX(ysize));
+ return result;
+}
+
+/*
+VALUE rb_rrd_info(VALUE self, VALUE args)
+{
+ string_arr a;
+ info_t *p;
+ VALUE result;
+
+ a = string_arr_new(args);
+ data = rrd_info(a.len, a.strings);
+ string_arr_delete(a);
+
+ RRD_CHECK_ERROR
+
+ result = rb_hash_new();
+ while (data) {
+ VALUE key = rb_str_new2(data->key);
+ switch (data->type) {
+ case RD_I_VAL:
+ if (isnan(data->u_val)) {
+ rb_hash_aset(result, key, Qnil);
+ }
+ else {
+ rb_hash_aset(result, key, rb_float_new(data->u_val));
+ }
+ break;
+ case RD_I_CNT:
+ rb_hash_aset(result, key, INT2FIX(data->u_cnt));
+ break;
+ case RD_I_STR:
+ rb_hash_aset(result, key, rb_str_new2(data->u_str));
+ free(data->u_str);
+ break;
+ }
+ p = data;
+ data = data->next;
+ free(p);
+ }
+ return result;
+}
+*/
+
+VALUE rb_rrd_last(VALUE self, VALUE args)
+{
+ string_arr a;
+ time_t last;
+
+ a = string_arr_new(args);
+ reset_rrd_state();
+ last = rrd_last(a.len, a.strings);
+ string_arr_delete(a);
+
+ RRD_CHECK_ERROR
+
+ return rb_funcall(rb_cTime, rb_intern("at"), 1, INT2FIX(last));
+}
+
+VALUE rb_rrd_resize(VALUE self, VALUE args)
+{
+ return rrd_call(rrd_resize, args);
+}
+
+VALUE rb_rrd_restore(VALUE self, VALUE args)
+{
+ return rrd_call(rrd_restore, args);
+}
+
+VALUE rb_rrd_tune(VALUE self, VALUE args)
+{
+ return rrd_call(rrd_tune, args);
+}
+
+VALUE rb_rrd_update(VALUE self, VALUE args)
+{
+ return rrd_call(rrd_update, args);
+}
+
+void Init_RRD()
+{
+ mRRD = rb_define_module("RRD");
+ rb_eRRDError = rb_define_class("RRDError", rb_eStandardError);
+
+ rb_define_module_function(mRRD, "create", rb_rrd_create, -2);
+ rb_define_module_function(mRRD, "dump", rb_rrd_dump, -2);
+ rb_define_module_function(mRRD, "fetch", rb_rrd_fetch, -2);
+ rb_define_module_function(mRRD, "graph", rb_rrd_graph, -2);
+ rb_define_module_function(mRRD, "last", rb_rrd_last, -2);
+ rb_define_module_function(mRRD, "resize", rb_rrd_resize, -2);
+ rb_define_module_function(mRRD, "restore", rb_rrd_restore, -2);
+ rb_define_module_function(mRRD, "tune", rb_rrd_tune, -2);
+ rb_define_module_function(mRRD, "update", rb_rrd_update, -2);
+}
diff --git a/bindings/ruby/test.rb b/bindings/ruby/test.rb
--- /dev/null
+++ b/bindings/ruby/test.rb
@@ -0,0 +1,50 @@
+#!/usr/bin/env ruby
+# $Id: test.rb,v 1.2 2002/10/22 17:34:00 miles Exp $
+# Driver does not carry cash.
+
+require "RRD"
+
+name = "test"
+rrd = "#{name}.rrd"
+start = Time.now.to_i
+
+puts "creating #{rrd}"
+RRD.create(
+ rrd,
+ "--start", "#{start - 1}",
+ "--step", "300",
+ "DS:a:GAUGE:600:U:U",
+ "DS:b:GAUGE:600:U:U",
+ "RRA:AVERAGE:0.5:1:300")
+puts
+
+puts "updating #{rrd}"
+start.to_i.step(start.to_i + 300 * 300, 300) { |i|
+ RRD.update(rrd, "#{i}:#{rand(100)}:#{Math.sin(i / 800) * 50 + 50}")
+}
+puts
+
+puts "fetching data from #{rrd}"
+(fstart, fend, data) = RRD.fetch(rrd, "--start", start.to_s, "--end", (start + 300 * 300).to_s, "AVERAGE")
+puts "got #{data.length} data points from #{fstart} to #{fend}"
+puts
+
+puts "generating graph #{name}.png"
+RRD.graph(
+ "#{name}.png",
+ "--title", " RubyRRD Demo",
+ "--start", "#{start} + 1 h",
+ "--end", "#{start} + 1000 min",
+ "--interlace",
+ "--imgformat", "PNG",
+ "--width=450",
+ "DEF:a=#{rrd}:a:AVERAGE",
+ "DEF:b=#{rrd}:b:AVERAGE",
+ "CDEF:line=TIME,2400,%,300,LT,a,UNKN,IF",
+ "AREA:b#00b6e4:beta",
+ "AREA:line#0022e9:alpha",
+ "LINE3:line#ff0000")
+puts
+
+print "This script has created #{name}.png in the current directory\n";
+print "This demonstrates the use of the TIME and % RPN operators\n";
diff --git a/configure.ac b/configure.ac
index 2d4a2425a87c9beb1aca16de7e9fac89b9b69f77..a39cd8dc771c8ac5b490e07840c9c63de09c0779 100644 (file)
--- a/configure.ac
+++ b/configure.ac
),
[AC_DEFINE(NEED_MALLOC_MALLOC_H)
AC_MSG_RESULT([yes we do])],
- [AC_MSG_ERROR([Can't figure how to compile malloc])]
+ [AC_MSG_ERROR([Can not figure how to compile malloc])]
)
]
)
AM_CONDITIONAL(BUILD_RRDCGI,[test $enable_rrdcgi != no])
+CORE_LIBS="$LIBS"
+
EX_CHECK_ALL(art_lgpl_2, art_vpath_add_point, libart_lgpl/libart.h, libart-2.0, 2.3.17, ftp://ftp.gnome.org/pub/GNOME/sources/libart_lgpl/2.3/, /usr/include/libart-2.0)
EX_CHECK_ALL(z, zlibVersion, zlib.h, zlib, 1.2.3, http://www.gzip.org/zlib/, "")
EX_CHECK_ALL(png, png_access_version_number, png.h, libpng, 1.2.10, http://prdownloads.sourceforge.net/libpng/, "")
AC_MSG_ERROR([Please fix the library issues listed above and try again.])
fi
+ALL_LIBS="$LIBS"
+LIBS=
+
+AC_SUBST(CORE_LIBS)
+AC_SUBST(ALL_LIBS)
CONFIGURE_PART(Prep for Building Language Bindings)
AC_SUBST(COMP_PERL)
AC_SUBST(PERL_VERSION)
+dnl Check for Ruby.
+AC_PATH_PROG(RUBY, ruby, no)
+
+AC_ARG_ENABLE(ruby,[ --disable-ruby do not build the ruby modules],
+[],[enable_ruby=yes])
+
+
+if test "x$RUBY" = "xno" -o x$enable_ruby = xno; then
+ COMP_RUBY=
+else
+ COMP_RUBY="ruby"
+
+fi
+
+AC_MSG_CHECKING(Ruby Modules to build)
+AC_MSG_RESULT(${COMP_RUBY:-No Ruby Modules will be built})
+
+dnl pass additional ruby options when generating Makefile from Makefile.PL
+AC_ARG_ENABLE(ruby-site-install,
+[ --enable-ruby-site-install by default the rrdtool ruby modules are installed
+ together with rrdtool in $prefix/lib/ruby. You have to
+ add $prefix/lib/ruby/$ruby_version/$sitearch to you $: variable
+ for ruby to find the RRD.so file.],
+[RUBY_MAKE_OPTIONS=],[RUBY_MAKE_OPTIONS="sitedir=$prefix/lib/ruby"])
+
+
+AC_ARG_WITH(ruby-options,
+[ --with-ruby-options=[OPTIONS] options to pass on command-line when
+ generating Makefile from extconf.rb. If you set this
+ option, interesting things may happen unless you know
+ what you are doing!],
+[RUBY_MAKE_OPTIONS=$withval])
+
+AC_SUBST(RUBY_MAKE_OPTIONS)
+AC_SUBST(RUBY)
+AC_SUBST(COMP_RUBY)
+
+
enable_tcl_site=no
AC_ARG_ENABLE(tcl,[ --disable-tcl do not build the tcl modules],
echo " Perl Binary: $PERL"
echo " Perl Version: $PERL_VERSION"
echo " Perl Options: $PERL_MAKE_OPTIONS"
+echo " Ruby Modules: $COMP_RUBY"
+echo " Ruby Binary: $RUBY"
+echo " Ruby Options: $RUBY_MAKE_OPTIONS"
echo " Build Tcl Bindings: $enable_tcl"
echo " Build Python Bindings: $enable_python"
echo " Build rrdcgi: $enable_rrdcgi"
echo "install everything to: $prefix."
echo
echo " ... that wishlist is NO JOKE. If you find RRDtool useful"
-echo "make me happy. Go to http://people.ee.ethz.ch/oetiker/wish and"
+echo "make me happy. Go to http://tobi.oetiker.ch/wish and"
echo "place an order."
echo
echo " -- Tobi Oetiker <tobi@oetiker.ch>"