Don't use string for command and params in keybinding.
authorDaniel Carl <danielcarl@gmx.de>
Fri, 14 Jun 2013 00:32:04 +0000 (02:32 +0200)
committerDaniel Carl <danielcarl@gmx.de>
Fri, 14 Jun 2013 00:35:32 +0000 (02:35 +0200)
It wasn't a good approach to use string for the command and it's params to
call if a keybinding is used. Now we translate the command string and
parameters to the right command function and a prepared Arg parameter. This
will save system resources during runtime.

gmon.out [new file with mode: 0644]
src/command.c
src/command.h
src/keybind.c
src/keybind.h

diff --git a/gmon.out b/gmon.out
new file mode 100644 (file)
index 0000000..b8c8afe
Binary files /dev/null and b/gmon.out differ
index 3788410..e087354 100644 (file)
@@ -36,7 +36,6 @@ typedef struct {
     Element *element;
 } OpenEditorData;
 
-typedef gboolean (*Command)(const Arg *arg);
 typedef struct {
     const char *name;
     const char *alias;
@@ -175,41 +174,15 @@ void command_cleanup(void)
     }
 }
 
-gboolean command_exists(const char *name)
-{
-    return g_hash_table_contains(short_commands, name)
-        || g_hash_table_contains(commands, name);
-}
-
-gboolean command_run(const char *name, const char *param)
-{
-    gboolean result;
-    Arg a;
-    CommandInfo *command = command_lookup(name);
-    if (!command) {
-        vb_echo(VB_MSG_ERROR, true, "Command '%s' not found", name);
-        vb_set_mode(VB_MODE_NORMAL, false);
-
-        return false;
-    }
-    a.i = command->arg.i;
-    a.s = g_strdup(param ? param : command->arg.s);
-    result = command->function(&a);
-    g_free(a.s);
-
-    return result;
-}
-
 /**
- * Runs a single command form string containing the command and possible
- * parameters.
+ * Parses given string and put corresponding command arg and command count in
+ * also given pointers.
+ * Returns true if parsing was successful.
  */
