From 2f758bbdb94e8b09ae41c05b0582d052708dd33c Mon Sep 17 00:00:00 2001
From: Přemysl Janouch
Date: Thu, 27 Oct 2016 20:58:14 +0200
Subject: degesch: allow lists of refs in introspection
---
degesch.c | 64 +++++++++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 44 insertions(+), 20 deletions(-)
diff --git a/degesch.c b/degesch.c
index 4f42fc5..b230b98 100644
--- a/degesch.c
+++ b/degesch.c
@@ -1252,17 +1252,13 @@ enum ispect_type
ISPECT_STR, ///< "struct str"
ISPECT_STR_MAP, ///< "struct str_map"
ISPECT_REF, ///< Weakly referenced object
-#if 0
- // XXX: maybe just a PTR type that doesn't warrant weak_refs but is copied,
- // LIST-ness seems to be more of a direct flag of a type
- ISPECT_LIST, ///< Typically copied, depending on type
-#endif
+
+ // XXX: maybe a PTR type that doesn't warrant weak_refs but is copied
};
// TODO: once this finalizes, turn instatiations into macros
struct ispect
{
- // TODO: "list" flag?
struct ispect_field *fields; ///< Fields
};
@@ -1271,13 +1267,14 @@ struct ispect_field
const char *name; ///< Name of the field
size_t offset; ///< Offset in the structure
enum ispect_type type; ///< Type of the field
+ bool is_list; ///< This object is a list
struct ispect *subtype; ///< Subtype information
};
#define ISPECT(object, field, type) \
- { #field, offsetof (struct object, field), ISPECT_ ## type, NULL },
-#define ISPECT_(object, field, type, subtype) \
- { #field, offsetof (struct object, field), ISPECT_ ## type, \
+ { #field, offsetof (struct object, field), ISPECT_ ## type, false, NULL },
+#define ISPECT_(object, field, type, is_list, subtype) \
+ { #field, offsetof (struct object, field), ISPECT_ ## type, is_list, \
&g_ ## subtype ## _ispect },
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -1595,9 +1592,9 @@ static struct ispect_field g_buffer_ispect_fields[] =
ISPECT ( buffer, new_unimportant_count, UINT )
ISPECT ( buffer, highlighted, BOOL )
ISPECT ( buffer, hide_unimportant, BOOL )
- ISPECT_( buffer, server, REF, server )
- ISPECT_( buffer, channel, REF, channel )
- ISPECT_( buffer, user, REF, user )
+ ISPECT_( buffer, server, REF, false, server )
+ ISPECT_( buffer, channel, REF, false, channel )
+ ISPECT_( buffer, user, REF, false, user )
{}
};
@@ -1763,11 +1760,13 @@ static struct ispect_field g_server_ispect_fields[] =
ISPECT ( server, irc_user_host, STRING )
ISPECT ( server, autoaway_active, BOOL )
ISPECT ( server, cap_echo_message, BOOL )
- ISPECT_( server, buffer, REF, buffer )
+ ISPECT_( server, buffer, REF, false, buffer )
// TODO: either rename the underlying field or fix the plugins
- { "user", offsetof (struct server, irc_user), ISPECT_REF, &g_user_ispect },
- { "user_mode", offsetof (struct server, irc_user_mode), ISPECT_STR, NULL },
+ { "user", offsetof (struct server, irc_user),
+ ISPECT_REF, false, &g_user_ispect },
+ { "user_mode", offsetof (struct server, irc_user_mode),
+ ISPECT_STR, false, NULL },
{}
};
@@ -2112,8 +2111,9 @@ struct app_context
static struct ispect_field g_ctx_ispect_fields[] =
{
- ISPECT_( app_context, global_buffer, REF, buffer )
- ISPECT_( app_context, current_buffer, REF, buffer )
+ ISPECT_( app_context, buffers, REF, true, buffer )
+ ISPECT_( app_context, global_buffer, REF, false, buffer )
+ ISPECT_( app_context, current_buffer, REF, false, buffer )
{}
};
@@ -9817,6 +9817,31 @@ lua_plugin_panic (lua_State *L)
return 0;
}
+struct list_header
+{
+ void *next; ///< Next item
+ void *prev; ///< Previous item
+};
+
+static void
+lua_plugin_push_ref (struct lua_plugin *self, void *object, bool is_list,
+ struct lua_weak_info *info)
+{
+ if (!is_list)
+ {
+ lua_weak_push (self, object, info);
+ return;
+ }
+
+ int i = 1;
+ lua_newtable (self->L);
+ LIST_FOR_EACH (struct list_header, iter, object)
+ {
+ lua_weak_push (self, iter, info);
+ lua_rawseti (self->L, -2, i++);
+ }
+}
+
static bool
lua_plugin_property_get_ispect (lua_State *L, const char *property_name)
{
@@ -9863,12 +9888,11 @@ lua_plugin_property_get_ispect (lua_State *L, const char *property_name)
{
// TODO: we can definitely make a resolution table right in Lua,
// lua_plugin_reg_weak() can fill it automatically (lightud->lightud)
- struct lua_weak_info *info = NULL;
for (size_t i = 0; i < N_ELEMENTS (lua_types); i++)
if (lua_types[i].ispect == iter->subtype)
{
- info = lua_types[i].info;
- lua_weak_push (weak->plugin, *(void **) p, info);
+ lua_plugin_push_ref (weak->plugin, *(void **) p,
+ iter->is_list, lua_types[i].info);
return true;
}
}
--
cgit v1.2.3-70-g09d2