}
static gsize
-lua_logger_out_str (lua_State *L, gint pos, gchar *outbuf, gsize len)
+lua_logger_out_str (lua_State *L, gint pos, gchar *outbuf, gsize len,
+ struct lua_logger_trace *trace)
{
gsize slen;
const gchar *str = lua_tolstring (L, pos, &slen);
}
static gsize
-lua_logger_out_num (lua_State *L, gint pos, gchar *outbuf, gsize len)
+lua_logger_out_num (lua_State *L, gint pos, gchar *outbuf, gsize len,
+ struct lua_logger_trace *trace)
{
gdouble num = lua_tonumber (L, pos);
glong inum;
}
static gsize
-lua_logger_out_boolean (lua_State *L, gint pos, gchar *outbuf, gsize len)
+lua_logger_out_boolean (lua_State *L, gint pos, gchar *outbuf, gsize len,
+ struct lua_logger_trace *trace)
{
gboolean val = lua_toboolean (L, pos);
gsize r = 0;
}
static gsize
-lua_logger_out_userdata (lua_State *L, gint pos, gchar *outbuf, gsize len)
+lua_logger_out_userdata (lua_State *L, gint pos, gchar *outbuf, gsize len,
+ struct lua_logger_trace *trace)
{
gint r, top;
const gchar *str = NULL;
if ((remain) == 0) { lua_pop (L, 1); break; }
static gsize
-lua_logger_out_table (lua_State *L, gint pos, gchar *outbuf, gsize len)
+lua_logger_out_table (lua_State *L, gint pos, gchar *outbuf, gsize len,
+ struct lua_logger_trace *trace)
{
gchar *d = outbuf;
gsize remain = len, r;
gboolean first = TRUE;
- gint i;
+ gconstpointer self = NULL;
+ gint i, tpos;
if (!lua_istable (L, pos) || remain == 0) {
return 0;
}
+ self = lua_topointer (L, pos);
+
+ /* Check if we have seen this pointer */
+ for (i = 0; i < TRACE_POINTS; i ++) {
+ if (trace->traces[i] == self) {
+ r = rspamd_snprintf (d, remain + 1, "ref(%p)", self);
+
+ d += r;
+
+ return (d - outbuf);
+ }
+ }
+
+ trace->traces[trace->cur_level % TRACE_POINTS] = self;
+
lua_pushvalue (L, pos);
r = rspamd_snprintf (d, remain + 1, "{");
remain -= r;
r = rspamd_snprintf (d, remain + 1, "[%d] = ", i);
MOVE_BUF(d, remain, r);
- r = lua_logger_out_type (L, lua_gettop (L), d, remain);
+ tpos = lua_gettop (L);
+
+ if (lua_topointer (L, tpos) == self) {
+ r = rspamd_snprintf (d, remain + 1, "__self");
+ }
+ else {
+ r = lua_logger_out_type (L, tpos, d, remain, trace);
+ }
MOVE_BUF(d, remain, r);
first = FALSE;
r = rspamd_snprintf (d, remain + 1, "[%s] = ",
lua_tostring (L, -2));
MOVE_BUF(d, remain, r);
- r = lua_logger_out_type (L, lua_gettop (L), d, remain);
+ tpos = lua_gettop (L);
+
+ if (lua_topointer (L, tpos) == self) {
+ r = rspamd_snprintf (d, remain + 1, "__self");
+ }
+ else {
+ r = lua_logger_out_type (L, tpos, d, remain, trace);
+ }
MOVE_BUF(d, remain, r);
first = FALSE;
#undef MOVE_BUF
gsize
-lua_logger_out_type (lua_State *L, gint pos, gchar *outbuf, gsize len)
+lua_logger_out_type (lua_State *L, gint pos, gchar *outbuf, gsize len,
+ struct lua_logger_trace *trace)
{
gint type;
gsize r = 0;
}
type = lua_type (L, pos);
+ trace->cur_level ++;
switch (type) {
case LUA_TNUMBER:
- r = lua_logger_out_num (L, pos, outbuf, len);
+ r = lua_logger_out_num (L, pos, outbuf, len, trace);
break;
case LUA_TBOOLEAN:
- r = lua_logger_out_boolean (L, pos, outbuf, len);
+ r = lua_logger_out_boolean (L, pos, outbuf, len, trace);
break;
case LUA_TTABLE:
- r = lua_logger_out_table (L, pos, outbuf, len);
+ r = lua_logger_out_table (L, pos, outbuf, len, trace);
break;
case LUA_TUSERDATA:
- r = lua_logger_out_userdata (L, pos, outbuf, len);
+ r = lua_logger_out_userdata (L, pos, outbuf, len, trace);
break;
case LUA_TFUNCTION:
r = rspamd_snprintf (outbuf, len + 1, "function");
break;
default:
/* Try to push everything as string using tostring magic */
- r = lua_logger_out_str (L, pos, outbuf, len);
+ r = lua_logger_out_str (L, pos, outbuf, len, trace);
break;
}
+ trace->cur_level --;
+
return r;
}
gsize r, cpylen = 0;
guint arg_num = 0, cur_arg;
bool num_arg = false;
+ struct lua_logger_trace tr;
enum {
copy_char = 0,
got_percent,
return FALSE;
}
- r = lua_logger_out_type (L, arg_num + 1, d, remain);
+ memset (&tr, 0, sizeof (tr));
+ r = lua_logger_out_type (L, arg_num + 1, d, remain, &tr);
g_assert (r <= remain);
remain -= r;
d += r;
return FALSE;
}
- r = lua_logger_out_type (L, arg_num + 1, d, remain);
+ memset (&tr, 0, sizeof (tr));
+ r = lua_logger_out_type (L, arg_num + 1, d, remain, &tr);
g_assert (r <= remain);
remain -= r;
d += r;
gint i, cbref;
int top = 0;
gchar outbuf[8192];
+ struct lua_logger_trace tr;
struct thread_entry *thread = lua_thread_pool_get_for_config (rspamd_main->cfg);
L = thread->lua_state;
rspamd_printf ("local function: %d\n", cbref);
} else {
- lua_logger_out_type (L, i, outbuf, sizeof (outbuf));
+ memset (&tr, 0, sizeof (tr));
+ lua_logger_out_type (L, i, outbuf, sizeof (outbuf), &tr);
rspamd_printf ("%s\n", outbuf);
}
}
gpointer map;
gsize len;
gchar outbuf[8192];
+ struct lua_logger_trace tr;
if (argv[1] == NULL) {
rspamd_printf ("no callback is specified\n");
rspamd_printf ("lua callback for %s returned:\n", argv[i]);
for (j = old_top + 1; j <= lua_gettop (L); j ++) {
- lua_logger_out_type (L, j, outbuf, sizeof (outbuf));
+ memset (&tr, 0, sizeof (tr));
+ lua_logger_out_type (L, j, outbuf, sizeof (outbuf), &tr);
rspamd_printf ("%s\n", outbuf);
}
}