2 * collectd - src/utils_lua.c
3 * Copyright (C) 2010 Florian Forster
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation; only version 2.1 of the License is
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 * Florian Forster <octo at collectd.org>
23 /* <lua5.1/luaconf.h> defines a macro using "sprintf". Although not used here,
24 * GCC will complain about the macro definition. */
25 #define DONT_POISON_SPRINTF_YET
27 #include "utils_lua.h"
30 static int ltoc_values (lua_State *l, /* {{{ */
36 if (!lua_istable (l, -1))
39 /* Push initial key */
40 lua_pushnil (l); /* +1 = 1 */
42 while (lua_next (l, /* idx = */ -2) != 0) /* -1+2 = 2 || -1 = 0 */
44 if (i >= ((size_t) ds->ds_num))
46 lua_pop (l, /* nelems = */ 2); /* -2 = 0 */
51 ret_values[i] = luaC_tovalue (l, /* idx = */ -1, ds->ds[i].type);
54 lua_pop (l, /* nelems = */ 1); /* -1 = 1 */
56 } /* while (lua_next) */
58 if (i == ((size_t) ds->ds_num))
62 } /* }}} int ltoc_values */
64 static int ltoc_table_values (lua_State *l, int idx, /* {{{ */
65 const data_set_t *ds, value_list_t *vl)
69 /* We're only called from "luaC_tovaluelist", which ensures that "idx" is an
70 * absolute index (i.e. a positive number) */
73 lua_getfield (l, idx, "values");
74 if (!lua_istable (l, -1))
76 WARNING ("utils_lua: ltoc_table_values: The \"values\" member is a %s value, not a table.",
77 lua_typename (l, lua_type (l, -1)));
78 lua_pop (l, /* nelem = */ 1);
82 vl->values_len = ds->ds_num;
83 vl->values = calloc ((size_t) vl->values_len, sizeof (*vl->values));
84 if (vl->values == NULL)
86 ERROR ("utils_lua: calloc failed.");
88 lua_pop (l, /* nelem = */ 1);
92 status = ltoc_values (l, ds, vl->values);
94 lua_pop (l, /* nelem = */ 1);
103 } /* }}} int ltoc_table_values */
105 static int luaC_pushvalues (lua_State *l, const data_set_t *ds, const value_list_t *vl) /* {{{ */
109 assert (vl->values_len == ds->ds_num);
112 for (i = 0; i < vl->values_len; i++)
114 lua_pushinteger (l, (lua_Integer) i);
115 luaC_pushvalue (l, vl->values[i], ds->ds[i].type);
116 lua_settable (l, /* idx = */ -3);
120 } /* }}} int luaC_pushvalues */
122 static int luaC_pushdstypes (lua_State *l, const data_set_t *ds) /* {{{ */
127 for (i = 0; i < ds->ds_num; i++)
129 lua_pushinteger (l, (lua_Integer) i);
130 lua_pushstring (l, DS_TYPE_TO_STRING (ds->ds[i].type));
131 lua_settable (l, /* idx = */ -3);
135 } /* }}} int luaC_pushdstypes */
137 static int luaC_pushdsnames (lua_State *l, const data_set_t *ds) /* {{{ */
142 for (i = 0; i < ds->ds_num; i++)
144 lua_pushinteger (l, (lua_Integer) i);
145 lua_pushstring (l, ds->ds[i].name);
146 lua_settable (l, /* idx = */ -3);
150 } /* }}} int luaC_pushdsnames */
155 cdtime_t luaC_tocdtime (lua_State *l, int idx) /* {{{ */
159 if (!lua_isnumber (l, /* stack pos = */ idx))
162 d = (double) lua_tonumber (l, idx);
164 return (DOUBLE_TO_CDTIME_T (d));
165 } /* }}} int ltoc_table_cdtime */
167 int luaC_tostringbuffer (lua_State *l, int idx, /* {{{ */
168 char *buffer, size_t buffer_size)
172 str = lua_tostring (l, idx);
176 sstrncpy (buffer, str, buffer_size);
178 } /* }}} int luaC_tostringbuffer */
180 value_t luaC_tovalue (lua_State *l, int idx, int ds_type) /* {{{ */
184 memset (&v, 0, sizeof (v));
186 if (!lua_isnumber (l, idx))
189 if (ds_type == DS_TYPE_GAUGE)
190 v.gauge = (gauge_t) lua_tonumber (l, /* stack pos = */ -1);
191 else if (ds_type == DS_TYPE_DERIVE)
192 v.derive = (derive_t) lua_tointeger (l, /* stack pos = */ -1);
193 else if (ds_type == DS_TYPE_COUNTER)
194 v.counter = (counter_t) lua_tointeger (l, /* stack pos = */ -1);
195 else if (ds_type == DS_TYPE_ABSOLUTE)
196 v.absolute = (absolute_t) lua_tointeger (l, /* stack pos = */ -1);
199 } /* }}} value_t luaC_tovalue */
201 value_list_t *luaC_tovaluelist (lua_State *l, int idx) /* {{{ */
203 const data_set_t *ds;
207 int stack_top_before = lua_gettop (l);
210 /* Convert relative indexes to absolute indexes, so it doesn't change when we
211 * push / pop stuff. */
213 idx += lua_gettop (l) + 1;
215 /* Check that idx is in the valid range */
216 if ((idx < 1) || (idx > lua_gettop (l)))
219 vl = malloc (sizeof (*vl));
222 memset (vl, 0, sizeof (*vl));
226 /* Push initial key */
228 while (lua_next (l, idx) != 0)
230 const char *key = lua_tostring (l, /* stack pos = */ -2);
234 DEBUG ("luaC_tovaluelist: Ignoring non-string key.");
236 else if (strcasecmp ("host", key) == 0)
237 luaC_tostringbuffer (l, /* idx = */ -1,
238 vl->host, sizeof (vl->host));
239 else if (strcasecmp ("plugin", key) == 0)
240 luaC_tostringbuffer (l, /* idx = */ -1,
241 vl->plugin, sizeof (vl->plugin));
242 else if (strcasecmp ("plugin_instance", key) == 0)
243 luaC_tostringbuffer (l, /* idx = */ -1,
244 vl->plugin_instance, sizeof (vl->plugin_instance));
245 else if (strcasecmp ("type", key) == 0)
246 luaC_tostringbuffer (l, /* idx = */ -1,
247 vl->type, sizeof (vl->type));
248 else if (strcasecmp ("type_instance", key) == 0)
249 luaC_tostringbuffer (l, /* idx = */ -1,
250 vl->type_instance, sizeof (vl->type_instance));
251 else if (strcasecmp ("time", key) == 0)
252 vl->time = luaC_tocdtime (l, -1);
253 else if (strcasecmp ("interval", key) == 0)
254 vl->interval = luaC_tocdtime (l, -1);
255 else if (strcasecmp ("values", key) == 0)
257 /* This key is not handled here, because we have to assure "type" is read
262 DEBUG ("luaC_tovaluelist: Ignoring unknown key \"%s\".", key);
269 ds = plugin_get_ds (vl->type);
272 INFO ("utils_lua: Unable to lookup type \"%s\".", vl->type);
277 status = ltoc_table_values (l, idx, ds, vl);
280 WARNING ("utils_lua: ltoc_table_values failed.");
286 assert (stack_top_before == lua_gettop (l));
289 } /* }}} value_list_t *luaC_tovaluelist */
291 int luaC_pushcdtime (lua_State *l, cdtime_t t) /* {{{ */
293 double d = CDTIME_T_TO_DOUBLE (t);
295 lua_pushnumber (l, (lua_Number) d);
297 } /* }}} int luaC_pushcdtime */
299 int luaC_pushvalue (lua_State *l, value_t v, int ds_type) /* {{{ */
301 if (ds_type == DS_TYPE_GAUGE)
302 lua_pushnumber (l, (lua_Number) v.gauge);
303 else if (ds_type == DS_TYPE_DERIVE)
304 lua_pushinteger (l, (lua_Integer) v.derive);
305 else if (ds_type == DS_TYPE_COUNTER)
306 lua_pushinteger (l, (lua_Integer) v.counter);
307 else if (ds_type == DS_TYPE_ABSOLUTE)
308 lua_pushinteger (l, (lua_Integer) v.absolute);
312 } /* }}} int luaC_pushvalue */
314 int luaC_pushvaluelist (lua_State *l, const data_set_t *ds, const value_list_t *vl) /* {{{ */
318 lua_pushstring (l, vl->host);
319 lua_setfield (l, /* idx = */ -2, "host");
321 lua_pushstring (l, vl->plugin);
322 lua_setfield (l, /* idx = */ -2, "plugin");
323 lua_pushstring (l, vl->plugin_instance);
324 lua_setfield (l, /* idx = */ -2, "plugin_instance");
326 lua_pushstring (l, vl->type);
327 lua_setfield (l, /* idx = */ -2, "type");
328 lua_pushstring (l, vl->type_instance);
329 lua_setfield (l, /* idx = */ -2, "type_instance");
331 luaC_pushvalues (l, ds, vl);
332 lua_setfield (l, /* idx = */ -2, "values");
334 luaC_pushdstypes (l, ds);
335 lua_setfield (l, /* idx = */ -2, "dstypes");
337 luaC_pushdsnames (l, ds);
338 lua_setfield (l, /* idx = */ -2, "dsnames");
340 luaC_pushcdtime (l, vl->time);
341 lua_setfield (l, /* idx = */ -2, "time");
343 luaC_pushcdtime (l, vl->interval);
344 lua_setfield (l, /* idx = */ -2, "interval");
347 } /* }}} int luaC_pushvaluelist */
349 /* vim: set sw=2 sts=2 et fdm=marker : */