degesch: create Lua refs through introspection
This commit is contained in:
parent
fed8b06aff
commit
9408dfc67c
173
degesch.c
173
degesch.c
|
@ -1252,9 +1252,9 @@ enum ispect_type
|
||||||
ISPECT_UINT,
|
ISPECT_UINT,
|
||||||
ISPECT_SIZE,
|
ISPECT_SIZE,
|
||||||
ISPECT_STRING,
|
ISPECT_STRING,
|
||||||
|
ISPECT_REF, ///< Weakly referenced
|
||||||
#if 0
|
#if 0
|
||||||
// TODO: also str_map, str_vector
|
// TODO: also str_map, str_vector
|
||||||
ISPECT_REF, ///< Weakly referenced
|
|
||||||
ISPECT_LIST, ///< Typically copied, depending on type
|
ISPECT_LIST, ///< Typically copied, depending on type
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -1262,9 +1262,7 @@ enum ispect_type
|
||||||
// TODO: once this finalizes, turn instatiations into macros
|
// TODO: once this finalizes, turn instatiations into macros
|
||||||
struct ispect
|
struct ispect
|
||||||
{
|
{
|
||||||
// TODO:
|
// TODO: "list" flag?
|
||||||
// - "list" flag?
|
|
||||||
// - weak_ref/weak_unref methods?
|
|
||||||
struct ispect_field *fields; ///< Fields
|
struct ispect_field *fields; ///< Fields
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1280,7 +1278,7 @@ struct ispect_field
|
||||||
{ #field, offsetof (struct object, field), ISPECT_ ## type, NULL },
|
{ #field, offsetof (struct object, field), ISPECT_ ## type, NULL },
|
||||||
#define ISPECT_(object, field, type, subtype) \
|
#define ISPECT_(object, field, type, subtype) \
|
||||||
{ #field, offsetof (struct object, field), ISPECT_ ## type, \
|
{ #field, offsetof (struct object, field), ISPECT_ ## type, \
|
||||||
&g_ ## subtype ## _type },
|
&g_ ## subtype ## _ispect },
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
@ -1588,13 +1586,17 @@ struct buffer
|
||||||
struct user *user; ///< Reference to user
|
struct user *user; ///< Reference to user
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct ispect g_server_ispect;
|
||||||
static struct ispect_field g_buffer_ispect_fields[] =
|
static struct ispect_field g_buffer_ispect_fields[] =
|
||||||
{
|
{
|
||||||
ISPECT( buffer, name, STRING )
|
ISPECT ( buffer, name, STRING )
|
||||||
ISPECT( buffer, new_messages_count, UINT )
|
ISPECT ( buffer, new_messages_count, UINT )
|
||||||
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, channel, REF, channel )
|
||||||
|
ISPECT_( buffer, user, REF, user )
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1753,13 +1755,18 @@ struct server
|
||||||
|
|
||||||
static struct ispect_field g_server_ispect_fields[] =
|
static struct ispect_field g_server_ispect_fields[] =
|
||||||
{
|
{
|
||||||
ISPECT( server, name, STRING )
|
ISPECT ( server, name, STRING )
|
||||||
ISPECT( server, state, INT )
|
ISPECT ( server, state, INT )
|
||||||
ISPECT( server, reconnect_attempt, UINT )
|
ISPECT ( server, reconnect_attempt, UINT )
|
||||||
ISPECT( server, manual_disconnect, BOOL )
|
ISPECT ( server, manual_disconnect, BOOL )
|
||||||
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 )
|
||||||
|
|
||||||
|
// TODO: either rename the underlying field or fix the plugins
|
||||||
|
{ "user", offsetof (struct server, irc_user), ISPECT_REF, &g_user_ispect },
|
||||||
|
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8521,8 +8528,6 @@ struct lua_weak_info
|
||||||
const char *name; ///< Metatable name
|
const char *name; ///< Metatable name
|
||||||
struct ispect *ispect; ///< Introspection data
|
struct ispect *ispect; ///< Introspection data
|
||||||
|
|
||||||
// XXX: not sure if these should be _here_ and not in "struct ispect"
|
|
||||||
|
|
||||||
lua_weak_ref_fn ref; ///< Weak link invalidator
|
lua_weak_ref_fn ref; ///< Weak link invalidator
|
||||||
lua_weak_unref_fn unref; ///< Weak link generator
|
lua_weak_unref_fn unref; ///< Weak link generator
|
||||||
};
|
};
|
||||||
|
@ -8683,33 +8688,6 @@ lua_buffer_gc (lua_State *L)
|
||||||
return lua_weak_gc (L, &lua_buffer_info);
|
return lua_weak_gc (L, &lua_buffer_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
lua_buffer_get_user (lua_State *L)
|
|
||||||
{
|
|
||||||
struct lua_weak *wrapper = lua_weak_deref (L, &lua_buffer_info);
|
|
||||||
struct buffer *buffer = wrapper->object;
|
|
||||||
lua_weak_push (wrapper->plugin, buffer->user, &lua_user_info);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
lua_buffer_get_channel (lua_State *L)
|
|
||||||
{
|
|
||||||
struct lua_weak *wrapper = lua_weak_deref (L, &lua_buffer_info);
|
|
||||||
struct buffer *buffer = wrapper->object;
|
|
||||||
lua_weak_push (wrapper->plugin, buffer->channel, &lua_channel_info);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
lua_buffer_get_server (lua_State *L)
|
|
||||||
{
|
|
||||||
struct lua_weak *wrapper = lua_weak_deref (L, &lua_buffer_info);
|
|
||||||
struct buffer *buffer = wrapper->object;
|
|
||||||
lua_weak_push (wrapper->plugin, buffer->server, &lua_server_info);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
lua_buffer_log (lua_State *L)
|
lua_buffer_log (lua_State *L)
|
||||||
{
|
{
|
||||||
|
@ -8734,9 +8712,6 @@ lua_buffer_execute (lua_State *L)
|
||||||
static luaL_Reg lua_buffer_table[] =
|
static luaL_Reg lua_buffer_table[] =
|
||||||
{
|
{
|
||||||
{ "__gc", lua_buffer_gc },
|
{ "__gc", lua_buffer_gc },
|
||||||
{ "get_user", lua_buffer_get_user },
|
|
||||||
{ "get_channel", lua_buffer_get_channel },
|
|
||||||
{ "get_server", lua_buffer_get_server },
|
|
||||||
{ "log", lua_buffer_log },
|
{ "log", lua_buffer_log },
|
||||||
{ "execute", lua_buffer_execute },
|
{ "execute", lua_buffer_execute },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
|
@ -8750,24 +8725,6 @@ lua_server_gc (lua_State *L)
|
||||||
return lua_weak_gc (L, &lua_server_info);
|
return lua_weak_gc (L, &lua_server_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
lua_server_get_user (lua_State *L)
|
|
||||||
{
|
|
||||||
struct lua_weak *wrapper = lua_weak_deref (L, &lua_server_info);
|
|
||||||
struct server *server = wrapper->object;
|
|
||||||
lua_weak_push (wrapper->plugin, server->irc_user, &lua_user_info);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
lua_server_get_buffer (lua_State *L)
|
|
||||||
{
|
|
||||||
struct lua_weak *wrapper = lua_weak_deref (L, &lua_server_info);
|
|
||||||
struct server *server = wrapper->object;
|
|
||||||
lua_weak_push (wrapper->plugin, server->buffer, &lua_buffer_info);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
lua_server_send (lua_State *L)
|
lua_server_send (lua_State *L)
|
||||||
{
|
{
|
||||||
|
@ -8780,8 +8737,6 @@ lua_server_send (lua_State *L)
|
||||||
static luaL_Reg lua_server_table[] =
|
static luaL_Reg lua_server_table[] =
|
||||||
{
|
{
|
||||||
{ "__gc", lua_server_gc },
|
{ "__gc", lua_server_gc },
|
||||||
{ "get_user", lua_server_get_user },
|
|
||||||
{ "get_buffer", lua_server_get_buffer },
|
|
||||||
{ "send", lua_server_send },
|
{ "send", lua_server_send },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
@ -9794,7 +9749,10 @@ static struct lua_ispect_mapping
|
||||||
}
|
}
|
||||||
lua_types[] =
|
lua_types[] =
|
||||||
{
|
{
|
||||||
{ &g_buffer_ispect, &lua_buffer_info },
|
{ &g_user_ispect, &lua_user_info },
|
||||||
|
{ &g_channel_ispect, &lua_channel_info },
|
||||||
|
{ &g_buffer_ispect, &lua_buffer_info },
|
||||||
|
{ &g_server_ispect, &lua_server_info },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
|
@ -9833,18 +9791,30 @@ lua_plugin_property_get_ispect (lua_State *L, const char *property_name)
|
||||||
for (iter = info->ispect->fields; iter->name; iter++)
|
for (iter = info->ispect->fields; iter->name; iter++)
|
||||||
if (!strcmp (property_name, iter->name))
|
if (!strcmp (property_name, iter->name))
|
||||||
break;
|
break;
|
||||||
|
if (!iter->name)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (iter->name)
|
void *p = (uint8_t *) weak->object + iter->offset;
|
||||||
|
switch (iter->type)
|
||||||
{
|
{
|
||||||
void *p = (uint8_t *) weak->object + iter->offset;
|
case ISPECT_BOOL: lua_pushboolean (L, *(bool *) p); return true;
|
||||||
switch (iter->type)
|
case ISPECT_INT: lua_pushinteger (L, *(int *) p); return true;
|
||||||
{
|
case ISPECT_UINT: lua_pushinteger (L, *(unsigned *) p); return true;
|
||||||
case ISPECT_BOOL: lua_pushboolean (L, *(bool *) p); return true;
|
case ISPECT_SIZE: lua_pushinteger (L, *(size_t *) p); return true;
|
||||||
case ISPECT_INT: lua_pushinteger (L, *(int *) p); return true;
|
case ISPECT_STRING: lua_pushstring (L, *(char **) p); return true;
|
||||||
case ISPECT_UINT: lua_pushinteger (L, *(unsigned *) p); return true;
|
case ISPECT_REF:
|
||||||
case ISPECT_SIZE: lua_pushinteger (L, *(size_t *) p); return true;
|
{
|
||||||
case ISPECT_STRING: lua_pushstring (L, *(char **) p); return true;
|
// 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);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -9910,13 +9880,10 @@ lua_plugin_property_set (lua_State *L)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
lua_plugin_create_meta (lua_State *L, const char *name, luaL_Reg *fns)
|
lua_plugin_reg_finish (lua_State *L, struct lua_weak_info *info)
|
||||||
{
|
{
|
||||||
luaL_newmetatable (L, name);
|
|
||||||
luaL_setfuncs (L, fns, 0);
|
|
||||||
|
|
||||||
// Emulate properties for convenience
|
// Emulate properties for convenience
|
||||||
lua_pushlightuserdata (L, NULL);
|
lua_pushlightuserdata (L, info);
|
||||||
lua_pushcclosure (L, lua_plugin_property_get, 1);
|
lua_pushcclosure (L, lua_plugin_property_get, 1);
|
||||||
lua_setfield (L, -2, "__index");
|
lua_setfield (L, -2, "__index");
|
||||||
lua_pushcfunction (L, lua_plugin_property_set);
|
lua_pushcfunction (L, lua_plugin_property_set);
|
||||||
|
@ -9926,19 +9893,19 @@ lua_plugin_create_meta (lua_State *L, const char *name, luaL_Reg *fns)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
lua_plugin_create_weak (lua_State *L, struct lua_weak_info *info, luaL_Reg *fns)
|
lua_plugin_reg_meta (lua_State *L, const char *name, luaL_Reg *fns)
|
||||||
|
{
|
||||||
|
luaL_newmetatable (L, name);
|
||||||
|
luaL_setfuncs (L, fns, 0);
|
||||||
|
lua_plugin_reg_finish (L, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
lua_plugin_reg_weak (lua_State *L, struct lua_weak_info *info, luaL_Reg *fns)
|
||||||
{
|
{
|
||||||
luaL_newmetatable (L, info->name);
|
luaL_newmetatable (L, info->name);
|
||||||
luaL_setfuncs (L, fns, 0);
|
luaL_setfuncs (L, fns, 0);
|
||||||
|
lua_plugin_reg_finish (L, info);
|
||||||
// Emulate properties for convenience
|
|
||||||
lua_pushlightuserdata (L, info);
|
|
||||||
lua_pushcclosure (L, lua_plugin_property_get, 1);
|
|
||||||
lua_setfield (L, -2, "__index");
|
|
||||||
lua_pushcfunction (L, lua_plugin_property_set);
|
|
||||||
lua_setfield (L, -2, "__newindex");
|
|
||||||
|
|
||||||
lua_pop (L, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct plugin *
|
static struct plugin *
|
||||||
|
@ -9969,14 +9936,14 @@ lua_plugin_load (struct app_context *ctx, const char *filename,
|
||||||
lua_setglobal (L, PROGRAM_NAME);
|
lua_setglobal (L, PROGRAM_NAME);
|
||||||
|
|
||||||
// Create metatables for our objects
|
// Create metatables for our objects
|
||||||
lua_plugin_create_meta (L, XLUA_HOOK_METATABLE, lua_hook_table);
|
lua_plugin_reg_meta (L, XLUA_HOOK_METATABLE, lua_hook_table);
|
||||||
lua_plugin_create_weak (L, &lua_user_info, lua_user_table);
|
lua_plugin_reg_weak (L, &lua_user_info, lua_user_table);
|
||||||
lua_plugin_create_weak (L, &lua_channel_info, lua_channel_table);
|
lua_plugin_reg_weak (L, &lua_channel_info, lua_channel_table);
|
||||||
lua_plugin_create_weak (L, &lua_buffer_info, lua_buffer_table);
|
lua_plugin_reg_weak (L, &lua_buffer_info, lua_buffer_table);
|
||||||
lua_plugin_create_weak (L, &lua_server_info, lua_server_table);
|
lua_plugin_reg_weak (L, &lua_server_info, lua_server_table);
|
||||||
lua_plugin_create_meta (L, XLUA_SCHEMA_METATABLE, lua_schema_table);
|
lua_plugin_reg_meta (L, XLUA_SCHEMA_METATABLE, lua_schema_table);
|
||||||
lua_plugin_create_meta (L, XLUA_CONNECTION_METATABLE, lua_connection_table);
|
lua_plugin_reg_meta (L, XLUA_CONNECTION_METATABLE, lua_connection_table);
|
||||||
lua_plugin_create_meta (L, XLUA_CONNECTOR_METATABLE, lua_connector_table);
|
lua_plugin_reg_meta (L, XLUA_CONNECTOR_METATABLE, lua_connector_table);
|
||||||
|
|
||||||
struct error *error = NULL;
|
struct error *error = NULL;
|
||||||
if (luaL_loadfile (L, filename))
|
if (luaL_loadfile (L, filename))
|
||||||
|
|
Loading…
Reference in New Issue