Code

8a762ada459201a2d86e9194f6cb60ca449dce77
[pkg-rrdtool.git] / bindings / ruby / main.c
1 /* $Id: main.c 1212 2007-11-08 10:13:48Z oetiker $
2  * Substantial penalty for early withdrawal.
3  */
5 #include <unistd.h>
6 #include <ruby.h>
7 #include "../../src/rrd_tool.h"
9 typedef struct string_arr_t {
10     int len;
11     char **strings;
12 } string_arr;
14 VALUE mRRD;
15 VALUE rb_eRRDError;
17 typedef int (*RRDFUNC)(int argc, char ** argv);
18 #define RRD_CHECK_ERROR  \
19     if (rrd_test_error()) \
20       rb_raise(rb_eRRDError, rrd_get_error()); \
21     rrd_clear_error();
23 string_arr string_arr_new(VALUE rb_strings)
24 {
25     string_arr a;
26     char buf[64];
27     int i;
28    
29     Check_Type(rb_strings, T_ARRAY);
30     a.len = RARRAY(rb_strings)->len + 1;
32     a.strings = malloc(a.len * sizeof(char *));
33     a.strings[0] = "dummy";     /* first element is a dummy element */
35     for (i = 0; i < a.len - 1; i++) {
36         VALUE v = rb_ary_entry(rb_strings, i);
37         switch (TYPE(v)) {
38         case T_STRING:
39             a.strings[i + 1] = strdup(STR2CSTR(v));
40             break;
41         case T_FIXNUM:
42             snprintf(buf, 63, "%d", FIX2INT(v));
43             a.strings[i + 1] = strdup(buf);
44             break;
45         default:
46             rb_raise(rb_eTypeError, "invalid argument - %s, expected T_STRING or T_FIXNUM on index %d", rb_class2name(CLASS_OF(v)), i);
47             break;
48         }
49     }
51     return a;
52 }
54 void string_arr_delete(string_arr a)
55 {
56     int i;
58     /* skip dummy first entry */
59     for (i = 1; i < a.len; i++) {
60         free(a.strings[i]);
61     }
63     free(a.strings);
64 }
66 void reset_rrd_state()
67 {
68     optind = 0; 
69     opterr = 0;
70     rrd_clear_error();
71 }
73 VALUE rrd_call(RRDFUNC func, VALUE args)
74 {
75     string_arr a;
77     a = string_arr_new(args);
78     reset_rrd_state();
79     func(a.len, a.strings);
80     string_arr_delete(a);
82     RRD_CHECK_ERROR
84     return Qnil;
85 }
87 VALUE rb_rrd_create(VALUE self, VALUE args)
88 {
89     return rrd_call(rrd_create, args);
90 }
92 VALUE rb_rrd_dump(VALUE self, VALUE args)
93 {
94     return rrd_call(rrd_dump, args);
95 }
97 VALUE rb_rrd_fetch(VALUE self, VALUE args)
98 {
99     string_arr a;
100     unsigned long i, j, k, step, ds_cnt;
101     rrd_value_t *raw_data;
102     char **raw_names;
103     VALUE data, names, result;
104     time_t start, end;
106     a = string_arr_new(args);
107     reset_rrd_state();
108     rrd_fetch(a.len, a.strings, &start, &end, &step, &ds_cnt, &raw_names, &raw_data);
109     string_arr_delete(a);
111     RRD_CHECK_ERROR
113     names = rb_ary_new();
114     for (i = 0; i < ds_cnt; i++) {
115         rb_ary_push(names, rb_str_new2(raw_names[i]));
116         free(raw_names[i]);
117     }
118     free(raw_names);
120     k = 0;
121     data = rb_ary_new();
122     for (i = start; i <= end; i += step) {
123         VALUE line = rb_ary_new2(ds_cnt);
124         for (j = 0; j < ds_cnt; j++) {
125             rb_ary_store(line, j, rb_float_new(raw_data[k]));
126             k++;
127         }
128         rb_ary_push(data, line);
129     }
130     free(raw_data);
131    
132     result = rb_ary_new2(4);
133     rb_ary_store(result, 0, INT2NUM(start));
134     rb_ary_store(result, 1, INT2NUM(end));
135     rb_ary_store(result, 2, names);
136     rb_ary_store(result, 3, data);
137     return result;
140 VALUE rb_rrd_graph(VALUE self, VALUE args)
142     string_arr a;
143     char **calcpr, **p;
144     VALUE result, print_results;
145     int xsize, ysize;
146     double ymin, ymax;
148     a = string_arr_new(args);
149     reset_rrd_state();
150     rrd_graph(a.len, a.strings, &calcpr, &xsize, &ysize, NULL, &ymin, &ymax);
151     string_arr_delete(a);
153     RRD_CHECK_ERROR
155     result = rb_ary_new2(3);
156     print_results = rb_ary_new();
157     p = calcpr;
158     for (p = calcpr; p && *p; p++) {
159         rb_ary_push(print_results, rb_str_new2(*p));
160         free(*p);
161     }
162     free(calcpr);
163     rb_ary_store(result, 0, print_results);
164     rb_ary_store(result, 1, INT2FIX(xsize));
165     rb_ary_store(result, 2, INT2FIX(ysize));
166     return result;
169 VALUE rb_rrd_info(VALUE self, VALUE args)
171     string_arr a;
172     info_t *p, *data;
173     VALUE result;
175     a = string_arr_new(args);
176     data = rrd_info(a.len, a.strings);
177     string_arr_delete(a);
179     RRD_CHECK_ERROR
181     result = rb_hash_new();
182     while (data) {
183         VALUE key = rb_str_new2(data->key);
184         switch (data->type) {
185         case RD_I_VAL:
186             if (isnan(data->value.u_val)) {
187                 rb_hash_aset(result, key, Qnil);
188             }
189             else {
190                 rb_hash_aset(result, key, rb_float_new(data->value.u_val));
191             }
192             break;
193         case RD_I_CNT:
194             rb_hash_aset(result, key, INT2FIX(data->value.u_cnt));
195             break;
196         case RD_I_STR:
197             rb_hash_aset(result, key, rb_str_new2(data->value.u_str));
198             free(data->value.u_str);
199             break;
200         }
201         p = data;
202         data = data->next;
203         free(p);
204     }
205     return result;
208 VALUE rb_rrd_last(VALUE self, VALUE args)
210     string_arr a;
211     time_t last;
213     a = string_arr_new(args);
214     reset_rrd_state();
215     last = rrd_last(a.len, a.strings);
216     string_arr_delete(a);
218     RRD_CHECK_ERROR
220     return rb_funcall(rb_cTime, rb_intern("at"), 1, INT2FIX(last));
223 VALUE rb_rrd_resize(VALUE self, VALUE args)
225     return rrd_call(rrd_resize, args);
228 VALUE rb_rrd_restore(VALUE self, VALUE args)
230     return rrd_call(rrd_restore, args);
233 VALUE rb_rrd_tune(VALUE self, VALUE args)
235     return rrd_call(rrd_tune, args);
238 VALUE rb_rrd_update(VALUE self, VALUE args)
240     return rrd_call(rrd_update, args);
243 void Init_RRD() 
245     mRRD = rb_define_module("RRD");
246     rb_eRRDError = rb_define_class("RRDError", rb_eStandardError);
248     rb_define_module_function(mRRD, "create", rb_rrd_create, -2);
249     rb_define_module_function(mRRD, "dump", rb_rrd_dump, -2);
250     rb_define_module_function(mRRD, "fetch", rb_rrd_fetch, -2);
251     rb_define_module_function(mRRD, "graph", rb_rrd_graph, -2);
252     rb_define_module_function(mRRD, "last", rb_rrd_last, -2);
253     rb_define_module_function(mRRD, "resize", rb_rrd_resize, -2);
254     rb_define_module_function(mRRD, "restore", rb_rrd_restore, -2);
255     rb_define_module_function(mRRD, "tune", rb_rrd_tune, -2);
256     rb_define_module_function(mRRD, "update", rb_rrd_update, -2);
257     rb_define_module_function(mRRD, "info", rb_rrd_info, -2);