From 3e9077078ca72cdd8b25d8fc04938188c14cd4f6 Mon Sep 17 00:00:00 2001
From: Daniel Carl <danielcarl@gmx.de>
Date: Fri, 14 Jun 2013 02:32:04 +0200
Subject: [PATCH] Don't use string for command and params in keybinding.

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      | Bin 0 -> 21650 bytes
 src/command.c |  73 +++++++++++++++++++++++++-------------------------
 src/command.h |   7 ++---
 src/keybind.c |  34 +++++++++--------------
 src/keybind.h |  13 ++++-----
 5 files changed, 61 insertions(+), 66 deletions(-)
 create mode 100644 gmon.out

diff --git a/gmon.out b/gmon.out
new file mode 100644
index 0000000000000000000000000000000000000000..b8c8afe6643f3141abc883e1308294547fcd2d59
GIT binary patch
literal 21650
zcmeI4%WG3n5QlH-Ju-@gg0F&zMXjyxXhB->Q5V`&TP*bzd`4}nh_->c5Q>tO7TnZT
z-3Ubx3U1;qE`)%axREY=M1)%KK^96EB1&!1-#M8Z4zBzIeu0qt-I+5p=es9a=F+u+
z{#fwOEAujx#;ZoIGz38pVuQUG2l{&kqpZqBbc3HXKm#;D12jMbG(ZD1Km#;D12jMb
zG(ZD1Km#;D12jMbG(ZD1Km#;D12jMbG(ZD1Km#;D12jMbG(ZD1Km#;D12jMbG(ZD1
zKm#;D12jMbG(ZD1Km#;D12jMbG(ZD1Km#;D12jMbG(ZD1Km#;D12piz24drHL)kGM
zN()xRihv`lj5Jy3DwZQREffG(KZLR?g5sx8=0|Ylb13%j^jzAL$xwD$2;PM<x5kJo
zkOj1(h=V**Y{aG2qU@KY3c~;!aeZVelsg>?B{Z}V*R&Z8Uz}IC0k9D_!7yO!1%;{E
zP<{srB|v8cNnAXf)2XG($RxJy3e+q#vZBVwJiCQDz`h9LfVRaN>C!Z}Cb7&&0C#Rb
zDZr0foh=PWE>|c3hL&ib4DQ~G(()_IAhu~9qpaShPvJ(Lk=NUGO?Iu3T(!dGdW^Ep
z$c$Z+Xhdn;SYTnqhoTRy>&t1bPi{lGKxo%YY%GJ@Pim8q*?80k@G+*42CRt2xeu@t
zxHaQ|Zj^VB^CNjc0rFj>2xx;l2X&i`)PC1U7I5p0LJsf%hoW2!aIr%n4|s$}?;-`j
zp9KmjIGe_9U1Vy9k<pzB@fIUvZ5}+|t<a3f)<X)dfa&P@Sa|<R$4LMNqNZIoE$U<8
zI^M47FfP90klVkCj7<Rc_h}@7QEX(PjTF%RZjVOddyMq<Dx`cE@ge6!$%mS~UV&C0
zG6#%wG->H9Acw=`1}y>7?F!8aBbV`Z5qmL%sDrVC9t6--iDWvB96zjI%_3k?w~^&`
za~1~A7^#Y2?z9K<BZ)TcMN0cv7($wBYC%pKamUia)1-cXEZjcf!L#EyfKi`nAI==}
zBK3eu>EbC5z8&?T_N)h^=M;Wn@y`aWHjW+@NMn==jA2N7DBRCe9{Z0)&on^UEdVDZ
Pi^p!kjg#y%@>t<7x~113

literal 0
HcmV?d00001

diff --git a/src/command.c b/src/command.c
index 3788410..e087354 100644
--- a/src/command.c
+++ b/src/command.c
@@ -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);
 }
 
 /**
diff --git a/src/command.h b/src/command.h
index f0e101c..c562272 100644
--- a/src/command.h
+++ b/src/command.h
@@ -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);
diff --git a/src/keybind.c b/src/keybind.c
index 40a4360..b532e91 100644
--- a/src/keybind.c
+++ b/src/keybind.c
@@ -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);
 }
diff --git a/src/keybind.h b/src/keybind.h
index abeadf2..0c7470a 100644
--- a/src/keybind.h
+++ b/src/keybind.h
@@ -20,16 +20,17 @@
 #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);
-- 
2.20.1