lua extension (ime.register_command) in progress.
authorPeng Wu <epico@dhcp-65-116.nay.redhat.com>
Wed, 14 Apr 2010 09:56:47 +0000 (17:56 +0800)
committerPeng Wu <alexepico@gmail.com>
Wed, 19 May 2010 02:09:32 +0000 (10:09 +0800)
lua/lua-plugin-init.c
lua/lua-plugin.c
lua/lua-plugin.h

index 996b314..417dbbb 100644 (file)
@@ -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;
 }
index ac03e15..65ab9e4 100644 (file)
@@ -1,4 +1,5 @@
 #include <string.h>
+#include <stdlib.h>
 #include <lua.h>
 #include <lualib.h>
 #include <lauxlib.h>
@@ -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;
index 6284f02..d7118d6 100644 (file)
@@ -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.