2 * Lua bindings for RRDTool
4 * This software is licensed to the public under the Free Software
5 * Foundation's GNU GPL, version 2 or later. You may obtain a copy
6 * of the GPL by visiting the Free Software Foundations web site at
7 * www.fsf.org, and a copy is included in this distribution.
9 * Copyright 2008 Fidelis Assis, all rights reserved.
27 #include "../../src/rrd_tool.h"
29 extern void rrd_freemem(void *mem);
31 extern int luaopen_rrd (lua_State * L);
32 typedef int (*RRD_FUNCTION)(int, char **);
33 typedef rrd_info_t *(RRD_FUNCTION_V)(int, char **);
35 /**********************************************************/
37 static void reset_rrd_state(void)
44 static char **make_argv(const char *cmd, lua_State * L)
48 int argc = lua_gettop(L) + 1;
50 if (!(argv = calloc(argc, sizeof (char *))))
51 /* raise an error and never return */
52 luaL_error(L, "Can't allocate memory for arguments array", cmd);
54 /* fprintf(stderr, "Args:\n"); */
55 argv[0] = (char *) cmd; /* Dummy arg. Cast to (char *) because rrd */
56 /* functions don't expect (const * char) */
57 /* fprintf(stderr, "%s\n", argv[0]); */
58 for (i=1; i<argc; i++) {
59 /* accepts string or number */
60 if (lua_isstring(L, i) || lua_isnumber(L, i)) {
61 if (!(argv[i] = strdup(lua_tostring (L, i)))) {
62 /* raise an error and never return */
63 luaL_error(L, "%s - error duplicating string area for arg #%d",
67 /* raise an error and never return */
68 luaL_error(L, "Invalid arg #%d to %s: args must be strings or numbers",
71 /* fprintf(stderr, "%s\n", argv[i]); */
77 rrd_common_call (lua_State *L, const char *cmd, RRD_FUNCTION rrd_function)
80 int argc = lua_gettop(L) + 1;
82 argv = make_argv(cmd, L);
84 rrd_function(argc, argv);
86 if (rrd_test_error()) luaL_error(L, rrd_get_error());
92 lua_rrd_infocall(lua_State *L, const char *cmd, RRD_FUNCTION_V rrd_function)
96 int argc = lua_gettop(L) + 1;
98 argv = make_argv(cmd, L);
100 data = rrd_function(argc, argv);
102 if (rrd_test_error()) luaL_error(L, rrd_get_error());
107 lua_pushstring(L, data->key);
108 switch (data->type) {
110 if (isnan(data->value.u_val)) {
113 lua_pushnumber(L, (lua_Number) data->value.u_val);
118 lua_pushnumber(L, (lua_Number) data->value.u_val);
122 lua_pushstring(L, data->value.u_str);
126 lua_pushlstring(L, (const char *) data->value.u_blo.ptr,
127 data->value.u_blo.size);
132 return luaL_error(L, "Wrong data type to info call");
142 /**********************************************************/
145 lua_rrd_create (lua_State * L)
147 rrd_common_call(L, "create", rrd_create);
152 lua_rrd_dump (lua_State * L)
154 rrd_common_call(L, "dump", rrd_dump);
159 lua_rrd_resize (lua_State * L)
161 rrd_common_call(L, "resize", rrd_resize);
166 lua_rrd_restore (lua_State * L)
168 rrd_common_call(L, "restore", rrd_restore);
173 lua_rrd_tune (lua_State * L)
175 rrd_common_call(L, "tune", rrd_tune);
180 lua_rrd_update (lua_State * L)
182 rrd_common_call(L, "update", rrd_update);
187 lua_rrd_fetch (lua_State * L)
189 int argc = lua_gettop(L) + 1;
190 char **argv = make_argv("fetch", L);
191 unsigned long i, j, step, ds_cnt;
192 rrd_value_t *data, *p;
194 time_t t, start, end;
197 rrd_fetch(argc, argv, &start, &end, &step, &ds_cnt, &names, &data);
199 if (rrd_test_error()) luaL_error(L, rrd_get_error());
201 lua_pushnumber(L, (lua_Number) start);
202 lua_pushnumber(L, (lua_Number) step);
203 /* fprintf(stderr, "%lu, %lu, %lu, %lu\n", start, end, step, num_points); */
205 /* create the ds names array */
207 for (i=0; i<ds_cnt; i++) {
208 lua_pushstring(L, names[i]);
209 lua_rawseti(L, -2, i+1);
210 rrd_freemem(names[i]);
214 /* create the data points array */
217 for (t=start, i=0; t<end; t+=step, i++) {
219 for (j=0; j<ds_cnt; j++) {
220 /*fprintf(stderr, "Point #%lu\n", j+1); */
221 lua_pushnumber(L, (lua_Number) *p++);
222 lua_rawseti(L, -2, j+1);
224 lua_rawseti(L, -2, i+1);
228 /* return the end as the last value */
229 lua_pushnumber(L, (lua_Number) end);
235 lua_rrd_first (lua_State * L)
238 int argc = lua_gettop(L) + 1;
239 char **argv = make_argv("first", L);
241 first = rrd_first(argc, argv);
243 if (rrd_test_error()) luaL_error(L, rrd_get_error());
244 lua_pushnumber(L, (lua_Number) first);
249 lua_rrd_last (lua_State * L)
252 int argc = lua_gettop(L) + 1;
253 char **argv = make_argv("last", L);
255 last = rrd_last(argc, argv);
257 if (rrd_test_error()) luaL_error(L, rrd_get_error());
258 lua_pushnumber(L, (lua_Number) last);
263 lua_rrd_graph (lua_State * L)
265 int argc = lua_gettop(L) + 1;
266 char **argv = make_argv("last", L);
272 rrd_graph(argc, argv, &calcpr, &xsize, &ysize, NULL, &ymin, &ymax);
274 if (rrd_test_error()) luaL_error(L, rrd_get_error());
275 lua_pushnumber(L, (lua_Number) xsize);
276 lua_pushnumber(L, (lua_Number) ysize);
278 for (i = 0; calcpr && calcpr[i]; i++) {
279 lua_pushstring(L, calcpr[i]);
280 lua_rawseti(L, -2, i+1);
281 rrd_freemem(calcpr[i]);
289 lua_rrd_info (lua_State * L)
291 return lua_rrd_infocall(L, "info", rrd_info);
295 lua_rrd_graphv (lua_State * L)
297 return lua_rrd_infocall(L, "graphv", rrd_graph_v);
301 lua_rrd_updatev (lua_State * L)
303 return lua_rrd_infocall(L, "updatev", rrd_update_v);
307 /**********************************************************/
310 ** Assumes the table is on top of the stack.
313 set_info (lua_State * L)
315 lua_pushliteral (L, "_COPYRIGHT");
316 lua_pushliteral (L, "Copyright (C) 2008 Fidelis Assis");
317 lua_settable (L, -3);
318 lua_pushliteral (L, "_DESCRIPTION");
319 lua_pushliteral (L, "RRD-lua is a Lua binding for RRDTool.");
320 lua_settable (L, -3);
321 lua_pushliteral (L, "_NAME");
322 lua_pushliteral (L, "RRD-Lua");
323 lua_settable (L, -3);
324 lua_pushliteral (L, "_VERSION");
325 lua_pushliteral (L, LIB_VERSION);
326 lua_settable (L, -3);
329 /**********************************************************/
331 static const struct luaL_reg rrd[] = {
332 {"create", lua_rrd_create},
333 {"dump", lua_rrd_dump},
334 {"fetch", lua_rrd_fetch},
335 {"first", lua_rrd_first},
336 {"graph", lua_rrd_graph},
337 {"last", lua_rrd_last},
338 {"resize", lua_rrd_resize},
339 {"restore", lua_rrd_restore},
340 {"tune", lua_rrd_tune},
341 {"update", lua_rrd_update},
343 {"info", lua_rrd_info},
344 {"updatev", lua_rrd_updatev},
345 {"graphv", lua_rrd_graphv},
355 luaopen_rrd (lua_State * L)
357 luaL_register (L, "rrd", rrd);