degesch: allow lists of refs in introspection

This commit is contained in:
Přemysl Eric Janouch 2016-10-27 20:58:14 +02:00
parent 911276b263
commit 2f758bbdb9
Signed by: p
GPG Key ID: B715679E3A361BE6
1 changed files with 44 additions and 20 deletions

View File

@ -1252,17 +1252,13 @@ enum ispect_type
ISPECT_STR, ///< "struct str" ISPECT_STR, ///< "struct str"
ISPECT_STR_MAP, ///< "struct str_map" ISPECT_STR_MAP, ///< "struct str_map"
ISPECT_REF, ///< Weakly referenced object ISPECT_REF, ///< Weakly referenced object
#if 0
// XXX: maybe just a PTR type that doesn't warrant weak_refs but is copied, // XXX: maybe 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
}; };
// TODO: once this finalizes, turn instatiations into macros // TODO: once this finalizes, turn instatiations into macros
struct ispect struct ispect
{ {
// TODO: "list" flag?
struct ispect_field *fields; ///< Fields struct ispect_field *fields; ///< Fields
}; };
@ -1271,13 +1267,14 @@ struct ispect_field
const char *name; ///< Name of the field const char *name; ///< Name of the field
size_t offset; ///< Offset in the structure size_t offset; ///< Offset in the structure
enum ispect_type type; ///< Type of the field enum ispect_type type; ///< Type of the field
bool is_list; ///< This object is a list
struct ispect *subtype; ///< Subtype information struct ispect *subtype; ///< Subtype information
}; };
#define ISPECT(object, field, type) \ #define ISPECT(object, field, type) \
{ #field, offsetof (struct object, field), ISPECT_ ## type, NULL }, { #field, offsetof (struct object, field), ISPECT_ ## type, false, NULL },
#define ISPECT_(object, field, type, subtype) \ #define ISPECT_(object, field, type, is_list, subtype) \
{ #field, offsetof (struct object, field), ISPECT_ ## type, \ { #field, offsetof (struct object, field), ISPECT_ ## type, is_list, \
&g_ ## subtype ## _ispect }, &g_ ## subtype ## _ispect },
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -1595,9 +1592,9 @@ static struct ispect_field g_buffer_ispect_fields[] =
ISPECT ( buffer, new_unimportant_count, UINT ) ISPECT ( buffer, new_unimportant_count, UINT )
ISPECT ( buffer, highlighted, BOOL ) ISPECT ( buffer, highlighted, BOOL )
ISPECT ( buffer, hide_unimportant, BOOL ) ISPECT ( buffer, hide_unimportant, BOOL )
ISPECT_( buffer, server, REF, server ) ISPECT_( buffer, server, REF, false, server )
ISPECT_( buffer, channel, REF, channel ) ISPECT_( buffer, channel, REF, false, channel )
ISPECT_( buffer, user, REF, user ) 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, irc_user_host, STRING )
ISPECT ( server, autoaway_active, BOOL ) ISPECT ( server, autoaway_active, BOOL )
ISPECT ( server, cap_echo_message, 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 // TODO: either rename the underlying field or fix the plugins
{ "user", offsetof (struct server, irc_user), ISPECT_REF, &g_user_ispect }, { "user", offsetof (struct server, irc_user),
{ "user_mode", offsetof (struct server, irc_user_mode), ISPECT_STR, NULL }, 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[] = static struct ispect_field g_ctx_ispect_fields[] =
{ {
ISPECT_( app_context, global_buffer, REF, buffer ) ISPECT_( app_context, buffers, REF, true, buffer )
ISPECT_( app_context, current_buffer, REF, 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; 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 static bool
lua_plugin_property_get_ispect (lua_State *L, const char *property_name) 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, // TODO: we can definitely make a resolution table right in Lua,
// lua_plugin_reg_weak() can fill it automatically (lightud->lightud) // 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++) for (size_t i = 0; i < N_ELEMENTS (lua_types); i++)
if (lua_types[i].ispect == iter->subtype) if (lua_types[i].ispect == iter->subtype)
{ {
info = lua_types[i].info; lua_plugin_push_ref (weak->plugin, *(void **) p,
lua_weak_push (weak->plugin, *(void **) p, info); iter->is_list, lua_types[i].info);
return true; return true;
} }
} }