From 7cf2505a5790195814e05e4a26f40fe8319d5e67 Mon Sep 17 00:00:00 2001 From: Peng Wu Date: Wed, 14 Apr 2010 17:56:47 +0800 Subject: [PATCH] lua extension (ime.register_command) in progress. --- lua/lua-plugin-init.c | 30 +++++++++++++------------- lua/lua-plugin.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++----- lua/lua-plugin.h | 4 ++-- 3 files changed, 72 insertions(+), 22 deletions(-) diff --git a/lua/lua-plugin-init.c b/lua/lua-plugin-init.c index 996b314..417dbbb 100644 --- a/lua/lua-plugin-init.c +++ b/lua/lua-plugin-init.c @@ -156,36 +156,36 @@ static int ime_parse_mapping(lua_State * L){ } static int ime_register_command(lua_State * L){ - const char * command_name = NULL; - const char * lua_function_name = NULL; - const char * description = NULL; - const char * leading = NULL; - const char * help = NULL; + lua_command_t new_command; size_t l; - command_name = luaL_checklstring(L, 1, &l); + new_command.command_name = luaL_checklstring(L, 1, &l); if ( 2 != l ){ - return luaL_error(L, "ime_register_command is called with command_name: %s, whose length is not 2.\n", command_name); + return luaL_error(L, "ime_register_command is called with command_name: %s, whose length is not 2.\n", new_command.command_name); } - lua_function_name = luaL_checklstring(L, 2, NULL); - lua_getglobal(L, lua_function_name); + new_command.lua_function_name = luaL_checklstring(L, 2, NULL); + lua_getglobal(L, new_command.lua_function_name); luaL_checktype(L, -1, LUA_TFUNCTION); lua_pop(L, 1); - description = luaL_checklstring(L, 3, NULL); + new_command.description = luaL_checklstring(L, 3, NULL); + if ( !lua_isnone(L, 4)) { - leading = luaL_checklstring(L, 4, NULL); + new_command.leading = luaL_checklstring(L, 4, NULL); }else{ - leading = "digit"; + new_command.leading = "digit"; } if ( !lua_isnone(L, 5)) { - help = luaL_checklstring(L, 5, NULL); + new_command.help = luaL_checklstring(L, 5, NULL); } - /* check whether the same command exists. */ - /* use the sorted array. */ + gboolean result = ibus_engine_plugin_add_command + (lua_plugin_retrieve_plugin(L), &new_command); + + if (!result) + return luaL_error(L, "register command %s with function %s failed.\n", new_command.command_name, new_command.lua_function_name); return 0; } diff --git a/lua/lua-plugin.c b/lua/lua-plugin.c index ac03e15..65ab9e4 100644 --- a/lua/lua-plugin.c +++ b/lua/lua-plugin.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -14,6 +15,22 @@ struct _IBusEnginePluginPrivate{ G_DEFINE_TYPE (IBusEnginePlugin, ibus_engine_plugin, G_TYPE_OBJECT); +static void lua_command_clone(lua_command_t * command, lua_command_t * new_command){ + new_command->command_name = g_strdup(command->command_name); + new_command->lua_function_name = g_strdup(command->command_name); + new_command->description = g_strdup(command->description); + new_command->leading = g_strdup(command->leading); + new_command->help = g_strdup(command->help); +} + +static void lua_command_reclaim(lua_command_t * command){ + g_free((gpointer)command->command_name); + g_free((gpointer)command->lua_function_name); + g_free((gpointer)command->description); + g_free((gpointer)command->leading); + g_free((gpointer)command->help); +} + static int lua_plugin_init(IBusEnginePluginPrivate * plugin){ g_assert(NULL == plugin->L); @@ -36,11 +53,7 @@ lua_plugin_fini(IBusEnginePluginPrivate * plugin){ if ( plugin->lua_commands ){ for ( i = 0; i < plugin->lua_commands->len; ++i){ command = &g_array_index(plugin->lua_commands, lua_command_t, i); - g_free((gpointer)command->command_name); - g_free((gpointer)command->lua_function_name); - g_free((gpointer)command->description); - g_free((gpointer)command->leading); - g_free((gpointer)command->help); + lua_command_reclaim(command); } g_array_free(plugin->lua_commands, TRUE); plugin->lua_commands = NULL; @@ -96,6 +109,43 @@ IBusEnginePlugin * ibus_engine_plugin_new(){ return plugin; } +static gint compare_command(gconstpointer a, gconstpointer b){ + lua_command_t * ca = (lua_command_t *) a; + lua_command_t * cb = (lua_command_t *) b; + return strcmp(ca->command_name, cb->command_name); +} + +gboolean ibus_engine_plugin_add_command(IBusEnginePlugin * plugin, lua_command_t * command){ + IBusEnginePluginPrivate * priv = IBUS_ENGINE_PLUGIN_GET_PRIVATE(plugin); + GArray * lua_commands = priv->lua_commands; + + if ( ibus_engine_plugin_lookup_command( plugin, command->command_name) ) + return FALSE; + + lua_command_t new_command; + lua_command_clone(command, &new_command); + + g_array_append_val(priv->lua_commands, new_command); + g_array_sort(priv->lua_commands, compare_command); + + return TRUE; +} + +lua_command_t * ibus_engine_plugin_lookup_command(IBusEnginePlugin * plugin, const char * command){ + IBusEnginePluginPrivate * priv = IBUS_ENGINE_PLUGIN_GET_PRIVATE(plugin); + GArray * lua_commands = priv->lua_commands; + lua_command_t lookup_command = {.command_name = command, }; + + lua_command_t * result = bsearch(&lookup_command, lua_commands->data, lua_commands->len, sizeof(lua_command_t), compare_command); + return result; +} + +const GArray * ibus_engine_plugin_get_available_commands(IBusEnginePlugin * plugin){ + IBusEnginePluginPrivate * priv = IBUS_ENGINE_PLUGIN_GET_PRIVATE(plugin); + return priv->lua_commands; +} + + /* will drop this function soon. */ lua_State * ibus_engine_plugin_get_lua_State(IBusEnginePlugin * plugin){ return plugin->priv->L; diff --git a/lua/lua-plugin.h b/lua/lua-plugin.h index 6284f02..d7118d6 100644 --- a/lua/lua-plugin.h +++ b/lua/lua-plugin.h @@ -68,9 +68,9 @@ gboolean ibus_engine_plugin_add_command(IBusEnginePlugin * plugin, lua_command_t /** * retrieve all available lua plugin commands. - * return array of command informations of type lua_command_t. + * return array of command informations of type lua_command_t without copies. */ -GArray * ibus_engine_plugin_get_available_commands(IBusEnginePlugin * plugin); +const GArray * ibus_engine_plugin_get_available_commands(IBusEnginePlugin * plugin); /** * Lookup a special command in ime lua extension. -- 2.7.4