[2958] in BarnOwl Developers

home help back first fref pref prev next nref lref last post

[PATCH 1/2] Make owl_keybinding new/delete instead of init/cleanup

daemon@ATHENA.MIT.EDU (David Benjamin)
Thu Mar 10 15:49:07 2011

From: David Benjamin <davidben@MIT.EDU>
To: barnowl-dev@mit.edu
Date: Thu, 10 Mar 2011 15:48:42 -0500

Valgrind is deeply disappointed in this code...

Hide owl_keybinding_make_keys again, so we don't construct half-baked
owl_keybinding instances. Instead allow for creating a dummy keybinding.
Also, initialize all fields of owl_keybinding, or freeing it afterwards
explodes. Also fix a memory leak in unbindkey.
---
 keybinding.c |   31 ++++++++++++++++---------------
 keymap.c     |   18 ++++++++----------
 owl.h        |    1 +
 3 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/keybinding.c b/keybinding.c
index 3b15cd9..a5c977f 100644
--- a/keybinding.c
+++ b/keybinding.c
@@ -10,30 +10,37 @@
  *      
  */
 
+static int owl_keybinding_make_keys(owl_keybinding *kb, const char *keyseq);
+
 /* sets up a new keybinding for a command */
-int owl_keybinding_init(owl_keybinding *kb, const char *keyseq, const char *command, void (*function_fn)(void), const char *desc)
+owl_keybinding *owl_keybinding_new(const char *keyseq, const char *command, void (*function_fn)(void), const char *desc)
 {
+  owl_keybinding *kb = g_new0(owl_keybinding, 1);
+
   owl_function_debugmsg("owl_keybinding_init: creating binding for <%s> with desc: <%s>", keyseq, desc);
-  if (command && !function_fn) {
+  if (command && function_fn) {
+    g_free(kb);
+    return NULL;
+  } else if (command && !function_fn) {
     kb->type = OWL_KEYBINDING_COMMAND;
   } else if (!command && function_fn) {
     kb->type = OWL_KEYBINDING_FUNCTION;
   } else {
-    return(-1);
+    kb->type = OWL_KEYBINDING_NOOP;
   }
 
   if (owl_keybinding_make_keys(kb, keyseq) != 0) {
-    return(-1);
+    g_free(kb);
+    return NULL;
   }
 
   if (command) kb->command = g_strdup(command);
   kb->function_fn = function_fn;
   if (desc) kb->desc = g_strdup(desc);
-  else kb->desc = NULL;
-  return(0);
+  return kb;
 }
 
-int owl_keybinding_make_keys(owl_keybinding *kb, const char *keyseq)
+static int owl_keybinding_make_keys(owl_keybinding *kb, const char *keyseq)
 {
   char **ktokens;
   int    nktokens, i;
@@ -58,18 +65,12 @@ int owl_keybinding_make_keys(owl_keybinding *kb, const char *keyseq)
   return(0);
 }
 
-/* Releases data associated with a keybinding */
-void owl_keybinding_cleanup(owl_keybinding *kb)
+/* Releases data associated with a keybinding, and the kb itself */
+void owl_keybinding_delete(owl_keybinding *kb)
 {
   if (kb->keys) g_free(kb->keys);
   if (kb->desc) g_free(kb->desc);
   if (kb->command) g_free(kb->command);
-}
-
-/* Releases data associated with a keybinding, and the kb itself */
-void owl_keybinding_delete(owl_keybinding *kb)
-{
-  owl_keybinding_cleanup(kb);
   g_free(kb);
 }
 
diff --git a/keymap.c b/keymap.c
index fdf8c65..13a07dc 100644
--- a/keymap.c
+++ b/keymap.c
@@ -37,11 +37,9 @@ int owl_keymap_create_binding(owl_keymap *km, const char *keyseq, const char *co
   owl_keybinding *kb, *curkb;
   int i;
 
-  if ((kb = g_new(owl_keybinding, 1)) == NULL) return(-1);
-  if (0 != owl_keybinding_init(kb, keyseq, command, function_fn, desc)) {
-    g_free(kb);
-    return(-1);
-  }
+  kb = owl_keybinding_new(keyseq, command, function_fn, desc);
+  if (kb == NULL)
+    return -1;
   /* see if another matching binding, and if so remove it.
    * otherwise just add this one. 
    */
@@ -62,20 +60,20 @@ int owl_keymap_remove_binding(owl_keymap *km, const char *keyseq)
   owl_keybinding *kb, *curkb;
   int i;
 
-  if ((kb = g_new(owl_keybinding, 1)) == NULL) return(-1);
-  if (0 != owl_keybinding_make_keys(kb, keyseq)) {
-    g_free(kb);
-    return(-1);
-  }
+  kb = owl_keybinding_new(keyseq, NULL, NULL, NULL);
+  if (kb == NULL)
+    return -1;
 
   for (i = owl_list_get_size(&km->bindings)-1; i >= 0; i--) {
     curkb = owl_list_get_element(&km->bindings, i);
     if (owl_keybinding_equal(curkb, kb)) {
       owl_list_remove_element(&km->bindings, i);
       owl_keybinding_delete(curkb);
+      owl_keybinding_delete(kb);
       return(0);
     }
   }
+  owl_keybinding_delete(kb);
   return(-2);
 }
 
diff --git a/owl.h b/owl.h
index 96640c6..56710ab 100644
--- a/owl.h
+++ b/owl.h
@@ -185,6 +185,7 @@ typedef void HV;
 
 #define OWL_KEYMAP_MAXSTACK     20
 
+#define OWL_KEYBINDING_NOOP     0   /* dummy binding that does nothing */
 #define OWL_KEYBINDING_COMMAND  1   /* command string */
 #define OWL_KEYBINDING_FUNCTION 2   /* function taking no args */
 
-- 
1.7.3.3.399.g06ddf


home help back first fref pref prev next nref lref last post