-gboolean command_run_string(const char *input)
+gboolean command_parse_from_string(const char *input, Command *func, Arg *arg, guint *count)
 {
-    gboolean success;
-    char *command = NULL, *str, **token;
-
-    vb_set_mode(VB_MODE_NORMAL, false);
+    char *command, *name, *str, **token;
+    CommandInfo *info;
 
     if (!input || *input == '\0') {
         return false;
@@ -220,7 +193,7 @@ gboolean command_run_string(const char *input)
     g_strchug(str);
 
     /* get a possible command count */
-    vb.state.count = g_ascii_strtoll(str, &command, 10);
+    *count = g_ascii_strtoll(str, &command, 10);
 
     /* split the input string into command and parameter part */
     token = g_strsplit(command, " ", 2);
@@ -230,10 +203,38 @@ gboolean command_run_string(const char *input)
         g_strfreev(token);
         return false;
     }
-    success = command_run(token[0], token[1] ? token[1] : NULL);
+
+    name = token[0];
+    info = command_lookup(name);
+    if (!info) {
+        vb_echo(VB_MSG_ERROR, true, "Command '%s' not found", name);
+        g_strfreev(token);
+        return false;
+    }
+
+    /* assigne the data to given pointers */
+    arg->i = info->arg.i;
+    arg->s = g_strdup(token[1] ? token[1] : info->arg.s);
+    *func = info->function;
+
     g_strfreev(token);
 
-    return success;
+    return true;
+}
+
+/**
+ * Runs a single command form string containing the command and possible
+ * parameters.
+ */
+gboolean command_run_string(const char *input)
+{
+    Command command = NULL;
+    Arg arg = {0};
+    if (!command_parse_from_string(input, &command, &arg, &vb.state.count)) {
+        return false;
+    }
+
+    return command(&arg);
 }
 
 /**
index f0e101c..c562272 100644 (file)
@@ -44,14 +44,15 @@ enum {
     COMMAND_SAVE_URI
 };
 
+typedef gboolean (*Command)(const Arg *arg);
+
 void command_init(void);
 GList *command_get_by_prefix(const char *prefix);
 void command_cleanup(void);
-gboolean command_exists(const char *name);
-gboolean command_run(const char *name, const char *param);
+gboolean command_parse_from_string(const char *input, Command *func, Arg *arg, guint *count);
 gboolean command_run_string(const char *input);
-
 gboolean command_run_multi(const Arg *arg);
+
 gboolean command_open(const Arg *arg);
 gboolean command_open_home(const Arg *arg);
 gboolean command_open_closed(const Arg *arg);
index 40a4360..b532e91 100644 (file)
@@ -56,35 +56,28 @@ void keybind_cleanup(void)
 
 gboolean keybind_add_from_string(char *keystring, const char *command, const Mode mode)
 {
-    char **token = NULL;
+    guint count;
     if (keystring == NULL || *keystring == '\0') {
         return false;
     }
 
-    /* split the input string into command and parameter part */
-    token = g_strsplit(command, " ", 2);
-    if (!token[0] || !command_exists(token[0])) {
-        g_strfreev(token);
+    Keybind *kb = g_new0(Keybind, 1);
+    kb->mode    = mode;
+    if (!command_parse_from_string(command, &kb->func, &kb->arg, &count)) {
         return false;
     }
 
-    Keybind *keybind = g_new0(Keybind, 1);
-    keybind->mode    = mode;
-    keybind->command = g_strdup(token[0]);
-    keybind->param   = g_strdup(token[1]);
-    g_strfreev(token);
+    string_to_keybind(keystring, kb);
 
-    string_to_keybind(keystring, keybind);
+    /* remove possible existing kbing */
+    keybind_remove(kb);
 
-    /* remove possible existing keybinding */
-    keybind_remove(keybind);
-
-    /* add the keybinding to the list */
-    keys = g_slist_prepend(keys, keybind);
+    /* add the kbing to the list */
+    keys = g_slist_prepend(keys, kb);
 
     /* save the modkey also in the modkey string if not exists already */
-    if (keybind->modkey && strchr(modkeys->str, keybind->modkey) == NULL) {
-        g_string_append_c(modkeys, keybind->modkey);
+    if (kb->modkey && strchr(modkeys->str, kb->modkey) == NULL) {
+        g_string_append_c(modkeys, kb->modkey);
     }
 
     return true;
@@ -286,7 +279,7 @@ static gboolean keypress_cb(WebKitWebView *webview, GdkEventKey *event)
         vb_update_statusbar();
 
         Keybind *keybind = (Keybind*)link->data;
-        command_run(keybind->command, keybind->param);
+        keybind->func(&keybind->arg);
 
         return true;
     }
@@ -296,7 +289,6 @@ static gboolean keypress_cb(WebKitWebView *webview, GdkEventKey *event)
 
 static void free_keybind(Keybind *keybind)
 {
-    g_free(keybind->command);
-    g_free(keybind->param);
+    g_free(keybind->arg.s);
     g_free(keybind);
 }
index abeadf2..0c7470a 100644 (file)
 #ifndef _KEYBIND_H
 #define _KEYBIND_H
 
+#include "command.h"
 #include <gdk/gdkkeysyms.h>
 #include <gdk/gdkkeysyms-compat.h>
 
 typedef struct {
-    int    mode;        /* mode maks for allowed browser modes */
-    guint  modkey;
-    guint  modmask;     /* modemask for the kayval */
-    guint  keyval;
-    char   *command;    /* command to run */
-    char   *param;
+    int     mode;        /* mode maks for allowed browser modes */
+    guint   modkey;
+    guint   modmask;     /* modemask for the kayval */
+    guint   keyval;
+    Command func;
+    Arg     arg;
 } Keybind;
 
 void keybind_init(void);