From 2f758bbdb94e8b09ae41c05b0582d052708dd33c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Janouch?= Date: Thu, 27 Oct 2016 20:58:14 +0200 Subject: [PATCH] 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; } }