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 #include "utils_lua.h"
26 static int ltoc_values (lua_State *l, /* {{{ */
33 if (!lua_istable (l, -1))
36 /* Push initial key */
38 for (i = 0; i < ((size_t) ds->ds_num); i++)
40 /* Pops old key and pushed new key and value. */
41 status = lua_next (l, -2);
42 if (status == 0) /* no more elements */
45 ret_values[i] = luaC_tovalue (l, /* idx = */ -1, ds->ds[i].type);
48 lua_pop (l, /* nelems = */ 1);
51 lua_pop (l, /* nelems = */ 1);
54 } /* }}} int ltoc_values */
56 static int ltoc_table_values (lua_State *l, int idx, /* {{{ */
57 const data_set_t *ds, value_list_t *vl)
61 /* We're only called from "luaC_tovaluelist", which ensures that "idx" is an
62 * absolute index (i.e. a positive number) */
65 lua_pushstring (l, "values");
66 lua_gettable (l, idx);
68 if (!lua_istable (l, -1))
70 NOTICE ("lua plugin: ltoc_table_values: The \"values\" member is not a table.");
71 lua_pop (l, /* nelem = */ 1);
75 vl->values_len = ds->ds_num;
76 vl->values = calloc ((size_t) vl->values_len, sizeof (*vl->values));
77 if (vl->values == NULL)
79 ERROR ("lua plugin: calloc failed.");
81 lua_pop (l, /* nelem = */ 1);
85 status = ltoc_values (l, ds, vl->values);
87 lua_pop (l, /* nelem = */ 1);
96 } /* }}} int ltoc_table_values */
98 static int luaC_pushvalues (lua_State *l, const data_set_t *ds, const value_list_t *vl) /* {{{ */
102 assert (vl->values_len == ds->ds_num);
105 for (i = 0; i < vl->values_len; i++)
107 lua_pushinteger (l, (lua_Integer) i);
108 luaC_pushvalue (l, vl->values[i], ds->ds[i].type);
109 lua_settable (l, /* idx = */ -3);
113 } /* }}} int luaC_pushvalues */
115 static int luaC_pushdstypes (lua_State *l, const data_set_t *ds) /* {{{ */
120 for (i = 0; i < ds->ds_num; i++)
122 lua_pushinteger (l, (lua_Integer) i);
123 lua_pushstring (l, DS_TYPE_TO_STRING (ds->ds[i].type));
124 lua_settable (l, /* idx = */ -3);
128 } /* }}} int luaC_pushdstypes */
130 static int luaC_pushdsnames (lua_State *l, const data_set_t *ds) /* {{{ */
135 for (i = 0; i < ds->ds_num; i++)
137 lua_pushinteger (l, (lua_Integer) i);
138 lua_pushstring (l, ds->ds[i].name);
139 lua_settable (l, /* idx = */ -3);
143 } /* }}} int luaC_pushdsnames */
148 cdtime_t luaC_tocdtime (lua_State *l, int idx) /* {{{ */
152 if (!lua_isnumber (l, /* stack pos = */ idx))
155 d = (double) lua_tonumber (l, idx);
157 return (DOUBLE_TO_CDTIME_T (d));
158 } /* }}} int ltoc_table_cdtime */
160 int luaC_tostringbuffer (lua_State *l, int idx, /* {{{ */
161 char *buffer, size_t buffer_size)
165 str = lua_tostring (l, idx);
169 sstrncpy (buffer, str, buffer_size);
171 } /* }}} int luaC_tostringbuffer */
173 value_t luaC_tovalue (lua_State *l, int idx, int ds_type) /* {{{ */
177 memset (&v, 0, sizeof (v));
179 if (!lua_isnumber (l, idx))
182 if (ds_type == DS_TYPE_GAUGE)
183 v.gauge = (gauge_t) lua_tonumber (l, /* stack pos = */ -1);
184 else if (ds_type == DS_TYPE_DERIVE)
185 v.derive = (derive_t) lua_tointeger (l, /* stack pos = */ -1);
186 else if (ds_type == DS_TYPE_COUNTER)
187 v.counter = (counter_t) lua_tointeger (l, /* stack pos = */ -1);
188 else if (ds_type == DS_TYPE_ABSOLUTE)
189 v.absolute = (absolute_t) lua_tointeger (l, /* stack pos = */ -1);
192 } /* }}} value_t luaC_tovalue */
194 value_list_t *luaC_tovaluelist (lua_State *l, int idx) /* {{{ */
196 const data_set_t *ds;
200 int stack_top_before = lua_gettop (l);
203 /* Convert relative indexes to absolute indexes, so it doesn't change when we
204 * push / pop stuff. */
206 idx += lua_gettop (l) + 1;
208 /* Check that idx is in the valid range */
209 if ((idx < 1) || (idx > lua_gettop (l)))
212 vl = malloc (sizeof (*vl));
215 memset (vl, 0, sizeof (*vl));
219 /* Push initial key */
221 while (lua_next (l, idx) != 0)
223 const char *key = lua_tostring (l, /* stack pos = */ -2);
227 DEBUG ("luaC_tovaluelist: Ignoring non-string key.");
229 else if (strcasecmp ("host", key) == 0)
230 luaC_tostringbuffer (l, /* idx = */ -1,
231 vl->host, sizeof (vl->host));
232 else if (strcasecmp ("plugin", key) == 0)
233 luaC_tostringbuffer (l, /* idx = */ -1,
234 vl->plugin, sizeof (vl->plugin));
235 else if (strcasecmp ("plugin_instance", key) == 0)
236 luaC_tostringbuffer (l, /* idx = */ -1,
237 vl->plugin_instance, sizeof (vl->plugin_instance));
238 else if (strcasecmp ("type", key) == 0)
239 luaC_tostringbuffer (l, /* idx = */ -1,
240 vl->type, sizeof (vl->type));
241 else if (strcasecmp ("type_instance", key) == 0)
242 luaC_tostringbuffer (l, /* idx = */ -1,
243 vl->type_instance, sizeof (vl->type_instance));
244 else if (strcasecmp ("time", key) == 0)
245 vl->time = luaC_tocdtime (l, -1);
246 else if (strcasecmp ("interval", key) == 0)
247 vl->interval = luaC_tocdtime (l, -1);
248 else if (strcasecmp ("values", key) == 0)
250 /* This key is not handled here, because we have to assure "type" is read
255 DEBUG ("luaC_tovaluelist: Ignoring unknown key \"%s\".", key);
264 ds = plugin_get_ds (vl->type);
267 INFO ("lua plugin: Unable to lookup type \"%s\".", vl->type);
272 status = ltoc_table_values (l, idx, ds, vl);
275 WARNING ("lua plugin: ltoc_table_values failed.");
281 assert (stack_top_before == lua_gettop (l));
284 } /* }}} value_list_t *luaC_tovaluelist */
286 int luaC_pushcdtime (lua_State *l, cdtime_t t) /* {{{ */
288 double d = CDTIME_T_TO_DOUBLE (t);
290 lua_pushnumber (l, (lua_Number) d);
292 } /* }}} int luaC_pushcdtime */
294 int luaC_pushvalue (lua_State *l, value_t v, int ds_type) /* {{{ */
296 if (ds_type == DS_TYPE_GAUGE)
297 lua_pushnumber (l, (lua_Number) v.gauge);
298 else if (ds_type == DS_TYPE_DERIVE)
299 lua_pushinteger (l, (lua_Integer) v.derive);
300 else if (ds_type == DS_TYPE_COUNTER)
301 lua_pushinteger (l, (lua_Integer) v.counter);
302 else if (ds_type == DS_TYPE_ABSOLUTE)
303 lua_pushinteger (l, (lua_Integer) v.absolute);
307 } /* }}} int luaC_pushvalue */
309 int luaC_pushvaluelist (lua_State *l, const data_set_t *ds, const value_list_t *vl) /* {{{ */
313 lua_pushstring (l, vl->host);
314 lua_setfield (l, /* idx = */ -2, "host");
316 lua_pushstring (l, vl->plugin);
317 lua_setfield (l, /* idx = */ -2, "plugin");
318 lua_pushstring (l, vl->plugin_instance);
319 lua_setfield (l, /* idx = */ -2, "plugin_instance");
321 lua_pushstring (l, vl->type);
322 lua_setfield (l, /* idx = */ -2, "type");
323 lua_pushstring (l, vl->type_instance);
324 lua_setfield (l, /* idx = */ -2, "type_instance");
326 luaC_pushvalues (l, ds, vl);
327 lua_setfield (l, /* idx = */ -2, "values");
329 luaC_pushdstypes (l, ds);
330 lua_setfield (l, /* idx = */ -2, "dstypes");
332 luaC_pushdsnames (l, ds);
333 lua_setfield (l, /* idx = */ -2, "dsnames");
335 luaC_pushcdtime (l, vl->time);
336 lua_setfield (l, /* idx = */ -2, "time");
338 luaC_pushcdtime (l, vl->interval);
339 lua_setfield (l, /* idx = */ -2, "interval");
342 } /* }}} int luaC_pushvaluelist */
344 /* vim: set sw=2 sts=2 et fdm=marker : */